Whiplash141

Whip's Artificial Horizon - v37 FIX

May 19th, 2017
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 43.00 KB | None | 0 0
  1. /*
  2. /// Whip's Artificial Horizon Script v36 // - rev: 5/19/17
  3. _______________________________________________________________________          
  4. ///DESCRIPTION///  
  5.  
  6.     This code creates an Artificial Horizon indicator that takes into account your pitch and roll.
  7.     Also displayed on the screen is a vector indicator of velocity, speed display, and bearing display.
  8.     The colors of the display grid are configurable in the code.
  9.  
  10. _______________________________________________________________________          
  11. ///SETUP///  
  12.  
  13.     1.) Find the control seat, cockpit, remote control, or passenger seat that you wish to  
  14.         use as your horizon reference and add the name tag "Forward" somewhere in its name
  15.        
  16.     2.) Find the Text Panel or LCD Panel that you want to display the Artificial Horizon on and add the tag
  17.         "Horizon" somewhere in the name of the block
  18.         - Change the font to MONOSPACED
  19.        
  20.     3.) Make a program block and put this code in it
  21.    
  22.     4.) Make a timer with actions
  23.         - "Trigger Now" itself
  24.         - "Start" itself
  25.         - "Run with default argument" the program from step 1
  26.     5.) Start the timer
  27.    
  28.     6.) Fly around and enjoy :)
  29.  
  30. _______________________________________________________________________          
  31. ///WHIP'S NOTES///
  32.  
  33.     I vastly improved the code's number -> pixel conversion system.
  34.     If you notice any bugs, be sure to comment on the workshop page.
  35.  
  36.     Coded by Whiplash141
  37. */
  38.  
  39. //-------------------------------------------------
  40. //CONFIGURABLE VARAIABLES
  41. //-------------------------------------------------
  42.     const string controlSeatNameTag = "Forward";
  43.     const string readoutScreenNameTag = "Horizon";
  44.    
  45.     const double maximumVelocity = 100; //supports up to 999 m/s max speed
  46.    
  47.     const int updatesPerSecond = 10;
  48.    
  49.     const bool enableOrientationIndicator = true; //specifies if the orientation axes are drawn with the artificial horizon
  50.     const bool useVelocityMagnitude = false; //if the magnitude of the velocity should be accounted for in the velocity indicator
  51.     bool pauseWhenAway = true; //whether or not the code should stop executing when no-one is piloting the ship
  52.     bool ignoreBlocksOnConnectors = true;
  53.     bool shipControllersOnSameGrid = false; //if the control seats are on same grid as the ship
  54.     bool enableColorBlindMode = false; //this will change all colors to the colorblind default constants automatically
  55.  
  56. //-------------------------------------------------
  57. //COLOR DEFAULTS: You can change these
  58. // Colors are defined with RGB color codes where
  59. // RGB values can range from (0,0,0) [black] to (7,7,7) [white].
  60. // You can also use the presets defined in the COLOR PRESETS section
  61. //-------------------------------------------------
  62.     static char backgroundColor = CreateCustomColor(0, 0, 0);
  63.     static char horizonLineColor = CreateCustomColor(0, 0, 0);
  64.     static char groundColor = CreateCustomColor(1, 2, 1);
  65.     static char skyColor = CreateCustomColor(1, 1, 2);
  66.     static char textColor = CreateCustomColor(4, 0, 0);
  67.     static char numberColor = CreateCustomColor(4, 4, 0);
  68.     static char velocityIndicatorColor = CreateCustomColor(4, 4, 0);
  69.     static char spaceOrientationColor = CreateCustomColor(0, 0, 4);
  70.     static char planetaryOrientationColor = CreateCustomColor(4, 0, 0);
  71.  
  72. //-------------------------------------------------
  73. //COLORBLIND OVERRIDES: These will overwrite the constants above
  74. // if colorblind mode is enabled
  75. //-------------------------------------------------    
  76. void ColorBlindOverrides()
  77. {
  78.     //these define the colorblind color constants
  79.     backgroundColor = black;
  80.     horizonLineColor = lightGray;
  81.     groundColor = mediumGray;
  82.     skyColor = black;
  83.     textColor = yellow;
  84.     numberColor = yellow;
  85.     velocityIndicatorColor = cyan;
  86.     spaceOrientationColor = green;
  87.     planetaryOrientationColor = red;
  88. }
  89.  
  90. //===================================================
  91. //DO NOT TOUCH ANYTHING BELOW THIS
  92. //===================================================
  93.  
  94. //-------------------------------------------------
  95. //COLOR PRESETS: Do not change!!!
  96.  
  97. const char red = '\uE200'; //No touchey
  98. const char medRed = '\uE1C0'; //No touchey
  99. const char darkRed = '\uE180'; //No touchey
  100.  
  101. const char green = '\uE120'; //No touchey
  102. const char medGreen = '\uE118'; //No touchey
  103. const char darkGreen = '\uE110'; //No touchey
  104.  
  105. const char blue = '\uE104'; //No touchey
  106. const char medBlue = '\uE103'; //No touchey
  107. const char darkBlue = '\uE102'; //No touchey
  108.  
  109. const char yellow = '\uE220'; //No touchey
  110. const char medYellow = '\uE1D8'; //No touchey
  111. const char darkYellow = '\uE190'; //No touchey
  112.  
  113. const char magenta = '\uE204'; //No touchey
  114. const char medMagenta = '\uE1C3'; //No touchey
  115. const char darkMagenta = '\uE182'; //No touchey
  116.  
  117. const char cyan = '\uE124'; //No touchey
  118. const char medCyan = '\uE11B'; //No touchey
  119. const char darkCyan = '\uE112'; //No touchey
  120.  
  121. const char white = '\uE2FF'; //No touchey
  122. const char lightGray = '\uE1DB'; //No touchey
  123. const char mediumGray = '\uE192'; //No touchey
  124. const char darkGray = '\uE149'; //No touchey
  125. const char black = '\uE100'; //No touchey
  126.  
  127. //-------------------------------------------------
  128.  
  129. const int horizontalMidpoint = 26; //DO NOT TOUCH
  130. const int verticalMidpoint = 24; //DO NOT TOUCH
  131. const int horizontalGridSize = horizontalMidpoint * 2 - 1;
  132. const int verticalGridSize = verticalMidpoint * 2 - 1;
  133. const int planeSymbolWidth = 10; //measured from center to wingtip
  134.  
  135. int velocityRow = 0;
  136. int velocityColumn = 0;
  137.  
  138. const double timeCycleMax = 1 / (double)updatesPerSecond;
  139. const double rad2deg = 180 / Math.PI;
  140. const double deg2rad = Math.PI / 180;
  141. const double horizontalVelocityIncrement = maximumVelocity / (double)horizontalMidpoint;
  142. const double verticalVelocityIncrement = maximumVelocity / (double)verticalMidpoint;
  143. const double pitchIncrement = 90 / (double)verticalMidpoint;
  144. double timeCurrentCycle = 0;
  145. double shipSpeed = 0;
  146. double shipAcceleration = 0;
  147. double rollAngle = 0;
  148. double pitchAngle = 0;
  149. double bearingAngle = 0;
  150. double altitude = 0;
  151. double lastSpeed = 0;
  152.  
  153. bool isUpsideDown = false;
  154. bool inGravity = false;
  155. bool isBackwards = false;
  156.  
  157. string headingAndVelocityPixelString = "";
  158. string altitudePixelString = "";
  159.  
  160. Vector3D absoluteNorthVec = new Vector3D(0.342063708833718, -0.704407897782847, -0.621934025954579);
  161. //This is the rotation axis of the sun in vanilla
  162. //this was determined from the game files
  163.  
  164. IMyShipController reference = null;
  165.  
  166. Program()
  167. {
  168.     if (enableColorBlindMode)
  169.     {
  170.         ColorBlindOverrides();
  171.     }
  172.  
  173.     InitializeGrid();
  174.     InitializeCharacterLists();
  175. }
  176.  
  177. StringBuilder gridBuilder = new StringBuilder();
  178. List<string> emptyGrid = new List<string>();
  179. List<string> skyGrid = new List<string>();
  180. List<StringBuilder> horizonGrid = new List<StringBuilder>();
  181.  
  182. void InitializeGrid()
  183. {
  184.     for (int i = 1; i <= verticalGridSize; i++)
  185.     {
  186.         emptyGrid.Add(new String(backgroundColor, horizontalGridSize));
  187.     }
  188.  
  189.     for (int i = 1; i <= verticalGridSize; i++)
  190.     {
  191.         skyGrid.Add(new String(skyColor, horizontalGridSize));
  192.     }
  193.    
  194.     for (int i = 1; i <= verticalGridSize; i++)
  195.     {
  196.         horizonGrid.Add(new StringBuilder());
  197.     }
  198. }
  199.  
  200. static char CreateCustomColor(int r, int g, int b)
  201. {
  202.     return (char)(0xE100 + (MathHelper.Clamp(r, 0, 7) << 6) + (MathHelper.Clamp(g, 0, 7) << 3) + MathHelper.Clamp(b, 0, 7));
  203. }
  204.  
  205. void AssignGridDefaultValues(List<string> gridDefault)
  206. {
  207.     for (int i = 0; i < horizonGrid.Count; i++)
  208.     {
  209.         var thisStringBuilder = horizonGrid[i];
  210.         thisStringBuilder.Clear();
  211.         thisStringBuilder.Append(gridDefault[i]);
  212.     }
  213. }
  214.  
  215. void Main()
  216. {  
  217.     timeCurrentCycle += Runtime.TimeSinceLastRun.TotalSeconds;
  218.  
  219.     if (timeCurrentCycle >= timeCycleMax)
  220.     {
  221.         Echo("WMI Artificial Horizon is online... " + RunningSymbol());
  222.  
  223.         bool isProperlySetup = CheckBlocks();
  224.  
  225.         if (isProperlySetup)
  226.         {
  227.             GetRollPitchAndHeading();
  228.             GetVelocity();
  229.             GetNumberPixelString();
  230.             DrawGrid();
  231.         }
  232.  
  233.         timeCurrentCycle = 0;
  234.     }
  235.  
  236. }
  237.  
  238. //Whip's Get Subgrid Base Method
  239.  
  240. IMyCubeGrid GetSubgridBase(IMyTerminalBlock thisBlock)
  241. {
  242.     //small rotor head, large base
  243.     var rotorHeads = new List<IMyMotorRotor>();
  244.     GridTerminalSystem.GetBlocksOfType(rotorHeads, block => block.CubeGrid == thisBlock.CubeGrid && block.CubeGrid.GridSizeEnum.ToString() == "Small");
  245.    
  246.     foreach (var thisHead in rotorHeads)
  247.     {
  248.         if (thisHead.IsAttached && thisHead.Base.CubeGrid.GridSizeEnum.ToString() == "Large")
  249.             return thisHead.Base.CubeGrid;
  250.     }
  251.  
  252.     //large rotor base, small head
  253.     var rotorBases = new List<IMyMotorStator>();
  254.     GridTerminalSystem.GetBlocksOfType(rotorBases, block => block.CubeGrid == thisBlock.CubeGrid && block.CubeGrid.GridSizeEnum.ToString() == "Small");
  255.  
  256.     foreach (var thisBase in rotorBases)
  257.     {
  258.         if (thisBase.IsAttached && thisBase.TopGrid.GridSizeEnum.ToString() == "Large")
  259.             return thisBase.TopGrid;
  260.     }
  261.  
  262.     return null;
  263. }
  264.  
  265. bool CheckBlocks()
  266. {
  267.     var shipControllers = new List<IMyShipController>();
  268.    
  269.     GridTerminalSystem.GetBlocksOfType(shipControllers, shouldAddController);
  270.    
  271.     if (shipControllers.Count == 0)
  272.     {
  273.         Echo("Error: No ship controllers with name " + controlSeatNameTag + " detected");
  274.         return false;
  275.     }
  276.     else
  277.     {
  278.         reference = shipControllers[0];
  279.         return true;
  280.     }
  281. }
  282.  
  283. bool shouldAddController(IMyTerminalBlock block)
  284. {
  285.     if (shipControllersOnSameGrid)
  286.         return block.CustomName.Contains(controlSeatNameTag) && block.CubeGrid == Me.CubeGrid;
  287.     else
  288.         return block.CustomName.Contains(controlSeatNameTag);
  289. }
  290.  
  291. T GetClosestBlockOfType<T>(string name = "") where T : class, IMyTerminalBlock
  292. {
  293.  
  294.     var allBlocks = new List<T>();
  295.  
  296.     if (name == "")
  297.         GridTerminalSystem.GetBlocksOfType(allBlocks);
  298.     else
  299.         GridTerminalSystem.GetBlocksOfType(allBlocks, block => block.CustomName.Contains(name));
  300.  
  301.     if (allBlocks.Count == 0)
  302.     {
  303.         return null;
  304.     }
  305.  
  306.     var closestBlock = allBlocks[0];
  307.     var shortestDistance = Vector3D.DistanceSquared(Me.GetPosition(), closestBlock.GetPosition());
  308.     allBlocks.Remove(closestBlock); //remove this block from the list
  309.  
  310.     foreach (T thisBlock in allBlocks)
  311.     {
  312.         var thisDistance = Vector3D.DistanceSquared(Me.GetPosition(), thisBlock.GetPosition());
  313.  
  314.         if (thisDistance < shortestDistance)
  315.         {
  316.             closestBlock = thisBlock;
  317.             shortestDistance = thisDistance;
  318.         }
  319.         //otherwise move to next one
  320.     }
  321.  
  322.     return closestBlock;
  323. }
  324.  
  325. void AddToGrid(int row, int column, char color)
  326. {
  327.     if (row - 1 >= 0 && row - 1 < horizonGrid.Count)
  328.     {
  329.         var thisRow = horizonGrid[row - 1]; //need to offset index down one
  330.         if (column - 1 >= 0 && column - 1 < thisRow.Length)
  331.         {
  332.             thisRow[column - 1] = color;
  333.         }
  334.     }    
  335. }
  336.  
  337. void GetVelocity() //This method gets the relative position of the velocity vector on the screen
  338. {
  339.     var velocityVec = reference.GetShipVelocities().LinearVelocity;
  340.     shipSpeed = velocityVec.Length(); //raw speed of ship
  341.     shipAcceleration = Math.Abs(shipSpeed - lastSpeed) / timeCycleMax;
  342.     lastSpeed = shipSpeed;
  343.  
  344.     if (!useVelocityMagnitude && velocityVec.Length() > 0.1)
  345.     {
  346.         velocityVec = Vector3D.Normalize(velocityVec) * maximumVelocity;
  347.     }
  348.  
  349.     var rightVelocity = VectorProjection(velocityVec, reference.WorldMatrix.Right).Length() * VectorCompareDirection(velocityVec, reference.WorldMatrix.Right);
  350.     var upVelocity = VectorProjection(velocityVec, reference.WorldMatrix.Up).Length() * VectorCompareDirection(velocityVec, reference.WorldMatrix.Up);
  351.     var forwardVelocity = VectorProjection(velocityVec, reference.WorldMatrix.Forward).Length() * VectorCompareDirection(velocityVec, reference.WorldMatrix.Forward);
  352.  
  353.     if (rightVelocity < 0)
  354.     {
  355.         velocityColumn = horizontalMidpoint - (int)Math.Round(-rightVelocity / horizontalVelocityIncrement);
  356.     }
  357.     else
  358.     {
  359.         velocityColumn = horizontalMidpoint + (int)Math.Round(rightVelocity / horizontalVelocityIncrement);
  360.     }
  361.  
  362.     if (upVelocity < 0)
  363.     {
  364.         velocityRow = verticalMidpoint + (int)Math.Round(-upVelocity / verticalVelocityIncrement);
  365.     }
  366.     else
  367.     {
  368.         velocityRow = verticalMidpoint - (int)Math.Round(upVelocity / verticalVelocityIncrement);
  369.     }
  370.  
  371.     if (forwardVelocity < 0)
  372.     {
  373.         isBackwards = true;
  374.     }
  375.     else
  376.     {
  377.         isBackwards = false;
  378.     }
  379.  
  380.     if (!isBackwards) //draws prograde velocity  
  381.     {
  382.         /*
  383.         Looks like:
  384.               o
  385.               o
  386.             o o o
  387.         o o o   o o o
  388.             o o o
  389.         */
  390.  
  391.         AddToGrid(velocityRow + 1, velocityColumn, velocityIndicatorColor);
  392.         AddToGrid(velocityRow + 1, velocityColumn + 1, velocityIndicatorColor);
  393.         AddToGrid(velocityRow + 1, velocityColumn - 1, velocityIndicatorColor);
  394.         AddToGrid(velocityRow - 1, velocityColumn, velocityIndicatorColor);
  395.         AddToGrid(velocityRow - 1, velocityColumn + 1, velocityIndicatorColor);
  396.         AddToGrid(velocityRow - 1, velocityColumn - 1, velocityIndicatorColor);
  397.         AddToGrid(velocityRow, velocityColumn + 1, velocityIndicatorColor);
  398.         AddToGrid(velocityRow, velocityColumn - 1, velocityIndicatorColor);
  399.         AddToGrid(velocityRow - 2, velocityColumn, velocityIndicatorColor);
  400.         AddToGrid(velocityRow - 3, velocityColumn, velocityIndicatorColor);
  401.         AddToGrid(velocityRow, velocityColumn + 2, velocityIndicatorColor);
  402.         AddToGrid(velocityRow, velocityColumn + 3, velocityIndicatorColor);
  403.         AddToGrid(velocityRow, velocityColumn - 2, velocityIndicatorColor);
  404.         AddToGrid(velocityRow, velocityColumn - 3, velocityIndicatorColor);
  405.  
  406.     }
  407.     else //draws retrograde velocity
  408.     {
  409.         /*
  410.         Looks like:
  411.            o       o
  412.              o   o
  413.                o
  414.              o   o
  415.            o       o
  416.         */
  417.  
  418.         AddToGrid(velocityRow, velocityColumn, velocityIndicatorColor);
  419.         AddToGrid(velocityRow - 1, velocityColumn + 1, velocityIndicatorColor);
  420.         AddToGrid(velocityRow - 1, velocityColumn - 1, velocityIndicatorColor);
  421.         AddToGrid(velocityRow + 1, velocityColumn + 1, velocityIndicatorColor);
  422.         AddToGrid(velocityRow + 1, velocityColumn - 1, velocityIndicatorColor);
  423.         AddToGrid(velocityRow - 2, velocityColumn + 2, velocityIndicatorColor);
  424.         AddToGrid(velocityRow - 2, velocityColumn - 2, velocityIndicatorColor);
  425.         AddToGrid(velocityRow + 2, velocityColumn + 2, velocityIndicatorColor);
  426.         AddToGrid(velocityRow + 2, velocityColumn - 2, velocityIndicatorColor);
  427.     }
  428.  
  429.     //Echo("Ship Velocity: " + Math.Round(shipSpeed, 2).ToString());
  430. }
  431.  
  432. void DrawOrientationIndicator()
  433. {
  434.     if (!inGravity)
  435.     {
  436.         for (int j = 1; j <= horizontalGridSize; j++)
  437.         {
  438.             AddToGrid(verticalMidpoint, j, spaceOrientationColor); //draws a horizontal line
  439.         }
  440.  
  441.         for (int j = 1; j <= verticalGridSize; j++)
  442.         {
  443.             AddToGrid(j, horizontalMidpoint, spaceOrientationColor); //draws a vertical line
  444.         }
  445.     }
  446.     else //draws a nose orientation indicator that looks like  --- W ---
  447.     {
  448.         AddToGrid(verticalMidpoint, horizontalMidpoint, planetaryOrientationColor);
  449.         AddToGrid(verticalMidpoint + 1, horizontalMidpoint + 1, planetaryOrientationColor);
  450.         AddToGrid(verticalMidpoint + 1, horizontalMidpoint - 1, planetaryOrientationColor);
  451.         AddToGrid(verticalMidpoint, horizontalMidpoint - 2, planetaryOrientationColor);
  452.         AddToGrid(verticalMidpoint, horizontalMidpoint + 2, planetaryOrientationColor);
  453.         AddToGrid(verticalMidpoint - 1, horizontalMidpoint - 3, planetaryOrientationColor);
  454.         AddToGrid(verticalMidpoint - 1, horizontalMidpoint + 3, planetaryOrientationColor);
  455.  
  456.         for (int j = horizontalMidpoint - planeSymbolWidth; j < horizontalMidpoint - 4; j++)
  457.         {
  458.             AddToGrid(verticalMidpoint, j, planetaryOrientationColor);
  459.         }
  460.  
  461.         for (int j = horizontalMidpoint + 5; j <= horizontalMidpoint + planeSymbolWidth; j++)
  462.         {
  463.             AddToGrid(verticalMidpoint, j, planetaryOrientationColor);
  464.         }
  465.     }
  466. }
  467.  
  468. void GetRollPitchAndHeading()
  469. {
  470.     /// Get Needed Vectors ///
  471.     Vector3D shipForwardVec = reference.WorldMatrix.Forward;
  472.     Vector3D shipLeftVec = reference.WorldMatrix.Left;
  473.     Vector3D shipDownVec = reference.WorldMatrix.Down;
  474.     Vector3D gravityVec = reference.GetNaturalGravity();
  475.     Vector3D planetRelativeLeftVec = shipForwardVec.Cross(gravityVec);
  476.  
  477.     reference.TryGetPlanetElevation(MyPlanetElevation.Surface, out altitude);
  478.  
  479.     if (gravityVec.LengthSquared() == 0)
  480.     {
  481.         Echo("No natural gravity field detected");
  482.         inGravity = false;
  483.         AssignGridDefaultValues(emptyGrid);
  484.         DrawOrientationIndicator();
  485.         return;
  486.     }
  487.    
  488.     inGravity = true;
  489.     AssignGridDefaultValues(skyGrid);
  490.  
  491.     isUpsideDown = false;
  492.  
  493.     /// Compute Pitch and Roll ///
  494.     if (!VectorIsSameDirection(shipDownVec, gravityVec))
  495.     {
  496.         isUpsideDown = true;
  497.     }
  498.  
  499.     rollAngle = VectorAngleBetween(shipLeftVec, planetRelativeLeftVec) * rad2deg;
  500.  
  501.     rollAngle *= VectorCompareDirection(VectorProjection(shipLeftVec, gravityVec), gravityVec); //ccw is positive
  502.  
  503.     if (rollAngle > 90 || rollAngle < -90)
  504.     {
  505.         rollAngle = 180 - rollAngle; //accounts for upsidedown
  506.     }
  507.  
  508.     pitchAngle = VectorAngleBetween(shipForwardVec, gravityVec) * rad2deg; //angle from nose direction to gravity
  509.     pitchAngle -= 90; //as 90 degrees is level with ground
  510.  
  511.     //Echo("Roll angle: " + Math.Round(rollAngle, 2).ToString() + "\nPitch angle: " + Math.Round(pitchAngle, 2).ToString());
  512.     GetHorizonLine(); //gets horizon line
  513.  
  514.     if (enableOrientationIndicator)
  515.     {
  516.         DrawOrientationIndicator(); //draws orientation indicator
  517.     }
  518.  
  519.     /// Compute Bearing ///
  520.     //get east vector  
  521.     Vector3D relativeEastVec = gravityVec.Cross(absoluteNorthVec);
  522.  
  523.     //get relative north vector  
  524.     Vector3D relativeNorthVec = relativeEastVec.Cross(gravityVec);
  525.  
  526.     //project forward vector onto a plane comprised of the north and east vectors  
  527.     Vector3D forwardProjNorthVec = VectorProjection(shipForwardVec, relativeNorthVec);
  528.     Vector3D forwardProjEastVec = VectorProjection(shipForwardVec, relativeEastVec);
  529.     Vector3D forwardProjPlaneVec = forwardProjEastVec + forwardProjNorthVec;
  530.  
  531.     //find angle from abs north to projected forward vector measured clockwise  
  532.     bearingAngle = VectorAngleBetween(forwardProjPlaneVec, relativeNorthVec) * rad2deg;
  533.     if (VectorIsSameDirection(shipForwardVec, relativeEastVec) == false)
  534.     {
  535.         bearingAngle = 360 - bearingAngle; //because of how the angle is measured  
  536.     }
  537.  
  538.     //Echo("Bearing: " + Math.Round(bearingAngle, 2).ToString());
  539. }
  540.  
  541. void GetHorizonLine()
  542. {
  543.     int horizontalOffset = (int)Math.Round(pitchAngle / pitchIncrement * Math.Sin(rollAngle * deg2rad)); //offset of every point in the horizontal direction
  544.     int verticalOffset = (int)Math.Round(pitchAngle / pitchIncrement * Math.Cos(rollAngle * deg2rad)); //offset of every point in the vertical direction
  545.  
  546.     double constant = 1;
  547.     if (isUpsideDown)
  548.     {
  549.         verticalOffset *= -1;
  550.         constant = -1;
  551.     }
  552.  
  553.     int adjustedMidpoint = verticalMidpoint - horizontalOffset; //offsets our midpoint horizontally due to pitch and roll
  554.  
  555.     for (int i = 1; i <= horizontalGridSize; i++) //rows
  556.     {
  557.         int thisHeight = 0;
  558.  
  559.         if (i < verticalMidpoint)
  560.         {
  561.             thisHeight = adjustedMidpoint - (int)Math.Round((adjustedMidpoint - i) * Math.Tan(constant * rollAngle * deg2rad));
  562.         }
  563.         else
  564.         {
  565.             thisHeight = adjustedMidpoint + (int)Math.Round((i - adjustedMidpoint) * Math.Tan(constant * rollAngle * deg2rad));
  566.         }
  567.  
  568.         thisHeight += verticalOffset; //offset our computed height by this value
  569.  
  570.         AddToGrid(thisHeight, i, horizonLineColor);
  571.  
  572.         for (int j = 1; j <= verticalGridSize; j++)
  573.         {
  574.             if (!isUpsideDown)
  575.             {
  576.                 if (j > thisHeight)
  577.                 {
  578.                     AddToGrid(j, i, groundColor);
  579.                 }
  580.             }
  581.             else
  582.             {
  583.                 if (j < thisHeight)
  584.                 {
  585.                     AddToGrid(j, i, groundColor);
  586.                 }
  587.             }
  588.            
  589.         }
  590.     }
  591. }
  592.  
  593.  
  594. void DrawGrid() //draws graphical grid
  595. {
  596.     gridBuilder.Clear();
  597.    
  598.     gridBuilder.Append(headingAndVelocityPixelString).Append("\n");
  599.    
  600.     foreach (StringBuilder thisRow in horizonGrid)
  601.     {
  602.         gridBuilder.Append("\ue077").AppendLine(thisRow.ToString());
  603.     }
  604.  
  605.     gridBuilder.Append("\n" + altitudePixelString);
  606.    
  607.     WriteToTextPanel(readoutScreenNameTag, gridBuilder.ToString());
  608. }
  609.  
  610. void GetNumberPixelString() //gets a graphical string from velocity and heading
  611. {
  612.     //Velocity Splitting
  613.  
  614.     string velocityString = string.Format("{0:000}", shipSpeed);
  615.     string altitudeString = string.Format("{0:00000}", altitude);
  616.     string headingOrAccelString = "";
  617.     if (inGravity)
  618.         headingOrAccelString = string.Format("{0:000}", bearingAngle);
  619.     else
  620.         headingOrAccelString = string.Format("{0:000}", shipAcceleration);
  621.  
  622.     DecomposeNumber velocityStruct;
  623.     DecomposeNumber headingOrAccelStruct;
  624.     DecomposeNumber altitudeStruct;
  625.  
  626.     List<string> velocityWordStruct = GetPixelsFromNumber("spd");
  627.     List<string> altitudeWordStruct = GetPixelsFromNumber("alt");
  628.     List<string> headingOrAccelWordStruct;
  629.  
  630.     if (inGravity)
  631.         headingOrAccelWordStruct = GetPixelsFromNumber("hdg");
  632.     else
  633.         headingOrAccelWordStruct = GetPixelsFromNumber("acc");
  634.  
  635.  
  636.     List<string> space = new List<string>()
  637.     {
  638.         "\ue076",
  639.         "\ue076",
  640.         "\ue076",
  641.         "\ue076",
  642.         "\ue076"
  643.     };
  644.  
  645.     velocityStruct.Hundreds = GetPixelsFromNumber(velocityString.Substring(0, 1));
  646.     velocityStruct.Tens = GetPixelsFromNumber(velocityString.Substring(1, 1));
  647.     velocityStruct.Ones = GetPixelsFromNumber(velocityString.Substring(2, 1));
  648.  
  649.     headingOrAccelStruct.Hundreds = GetPixelsFromNumber(headingOrAccelString.Substring(0, 1));
  650.     headingOrAccelStruct.Tens = GetPixelsFromNumber(headingOrAccelString.Substring(1, 1));
  651.     headingOrAccelStruct.Ones = GetPixelsFromNumber(headingOrAccelString.Substring(2, 1));
  652.  
  653.     altitudeStruct.TenThousands = GetPixelsFromNumber(altitudeString.Substring(0, 1));
  654.     altitudeStruct.Thousands = GetPixelsFromNumber(altitudeString.Substring(1, 1));
  655.     altitudeStruct.Hundreds = GetPixelsFromNumber(altitudeString.Substring(2, 1));
  656.     altitudeStruct.Tens = GetPixelsFromNumber(altitudeString.Substring(3, 1));
  657.     altitudeStruct.Ones = GetPixelsFromNumber(altitudeString.Substring(4, 1));
  658.  
  659.     List<List<string>> headingAndVelocityCharacterList = new List<List<string>>()
  660.     {
  661.         space, velocityWordStruct, velocityStruct.Hundreds, velocityStruct.Tens, velocityStruct.Ones, space, headingOrAccelWordStruct, headingOrAccelStruct.Hundreds, headingOrAccelStruct.Tens, headingOrAccelStruct.Ones
  662.     };
  663.  
  664.     List<List<string>> altitudeCharacterList = new List<List<string>>();
  665.     if (inGravity)
  666.     {
  667.         altitudeCharacterList = new List<List<string>>()
  668.         {
  669.             altitudeWordStruct, altitudeStruct.TenThousands, altitudeStruct.Thousands, altitudeStruct.Hundreds, altitudeStruct.Tens, altitudeStruct.Ones
  670.         };
  671.     }
  672.     else
  673.     {
  674.         altitudeCharacterList = new List<List<string>>()
  675.         {
  676.             altitudeWordStruct, GetPixelsFromNumber("no grav")
  677.         };
  678.     }
  679.  
  680.     headingAndVelocityPixelString = ConstructPixelString(headingAndVelocityCharacterList);
  681.     altitudePixelString = ConstructPixelString(altitudeCharacterList);
  682. }
  683.  
  684. StringBuilder pixelString = new StringBuilder();
  685. string ConstructPixelString(List<List<string>> pixelCharacters) //each list has 1-5 rows
  686. {
  687.     pixelString.Clear();
  688.  
  689.     for (int i = 0; i < 5; i++)
  690.     {
  691.         foreach (List<string> thisCharacter in pixelCharacters)
  692.         {
  693.             pixelString.Append(thisCharacter[i]);
  694.         }
  695.         pixelString.Append("\n");
  696.     }
  697.  
  698.     return pixelString.ToString();
  699. }
  700.  
  701. struct DecomposeNumber
  702. {
  703.     public List<string> Ones;
  704.     public List<string> Tens;
  705.     public List<string> Hundreds;
  706.     public List<string> Thousands;
  707.     public List<string> TenThousands;
  708. }
  709.  
  710.  
  711. const string largeSpace = "\ue078\ue077";
  712. List<string> GetPixelsFromNumber(string num) //gets graphical representation from a double
  713. {
  714.     List<string> numberGraphicRows = new List<string>();
  715.  
  716.     switch (num)
  717.     {
  718.         case "0":
  719.             numberGraphicRows = rows0;
  720.             break;
  721.  
  722.         case "1":
  723.             numberGraphicRows = rows1;
  724.             break;
  725.  
  726.         case "2":
  727.             numberGraphicRows = rows2;
  728.            break;
  729.  
  730.         case "3":
  731.             numberGraphicRows = rows3;
  732.             break;
  733.  
  734.         case "4":
  735.             numberGraphicRows = rows4;
  736.             break;
  737.  
  738.         case "5":
  739.             numberGraphicRows = rows5;
  740.             break;
  741.  
  742.         case "6":
  743.             numberGraphicRows = rows6;
  744.             break;
  745.  
  746.         case "7":
  747.             numberGraphicRows = rows7;
  748.             break;
  749.  
  750.         case "8":
  751.             numberGraphicRows = rows8;
  752.             break;
  753.  
  754.         case "9":
  755.             numberGraphicRows = rows9;
  756.             break;
  757.  
  758.         case "spd":
  759.             numberGraphicRows = rowsSpd;
  760.             break;
  761.  
  762.         case "hdg":
  763.             numberGraphicRows = rowsHdg;
  764.             break;
  765.  
  766.         case "alt":
  767.             numberGraphicRows = rowsAlt;
  768.             break;
  769.  
  770.         case "no grav":
  771.             numberGraphicRows = rowsNoGrav;
  772.             break;
  773.  
  774.         case "acc":
  775.             numberGraphicRows = rowsAcc;
  776.             break;
  777.  
  778.         default:
  779.             numberGraphicRows = rows0;
  780.             break;
  781.     }
  782.     return numberGraphicRows;
  783. }
  784.  
  785. void WriteToTextPanel(string textPanelName, string textToWrite, bool append = false)
  786. {
  787.     var listScreens = new List<IMyTextPanel>();
  788.    
  789.     if (!ignoreBlocksOnConnectors)
  790.     {
  791.         GridTerminalSystem.GetBlocksOfType(listScreens, block => block.CustomName.Contains(textPanelName));
  792.     }
  793.     else
  794.     {
  795.         var connectors = new List<IMyShipConnector>();
  796.         var connectorGrids = new List<IMyCubeGrid>();
  797.         GridTerminalSystem.GetBlocksOfType(connectors, block => block.CubeGrid == Me.CubeGrid);
  798.         foreach (IMyShipConnector thisConnector in connectors)
  799.         {
  800.             if (thisConnector.Status == MyShipConnectorStatus.Connected)
  801.             {
  802.                 connectorGrids.Add(thisConnector.OtherConnector.CubeGrid);
  803.             }
  804.         }
  805.            
  806.         GridTerminalSystem.GetBlocksOfType(listScreens, block => block.CustomName.Contains(textPanelName) && !connectorGrids.Contains(block.CubeGrid));
  807.     }
  808.  
  809.     if (listScreens.Count == 0)
  810.     {
  811.         Echo("Error: No text panel with name tag '" + textPanelName + "' was found");
  812.         return;
  813.     }
  814.     else
  815.     {
  816.         for (int i = 0; i < listScreens.Count; i++)
  817.         {
  818.             var thisScreen = listScreens[i];
  819.             thisScreen.WritePublicText(textToWrite, append);
  820.             thisScreen.ShowTextureOnScreen();
  821.             thisScreen.ShowPublicTextOnScreen();
  822.             thisScreen.SetValue("FontSize", 0.3f); //for large grid
  823.             thisScreen.SetValue<long>("Font", 1147350002);
  824.         }
  825.     }
  826. }
  827.  
  828. int VectorCompareDirection(Vector3D a, Vector3D b) //returns -1 if vectors return negative dot product
  829. {
  830.     double check = a.Dot(b);
  831.     if (check < 0)
  832.         return -1;
  833.     else
  834.         return 1;
  835. }
  836.  
  837. double VectorAngleBetween(Vector3D a, Vector3D b) //returns radians
  838. {
  839.     if (a.LengthSquared() == 0 || b.LengthSquared() == 0)
  840.         return 0;
  841.     else
  842.         return Math.Acos(MathHelper.Clamp(a.Dot(b) / a.Length() / b.Length(), -1, 1));
  843. }
  844.  
  845. Vector3D VectorProjection(Vector3D a, Vector3D b) //projects a onto b
  846. {
  847.     Vector3D projection = a.Dot(b) / b.LengthSquared() * b;
  848.     return projection;
  849. }
  850.  
  851. bool VectorIsSameDirection(Vector3D a, Vector3D b) //returns true if vectors produce positive dot product
  852. {
  853.     double check = a.Dot(b);
  854.     if (check < 0)
  855.         return false;
  856.     else
  857.         return true;
  858. }
  859.  
  860. //Whip's Running Symbol Method v6
  861. int runningSymbolVariant = 0;
  862. string RunningSymbol()
  863. {
  864.     runningSymbolVariant++;
  865.     string strRunningSymbol = "";
  866.    
  867.     if (runningSymbolVariant == 0)
  868.         strRunningSymbol = "|";
  869.     else if (runningSymbolVariant == 1)
  870.         strRunningSymbol = "/";
  871.     else if (runningSymbolVariant == 2)
  872.         strRunningSymbol = "--";
  873.     else if (runningSymbolVariant == 3)
  874.     {
  875.         strRunningSymbol = "\\";
  876.         runningSymbolVariant = -1;
  877.     }
  878.  
  879.     return strRunningSymbol;
  880. }
  881.  
  882. List<string> rows0 = new List<string>();
  883. List<string> rows1 = new List<string>();
  884. List<string> rows2 = new List<string>();
  885. List<string> rows3 = new List<string>();
  886. List<string> rows4 = new List<string>();
  887. List<string> rows5 = new List<string>();
  888. List<string> rows6 = new List<string>();
  889. List<string> rows7 = new List<string>();
  890. List<string> rows8 = new List<string>();
  891. List<string> rows9 = new List<string>();
  892. List<string> rowsSpd = new List<string>();
  893. List<string> rowsHdg = new List<string>();
  894. List<string> rowsAlt = new List<string>();
  895. List<string> rowsNoGrav = new List<string>();
  896. List<string> rowsAcc= new List<string>();
  897.  
  898. void InitializeCharacterLists()
  899. {
  900.     #region character_list_declaration
  901.     rows0 = new List<string>()
  902.     {
  903.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  904.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor }),
  905.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor }),
  906.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor }),
  907.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor })
  908.     };
  909.  
  910.     rows1 = new List<string>()
  911.     {
  912.         new string(new char[] { backgroundColor, numberColor, backgroundColor, backgroundColor }),
  913.         new string(new char[] { backgroundColor, numberColor, backgroundColor, backgroundColor }),
  914.         new string(new char[] { backgroundColor, numberColor, backgroundColor, backgroundColor }),
  915.         new string(new char[] { backgroundColor, numberColor, backgroundColor, backgroundColor }),
  916.         new string(new char[] { backgroundColor, numberColor, backgroundColor, backgroundColor })
  917.     };
  918.  
  919.     rows2 = new List<string>()
  920.     {
  921.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  922.         new string(new char[] { backgroundColor, backgroundColor, numberColor, backgroundColor }),
  923.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  924.         new string(new char[] { numberColor, backgroundColor, backgroundColor, backgroundColor }),
  925.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor })
  926.     };
  927.  
  928.     rows3 = new List<string>()
  929.     {
  930.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  931.         new string(new char[] { backgroundColor, backgroundColor, numberColor, backgroundColor }),
  932.         new string(new char[] { backgroundColor, numberColor, numberColor, backgroundColor }),
  933.         new string(new char[] { backgroundColor, backgroundColor, numberColor, backgroundColor }),
  934.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor })
  935.     };
  936.  
  937.     rows4 = new List<string>()
  938.     {
  939.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor }),
  940.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor }),
  941.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  942.         new string(new char[] { backgroundColor, backgroundColor, numberColor, backgroundColor }),
  943.         new string(new char[] { backgroundColor, backgroundColor, numberColor, backgroundColor })
  944.     };
  945.  
  946.     rows5 = new List<string>()
  947.     {
  948.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  949.         new string(new char[] { numberColor, backgroundColor, backgroundColor, backgroundColor }),
  950.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  951.         new string(new char[] { backgroundColor, backgroundColor, numberColor, backgroundColor }),
  952.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor })
  953.     };
  954.  
  955.     rows6 = new List<string>()
  956.     {
  957.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  958.         new string(new char[] { numberColor, backgroundColor, backgroundColor, backgroundColor }),
  959.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  960.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor }),
  961.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor })
  962.     };
  963.  
  964.     rows7 = new List<string>()
  965.     {
  966.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  967.         new string(new char[] { backgroundColor, backgroundColor, numberColor, backgroundColor }),
  968.         new string(new char[] { backgroundColor, numberColor, backgroundColor, backgroundColor }),
  969.         new string(new char[] { backgroundColor, numberColor, backgroundColor, backgroundColor }),
  970.         new string(new char[] { backgroundColor, numberColor, backgroundColor, backgroundColor })
  971.     };
  972.  
  973.     rows8 = new List<string>()
  974.     {
  975.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  976.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor }),
  977.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  978.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor }),
  979.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor })
  980.     };
  981.  
  982.     rows9 = new List<string>()
  983.     {
  984.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  985.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor }),
  986.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor }),
  987.         new string(new char[] { backgroundColor, backgroundColor, numberColor, backgroundColor }),
  988.         new string(new char[] { numberColor, numberColor, numberColor, backgroundColor })
  989.     };
  990.  
  991.     rowsSpd = new List<string>()
  992.     {
  993.         new string(new char[] { backgroundColor, textColor, textColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor }),
  994.         new string(new char[] { textColor, backgroundColor, backgroundColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor }),
  995.         new string(new char[] { textColor, textColor, textColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor }),
  996.         new string(new char[] { backgroundColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor }),
  997.         new string(new char[] { textColor, textColor, backgroundColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor })
  998.     };
  999.  
  1000.     rowsHdg = new List<string>()
  1001.     {
  1002.         new string(new char[] { textColor, backgroundColor, textColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor }),
  1003.         new string(new char[] { textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor, textColor, backgroundColor }),
  1004.         new string(new char[] { textColor, textColor, textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, backgroundColor }),
  1005.         new string(new char[] { textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor }),
  1006.         new string(new char[] { textColor, backgroundColor, textColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor })
  1007.     };
  1008.  
  1009.     rowsAlt = new List<string>()
  1010.     {
  1011.         largeSpace + new string(new char[] { backgroundColor, textColor, backgroundColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, textColor, textColor, textColor, backgroundColor, backgroundColor, backgroundColor }),
  1012.         largeSpace + new string(new char[] { textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor, textColor, backgroundColor, backgroundColor, textColor, backgroundColor }),
  1013.         largeSpace + new string(new char[] { textColor, textColor, textColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor }),
  1014.         largeSpace + new string(new char[] { textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor, textColor, backgroundColor, backgroundColor, textColor, backgroundColor }),
  1015.         largeSpace + new string(new char[] { textColor, backgroundColor, textColor, backgroundColor, textColor, textColor, textColor, backgroundColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor })
  1016.     };
  1017.  
  1018.     rowsNoGrav = new List<string>()
  1019.     {
  1020.         new string(new char[] { numberColor, numberColor, backgroundColor, backgroundColor, backgroundColor, numberColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor, numberColor, numberColor, backgroundColor, backgroundColor, numberColor, numberColor, backgroundColor, backgroundColor, backgroundColor, numberColor, backgroundColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor }),
  1021.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, backgroundColor, numberColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor }),
  1022.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, backgroundColor, numberColor, backgroundColor, numberColor, numberColor, backgroundColor, numberColor, numberColor, backgroundColor, backgroundColor, numberColor, numberColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor }),
  1023.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, backgroundColor, numberColor, backgroundColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, numberColor, backgroundColor, backgroundColor }),
  1024.         new string(new char[] { numberColor, backgroundColor, numberColor, backgroundColor, backgroundColor, numberColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor, numberColor, numberColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, numberColor, backgroundColor, backgroundColor, backgroundColor })
  1025.     };
  1026.  
  1027.     rowsAcc= new List<string>()
  1028.     {
  1029.         new string(new char[] { backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, backgroundColor }),
  1030.         new string(new char[] { textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, textColor, backgroundColor }),
  1031.         new string(new char[] { textColor, textColor, textColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor, backgroundColor }),
  1032.         new string(new char[] { textColor, backgroundColor, textColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, textColor, backgroundColor, backgroundColor, backgroundColor, textColor, backgroundColor }),
  1033.         new string(new char[] { textColor, backgroundColor, textColor, backgroundColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, textColor, textColor, backgroundColor, backgroundColor, backgroundColor })
  1034.     };
  1035.     #endregion
  1036. }
  1037.  
  1038. /*          
  1039. ///WHAT'S CHANGED///
  1040.  
  1041. - Fixed incorrect display of pitch
  1042. - Fixed some variable name typos
  1043. - This code can now display altitude (only in DEV branch!)
  1044. - Removed character limit bypass
  1045. - Clamped arccosine inputs to avoid NaN errors
  1046. - Used string builder instead of string to help performance
  1047. - Added in monospace support - v29
  1048. - Added more color presets - v30
  1049. - Added in a custom color method - v30
  1050. - Fixed colorblind mode settings not updating the text and number colors - v31
  1051. - Added automatic font selection - 31
  1052. - [REVERTED] ~~Code now ignores programs on other grids connected via connectors - v32~~
  1053. - Changed color defaults - v35
  1054. - [REVERTED] ~~Added method to only consider grids that are the same as the program or are attached via rotor trick - v34~~ - v37
  1055. */
Advertisement
Add Comment
Please, Sign In to add comment