VOID_Core: Change to use the same Toolbar button for both editor and flight drivers.
VOID_Core: Change to use the same Toolbar button for both editor and flight drivers.

file:b/IntCollection.cs (new)
  //
  // IntCollection.cs
  //
  // Author:
  // toadicus <>
  //
  // Copyright (c) 2013 toadicus
  //
  // This program is free software: you can redistribute it and/or modify
  // it under the terms of the GNU General Public License as published by
  // the Free Software Foundation, either version 3 of the License, or
  // (at your option) any later version.
  //
  // This program is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  // GNU General Public License for more details.
  //
  // You should have received a copy of the GNU General Public License
  // along with this program. If not, see <http://www.gnu.org/licenses/>.
  using System;
 
  namespace VOID
  {
  public class IntCollection
  {
  public static implicit operator long(IntCollection c)
  {
  return c.collection;
  }
 
  protected long mask;
 
  public long collection { get; protected set; }
  public ushort maxCount { get; protected set; }
  public ushort wordLength { get; protected set; }
 
  public IntCollection (ushort wordLength = 4, long initialCollection = 0)
  {
  this.collection = initialCollection;
  this.wordLength = wordLength;
  this.maxCount = (ushort)((sizeof(long) * 8 - 1) / wordLength);
  this.mask = ((1 << this.wordLength) - 1);
  }
 
  public ushort this[int idx]
  {
  get {
  if (idx < 0) {
  idx += this.maxCount;
  }
 
  if (idx >= maxCount || idx < 0) {
  throw new IndexOutOfRangeException ();
  }
 
  idx *= wordLength;
 
  return (ushort)((this.collection & (this.mask << idx)) >> idx);
  }
  set {
  if (idx < 0) {
  idx += this.maxCount;
  }
 
  if (idx >= maxCount || idx < 0) {
  throw new IndexOutOfRangeException ();
  }
 
  idx *= wordLength;
 
  long packvalue = value & this.mask;
 
  this.collection &= ~(this.mask << idx);
  this.collection |= packvalue << idx;
  }
  }
  }
  }
 
 
file:a/Tools.cs -> file:b/Tools.cs
// //
// Tools.cs // Tools.cs
// //
// Author: // Author:
// toadicus // toadicus
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
// This software uses VesselSimulator and Engineer.Extensions from Engineer Redux. // This software uses VesselSimulator and Engineer.Extensions from Engineer Redux.
// Engineer Redux (c) 2013 cybutek // Engineer Redux (c) 2013 cybutek
// Used by permission. // Used by permission.
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
   
   
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public static class VOIDLabels public static class VOIDLabels
{ {
public static string void_primary = "Primary"; public static string void_primary = "Primary";
public static string void_altitude_asl = "Altitude (ASL)"; public static string void_altitude_asl = "Altitude (ASL)";
public static string void_velocity = "Velocity"; public static string void_velocity = "Velocity";
public static string void_apoapsis = "Apoapsis"; public static string void_apoapsis = "Apoapsis";
public static string void_periapsis = "Periapsis"; public static string void_periapsis = "Periapsis";
} }
   
public static class Tools public static class Tools
{ {
// Toadicus edit: Added re-implementation of the CBAttributeMap.GetAtt function that does not fire a debug message to the game screen. // Toadicus edit: Added re-implementation of the CBAttributeMap.GetAtt function that does not fire a debug message to the game screen.
public static CBAttributeMap.MapAttribute Toadicus_GetAtt(Vessel vessel) public static CBAttributeMap.MapAttribute Toadicus_GetAtt(Vessel vessel)
{ {
CBAttributeMap.MapAttribute mapAttribute; CBAttributeMap.MapAttribute mapAttribute;
   
try try
{ {
CBAttributeMap BiomeMap = vessel.mainBody.BiomeMap; CBAttributeMap BiomeMap = vessel.mainBody.BiomeMap;
   
double lat = vessel.latitude * Math.PI / 180d; double lat = vessel.latitude * Math.PI / 180d;
double lon = vessel.longitude * Math.PI / 180d; double lon = vessel.longitude * Math.PI / 180d;
   
  mapAttribute = BiomeMap.GetAtt(lat, lon);
   
  /*
lon -= Math.PI / 2d; lon -= Math.PI / 2d;
   
if (lon < 0d) if (lon < 0d)
{ {
lon += 2d * Math.PI; lon += 2d * Math.PI;
} }
   
float v = (float)(lat / Math.PI) + 0.5f; float v = (float)(lat / Math.PI) + 0.5f;
float u = (float)(lon / (2d * Math.PI)); float u = (float)(lon / (2d * Math.PI));
   
Color pixelBilinear = BiomeMap.Map.GetPixelBilinear (u, v); Color pixelBilinear = BiomeMap.Map.GetPixelBilinear(u, v);
mapAttribute = BiomeMap.defaultAttribute; mapAttribute = BiomeMap.defaultAttribute;
   
if (BiomeMap.Map != null) if (BiomeMap.Map != null)
{ {
if (BiomeMap.exactSearch) if (BiomeMap.exactSearch)
{ {
for (int i = 0; i < BiomeMap.Attributes.Length; ++i) for (int i = 0; i < BiomeMap.Attributes.Length; ++i)
{ {
if (pixelBilinear == BiomeMap.Attributes[i].mapColor) if (pixelBilinear == BiomeMap.Attributes[i].mapColor)
{ {
mapAttribute = BiomeMap.Attributes[i]; mapAttribute = BiomeMap.Attributes[i];
} }
} }
} }
else else
{ {
float zero = 0; float zero = 0;
float num = 1 / zero; float num = 1 / zero;
for (int j = 0; j < BiomeMap.Attributes.Length; ++j) for (int j = 0; j < BiomeMap.Attributes.Length; ++j)
{ {
Color mapColor = BiomeMap.Attributes [j].mapColor; Color mapColor = BiomeMap.Attributes[j].mapColor;
float sqrMagnitude = ((Vector4)(mapColor - pixelBilinear)).sqrMagnitude; float sqrMagnitude = ((Vector4)(mapColor - pixelBilinear)).sqrMagnitude;
if (sqrMagnitude < num) if (sqrMagnitude < num)
{ {
bool testCase = true; bool testCase = true;
if (BiomeMap.nonExactThreshold != -1) if (BiomeMap.nonExactThreshold != -1)
{ {
testCase = (sqrMagnitude < BiomeMap.nonExactThreshold); testCase = (sqrMagnitude < BiomeMap.nonExactThreshold);
} }
if (testCase) if (testCase)
{ {
mapAttribute = BiomeMap.Attributes[j]; mapAttribute = BiomeMap.Attributes[j];
num = sqrMagnitude; num = sqrMagnitude;
} }
} }
} }
} }
} }
  */
} }
catch (NullReferenceException) catch (NullReferenceException)
{ {
mapAttribute = new CBAttributeMap.MapAttribute(); mapAttribute = new CBAttributeMap.MapAttribute();
mapAttribute.name = "N/A"; mapAttribute.name = "N/A";
} }
   
return mapAttribute; return mapAttribute;
} }
   
public static string GetLongitudeString(Vessel vessel, string format="F4") public static string GetLongitudeString(Vessel vessel, string format = "F4")
{ {
string dir_long = "W"; string dir_long = "W";
double v_long = vessel.longitude; double v_long = vessel.longitude;
   
v_long = FixDegreeDomain(v_long); v_long = FixDegreeDomain(v_long);
   
if (v_long < -180d) if (v_long < -180d)
{ {
v_long += 360d; v_long += 360d;
} }
if (v_long >= 180) if (v_long >= 180)
{ {
v_long -= 360d; v_long -= 360d;
} }
   
if (v_long > 0) dir_long = "E"; if (v_long > 0)
  dir_long = "E";
   
return string.Format("{0}° {1}", Math.Abs(v_long).ToString(format), dir_long); return string.Format("{0}° {1}", Math.Abs(v_long).ToString(format), dir_long);
} }
   
public static string GetLatitudeString(Vessel vessel, string format="F4") public static string GetLatitudeString(Vessel vessel, string format = "F4")
{ {
string dir_lat = "S"; string dir_lat = "S";
double v_lat = vessel.latitude; double v_lat = vessel.latitude;
if (v_lat > 0) dir_lat = "N"; if (v_lat > 0)
  dir_lat = "N";
   
return string.Format("{0}° {1}", Math.Abs(v_lat).ToString(format), dir_lat); return string.Format("{0}° {1}", Math.Abs(v_lat).ToString(format), dir_lat);
} }
   
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
   
//For MuMech_get_heading() //For MuMech_get_heading()
public class MuMech_MovingAverage public class MuMech_MovingAverage
{ {
private double[] store; private double[] store;
private int storeSize; private int storeSize;
private int nextIndex = 0; private int nextIndex = 0;
   
public double value public double value
{ {
get get
{ {
double tmp = 0; double tmp = 0;
foreach (double i in store) foreach (double i in store)
{ {
tmp += i; tmp += i;
} }
return tmp / storeSize; return tmp / storeSize;
} }
set set
{ {
store[nextIndex] = value; store[nextIndex] = value;
nextIndex = (nextIndex + 1) % storeSize; nextIndex = (nextIndex + 1) % storeSize;
} }
} }
   
public MuMech_MovingAverage(int size = 10, double startingValue = 0) public MuMech_MovingAverage(int size = 10, double startingValue = 0)
{ {
storeSize = size; storeSize = size;
store = new double[size]; store = new double[size];
force(startingValue); force(startingValue);
} }
   
public void force(double newValue) public void force(double newValue)
{ {
for (int i = 0; i < storeSize; i++) for (int i = 0; i < storeSize; i++)
{ {
store[i] = newValue; store[i] = newValue;
} }
} }
   
public static implicit operator double(MuMech_MovingAverage v) public static implicit operator double(MuMech_MovingAverage v)
{ {
return v.value; return v.value;
} }
   
public override string ToString() public override string ToString()
{ {
return value.ToString(); return value.ToString();
} }
   
public string ToString(string format) public string ToString(string format)
{ {
return value.ToString(format); return value.ToString(format);
} }
} }
  //From http://svn.mumech.com/KSP/trunk/MuMechLib/VOID.vesselState.cs
//From http://svn.mumech.com/KSP/trunk/MuMechLib/VOID.vesselState.cs public static double MuMech_get_heading(Vessel vessel)
public static double MuMech_get_heading(Vessel vessel) {
{ Vector3d CoM;
Vector3d CoM = vessel.findWorldCenterOfMass();  
Vector3d up = (CoM - vessel.mainBody.position).normalized; try
Vector3d north = Vector3d.Exclude(up, (vessel.mainBody.position + vessel.mainBody.transform.up * (float)vessel.mainBody.Radius) - CoM).normalized; {
  CoM = vessel.findWorldCenterOfMass();
Quaternion rotationSurface = Quaternion.LookRotation(north, up); }
Quaternion rotationvesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vessel.transform.rotation) * rotationSurface); catch
MuMech_MovingAverage vesselHeading = new MuMech_MovingAverage(); {
vesselHeading.value = rotationvesselSurface.eulerAngles.y; return double.NaN;
return vesselHeading.value * 10; // *10 by me }
}  
  Vector3d up = (CoM - vessel.mainBody.position).normalized;
//From http://svn.mumech.com/KSP/trunk/MuMechLib/MuUtils.cs Vector3d north = Vector3d.Exclude(
public static string MuMech_ToSI(double d) up,
{ (vessel.mainBody.position +
int digits = 2; vessel.mainBody.transform.up * (float)vessel.mainBody.Radius
double exponent = Math.Log10(Math.Abs(d)); ) - CoM).normalized;
if (Math.Abs(d) >= 1)  
{ Quaternion rotationSurface = Quaternion.LookRotation(north, up);
switch ((int)Math.Floor(exponent)) Quaternion rotationvesselSurface = Quaternion.Inverse(
{ Quaternion.Euler(90, 0, 0) *
case 0: Quaternion.Inverse(vessel.transform.rotation) *
case 1: rotationSurface);
case 2:  
return d.ToString("F" + digits); return rotationvesselSurface.eulerAngles.y;
case 3: }
case 4: //From http://svn.mumech.com/KSP/trunk/MuMechLib/MuUtils.cs
case 5: public static string MuMech_ToSI(
return (d / 1e3).ToString("F" + digits) + "k"; double d, int digits = 3, int MinMagnitude = 0, int MaxMagnitude = int.MaxValue
case 6: )
case 7: {
case 8: float exponent = (float)Math.Log10(Math.Abs(d));
return (d / 1e6).ToString("F" + digits) + "M"; exponent = Mathf.Clamp(exponent, (float)MinMagnitude, (float)MaxMagnitude);
case 9:  
case 10: if (exponent >= 0)
case 11: {
return (d / 1e9).ToString("F" + digits) + "G"; switch ((int)Math.Floor(exponent))
case 12: {
case 13: case 0:
case 14: case 1:
return (d / 1e12).ToString("F" + digits) + "T"; case 2:
case 15: return d.ToString("F" + digits);
case 16: case 3:
case 17: case 4:
return (d / 1e15).ToString("F" + digits) + "P"; case 5:
case 18: return (d / 1e3).ToString("F" + digits) + "k";
case 19: case 6:
case 20: case 7:
return (d / 1e18).ToString("F" + digits) + "E"; case 8:
case 21: return (d / 1e6).ToString("F" + digits) + "M";
case 22: case 9:
case 23: case 10:
return (d / 1e21).ToString("F" + digits) + "Z"; case 11:
default: return (d / 1e9).ToString("F" + digits) + "G";
return (d / 1e24).ToString("F" + digits) + "Y"; case 12:
} case 13:
} case 14:
else if (Math.Abs(d) > 0) return (d / 1e12).ToString("F" + digits) + "T";
{ case 15:
switch ((int)Math.Floor(exponent)) case 16:
{ case 17:
case -1: return (d / 1e15).ToString("F" + digits) + "P";
case -2: case 18:
case -3: case 19:
return (d * 1e3).ToString("F" + digits) + "m"; case 20:
case -4: return (d / 1e18).ToString("F" + digits) + "E";
case -5: case 21:
case -6: case 22:
return (d * 1e6).ToString("F" + digits) + "μ"; case 23:
case -7: return (d / 1e21).ToString("F" + digits) + "Z";
case -8: default:
case -9: return (d / 1e24).ToString("F" + digits) + "Y";
return (d * 1e9).ToString("F" + digits) + "n"; }
case -10: }
case -11: else if (exponent < 0)
case -12: {
return (d * 1e12).ToString("F" + digits) + "p"; switch ((int)Math.Floor(exponent))
case -13: {
case -14: case -1:
case -15: case -2:
return (d * 1e15).ToString("F" + digits) + "f"; case -3:
case -16: return (d * 1e3).ToString("F" + digits) + "m";
case -17: case -4:
case -18: case -5:
return (d * 1e18).ToString("F" + digits) + "a"; case -6:
case -19: return (d * 1e6).ToString("F" + digits) + "μ";
case -20: case -7:
case -21: case -8:
return (d * 1e21).ToString("F" + digits) + "z"; case -9:
default: return (d * 1e9).ToString("F" + digits) + "n";
return (d * 1e24).ToString("F" + digits) + "y"; case -10:
} case -11:
} case -12:
else return (d * 1e12).ToString("F" + digits) + "p";
{ case -13:
return "0"; case -14:
} case -15:
} return (d * 1e15).ToString("F" + digits) + "f";
  case -16:
public static string ConvertInterval(double seconds) case -17:
{ case -18:
string format_1 = "{0:D1}y {1:D1}d {2:D2}h {3:D2}m {4:D2}.{5:D1}s"; return (d * 1e18).ToString("F" + digits) + "a";
string format_2 = "{0:D1}d {1:D2}h {2:D2}m {3:D2}.{4:D1}s"; case -19:
string format_3 = "{0:D2}h {1:D2}m {2:D2}.{3:D1}s"; case -20:
  case -21:
  return (d * 1e21).ToString("F" + digits) + "z";
  default:
  return (d * 1e24).ToString("F" + digits) + "y";
  }
  }
  else
  {
  return "0";
  }
  }
   
  public static string ConvertInterval(double seconds)
  {
  string format_1 = "{0:D1}y {1:D1}d {2:D2}h {3:D2}m {4:D2}.{5:D1}s";
  string format_2 = "{0:D1}d {1:D2}h {2:D2}m {3:D2}.{4:D1}s";
  string format_3 = "{0:D2}h {1:D2}m {2:D2}.{3:D1}s";
   
TimeSpan interval; TimeSpan interval;
   
try try
{ {
interval = TimeSpan.FromSeconds(seconds); interval = TimeSpan.FromSeconds(seconds);
} }
catch (OverflowException) catch (OverflowException)
{ {
return "NaN"; return "NaN";
} }
   
int years = interval.Days / 365; int years = interval.Days / 365;
   
string output; string output;
if (years > 0) if (years > 0)
{ {
output = string.Format(format_1, output = string.Format(format_1,
years, years,
interval.Days - (years * 365), // subtract years * 365 for accurate day count interval.Days - (years * 365), // subtract years * 365 for accurate day count
interval.Hours, interval.Hours,
interval.Minutes, interval.Minutes,
interval.Seconds, interval.Seconds,
interval.Milliseconds.ToString().Substring(0, 1)); interval.Milliseconds.ToString().Substring(0, 1));
} }
else if (interval.Days > 0) else if (interval.Days > 0)
{ {
output = string.Format(format_2, output = string.Format(format_2,
interval.Days, interval.Days,
interval.Hours, interval.Hours,
interval.Minutes, interval.Minutes,
interval.Seconds, interval.Seconds,
interval.Milliseconds.ToString().Substring(0, 1)); interval.Milliseconds.ToString().Substring(0, 1));
} }
else else
{ {
output = string.Format(format_3, output = string.Format(format_3,
interval.Hours, interval.Hours,
interval.Minutes, interval.Minutes,
interval.Seconds, interval.Seconds,
interval.Milliseconds.ToString().Substring(0, 1)); interval.Milliseconds.ToString().Substring(0, 1));
} }
return output; return output;
} }
   
public static string UppercaseFirst(string s) public static string UppercaseFirst(string s)
{ {
if (string.IsNullOrEmpty(s)) if (string.IsNullOrEmpty(s))
{ {
return string.Empty; return string.Empty;
} }
char[] a = s.ToCharArray(); char[] a = s.ToCharArray();
a[0] = char.ToUpper(a[0]); a[0] = char.ToUpper(a[0]);
return new string(a); return new string(a);
} }
  //transfer angles
//transfer angles public static double Nivvy_CalcTransferPhaseAngle(double r_current, double r_target, double grav_param)
  {
public static double Nivvy_CalcTransferPhaseAngle(double r_current, double r_target, double grav_param) double T_target = (2 * Math.PI) * Math.Sqrt(Math.Pow((r_target / 1000), 3) / (grav_param / 1000000000));
{ double T_transfer = (2 * Math.PI) * Math.Sqrt(Math.Pow((((r_target / 1000) + (r_current / 1000)) / 2), 3) / (grav_param / 1000000000));
double T_target = (2 * Math.PI) * Math.Sqrt(Math.Pow((r_target / 1000), 3) / (grav_param / 1000000000)); return 360 * (0.5 - (T_transfer / (2 * T_target)));
double T_transfer = (2 * Math.PI) * Math.Sqrt(Math.Pow((((r_target / 1000) + (r_current / 1000)) / 2), 3) / (grav_param / 1000000000)); }
return 360 * (0.5 - (T_transfer / (2 * T_target)));  
} public static double Younata_DeltaVToGetToOtherBody(double mu, double r1, double r2)
  {
public static double Younata_DeltaVToGetToOtherBody(double mu, double r1, double r2) /*
{  
/*  
def deltaVToGetToOtherBody(mu, r1, r2): def deltaVToGetToOtherBody(mu, r1, r2):
# mu = gravity param of common orbiting body of r1 and r2 # mu = gravity param of common orbiting body of r1 and r2
# (e.g. for mun to minmus, mu is kerbin's gravity param # (e.g. for mun to minmus, mu is kerbin's gravity param
# r1 = initial body's orbit radius # r1 = initial body's orbit radius
# r2 = target body's orbit radius # r2 = target body's orbit radius
# return value is km/s # return value is km/s
sur1 = math.sqrt(mu / r1) sur1 = math.sqrt(mu / r1)
sr1r2 = math.sqrt(float(2*r2)/float(r1+r2)) sr1r2 = math.sqrt(float(2*r2)/float(r1+r2))
mult = sr1r2 - 1 mult = sr1r2 - 1
return sur1 * mult return sur1 * mult
*/ */
double sur1, sr1r2, mult; double sur1, sr1r2, mult;
sur1 = Math.Sqrt(mu / r1); sur1 = Math.Sqrt(mu / r1);
sr1r2 = Math.Sqrt((2 * r2) / (r1 + r2)); sr1r2 = Math.Sqrt((2 * r2) / (r1 + r2));
mult = sr1r2 - 1; mult = sr1r2 - 1;
return sur1 * mult; return sur1 * mult;
} }
   
public static double Younata_DeltaVToExitSOI(double mu, double r1, double r2, double v) public static double Younata_DeltaVToExitSOI(double mu, double r1, double r2, double v)
{ {
/* /*
def deltaVToExitSOI(mu, r1, r2, v): def deltaVToExitSOI(mu, r1, r2, v):
# mu = gravity param of current body # mu = gravity param of current body
# r1 = current orbit radius # r1 = current orbit radius
# r2 = SOI radius # r2 = SOI radius
# v = SOI exit velocity # v = SOI exit velocity
foo = r2 * (v**2) - 2 * mu foo = r2 * (v**2) - 2 * mu
bar = r1 * foo + (2 * r2 * mu) bar = r1 * foo + (2 * r2 * mu)
r = r1*r2 r = r1*r2
return math.sqrt(bar / r) return math.sqrt(bar / r)
*/ */
double foo = r2 * Math.Pow(v, 2) - 2 * mu; double foo = r2 * Math.Pow(v, 2) - 2 * mu;
double bar = r1 * foo + (2 * r2 * mu); double bar = r1 * foo + (2 * r2 * mu);
double r = r1 * r2; double r = r1 * r2;
return Math.Sqrt(bar / r); return Math.Sqrt(bar / r);
} }
   
public static double Younata_TransferBurnPoint(double r, double v, double angle, double mu) public static double Younata_TransferBurnPoint(double r, double v, double angle, double mu)
{ {
/* /*
def transferBurnPoint(r, v, angle, mu): def transferBurnPoint(r, v, angle, mu):
# r = parking orbit radius # r = parking orbit radius
# v = ejection velocity # v = ejection velocity
# angle = phase angle (from function phaseAngle()) # angle = phase angle (from function phaseAngle())
# mu = gravity param of current body. # mu = gravity param of current body.
epsilon = ((v**2)/2) - (mu / r) epsilon = ((v**2)/2) - (mu / r)
h = r * v * math.sin(angle) h = r * v * math.sin(angle)
e = math.sqrt(1 + ((2 * epsilon * h**2)/(mu**2))) e = math.sqrt(1 + ((2 * epsilon * h**2)/(mu**2)))
theta = math.acos(1.0 / e) theta = math.acos(1.0 / e)
degrees = theta * (180.0 / math.pi) degrees = theta * (180.0 / math.pi)
return 180 - degrees return 180 - degrees
*/ */
double epsilon, h, ee, theta, degrees; double epsilon, h, ee, theta, degrees;
epsilon = (Math.Pow(v, 2) / 2) - (mu / r); epsilon = (Math.Pow(v, 2) / 2) - (mu / r);
h = r * v * Math.Sin(angle); h = r * v * Math.Sin(angle);
ee = Math.Sqrt(1 + ((2 * epsilon * Math.Pow(h, 2)) / Math.Pow(mu, 2))); ee = Math.Sqrt(1 + ((2 * epsilon * Math.Pow(h, 2)) / Math.Pow(mu, 2)));
theta = Math.Acos(1.0 / ee); theta = Math.Acos(1.0 / ee);
degrees = theta * (180.0 / Math.PI); degrees = theta * (180.0 / Math.PI);
return 180 - degrees; return 180 - degrees;
// returns the ejection angle // returns the ejection angle
} }
   
public static double Adammada_CurrrentPhaseAngle(double body_LAN, double body_orbitPct, double origin_LAN, double origin_orbitPct) public static double Adammada_CurrrentPhaseAngle(
{ double body_LAN,
double angle = (body_LAN / 360 + body_orbitPct) - (origin_LAN / 360 + origin_orbitPct); double body_orbitPct,
if (angle > 1) angle = angle - 1; double origin_LAN,
if (angle < 0) angle = angle + 1; double origin_orbitPct
if (angle > 0.5) angle = angle - 1; )
angle = angle * 360; {
return angle; double angle = (body_LAN / 360 + body_orbitPct) - (origin_LAN / 360 + origin_orbitPct);
} if (angle > 1)
  angle = angle - 1;
public static double Adammada_CurrentEjectionAngle(double vessel_long, double origin_rotAngle, double origin_LAN, double origin_orbitPct) if (angle < 0)
{ angle = angle + 1;
//double eangle = ((FlightGlobals.ActiveVOID.vessel.longitude + orbiting.rotationAngle) - (orbiting.orbit.LAN / 360 + orbiting.orbit.orbitPercent) * 360); if (angle > 0.5)
double eangle = ((vessel_long + origin_rotAngle) - (origin_LAN / 360 + origin_orbitPct) * 360); angle = angle - 1;
  angle = angle * 360;
while (eangle < 0) eangle = eangle + 360; return angle;
while (eangle > 360) eangle = eangle - 360; }
if (eangle < 270) eangle = 90 - eangle;  
else eangle = 450 - eangle; public static double Adammada_CurrentEjectionAngle(
return eangle; double vessel_long,
} double origin_rotAngle,
  double origin_LAN,
public static double mrenigma03_calcphase(Vessel vessel, CelestialBody target) //calculates phase angle between the current body and target body double origin_orbitPct
{ )
Vector3d vecthis = new Vector3d(); {
Vector3d vectarget = new Vector3d(); //double eangle = ((FlightGlobals.ActiveVOID.vessel.longitude + orbiting.rotationAngle) - (orbiting.orbit.LAN / 360 + orbiting.orbit.orbitPercent) * 360);
vectarget = target.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()); double eangle = ((vessel_long + origin_rotAngle) - (origin_LAN / 360 + origin_orbitPct) * 360);
   
if ((vessel.mainBody.name == "Sun") || (vessel.mainBody.referenceBody.referenceBody.name == "Sun")) while (eangle < 0)
{ eangle = eangle + 360;
vecthis = vessel.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()); while (eangle > 360)
} eangle = eangle - 360;
else if (eangle < 270)
{ eangle = 90 - eangle;
vecthis = vessel.mainBody.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()); else
} eangle = 450 - eangle;
  return eangle;
vecthis = Vector3d.Project(new Vector3d(vecthis.x, 0, vecthis.z), vecthis); }
vectarget = Vector3d.Project(new Vector3d(vectarget.x, 0, vectarget.z), vectarget);  
  public static double mrenigma03_calcphase(Vessel vessel, CelestialBody target) //calculates phase angle between the current body and target body
Vector3d prograde = new Vector3d(); {
prograde = Quaternion.AngleAxis(90, Vector3d.forward) * vecthis; Vector3d vecthis = new Vector3d();
  Vector3d vectarget = new Vector3d();
double phase = Vector3d.Angle(vecthis, vectarget); vectarget = target.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime());
   
if (Vector3d.Angle(prograde, vectarget) > 90) phase = 360 - phase; if ((vessel.mainBody.name == "Sun") || (vessel.mainBody.referenceBody.referenceBody.name == "Sun"))
  {
return (phase + 360) % 360; vecthis = vessel.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime());
} }
  else
  {
  vecthis = vessel.mainBody.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime());
  }
   
  vecthis = Vector3d.Project(new Vector3d(vecthis.x, 0, vecthis.z), vecthis);
  vectarget = Vector3d.Project(new Vector3d(vectarget.x, 0, vectarget.z), vectarget);
   
  Vector3d prograde = new Vector3d();
  prograde = Quaternion.AngleAxis(90, Vector3d.forward) * vecthis;
   
  double phase = Vector3d.Angle(vecthis, vectarget);
   
  if (Vector3d.Angle(prograde, vectarget) > 90)
  phase = 360 - phase;
   
  return (phase + 360) % 360;
  }
   
public static double FixAngleDomain(double Angle, bool Degrees = false) public static double FixAngleDomain(double Angle, bool Degrees = false)
{ {
double Extent = 2d * Math.PI; double Extent = 2d * Math.PI;
if (Degrees) { if (Degrees)
  {
Extent = 360d; Extent = 360d;
} }
   
Angle = Angle % (Extent); Angle = Angle % (Extent);
if (Angle < 0d) if (Angle < 0d)
{ {
Angle += Extent; Angle += Extent;
} }
   
return Angle; return Angle;
} }
   
public static double FixDegreeDomain(double Angle) public static double FixDegreeDomain(double Angle)
{ {
return FixAngleDomain (Angle, true); return FixAngleDomain(Angle, true);
} }
   
public static double adjustCurrPhaseAngle(double transfer_angle, double curr_phase) public static double adjustCurrPhaseAngle(double transfer_angle, double curr_phase)
{ {
if (transfer_angle < 0) if (transfer_angle < 0)
{ {
if (curr_phase > 0) return (-1 * (360 - curr_phase)); if (curr_phase > 0)
else if (curr_phase < 0) return curr_phase; return (-1 * (360 - curr_phase));
} else if (curr_phase < 0)
else if (transfer_angle > 0) return curr_phase;
{ }
if (curr_phase > 0) return curr_phase; else if (transfer_angle > 0)
else if (curr_phase < 0) return (360 + curr_phase); {
} if (curr_phase > 0)
return curr_phase; return curr_phase;
} else if (curr_phase < 0)
  return (360 + curr_phase);
public static double adjust_current_ejection_angle(double curr_ejection) }
{ return curr_phase;
//curr_ejection WILL need to be adjusted once for all transfers as it returns values ranging -180 to 180 }
// need 0-360 instead  
// public static double adjust_current_ejection_angle(double curr_ejection)
// ie i have -17 in the screenshot {
// need it to show 343 //curr_ejection WILL need to be adjusted once for all transfers as it returns values ranging -180 to 180
// // need 0-360 instead
// do this //
// // ie i have -17 in the screenshot
// if < 0, add curr to 360 // 360 + (-17) = 343 // need it to show 343
// else its good as it is //
  // do this
if (curr_ejection < 0) return 360 + curr_ejection; //
else return curr_ejection; // if < 0, add curr to 360 // 360 + (-17) = 343
  // else its good as it is
}  
  if (curr_ejection < 0)
public static double adjust_transfer_ejection_angle(double trans_ejection, double trans_phase) return 360 + curr_ejection;
{ else
// if transfer_phase_angle < 0 its a lower transfer return curr_ejection;
//180 + curr_ejection  
// else if transfer_phase_angle > 0 its good as it is }
   
if (trans_phase < 0) return 180 + trans_ejection; public static double adjust_transfer_ejection_angle(double trans_ejection, double trans_phase)
else return trans_ejection; {
  // if transfer_phase_angle < 0 its a lower transfer
} //180 + curr_ejection
  // else if transfer_phase_angle > 0 its good as it is
public static double TrueAltitude(Vessel vessel)  
  if (trans_phase < 0)
  return 180 + trans_ejection;
  else
  return trans_ejection;
   
  }
   
  public static double TrueAltitude(Vessel vessel)
{ {
double trueAltitude = vessel.orbit.altitude - vessel.terrainAltitude; double trueAltitude = vessel.orbit.altitude - vessel.terrainAltitude;
   
// HACK: This assumes that on worlds with oceans, all water is fixed at 0 m, and water covers the whole surface at 0 m. // HACK: This assumes that on worlds with oceans, all water is fixed at 0 m,
if (vessel.terrainAltitude < 0 && vessel.mainBody.ocean ) // and water covers the whole surface at 0 m.
  if (vessel.terrainAltitude < 0 && vessel.mainBody.ocean)
{ {
trueAltitude = vessel.orbit.altitude; trueAltitude = vessel.orbit.altitude;
} }
   
return trueAltitude; return trueAltitude;
} }
   
public static string get_heading_text(double heading) public static string get_heading_text(double heading)
{ {
if (heading > 348.75 || heading <= 11.25) return "N"; if (heading > 348.75 || heading <= 11.25)
else if (heading > 11.25 && heading <= 33.75) return "NNE"; return "N";
else if (heading > 33.75 && heading <= 56.25) return "NE"; else if (heading > 11.25 && heading <= 33.75)
else if (heading > 56.25 && heading <= 78.75) return "ENE"; return "NNE";
else if (heading > 78.75 && heading <= 101.25) return "E"; else if (heading > 33.75 && heading <= 56.25)
else if (heading > 101.25 && heading <= 123.75) return "ESE"; return "NE";
else if (heading > 123.75 && heading <= 146.25) return "SE"; else if (heading > 56.25 && heading <= 78.75)
else if (heading > 146.25 && heading <= 168.75) return "SSE"; return "ENE";
else if (heading > 168.75 && heading <= 191.25) return "S"; else if (heading > 78.75 && heading <= 101.25)
else if (heading > 191.25 && heading <= 213.75) return "SSW"; return "E";
else if (heading > 213.75 && heading <= 236.25) return "SW"; else if (heading > 101.25 && heading <= 123.75)
else if (heading > 236.25 && heading <= 258.75) return "WSW"; return "ESE";
else if (heading > 258.75 && heading <= 281.25) return "W"; else if (heading > 123.75 && heading <= 146.25)
else if (heading > 281.25 && heading <= 303.75) return "WNW"; return "SE";
else if (heading > 303.75 && heading <= 326.25) return "NW"; else if (heading > 146.25 && heading <= 168.75)
else if (heading > 326.25 && heading <= 348.75) return "NNW"; return "SSE";
else return ""; else if (heading > 168.75 && heading <= 191.25)
} return "S";
  else if (heading > 191.25 && heading <= 213.75)
  return "SSW";
  else if (heading > 213.75 && heading <= 236.25)
  return "SW";
  else if (heading > 236.25 && heading <= 258.75)
  return "WSW";
  else if (heading > 258.75 && heading <= 281.25)
  return "W";
  else if (heading > 281.25 && heading <= 303.75)
  return "WNW";
  else if (heading > 303.75 && heading <= 326.25)
  return "NW";
  else if (heading > 326.25 && heading <= 348.75)
  return "NNW";
  else
  return "";
  }
   
public static void display_transfer_angles_SUN2PLANET(CelestialBody body, Vessel vessel) public static void display_transfer_angles_SUN2PLANET(CelestialBody body, Vessel vessel)
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Phase angle (curr/trans):"); GUILayout.Label("Phase angle (curr/trans):");
GUILayout.Label(Tools.mrenigma03_calcphase(vessel, body).ToString("F3") + "° / " + Tools.Nivvy_CalcTransferPhaseAngle(vessel.orbit.semiMajorAxis, body.orbit.semiMajorAxis, vessel.mainBody.gravParameter).ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(
  Tools.mrenigma03_calcphase(vessel, body).ToString("F3") + "° / " + Tools.Nivvy_CalcTransferPhaseAngle(
  vessel.orbit.semiMajorAxis,
  body.orbit.semiMajorAxis,
  vessel.mainBody.gravParameter
  ).ToString("F3") + "°",
  GUILayout.ExpandWidth(false)
  );
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Transfer velocity:"); GUILayout.Label("Transfer velocity:");
GUILayout.Label((Tools.Younata_DeltaVToGetToOtherBody((vessel.mainBody.gravParameter / 1000000000), (vessel.orbit.semiMajorAxis / 1000), (body.orbit.semiMajorAxis / 1000)) * 1000).ToString("F2") + "m/s", GUILayout.ExpandWidth(false)); GUILayout.Label(
  (Tools.Younata_DeltaVToGetToOtherBody(
  (vessel.mainBody.gravParameter / 1000000000),
  (vessel.orbit.semiMajorAxis / 1000),
  (body.orbit.semiMajorAxis / 1000)
  ) * 1000).ToString("F2") + "m/s",
  GUILayout.ExpandWidth(false)
  );
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
   
public static void display_transfer_angles_PLANET2PLANET(CelestialBody body, Vessel vessel) public static void display_transfer_angles_PLANET2PLANET(CelestialBody body, Vessel vessel)
{ {
double dv1 = Tools.Younata_DeltaVToGetToOtherBody((vessel.mainBody.referenceBody.gravParameter / 1000000000), (vessel.mainBody.orbit.semiMajorAxis / 1000), (body.orbit.semiMajorAxis / 1000)); double dv1 = Tools.Younata_DeltaVToGetToOtherBody(
double dv2 = Tools.Younata_DeltaVToExitSOI((vessel.mainBody.gravParameter / 1000000000), (vessel.orbit.semiMajorAxis / 1000), (vessel.mainBody.sphereOfInfluence / 1000), Math.Abs(dv1)); (vessel.mainBody.referenceBody.gravParameter / 1000000000),
  (vessel.mainBody.orbit.semiMajorAxis / 1000),
double trans_ejection_angle = Tools.Younata_TransferBurnPoint((vessel.orbit.semiMajorAxis / 1000), dv2, (Math.PI / 2.0), (vessel.mainBody.gravParameter / 1000000000)); (body.orbit.semiMajorAxis / 1000)
double curr_ejection_angle = Tools.Adammada_CurrentEjectionAngle(FlightGlobals.ActiveVessel.longitude, FlightGlobals.ActiveVessel.orbit.referenceBody.rotationAngle, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent); );
  double dv2 = Tools.Younata_DeltaVToExitSOI(
double trans_phase_angle = Tools.Nivvy_CalcTransferPhaseAngle(vessel.mainBody.orbit.semiMajorAxis, body.orbit.semiMajorAxis, vessel.mainBody.referenceBody.gravParameter) % 360; (vessel.mainBody.gravParameter / 1000000000),
double curr_phase_angle = Tools.Adammada_CurrrentPhaseAngle(body.orbit.LAN, body.orbit.orbitPercent, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent); (vessel.orbit.semiMajorAxis / 1000),
  (vessel.mainBody.sphereOfInfluence / 1000),
  Math.Abs(dv1)
  );
   
  double trans_ejection_angle = Tools.Younata_TransferBurnPoint(
  (vessel.orbit.semiMajorAxis / 1000),
  dv2,
  (Math.PI / 2.0),
  (vessel.mainBody.gravParameter / 1000000000)
  );
  double curr_ejection_angle = Tools.Adammada_CurrentEjectionAngle(
  FlightGlobals.ActiveVessel.longitude,
  FlightGlobals.ActiveVessel.orbit.referenceBody.rotationAngle,
  FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN,
  FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent
  );
   
  double trans_phase_angle = Tools.Nivvy_CalcTransferPhaseAngle(
  vessel.mainBody.orbit.semiMajorAxis,
  body.orbit.semiMajorAxis,
  vessel.mainBody.referenceBody.gravParameter
  ) % 360;
  double curr_phase_angle = Tools.Adammada_CurrrentPhaseAngle(
  body.orbit.LAN,
  body.orbit.orbitPercent,
  FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN,
  FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent
  );
   
double adj_phase_angle = Tools.adjustCurrPhaseAngle(trans_phase_angle, curr_phase_angle); double adj_phase_angle = Tools.adjustCurrPhaseAngle(trans_phase_angle, curr_phase_angle);
double adj_trans_ejection_angle = Tools.adjust_transfer_ejection_angle(trans_ejection_angle, trans_phase_angle); double adj_trans_ejection_angle = Tools.adjust_transfer_ejection_angle(trans_ejection_angle, trans_phase_angle);
double adj_curr_ejection_angle = Tools.adjust_current_ejection_angle(curr_ejection_angle); double adj_curr_ejection_angle = Tools.adjust_current_ejection_angle(curr_ejection_angle);
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Phase angle (curr/trans):"); GUILayout.Label("Phase angle (curr/trans):");
GUILayout.Label(adj_phase_angle.ToString("F3") + "° / " + trans_phase_angle.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(
  adj_phase_angle.ToString("F3") + "° / " + trans_phase_angle.ToString("F3") + "°",
  GUILayout.ExpandWidth(false)
  );
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Ejection angle (curr/trans):"); GUILayout.Label("Ejection angle (curr/trans):");
GUILayout.Label(adj_curr_ejection_angle.ToString("F3") + "° / " + adj_trans_ejection_angle.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(
  adj_curr_ejection_angle.ToString("F3") + "° / " + adj_trans_ejection_angle.ToString("F3") + "°",
  GUILayout.ExpandWidth(false)
  );
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Transfer velocity:"); GUILayout.Label("Transfer velocity:");
GUILayout.Label((dv2 * 1000).ToString("F2") + "m/s", GUILayout.ExpandWidth(false)); GUILayout.Label((dv2 * 1000).ToString("F2") + "m/s", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
   
public static void display_transfer_angles_PLANET2MOON(CelestialBody body, Vessel vessel) public static void display_transfer_angles_PLANET2MOON(CelestialBody body, Vessel vessel)
{ {
double dv1 = Tools.Younata_DeltaVToGetToOtherBody((vessel.mainBody.gravParameter / 1000000000), (vessel.orbit.semiMajorAxis / 1000), (body.orbit.semiMajorAxis / 1000)); double dv1 = Tools.Younata_DeltaVToGetToOtherBody(
  (vessel.mainBody.gravParameter / 1000000000),
double trans_phase_angle = Tools.Nivvy_CalcTransferPhaseAngle(vessel.orbit.semiMajorAxis, body.orbit.semiMajorAxis, vessel.mainBody.gravParameter); (vessel.orbit.semiMajorAxis / 1000),
  (body.orbit.semiMajorAxis / 1000)
  );
   
  double trans_phase_angle = Tools.Nivvy_CalcTransferPhaseAngle(
  vessel.orbit.semiMajorAxis,
  body.orbit.semiMajorAxis,
  vessel.mainBody.gravParameter
  );
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Phase angle (curr/trans):"); GUILayout.Label("Phase angle (curr/trans):");
GUILayout.Label(Tools.mrenigma03_calcphase(vessel, body).ToString("F3") + "° / " + trans_phase_angle.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(
  Tools.mrenigma03_calcphase(vessel, body).ToString("F3") + "° / " + trans_phase_angle.ToString("F3") + "°",
  GUILayout.ExpandWidth(false)
  );
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Transfer velocity:"); GUILayout.Label("Transfer velocity:");
GUILayout.Label((dv1 * 1000).ToString("F2") + "m/s", GUILayout.ExpandWidth(false)); GUILayout.Label((dv1 * 1000).ToString("F2") + "m/s", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
   
public static void display_transfer_angles_MOON2MOON(CelestialBody body, Vessel vessel) public static void display_transfer_angles_MOON2MOON(CelestialBody body, Vessel vessel)
{ {
double dv1 = Tools.Younata_DeltaVToGetToOtherBody((vessel.mainBody.referenceBody.gravParameter / 1000000000), (vessel.mainBody.orbit.semiMajorAxis / 1000), (body.orbit.semiMajorAxis / 1000)); double dv1 = Tools.Younata_DeltaVToGetToOtherBody(
double dv2 = Tools.Younata_DeltaVToExitSOI((vessel.mainBody.gravParameter / 1000000000), (vessel.orbit.semiMajorAxis / 1000), (vessel.mainBody.sphereOfInfluence / 1000), Math.Abs(dv1)); (vessel.mainBody.referenceBody.gravParameter / 1000000000),
double trans_ejection_angle = Tools.Younata_TransferBurnPoint((vessel.orbit.semiMajorAxis / 1000), dv2, (Math.PI / 2.0), (vessel.mainBody.gravParameter / 1000000000)); (vessel.mainBody.orbit.semiMajorAxis / 1000),
  (body.orbit.semiMajorAxis / 1000)
double curr_phase_angle = Tools.Adammada_CurrrentPhaseAngle(body.orbit.LAN, body.orbit.orbitPercent, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent); );
double curr_ejection_angle = Tools.Adammada_CurrentEjectionAngle(FlightGlobals.ActiveVessel.longitude, FlightGlobals.ActiveVessel.orbit.referenceBody.rotationAngle, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent); double dv2 = Tools.Younata_DeltaVToExitSOI(
  (vessel.mainBody.gravParameter / 1000000000),
double trans_phase_angle = Tools.Nivvy_CalcTransferPhaseAngle(vessel.mainBody.orbit.semiMajorAxis, body.orbit.semiMajorAxis, vessel.mainBody.referenceBody.gravParameter) % 360; (vessel.orbit.semiMajorAxis / 1000),
  (vessel.mainBody.sphereOfInfluence / 1000),
  Math.Abs(dv1)
  );
  double trans_ejection_angle = Tools.Younata_TransferBurnPoint(
  (vessel.orbit.semiMajorAxis / 1000),
  dv2,
  (Math.PI / 2.0),
  (vessel.mainBody.gravParameter / 1000000000)
  );
   
  double curr_phase_angle = Tools.Adammada_CurrrentPhaseAngle(
  body.orbit.LAN,
  body.orbit.orbitPercent,
  FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN,
  FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent
  );
  double curr_ejection_angle = Tools.Adammada_CurrentEjectionAngle(
  FlightGlobals.ActiveVessel.longitude,
  FlightGlobals.ActiveVessel.orbit.referenceBody.rotationAngle,
  FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN,
  FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent
  );
   
  double trans_phase_angle = Tools.Nivvy_CalcTransferPhaseAngle(
  vessel.mainBody.orbit.semiMajorAxis,
  body.orbit.semiMajorAxis,
  vessel.mainBody.referenceBody.gravParameter
  ) % 360;
   
double adj_phase_angle = Tools.adjustCurrPhaseAngle(trans_phase_angle, curr_phase_angle); double adj_phase_angle = Tools.adjustCurrPhaseAngle(trans_phase_angle, curr_phase_angle);
//double adj_ejection_angle = adjustCurrEjectionAngle(trans_phase_angle, curr_ejection_angle); //double adj_ejection_angle = adjustCurrEjectionAngle(trans_phase_angle, curr_ejection_angle);
   
//new stuff //new stuff
// //
double adj_trans_ejection_angle = Tools.adjust_transfer_ejection_angle(trans_ejection_angle, trans_phase_angle); double adj_trans_ejection_angle = Tools.adjust_transfer_ejection_angle(trans_ejection_angle, trans_phase_angle);
double adj_curr_ejection_angle = Tools.adjust_current_ejection_angle(curr_ejection_angle); double adj_curr_ejection_angle = Tools.adjust_current_ejection_angle(curr_ejection_angle);
// //
// //
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Phase angle (curr/trans):"); GUILayout.Label("Phase angle (curr/trans):");
GUILayout.Label(adj_phase_angle.ToString("F3") + "° / " + trans_phase_angle.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(
  adj_phase_angle.ToString("F3") + "° / " + trans_phase_angle.ToString("F3") + "°",
  GUILayout.ExpandWidth(false)
  );
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Ejection angle (curr/trans):"); GUILayout.Label("Ejection angle (curr/trans):");
GUILayout.Label(adj_curr_ejection_angle.ToString("F3") + "° / " + adj_trans_ejection_angle.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(
  adj_curr_ejection_angle.ToString("F3") + "° / " + adj_trans_ejection_angle.ToString("F3") + "°",
  GUILayout.ExpandWidth(false)
  );
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Transfer velocity:"); GUILayout.Label("Transfer velocity:");
GUILayout.Label((dv2 * 1000).ToString("F2") + "m/s", GUILayout.ExpandWidth(false)); GUILayout.Label((dv2 * 1000).ToString("F2") + "m/s", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
   
// This implementation is adapted from FARGUIUtils.ClampToScreen // This implementation is adapted from FARGUIUtils.ClampToScreen
public static Rect ClampRectToScreen(Rect window, int xMargin, int yMargin) public static Rect ClampRectToScreen(Rect window, int xMargin, int yMargin)
{ {
window.x = Mathf.Clamp (window.x, xMargin - window.width, Screen.width - xMargin); window.x = Mathf.Clamp(window.x, xMargin - window.width, Screen.width - xMargin);
window.y = Mathf.Clamp (window.y, yMargin - window.height, Screen.height - yMargin); window.y = Mathf.Clamp(window.y, yMargin - window.height, Screen.height - yMargin);
   
return window; return window;
} }
   
public static Rect ClampRectToScreen(Rect window, int Margin) public static Rect ClampRectToScreen(Rect window, int Margin)
{ {
return ClampRectToScreen(window, Margin, Margin); return ClampRectToScreen(window, Margin, Margin);
} }
   
public static Rect ClampRectToScreen(Rect window) public static Rect ClampRectToScreen(Rect window)
{ {
return ClampRectToScreen (window, 30); return ClampRectToScreen(window, 30);
} }
   
public static Vector2 ClampV2ToScreen(Vector2 vec, uint xMargin, uint yMargin) public static Vector2 ClampV2ToScreen(Vector2 vec, uint xMargin, uint yMargin)
{ {
vec.x = Mathf.Clamp (vec.x, xMargin, Screen.width - xMargin); vec.x = Mathf.Clamp(vec.x, xMargin, Screen.width - xMargin);
vec.y = Mathf.Clamp (vec.y, yMargin, Screen.height - yMargin); vec.y = Mathf.Clamp(vec.y, yMargin, Screen.height - yMargin);
   
return vec; return vec;
} }
   
public static Vector2 ClampV2ToScreen(Vector2 vec, uint Margin) public static Vector2 ClampV2ToScreen(Vector2 vec, uint Margin)
{ {
return ClampV2ToScreen(vec, Margin, Margin); return ClampV2ToScreen(vec, Margin, Margin);
} }
   
public static Vector2 ClampV2ToScreen(Vector2 vec) public static Vector2 ClampV2ToScreen(Vector2 vec)
{ {
return ClampV2ToScreen (vec, 15); return ClampV2ToScreen(vec, 15);
} }
   
// UNDONE: This seems messy. Can we clean it up? // UNDONE: This seems messy. Can we clean it up?
public static Rect DockToWindow(Rect icon, Rect window) public static Rect DockToWindow(Rect icon, Rect window)
{ {
// We can't set the x and y of the center point directly, so build a new vector. // We can't set the x and y of the center point directly, so build a new vector.
Vector2 center = new Vector2 (); Vector2 center = new Vector2();
   
// If we are near the top or bottom of the screen... // If we are near the top or bottom of the screen...
if (window.yMax > Screen.height - icon.height || if (window.yMax > Screen.height - icon.height ||
window.yMin < icon.height window.yMin < icon.height)
)  
{ {
// If we are in a corner... // If we are in a corner...
if (window.xMax > Screen.width - icon.width || if (window.xMax > Screen.width - icon.width ||
window.xMin < icon.width window.xMin < icon.width)
)  
{ {
// If it is a top corner, put the icon below the window. // If it is a top corner, put the icon below the window.
if (window.yMax < Screen.height / 2) if (window.yMax < Screen.height / 2)
{ {
center.y = window.yMax + icon.height / 2; center.y = window.yMax + icon.height / 2;
} }
// If it is a bottom corner, put the icon above the window. // If it is a bottom corner, put the icon above the window.
else else
{ {
center.y = window.yMin - icon.height / 2; center.y = window.yMin - icon.height / 2;
} }
} }
// If we are not in a corner... // If we are not in a corner...
else else
{ {
// If we are along the top edge, align the icon's top edge with the top edge of the window // If we are along the top edge, align the icon's top edge with the top edge of the window
if (window.yMax > Screen.height / 2) if (window.yMax > Screen.height / 2)
{ {
center.y = window.yMax - icon.height / 2; center.y = window.yMax - icon.height / 2;
} }
// If we are along the bottom edge, align the icon's bottom edge with the bottom edge of the window // If we are along the bottom edge, align the icon's bottom edge with the bottom edge of the window
else else
{ {
center.y = window.yMin + icon.height / 2; center.y = window.yMin + icon.height / 2;
} }
} }
   
// At the top or bottom, if we are towards the right, put the icon to the right of the window // At the top or bottom, if we are towards the right, put the icon to the right of the window
if (window.center.x < Screen.width / 2) if (window.center.x < Screen.width / 2)
{ {
center.x = window.xMin - icon.width / 2; center.x = window.xMin - icon.width / 2;
} }
// At the top or bottom, if we are towards the left, put the icon to the left of the window // At the top or bottom, if we are towards the left, put the icon to the left of the window
else else
{ {
center.x = window.xMax + icon.width / 2; center.x = window.xMax + icon.width / 2;
} }
   
} }
// If we are not along the top or bottom of the screen... // If we are not along the top or bottom of the screen...
else else
{ {
// By default, center the icon above the window // By default, center the icon above the window
center.y = window.yMin - icon.height / 2; center.y = window.yMin - icon.height / 2;
center.x = window.center.x; center.x = window.center.x;
   
// If we are along a side... // If we are along a side...
if (window.xMax > Screen.width - icon.width || if (window.xMax > Screen.width - icon.width ||
window.xMin < icon.width window.xMin < icon.width)
)  
{ {
// UNDONE: I'm not sure I like the feel of this part. // UNDONE: I'm not sure I like the feel of this part.
// If we are along a side towards the bottom, put the icon below the window // If we are along a side towards the bottom, put the icon below the window
if (window.center.y > Screen.height / 2) if (window.center.y > Screen.height / 2)
{ {
center.y = window.yMax + icon.height / 2; center.y = window.yMax + icon.height / 2;
} }
   
// Along the left side, align the left edge of the icon with the left edge of the window. // Along the left side, align the left edge of the icon with the left edge of the window.
if (window.xMax > Screen.width - icon.width) if (window.xMax > Screen.width - icon.width)
{ {
center.x = window.xMax - icon.width / 2; center.x = window.xMax - icon.width / 2;
} }
// Along the right side, align the right edge of the icon with the right edge of the window. // Along the right side, align the right edge of the icon with the right edge of the window.
else if (window.xMin < icon.width) else if (window.xMin < icon.width)
{ {
center.x = window.xMin + icon.width / 2; center.x = window.xMin + icon.width / 2;
} }
} }
} }
   
// Assign the vector to the center of the rect. // Assign the vector to the center of the rect.
icon.center = center; icon.center = center;
   
// Return the icon's position. // Return the icon's position.
return icon; return icon;
} }
   
  public static ExperimentSituations GetExperimentSituation(this Vessel vessel)
  {
  Vessel.Situations situation = vessel.situation;
   
  switch (situation)
  {
  case Vessel.Situations.PRELAUNCH:
  case Vessel.Situations.LANDED:
  return ExperimentSituations.SrfLanded;
  case Vessel.Situations.SPLASHED:
  return ExperimentSituations.SrfSplashed;
  case Vessel.Situations.FLYING:
  if (vessel.altitude < (double)vessel.mainBody.scienceValues.flyingAltitudeThreshold)
  {
  return ExperimentSituations.FlyingLow;
  }
  else
  {
  return ExperimentSituations.FlyingHigh;
  }
  }
   
  if (vessel.altitude < (double)vessel.mainBody.scienceValues.spaceAltitudeThreshold)
  {
  return ExperimentSituations.InSpaceLow;
  }
  else
  {
  return ExperimentSituations.InSpaceHigh;
  }
  }
   
  public static double Radius(this Vessel vessel)
  {
  double radius;
   
  radius = vessel.altitude;
   
  if (vessel.mainBody != null)
  {
  radius += vessel.mainBody.Radius;
  }
   
  return radius;
  }
   
  public static double TryGetLastMass(this Engineer.VesselSimulator.SimManager simManager)
  {
  if (simManager.Stages == null || simManager.Stages.Length <= Staging.lastStage)
  {
  return double.NaN;
  }
   
  return simManager.Stages[Staging.lastStage].totalMass;
  }
   
  public static string HumanString(this ExperimentSituations situation)
  {
  switch (situation)
  {
  case ExperimentSituations.FlyingHigh:
  return "Upper Atmosphere";
  case ExperimentSituations.FlyingLow:
  return "Flying";
  case ExperimentSituations.SrfLanded:
  return "Surface";
  case ExperimentSituations.InSpaceLow:
  return "Near in Space";
  case ExperimentSituations.InSpaceHigh:
  return "High in Space";
  case ExperimentSituations.SrfSplashed:
  return "Splashed Down";
  default:
  return "Unknown";
  }
  }
   
private static ScreenMessage debugmsg = new ScreenMessage("", 2f, ScreenMessageStyle.UPPER_RIGHT); private static ScreenMessage debugmsg = new ScreenMessage("", 2f, ScreenMessageStyle.UPPER_RIGHT);
   
[System.Diagnostics.Conditional("DEBUG")] [System.Diagnostics.Conditional("DEBUG")]
public static void PostDebugMessage(string Msg) public static void PostDebugMessage(string Msg)
{ {
if (HighLogic.LoadedScene > GameScenes.SPACECENTER) if (HighLogic.LoadedScene > GameScenes.SPACECENTER)
{ {
debugmsg.message = Msg; debugmsg.message = Msg;
ScreenMessages.PostScreenMessage(debugmsg, true); ScreenMessages.PostScreenMessage(debugmsg, true);
} }
   
KSPLog.print(Msg); KSPLog.print(Msg);
} }
} }
} }
file:a/VOID.csproj (deleted)
<?xml version="1.0" encoding="utf-8"?>  
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  
<PropertyGroup>  
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>  
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>  
<ProductVersion>10.0.0</ProductVersion>  
<SchemaVersion>2.0</SchemaVersion>  
<ProjectGuid>{45ACC1CC-942C-4A66-BFC7-8BE375938B18}</ProjectGuid>  
<OutputType>Library</OutputType>  
<RootNamespace>VOID</RootNamespace>  
<AssemblyName>VOID</AssemblyName>  
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>  
</PropertyGroup>  
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">  
<DebugSymbols>true</DebugSymbols>  
<DebugType>full</DebugType>  
<Optimize>false</Optimize>  
<OutputPath>bin\Debug</OutputPath>  
<DefineConstants>DEBUG; TRACE</DefineConstants>  
<ErrorReport>prompt</ErrorReport>  
<WarningLevel>4</WarningLevel>  
<ConsolePause>false</ConsolePause>  
<CustomCommands>  
<CustomCommands>  
<Command type="AfterBuild" command="/usr/bin/cp -fv ${ProjectDir}/bin/Debug/VOID.dll /mnt/games/ssd/KSP_linux/GameData/VOID/Plugins/" />  
</CustomCommands>  
</CustomCommands>  
</PropertyGroup>  
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">  
<Optimize>true</Optimize>  
<OutputPath>bin\Release</OutputPath>  
<ErrorReport>prompt</ErrorReport>  
<WarningLevel>4</WarningLevel>  
<ConsolePause>false</ConsolePause>  
<DefineConstants>TRACE</DefineConstants>  
<CustomCommands>  
<CustomCommands>  
<Command type="AfterBuild" command="/usr/bin/cp -fv ${ProjectDir}/bin/Release/VOID.dll /mnt/games/ssd/KSP_linux/GameData/VOID/Plugins/" />  
</CustomCommands>  
</CustomCommands>  
</PropertyGroup>  
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />  
<ItemGroup>  
<Compile Include="Tools.cs" />  
<Compile Include="IVOID_Module.cs" />  
<Compile Include="VOIDFlightMaster.cs" />  
<Compile Include="VOID_Core.cs" />  
<Compile Include="VOID_Module.cs" />  
<Compile Include="VOID_HUD.cs" />  
<Compile Include="VOID_SaveValue.cs" />  
<Compile Include="VOID_Orbital.cs" />  
<Compile Include="VOID_SurfAtmo.cs" />  
<Compile Include="VOID_VesselInfo.cs" />  
<Compile Include="VOID_Transfer.cs" />  
<Compile Include="VOID_CBInfoBrowser.cs" />  
<Compile Include="VOID_Rendezvous.cs" />  
<Compile Include="VOID_VesselRegister.cs" />  
<Compile Include="VOID_DataLogger.cs" />  
<Compile Include="VOID_EditorCore.cs" />  
<Compile Include="VOID_EditorHUD.cs" />  
</ItemGroup>  
<ItemGroup>  
<Reference Include="Assembly-CSharp">  
<HintPath>..\..\..\..\..\mnt\games-ssd\KSP_linux\KSP_Data\Managed\Assembly-CSharp.dll</HintPath>  
<Private>False</Private>  
</Reference>  
<Reference Include="UnityEngine">  
<HintPath>..\..\..\..\..\mnt\games-ssd\KSP_linux\KSP_Data\Managed\UnityEngine.dll</HintPath>  
<Private>False</Private>  
</Reference>  
<Reference Include="System">  
<HintPath>..\..\..\..\..\mnt\games-ssd\KSP_linux\KSP_Data\Managed\System.dll</HintPath>  
<Private>False</Private>  
</Reference>  
</ItemGroup>  
<ItemGroup>  
<ProjectReference Include="..\Engineer.Extensions\Engineer.Extensions.csproj">  
<Project>{2FCF882B-0771-4649-8D04-81D7AA76A486}</Project>  
<Name>Engineer.Extensions</Name>  
</ProjectReference>  
<ProjectReference Include="..\VesselSimulator\VesselSimulator.csproj">  
<Project>{30FD6C0B-D36E-462F-B0FF-F0FAC9C666CF}</Project>  
<Name>VesselSimulator</Name>  
</ProjectReference>  
</ItemGroup>  
<ProjectExtensions>  
<MonoDevelop>  
<Properties>  
<Policies>  
<StandardHeader Text=" &#xA; ${FileName}&#xA; &#xA; Author:&#xA; ${AuthorName} &lt;${AuthorEmail}&gt;&#xA;&#xA; Copyright (c) ${Year} ${CopyrightHolder}&#xA;&#xA; This program is free software: you can redistribute it and/or modify&#xA; it under the terms of the GNU General Public License as published by&#xA; the Free Software Foundation, either version 3 of the License, or&#xA; (at your option) any later version.&#xA;&#xA; This program is distributed in the hope that it will be useful,&#xA; but WITHOUT ANY WARRANTY; without even the implied warranty of&#xA; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#xA; GNU General Public License for more details.&#xA;&#xA; You should have received a copy of the GNU General Public License&#xA; along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;." IncludeInNewFiles="True" />  
</Policies>  
</Properties>  
</MonoDevelop>  
</ProjectExtensions>  
</Project>  
  ///////////////////////////////////////////////////////////////////////////////
  //
  // VOID - Vessel Orbital Information Display for Kerbal Space Program
  // Copyright (C) 2012 Iannic-ann-od
  // Copyright (C) 2013 Toadicus
  //
  // This program is free software: you can redistribute it and/or modify
  // it under the terms of the GNU General Public License as published by
  // the Free Software Foundation, either version 3 of the License, or
  // (at your option) any later version.
  //
  // This program is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  // GNU General Public License for more details.
  //
  // You should have received a copy of the GNU General Public License
  // along with this program. If not, see <http://www.gnu.org/licenses/>.
  //
  ///////////////////////////////////////////////////////////////////////////////
  //
  // Much, much credit to Younata, Adammada, Nivvydaskrl and to all the authors
  // behind MechJeb, RemoteTech Relay Network, ISA MapSat, and Protractor for some
  // invaluable functions and making your nicely written code available to learn from.
  //
  ///////////////////////////////////////////////////////////////////////////////
  //
  // This software uses VesselSimulator and Engineer.Extensions from Engineer Redux.
  // Engineer Redux (c) 2013 cybutek
  // Used by permission.
  //
  ///////////////////////////////////////////////////////////////////////////////
 
  using System;
  using UnityEngine;
  using Engineer.VesselSimulator;
 
  namespace VOID
  {
  [KSPAddon(KSPAddon.Startup.EditorAny, false)]
  public class VOIDEditorMaster : MonoBehaviour
  {
  protected VOID_EditorCore Core;
 
  public void Awake()
  {
  Tools.PostDebugMessage ("VOIDEditorMaster: Waking up.");
  this.Core = VOID_EditorCore.Instance;
  this.Core.ResetGUI ();
  SimManager.HardReset();
  Tools.PostDebugMessage ("VOIDEditorMaster: Awake.");
  }
 
  public void Update()
  {
  if (!HighLogic.LoadedSceneIsEditor && this.Core != null)
  {
  this.Core.SaveConfig ();
  this.Core = null;
  VOID_EditorCore.Reset();
  return;
  }
 
  if (this.Core == null)
  {
  this.Awake();
  }
 
  this.Core.Update ();
 
  if (this.Core.factoryReset)
  {
  KSP.IO.File.Delete<VOID_EditorCore>("config.xml");
  this.Core = null;
  VOID_EditorCore.Reset();
  }
  }
 
  public void FixedUpdate()
  {
  if (this.Core == null || !HighLogic.LoadedSceneIsEditor)
  {
  return;
  }
 
  this.Core.FixedUpdate ();
  }
 
  public void OnGUI()
  {
  if (this.Core == null)
  {
  return;
  }
 
  this.Core.OnGUI();
  }
  }
  }
 
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// VOID - Vessel Orbital Information Display for Kerbal Space Program // VOID - Vessel Orbital Information Display for Kerbal Space Program
// Copyright (C) 2012 Iannic-ann-od // Copyright (C) 2012 Iannic-ann-od
// Copyright (C) 2013 Toadicus // Copyright (C) 2013 Toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// Much, much credit to Younata, Adammada, Nivvydaskrl and to all the authors // Much, much credit to Younata, Adammada, Nivvydaskrl and to all the authors
// behind MechJeb, RemoteTech Relay Network, ISA MapSat, and Protractor for some // behind MechJeb, RemoteTech Relay Network, ISA MapSat, and Protractor for some
// invaluable functions and making your nicely written code available to learn from. // invaluable functions and making your nicely written code available to learn from.
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// This software uses VesselSimulator and Engineer.Extensions from Engineer Redux. // This software uses VesselSimulator and Engineer.Extensions from Engineer Redux.
// Engineer Redux (c) 2013 cybutek // Engineer Redux (c) 2013 cybutek
// Used by permission. // Used by permission.
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
   
using System; using System;
using System.Collections.Generic;  
using System.Linq;  
using UnityEngine; using UnityEngine;
using Engineer.VesselSimulator; using Engineer.VesselSimulator;
   
namespace VOID namespace VOID
{ {
[KSPAddon(KSPAddon.Startup.Flight, false)] [KSPAddon(KSPAddon.Startup.Flight, false)]
public class VOIDFlightMaster : MonoBehaviour public class VOIDFlightMaster : MonoBehaviour
{ {
protected VOID_Core Core; protected VOID_Core Core;
   
public void Awake() public void Awake()
{ {
Tools.PostDebugMessage ("VOIDFlightMaster: Waking up."); Tools.PostDebugMessage ("VOIDFlightMaster: Waking up.");
this.Core = (VOID_Core)VOID_Core.Instance; this.Core = (VOID_Core)VOID_Core.Instance;
this.Core.ResetGUI (); this.Core.ResetGUI ();
  SimManager.HardReset();
Tools.PostDebugMessage ("VOIDFlightMaster: Awake."); Tools.PostDebugMessage ("VOIDFlightMaster: Awake.");
} }
   
public void Update() public void Update()
{ {
if (!HighLogic.LoadedSceneIsFlight && this.Core != null) if (!HighLogic.LoadedSceneIsFlight && this.Core != null)
{ {
this.Core.SaveConfig (); this.Core.SaveConfig ();
this.Core = null; this.Core = null;
VOID_Core.Reset(); VOID_Core.Reset();
return; return;
} }
   
if (this.Core == null) if (this.Core == null)
{ {
this.Awake(); this.Awake();
} }
   
this.Core.Update (); this.Core.Update ();
   
if (this.Core.vessel != null)  
{  
SimManager.Instance.Gravity = VOID_Core.Instance.vessel.mainBody.gravParameter /  
Math.Pow(VOID_Core.Instance.vessel.mainBody.Radius, 2);  
SimManager.Instance.TryStartSimulation();  
}  
   
if (this.Core.factoryReset) if (this.Core.factoryReset)
{ {
KSP.IO.File.Delete<VOID_Core>("config.xml"); KSP.IO.File.Delete<VOID_Core>("config.xml");
this.Core = null; this.Core = null;
VOID_Core.Reset(); VOID_Core.Reset();
} }
} }
   
public void FixedUpdate() public void FixedUpdate()
{ {
if (this.Core == null || !HighLogic.LoadedSceneIsFlight) if (this.Core == null || !HighLogic.LoadedSceneIsFlight)
{ {
return; return;
} }
   
this.Core.FixedUpdate (); this.Core.FixedUpdate ();
} }
   
public void OnGUI() public void OnGUI()
{ {
if (this.Core == null) if (this.Core == null)
{ {
return; return;
} }
   
this.Core.OnGUI(); this.Core.OnGUI();
} }
} }
   
[KSPAddon(KSPAddon.Startup.EditorAny, false)]  
public class VOIDEditorMaster : MonoBehaviour  
{  
protected VOID_EditorCore Core;  
   
public void Awake()  
{  
Tools.PostDebugMessage ("VOIDEditorMaster: Waking up.");  
this.Core = VOID_EditorCore.Instance;  
this.Core.ResetGUI ();  
Tools.PostDebugMessage ("VOIDEditorMaster: Awake.");  
}  
   
public void Update()  
{  
if (!HighLogic.LoadedSceneIsEditor && this.Core != null)  
{  
this.Core.SaveConfig ();  
this.Core = null;  
VOID_EditorCore.Reset();  
return;  
}  
   
if (this.Core == null)  
{  
this.Awake();  
}  
   
this.Core.Update ();  
   
if (this.Core.factoryReset)  
{  
KSP.IO.File.Delete<VOID_EditorCore>("config.xml");  
this.Core = null;  
VOID_EditorCore.Reset();  
}  
}  
   
public void FixedUpdate()  
{  
if (this.Core == null || !HighLogic.LoadedSceneIsEditor)  
{  
return;  
}  
   
this.Core.FixedUpdate ();  
}  
   
public void OnGUI()  
{  
if (this.Core == null)  
{  
return;  
}  
   
this.Core.OnGUI();  
}  
}  
} }
   
// //
// VOID_Orbital.cs // VOID_Orbital.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using KSP; using KSP;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_CBInfoBrowser : VOID_WindowModule public class VOID_CBInfoBrowser : VOID_WindowModule
{ {
[AVOID_SaveValue("selectedBodyIdx1")] [AVOID_SaveValue("selectedBodyIdx1")]
protected VOID_SaveValue<int> selectedBodyIdx1 = 1; protected VOID_SaveValue<int> selectedBodyIdx1 = 1;
   
[AVOID_SaveValue("selectedBodyIdx2")] [AVOID_SaveValue("selectedBodyIdx2")]
protected VOID_SaveValue<int> selectedBodyIdx2 = 2; protected VOID_SaveValue<int> selectedBodyIdx2 = 2;
   
protected CelestialBody selectedBody1; protected CelestialBody selectedBody1;
protected CelestialBody selectedBody2; protected CelestialBody selectedBody2;
   
[AVOID_SaveValue("toggleOrbital")] [AVOID_SaveValue("toggleOrbital")]
protected VOID_SaveValue<bool> toggleOrbital = false; protected VOID_SaveValue<bool> toggleOrbital = false;
   
[AVOID_SaveValue("togglePhysical")] [AVOID_SaveValue("togglePhysical")]
protected VOID_SaveValue<bool> togglePhysical = false; protected VOID_SaveValue<bool> togglePhysical = false;
   
public VOID_CBInfoBrowser() public VOID_CBInfoBrowser()
{ {
this._Name = "Celestial Body Information Browser"; this._Name = "Celestial Body Information Browser";
   
this.WindowPos.x = 10; this.WindowPos.x = 10;
this.WindowPos.y = 85; this.WindowPos.y = 85;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
   
GUILayout.BeginVertical(GUILayout.Width(150)); GUILayout.BeginVertical(GUILayout.Width(150));
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("", GUILayout.ExpandWidth(true)); GUILayout.Label("", GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.EndVertical(); GUILayout.EndVertical();
   
GUILayout.BeginVertical(GUILayout.Width(150)); GUILayout.BeginVertical(GUILayout.Width(150));
   
selectedBody1 = VOID_Core.Instance.allBodies[selectedBodyIdx1]; selectedBody1 = VOID_Core.Instance.allBodies[selectedBodyIdx1];
selectedBody2 = VOID_Core.Instance.allBodies[selectedBodyIdx2]; selectedBody2 = VOID_Core.Instance.allBodies[selectedBodyIdx2];
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button("<", GUILayout.ExpandWidth(false))) if (GUILayout.Button("<", GUILayout.ExpandWidth(false)))
{ {
selectedBodyIdx1--; selectedBodyIdx1--;
if (selectedBodyIdx1 < 0) selectedBodyIdx1 = VOID_Core.Instance.allBodies.Count - 1; if (selectedBodyIdx1 < 0) selectedBodyIdx1 = VOID_Core.Instance.allBodies.Count - 1;
} }
GUILayout.Label(VOID_Core.Instance.allBodies[selectedBodyIdx1].bodyName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); GUILayout.Label(VOID_Core.Instance.allBodies[selectedBodyIdx1].bodyName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true));
if (GUILayout.Button(">", GUILayout.ExpandWidth(false))) if (GUILayout.Button(">", GUILayout.ExpandWidth(false)))
{ {
selectedBodyIdx1++; selectedBodyIdx1++;
if (selectedBodyIdx1 > VOID_Core.Instance.allBodies.Count - 1) selectedBodyIdx1 = 0; if (selectedBodyIdx1 > VOID_Core.Instance.allBodies.Count - 1) selectedBodyIdx1 = 0;
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUILayout.EndVertical(); GUILayout.EndVertical();
   
GUILayout.BeginVertical(GUILayout.Width(150)); GUILayout.BeginVertical(GUILayout.Width(150));
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button("<", GUILayout.ExpandWidth(false))) if (GUILayout.Button("<", GUILayout.ExpandWidth(false)))
{ {
selectedBodyIdx2--; selectedBodyIdx2--;
if (selectedBodyIdx2 < 0) selectedBodyIdx2 = VOID_Core.Instance.allBodies.Count - 1; if (selectedBodyIdx2 < 0) selectedBodyIdx2 = VOID_Core.Instance.allBodies.Count - 1;
} }
GUILayout.Label(VOID_Core.Instance.allBodies[selectedBodyIdx2].bodyName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); GUILayout.Label(VOID_Core.Instance.allBodies[selectedBodyIdx2].bodyName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true));
if (GUILayout.Button(">", GUILayout.ExpandWidth(false))) if (GUILayout.Button(">", GUILayout.ExpandWidth(false)))
{ {
selectedBodyIdx2++; selectedBodyIdx2++;
if (selectedBodyIdx2 > VOID_Core.Instance.allBodies.Count - 1) selectedBodyIdx2 = 0; if (selectedBodyIdx2 > VOID_Core.Instance.allBodies.Count - 1) selectedBodyIdx2 = 0;
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUILayout.EndVertical(); GUILayout.EndVertical();
   
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
//}  
   
//toggle for orbital info chunk //toggle for orbital info chunk
if (GUILayout.Button("Orbital Characteristics", GUILayout.ExpandWidth(true))) toggleOrbital = !toggleOrbital; if (GUILayout.Button("Orbital Characteristics", GUILayout.ExpandWidth(true))) toggleOrbital.value = !toggleOrbital;
   
if (toggleOrbital) if (toggleOrbital)
{ {
//begin orbital into horizontal chunk //begin orbital into horizontal chunk
//print("begin orbital info section..."); //print("begin orbital info section...");
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
   
//begin orbital value labels column //begin orbital value labels column
GUILayout.BeginVertical(GUILayout.Width(150)); GUILayout.BeginVertical(GUILayout.Width(150));
   
//print("printing row labels..."); //print("printing row labels...");
   
GUILayout.Label("Apoapsis:"); GUILayout.Label("Apoapsis:");
GUILayout.Label("Time to Ap:"); GUILayout.Label("Time to Ap:");
GUILayout.Label("Periapsis:"); GUILayout.Label("Periapsis:");
GUILayout.Label("Time to Pe:"); GUILayout.Label("Time to Pe:");
GUILayout.Label("Semi-major axis:"); GUILayout.Label("Semi-major axis:");
GUILayout.Label("Eccentricity:"); GUILayout.Label("Eccentricity:");
GUILayout.Label("Orbital period:"); GUILayout.Label("Orbital period:");
GUILayout.Label("Rotational period:"); GUILayout.Label("Rotational period:");
GUILayout.Label("Velocity:"); GUILayout.Label("Velocity:");
GUILayout.Label("Mean anomaly:"); GUILayout.Label("Mean anomaly:");
GUILayout.Label("True anomaly:"); GUILayout.Label("True anomaly:");
GUILayout.Label("Eccentric anomaly:"); GUILayout.Label("Eccentric anomaly:");
GUILayout.Label("Inclination:"); GUILayout.Label("Inclination:");
GUILayout.Label("Long. ascending node:"); GUILayout.Label("Long. ascending node:");
GUILayout.Label("Arg. of periapsis:"); GUILayout.Label("Arg. of periapsis:");
GUILayout.Label("Tidally locked:"); GUILayout.Label("Tidally locked:");
   
//end orbital value labels column //end orbital value labels column
GUILayout.EndVertical(); GUILayout.EndVertical();
   
//begin primary orbital values column //begin primary orbital values column
GUILayout.BeginVertical(GUILayout.Width(150)); GUILayout.BeginVertical(GUILayout.Width(150));
   
body_OP_show_orbital_info(selectedBody1); body_OP_show_orbital_info(selectedBody1);
   
//end primary orbital values column //end primary orbital values column
GUILayout.EndVertical(); GUILayout.EndVertical();
   
//begin secondary orbital values column //begin secondary orbital values column
GUILayout.BeginVertical(GUILayout.Width(150)); GUILayout.BeginVertical(GUILayout.Width(150));
   
body_OP_show_orbital_info(selectedBody2); body_OP_show_orbital_info(selectedBody2);
   
//end secondary orbital values column //end secondary orbital values column
GUILayout.EndVertical(); GUILayout.EndVertical();
   
//end orbital info horizontal chunk //end orbital info horizontal chunk
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
   
//toggle for physical info chunk //toggle for physical info chunk
if (GUILayout.Button("Physical Characteristics", GUILayout.ExpandWidth(true))) togglePhysical = !togglePhysical; if (GUILayout.Button("Physical Characteristics", GUILayout.ExpandWidth(true))) togglePhysical.value = !togglePhysical;
   
if (togglePhysical) if (togglePhysical)
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
   
//begin physical info value label column //begin physical info value label column
GUILayout.BeginVertical(GUILayout.Width(150)); GUILayout.BeginVertical(GUILayout.Width(150));
   
GUILayout.Label("Radius:"); GUILayout.Label("Radius:");
GUILayout.Label("Surface area:"); GUILayout.Label("Surface area:");
GUILayout.Label("Volume:"); GUILayout.Label("Volume:");
GUILayout.Label("Mass:"); GUILayout.Label("Mass:");
GUILayout.Label("Density:"); GUILayout.Label("Density:");
GUILayout.Label("Sphere of influence:"); GUILayout.Label("Sphere of influence:");
GUILayout.Label("Natural satellites:"); GUILayout.Label("Natural satellites:");
GUILayout.Label("Artificial satellites:"); GUILayout.Label("Artificial satellites:");
GUILayout.Label("Surface gravity:"); GUILayout.Label("Surface gravity:");
GUILayout.Label("Atmosphere altitude:"); GUILayout.Label("Atmosphere altitude:");
GUILayout.Label("Atmospheric O\u2082:"); GUILayout.Label("Atmospheric O\u2082:");
GUILayout.Label("Has ocean:"); GUILayout.Label("Has ocean:");
   
//end physical info value label column //end physical info value label column
GUILayout.EndVertical(); GUILayout.EndVertical();
   
//begin primary physical values column //begin primary physical values column
GUILayout.BeginVertical(GUILayout.Width(150)); GUILayout.BeginVertical(GUILayout.Width(150));
   
body_OP_show_physical_info(selectedBody1); body_OP_show_physical_info(selectedBody1);
   
//end primary physical column //end primary physical column
GUILayout.EndVertical(); GUILayout.EndVertical();
   
//begin secondary physical values column //begin secondary physical values column
GUILayout.BeginVertical(GUILayout.Width(150)); GUILayout.BeginVertical(GUILayout.Width(150));
   
body_OP_show_physical_info(selectedBody2); body_OP_show_physical_info(selectedBody2);
   
//end target physical values column //end target physical values column
GUILayout.EndVertical(); GUILayout.EndVertical();
   
//end physical value horizontal chunk //end physical value horizontal chunk
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
   
GUI.DragWindow(); GUI.DragWindow();
} }
   
private void body_OP_show_orbital_info(CelestialBody body) private void body_OP_show_orbital_info(CelestialBody body)
{ {
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); else GUILayout.Label((body.orbit.ApA / 1000).ToString("##,#") + "km", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
else GUILayout.Label((body.orbit.ApA / 1000).ToString("##,#") + "km", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal(); if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
  else GUILayout.Label(Tools.ConvertInterval(body.orbit.timeToAp), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
else GUILayout.Label(Tools.ConvertInterval(body.orbit.timeToAp), VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); else GUILayout.Label((body.orbit.PeA / 1000).ToString("##,#") + "km", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.EndHorizontal();  
  if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); else GUILayout.Label(Tools.ConvertInterval(body.orbit.timeToPe), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
else GUILayout.Label((body.orbit.PeA / 1000).ToString("##,#") + "km", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.EndHorizontal(); else GUILayout.Label((body.orbit.semiMajorAxis / 1000).ToString("##,#") + "km", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); else GUILayout.Label(body.orbit.eccentricity.ToString("F4") + "", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
else GUILayout.Label(Tools.ConvertInterval(body.orbit.timeToPe), VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal(); if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
  else GUILayout.Label(Tools.ConvertInterval(body.orbit.period), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
else GUILayout.Label((body.orbit.semiMajorAxis / 1000).ToString("##,#") + "km", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); else GUILayout.Label(Tools.ConvertInterval(body.rotationPeriod), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.EndHorizontal();  
  if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); else GUILayout.Label((body.orbit.orbitalSpeed / 1000).ToString("F2") + "km/s", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
else GUILayout.Label(body.orbit.eccentricity.ToString("F4") + "", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal();  
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
else GUILayout.Label(Tools.ConvertInterval(body.orbit.period), VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal();  
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
else GUILayout.Label(Tools.ConvertInterval(body.rotationPeriod), VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal();  
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
else GUILayout.Label((body.orbit.orbitalSpeed / 1000).ToString("F2") + "km/s", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal();  
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
// Toadicus edit: convert mean anomaly into degrees. // Toadicus edit: convert mean anomaly into degrees.
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
else GUILayout.Label((body.orbit.meanAnomaly * 180d / Math.PI).ToString("F3") + "°", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); else GUILayout.Label((body.orbit.meanAnomaly * 180d / Math.PI).ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.EndHorizontal();  
  if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); else GUILayout.Label(body.orbit.trueAnomaly.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
else GUILayout.Label(body.orbit.trueAnomaly.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal();  
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
// Toadicus edit: convert eccentric anomaly into degrees. // Toadicus edit: convert eccentric anomaly into degrees.
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
else GUILayout.Label((body.orbit.eccentricAnomaly * 180d / Math.PI).ToString("F3") + "°", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); else GUILayout.Label((body.orbit.eccentricAnomaly * 180d / Math.PI).ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.EndHorizontal();  
  if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); else GUILayout.Label(body.orbit.inclination.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
else GUILayout.Label(body.orbit.inclination.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.EndHorizontal(); else GUILayout.Label(body.orbit.LAN.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); else GUILayout.Label(body.orbit.argumentOfPeriapsis.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
else GUILayout.Label(body.orbit.LAN.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal(); if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
else GUILayout.Label(body.orbit.argumentOfPeriapsis.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal();  
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
if (body.bodyName == "Sun") GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
else else
{ {
string body_tidally_locked = "No"; string body_tidally_locked = "No";
if (body.tidallyLocked) body_tidally_locked = "Yes"; if (body.tidallyLocked) body_tidally_locked = "Yes";
GUILayout.Label(body_tidally_locked, VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); GUILayout.Label(body_tidally_locked, VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
} }
//GUILayout.EndHorizontal();  
} }
   
private void body_OP_show_physical_info(CelestialBody body) private void body_OP_show_physical_info(CelestialBody body)
{ {
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label((body.Radius / 1000).ToString("##,#") + "km", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); GUILayout.Label((body.Radius / 1000).ToString("##,#") + "km", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.EndHorizontal();  
  GUILayout.Label(((Math.Pow((body.Radius), 2) * 4 * Math.PI) / 1000).ToString("0.00e+00") + "km²", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label(((Math.Pow((body.Radius), 2) * 4 * Math.PI) / 1000).ToString("0.00e+00") + "km²", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal();  
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
// divide by 1000 to convert m to km // divide by 1000 to convert m to km
GUILayout.Label((((4d / 3) * Math.PI * Math.Pow(body.Radius, 3)) / 1000).ToString("0.00e+00") + "km³", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); GUILayout.Label((((4d / 3) * Math.PI * Math.Pow(body.Radius, 3)) / 1000).ToString("0.00e+00") + "km³", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.Label(((4 / 3) * Math.PI * Math.Pow((vessel.mainBody.Radius / 1000), 3)).ToString(), txt_right, GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal(); GUILayout.Label(body.Mass.ToString("0.00e+00") + "kg", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label(body.Mass.ToString("0.00e+00") + "kg", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal();  
   
double p = body.Mass / (Math.Pow(body.Radius, 3) * (4d / 3) * Math.PI); double p = body.Mass / (Math.Pow(body.Radius, 3) * (4d / 3) * Math.PI);
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label(p.ToString("##,#") + "kg/m³", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); GUILayout.Label(p.ToString("##,#") + "kg/m³", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.EndHorizontal();  
  if (body.bodyName == "Sun") GUILayout.Label(Tools.MuMech_ToSI(body.sphereOfInfluence), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); else GUILayout.Label(Tools.MuMech_ToSI(body.sphereOfInfluence), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
if (body.bodyName == "Sun") GUILayout.Label(Tools.MuMech_ToSI(body.sphereOfInfluence), VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
else GUILayout.Label(Tools.MuMech_ToSI(body.sphereOfInfluence), VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); GUILayout.Label(body.orbitingBodies.Count.ToString(), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.EndHorizontal();  
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label(body.orbitingBodies.Count.ToString(), VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal();  
   
//show # artificial satellites //show # artificial satellites
int num_art_sats = 0; int num_art_sats = 0;
foreach (Vessel v in FlightGlobals.Vessels) foreach (Vessel v in FlightGlobals.Vessels)
{ {
if (v.mainBody == body && v.situation.ToString() == "ORBITING") num_art_sats++; if (v.mainBody == body && v.situation.ToString() == "ORBITING") num_art_sats++;
} }
   
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.Label(num_art_sats.ToString(), VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
GUILayout.Label(num_art_sats.ToString(), VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true));  
//GUILayout.EndHorizontal();  
   
double g_ASL = (VOID_Core.Constant_G * body.Mass) / Math.Pow(body.Radius, 2); double g_ASL = (VOID_Core.Constant_G * body.Mass) / Math.Pow(body.Radius, 2);
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label(Tools.MuMech_ToSI(g_ASL) + "m/s²", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); GUILayout.Label(Tools.MuMech_ToSI(g_ASL) + "m/s²", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.EndHorizontal();  
  if (body.atmosphere)
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); {
GUILayout.Label("≈ " + Tools.MuMech_ToSI(body.maxAtmosphereAltitude) + "m", VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); GUILayout.Label("≈ " + Tools.MuMech_ToSI(body.maxAtmosphereAltitude) + "m",
//GUILayout.EndHorizontal(); VOID_Core.Instance.LabelStyles["right"],
  GUILayout.ExpandWidth(true));
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
string O2 = "No"; string O2 = "No";
if (body.atmosphereContainsOxygen == true) O2 = "Yes"; if (body.atmosphereContainsOxygen == true) O2 = "Yes";
GUILayout.Label(O2, VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); GUILayout.Label(O2, VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
//GUILayout.EndHorizontal();  
  string ocean = "No";
//GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); if (body.ocean == true) ocean = "Yes";
string ocean = "No"; GUILayout.Label(ocean, VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
if (body.ocean == true) ocean = "Yes"; }
GUILayout.Label(ocean, VOID_Core.Instance.LabelStyles["txt_right"], GUILayout.ExpandWidth(true)); else
//GUILayout.EndHorizontal(); {
  GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
  GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
  GUILayout.Label("N/A", VOID_Core.Instance.LabelStyles["right"], GUILayout.ExpandWidth(true));
  }
} }
} }
} }
// //
// VOID_Core.cs // VOID_Core.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;  
using KSP; using KSP;
using UnityEngine; using UnityEngine;
  using Engineer.VesselSimulator;
   
namespace VOID namespace VOID
{ {
public class VOID_Core : VOID_Module, IVOID_Module public class VOID_Core : VOID_Module, IVOID_Module
{ {
/* /*
* Static Members * Static Members
* */ * */
protected static bool _initialized = false; protected static bool _initialized = false;
   
public static bool Initialized public static bool Initialized
{ {
get get
{ {
return _initialized; return _initialized;
} }
} }
   
protected static VOID_Core _instance; protected static VOID_Core _instance;
   
public static VOID_Core Instance public static VOID_Core Instance
{ {
get get
{ {
if (_instance == null) if (_instance == null)
{ {
_instance = new VOID_Core(); _instance = new VOID_Core();
_initialized = true; _initialized = true;
} }
return _instance; return _instance;
} }
} }
   
public static void Reset() public static void Reset()
{ {
_instance.StopGUI(); _instance.StopGUI();
_instance = null; _instance = null;
_initialized = false; _initialized = false;
} }
   
public static double Constant_G = 6.674e-11; public static double Constant_G = 6.674e-11;
   
/* /*
* Fields * Fields
* */ * */
protected string VoidName = "VOID"; protected string VoidName = "VOID";
protected string VoidVersion = "0.9.11"; protected string VoidVersion = "0.9.20";
   
protected bool _factoryReset = false; protected bool _factoryReset = false;
   
[AVOID_SaveValue("configValue")] [AVOID_SaveValue("configValue")]
protected VOID_SaveValue<int> configVersion = 1; protected VOID_SaveValue<int> configVersion = 1;
   
protected List<IVOID_Module> _modules = new List<IVOID_Module>(); protected List<IVOID_Module> _modules = new List<IVOID_Module>();
protected bool _modulesLoaded = false; protected bool _modulesLoaded = false;
   
[AVOID_SaveValue("mainWindowPos")] [AVOID_SaveValue("mainWindowPos")]
protected VOID_SaveValue<Rect> mainWindowPos = new Rect(475, 575, 10f, 10f); protected VOID_SaveValue<Rect> mainWindowPos = new Rect(475, 575, 10f, 10f);
   
[AVOID_SaveValue("mainGuiMinimized")] [AVOID_SaveValue("mainGuiMinimized")]
protected VOID_SaveValue<bool> mainGuiMinimized = false; protected VOID_SaveValue<bool> mainGuiMinimized = false;
   
[AVOID_SaveValue("configWindowPos")] [AVOID_SaveValue("configWindowPos")]
protected VOID_SaveValue<Rect> configWindowPos = new Rect(825, 625, 10f, 10f); protected VOID_SaveValue<Rect> configWindowPos = new Rect(825, 625, 10f, 10f);
   
[AVOID_SaveValue("configWindowMinimized")] [AVOID_SaveValue("configWindowMinimized")]
   
protected VOID_SaveValue<bool> configWindowMinimized = true; protected VOID_SaveValue<bool> configWindowMinimized = true;
   
[AVOID_SaveValue("VOIDIconPos")] [AVOID_SaveValue("VOIDIconPos")]
protected VOID_SaveValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 30, 30f, 30f); protected VOID_SaveValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 32, 32f, 32f);
protected Texture2D VOIDIconOff = new Texture2D(30, 30, TextureFormat.ARGB32, false);  
protected Texture2D VOIDIconOn = new Texture2D(30, 30, TextureFormat.ARGB32, false);  
protected Texture2D VOIDIconTexture; protected Texture2D VOIDIconTexture;
protected string VOIDIconOnPath = "VOID/Textures/void_icon_on"; protected string VOIDIconOnActivePath;
protected string VOIDIconOffPath = "VOID/Textures/void_icon_off"; protected string VOIDIconOnInactivePath;
  protected string VOIDIconOffActivePath;
  protected string VOIDIconOffInactivePath;
   
protected bool VOIDIconLocked = true; protected bool VOIDIconLocked = true;
   
  protected GUIStyle iconStyle;
   
protected int windowBaseID = -96518722; protected int windowBaseID = -96518722;
protected int _windowID = 0; protected int _windowID = 0;
   
protected bool GUIStylesLoaded = false; protected bool GUIStylesLoaded = false;
   
protected Dictionary<string, GUIStyle> _LabelStyles = new Dictionary<string, GUIStyle>(); protected Dictionary<string, GUIStyle> _LabelStyles = new Dictionary<string, GUIStyle>();
   
  protected CelestialBody _Kerbin;
   
[AVOID_SaveValue("togglePower")] [AVOID_SaveValue("togglePower")]
public VOID_SaveValue<bool> togglePower = true; public VOID_SaveValue<bool> togglePower = true;
   
public bool powerAvailable = true; public bool powerAvailable = true;
   
[AVOID_SaveValue("consumeResource")] [AVOID_SaveValue("consumeResource")]
protected VOID_SaveValue<bool> consumeResource = false; protected VOID_SaveValue<bool> consumeResource = false;
   
[AVOID_SaveValue("resourceName")] [AVOID_SaveValue("resourceName")]
protected VOID_SaveValue<string> resourceName = "ElectricCharge"; protected VOID_SaveValue<string> resourceName = "ElectricCharge";
   
[AVOID_SaveValue("resourceRate")] [AVOID_SaveValue("resourceRate")]
protected VOID_SaveValue<float> resourceRate = 0.2f; protected VOID_SaveValue<float> resourceRate = 0.2f;
   
// Celestial Body Housekeeping [AVOID_SaveValue("updatePeriod")]
protected List<CelestialBody> _allBodies = new List<CelestialBody>(); protected VOID_SaveValue<double> _updatePeriod = 1001f / 15000f;
protected bool bodiesLoaded = false; protected float _updateTimer = 0f;
  protected string stringFrequency;
   
// Vessel Type Housekeeping // Vessel Type Housekeeping
protected List<VesselType> _allVesselTypes = new List<VesselType>(); protected List<VesselType> _allVesselTypes = new List<VesselType>();
protected bool vesselTypesLoaded = false; protected bool vesselTypesLoaded = false;
   
public float saveTimer = 0; public float saveTimer = 0;
   
  protected string defaultSkin = "KSP window 2";
[AVOID_SaveValue("defaultSkin")] [AVOID_SaveValue("defaultSkin")]
protected VOID_SaveValue<string> defaultSkin = "KSP window 2"; protected VOID_SaveValue<string> _skinName;
protected int _skinIdx = int.MinValue; protected Dictionary<string, GUISkin> skin_list;
protected List<GUISkin> skin_list; protected List<string> skinNames;
protected string[] forbiddenSkins = protected string[] forbiddenSkins =
{ {
"PlaqueDialogSkin", "PlaqueDialogSkin",
"FlagBrowserSkin", "FlagBrowserSkin",
"SSUITextAreaDefault", "SSUITextAreaDefault",
"ExperimentsDialogSkin", "ExperimentsDialogSkin",
"ExpRecoveryDialogSkin", "ExpRecoveryDialogSkin",
"KSP window 5", "KSP window 5",
"KSP window 6" "KSP window 6",
}; "PartTooltipSkin"
  };
protected bool skinsLoaded = false; protected bool skinsLoaded = false;
   
public bool configDirty; public bool configDirty;
   
  [AVOID_SaveValue("UseBlizzyToolbar")]
  protected VOID_SaveValue<bool> _UseToolbarManager;
  internal IButton ToolbarButton;
   
/* /*
* Properties * Properties
* */ * */
public bool factoryReset public bool factoryReset
{ {
get get
{ {
return this._factoryReset; return this._factoryReset;
} }
} }
   
public List<IVOID_Module> Modules public List<IVOID_Module> Modules
{ {
get get
{ {
return this._modules; return this._modules;
} }
} }
   
public GUISkin Skin public GUISkin Skin
{ {
get get
{ {
if (this.skin_list == null || this._skinIdx < 0 || this._skinIdx > this.skin_list.Count) if (!this.skinsLoaded || this._skinName == null)
{ {
return AssetBase.GetGUISkin(this.defaultSkin); return AssetBase.GetGUISkin(this.defaultSkin);
} }
return this.skin_list[this._skinIdx]; return this.skin_list[this._skinName];
} }
} }
   
public int windowID public int windowID
{ {
get get
{ {
if (this._windowID == 0) if (this._windowID == 0)
{ {
this._windowID = this.windowBaseID; this._windowID = this.windowBaseID;
} }
return this._windowID++; return this._windowID++;
} }
} }
   
public Dictionary<string, GUIStyle> LabelStyles public Dictionary<string, GUIStyle> LabelStyles
{ {
get get
{ {
return this._LabelStyles; return this._LabelStyles;
} }
} }
   
public List<CelestialBody> allBodies public List<CelestialBody> allBodies
{ {
get get
{ {
return this._allBodies; return FlightGlobals.Bodies;
  }
  }
   
  public CelestialBody Kerbin
  {
  get
  {
  if (this._Kerbin == null)
  {
  if (FlightGlobals.Bodies != null)
  {
  this._Kerbin = FlightGlobals.Bodies.First(b => b.name == "Kerbin");
  }
  }
   
  return this._Kerbin;
} }
} }
   
public List<VesselType> allVesselTypes public List<VesselType> allVesselTypes
{ {
get get
{ {
return this._allVesselTypes; return this._allVesselTypes;
  }
  }
   
  public float updateTimer
  {
  get
  {
  return this._updateTimer;
  }
  }
   
  public double updatePeriod
  {
  get
  {
  return this._updatePeriod;
  }
  }
   
  protected IconState powerState
  {
  get
  {
  if (this.togglePower && this.powerAvailable)
  {
  return IconState.PowerOn;
  }
  else
  {
  return IconState.PowerOff;
  }
   
  }
  }
   
  protected IconState activeState
  {
  get
  {
  if (this.mainGuiMinimized)
  {
  return IconState.Inactive;
  }
  else
  {
  return IconState.Active;
  }
   
  }
  }
   
  protected bool UseToolbarManager
  {
  get
  {
  return _UseToolbarManager;
  }
  set
  {
  if (this._UseToolbarManager == value)
  {
  return;
  }
   
  if (value == false && this.ToolbarButton != null)
  {
  this.ToolbarButton.Destroy();
  this.ToolbarButton = null;
  }
  if (value == true && this.ToolbarButton == null)
  {
  this.InitializeToolbarButton();
  }
   
  this.SetIconTexture(this.powerState | this.activeState);
   
  _UseToolbarManager.value = value;
} }
} }
   
/* /*
* Methods * Methods
* */ * */
protected VOID_Core() public override void DrawGUI()
{ {
this._Name = "VOID Core"; this._windowID = this.windowBaseID;
   
this._Active = true; if (!this._modulesLoaded)
  {
this.VOIDIconOn = GameDatabase.Instance.GetTexture (this.VOIDIconOnPath, false); this.LoadModulesOfType<IVOID_Module>();
this.VOIDIconOff = GameDatabase.Instance.GetTexture (this.VOIDIconOffPath, false); }
   
this.LoadConfig (); if (!this.skinsLoaded)
} {
  this.LoadSkins();
protected void LoadModulesOfType<T>() }
{  
var types = AssemblyLoader.loadedAssemblies GUI.skin = this.Skin;
.Select (a => a.assembly.GetExportedTypes ())  
.SelectMany (t => t) if (!this.GUIStylesLoaded)
.Where (v => typeof(T).IsAssignableFrom (v) {
&& !(v.IsInterface || v.IsAbstract) && this.LoadGUIStyles();
!typeof(VOID_Core).IsAssignableFrom (v) }
);  
  if (!this.UseToolbarManager)
Tools.PostDebugMessage (string.Format ( {
"{0}: Found {1} modules to check.", if (GUI.Button(VOIDIconPos, VOIDIconTexture, this.iconStyle) && this.VOIDIconLocked)
this.GetType ().Name, {
types.Count () this.ToggleMainWindow();
)); }
foreach (var voidType in types) }
{ else if (this.ToolbarButton == null)
if (!HighLogic.LoadedSceneIsEditor && {
typeof(IVOID_EditorModule).IsAssignableFrom(voidType) this.InitializeToolbarButton();
) }
{  
continue; if (!this.mainGuiMinimized)
} {
   
Tools.PostDebugMessage (string.Format ( Rect _mainWindowPos = this.mainWindowPos;
"{0}: found Type {1}",  
this.GetType ().Name, _mainWindowPos = GUILayout.Window(
voidType.Name this.windowID,
)); _mainWindowPos,
  this.VOIDMainWindow,
this.LoadModule(voidType); string.Join(" ", new string[] { this.VoidName, this.VoidVersion }),
} GUILayout.Width(250),
  GUILayout.Height(50)
this._modulesLoaded = true; );
   
Tools.PostDebugMessage(string.Format( _mainWindowPos = Tools.ClampRectToScreen(_mainWindowPos);
"{0}: Loaded {1} modules.",  
this.GetType().Name, if (_mainWindowPos != this.mainWindowPos)
this.Modules.Count {
)); this.mainWindowPos = _mainWindowPos;
} }
  }
protected void LoadModule(Type T)  
{ if (!this.configWindowMinimized && !this.mainGuiMinimized)
var existingModules = this._modules.Where (mod => mod.GetType ().Name == T.Name); {
if (existingModules.Any()) Rect _configWindowPos = this.configWindowPos;
{  
Tools.PostDebugMessage(string.Format( _configWindowPos = GUILayout.Window(
"{0}: refusing to load {1}: already loaded", this.windowID,
this.GetType().Name, _configWindowPos,
T.Name this.VOIDConfigWindow,
)); string.Join(" ", new string[] { this.VoidName, "Configuration" }),
  GUILayout.Width(250),
  GUILayout.Height(50)
  );
   
  _configWindowPos = Tools.ClampRectToScreen(_configWindowPos);
   
  if (_configWindowPos != this.configWindowPos)
  {
  this.configWindowPos = _configWindowPos;
  }
  }
  }
   
  public void OnGUI()
  {
  if (Event.current.type == EventType.Repaint)
  {
return; return;
} }
IVOID_Module module = Activator.CreateInstance (T) as IVOID_Module;  
module.LoadConfig(); /*
this._modules.Add (module);  
   
Tools.PostDebugMessage(string.Format(  
"{0}: loaded module {1}.",  
this.GetType().Name,  
T.Name  
));  
}  
   
protected void Preload_BeforeUpdate()  
{  
if (!this.bodiesLoaded)  
{  
this.LoadAllBodies();  
}  
   
if (!this.vesselTypesLoaded)  
{  
this.LoadVesselTypes();  
}  
}  
   
public void Update()  
{  
this.Preload_BeforeUpdate ();  
   
if (!this.guiRunning)  
{  
this.StartGUI ();  
}  
   
if (!HighLogic.LoadedSceneIsFlight && this.guiRunning)  
{  
this.StopGUI ();  
}  
   
foreach (IVOID_Module module in this.Modules)  
{  
if (!module.guiRunning && module.toggleActive)  
{  
module.StartGUI ();  
}  
if (module.guiRunning && !module.toggleActive ||  
!this.togglePower ||  
!HighLogic.LoadedSceneIsFlight  
|| this.factoryReset  
)  
{  
module.StopGUI();  
}  
   
if (module is IVOID_BehaviorModule)  
{  
((IVOID_BehaviorModule)module).Update();  
}  
}  
   
this.CheckAndSave ();  
}  
   
public void FixedUpdate()  
{  
if (this.consumeResource &&  
this.vessel.vesselType != VesselType.EVA &&  
TimeWarp.deltaTime != 0  
)  
{  
float powerReceived = this.vessel.rootPart.RequestResource(this.resourceName,  
this.resourceRate * TimeWarp.fixedDeltaTime);  
if (powerReceived > 0)  
{  
this.powerAvailable = true;  
}  
else  
{  
this.powerAvailable = false;  
}  
}  
   
foreach (IVOID_BehaviorModule module in  
this._modules.OfType<IVOID_BehaviorModule>().Where(m => !m.GetType().IsAbstract))  
{  
module.FixedUpdate();  
}  
}  
   
protected void LoadSkins()  
{  
this.skin_list = AssetBase.FindObjectsOfTypeIncludingAssets(typeof(GUISkin))  
.Where(s => !this.forbiddenSkins.Contains(s.name))  
.Select(s => s as GUISkin)  
.ToList();  
   
Tools.PostDebugMessage(string.Format(  
"{0}: loaded {1} GUISkins.",  
this.GetType().Name,  
this.skin_list.Count  
));  
   
if (this._skinIdx == int.MinValue)  
{  
this._skinIdx = this.skin_list.IndexOf(this.Skin);  
Tools.PostDebugMessage(string.Format(  
"{0}: resetting _skinIdx to default.",  
this.GetType().Name  
));  
}  
   
Tools.PostDebugMessage(string.Format(  
"{0}: _skinIdx = {1}.",  
this.GetType().Name,  
this._skinIdx.ToString()  
));  
   
this.skinsLoaded = true;  
}  
   
protected void LoadGUIStyles()  
{  
this.LabelStyles["center"] = new GUIStyle(GUI.skin.label);  
this.LabelStyles["center"].normal.textColor = Color.white;  
this.LabelStyles["center"].alignment = TextAnchor.UpperCenter;  
   
this.LabelStyles["center_bold"] = new GUIStyle(GUI.skin.label);  
this.LabelStyles["center_bold"].normal.textColor = Color.white;  
this.LabelStyles["center_bold"].alignment = TextAnchor.UpperCenter;  
this.LabelStyles["center_bold"].fontStyle = FontStyle.Bold;  
   
this.LabelStyles["txt_right"] = new GUIStyle(GUI.skin.label);  
this.LabelStyles["txt_right"].normal.textColor = Color.white;  
this.LabelStyles["txt_right"].alignment = TextAnchor.UpperRight;  
   
this.GUIStylesLoaded = true;  
}  
   
   
protected void LoadAllBodies()  
{  
this._allBodies = FlightGlobals.Bodies;  
this.bodiesLoaded = true;  
}  
   
protected void LoadVesselTypes()  
{  
this._allVesselTypes = Enum.GetValues(typeof(VesselType)).OfType<VesselType>().ToList();  
this.vesselTypesLoaded = true;  
}  
   
protected void CheckAndSave()  
{  
this.saveTimer += Time.deltaTime;  
   
Tools.PostDebugMessage (string.Format (  
"{0}: Checking if time to save; saveTimer: {1}",  
this.GetType ().Name,  
this.saveTimer  
));  
   
if (this.saveTimer > 2f)  
{  
Tools.PostDebugMessage (string.Format (  
"{0}: Time to save, checking if configDirty: {1}",  
this.GetType ().Name,  
this.configDirty  
));  
   
if (!this.configDirty)  
{  
return;  
}  
   
this.SaveConfig ();  
this.saveTimer = 0;  
}  
}  
   
public void VOIDMainWindow(int _)  
{  
GUILayout.BeginVertical();  
   
if (this.powerAvailable || HighLogic.LoadedSceneIsEditor)  
{  
if (!HighLogic.LoadedSceneIsEditor)  
{  
string str = "ON";  
if (togglePower) str = "OFF";  
if (GUILayout.Button("Power " + str)) togglePower = !togglePower;  
}  
   
if (togglePower || HighLogic.LoadedSceneIsEditor)  
{  
foreach (IVOID_Module module in this.Modules)  
{  
module.toggleActive = GUILayout.Toggle (module.toggleActive, module.Name);  
}  
}  
}  
else  
{  
GUIStyle label_txt_red = new GUIStyle(GUI.skin.label);  
label_txt_red.normal.textColor = Color.red;  
label_txt_red.alignment = TextAnchor.MiddleCenter;  
GUILayout.Label("-- POWER LOST --", label_txt_red);  
}  
   
this.configWindowMinimized = !GUILayout.Toggle (!this.configWindowMinimized, "Configuration");  
   
GUILayout.EndVertical();  
GUI.DragWindow();  
}  
   
public void VOIDConfigWindow(int _)  
{  
GUILayout.BeginVertical ();  
   
this.DrawConfigurables ();  
   
GUILayout.EndVertical ();  
GUI.DragWindow ();  
}  
   
public override void DrawConfigurables()  
{  
if (HighLogic.LoadedSceneIsFlight)  
{  
this.consumeResource = GUILayout.Toggle (this.consumeResource, "Consume Resources");  
   
this.VOIDIconLocked = GUILayout.Toggle (this.VOIDIconLocked, "Lock Icon Position");  
}  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
   
GUILayout.Label("Skin:", GUILayout.ExpandWidth(false));  
   
GUIContent _content = new GUIContent();  
   
_content.text = "◄";  
_content.tooltip = "Select previous skin";  
if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))  
{  
this._skinIdx--;  
if (this._skinIdx < 0) this._skinIdx = skin_list.Count - 1;  
Tools.PostDebugMessage (string.Format (  
"{0}: new this._skinIdx = {1} :: skin_list.Count = {2}",  
this.GetType().Name,  
this._skinIdx,  
this.skin_list.Count  
));  
}  
   
string skin_name = skin_list[this._skinIdx].name;  
_content.text = skin_name;  
_content.tooltip = "Current skin";  
GUILayout.Label(_content, this.LabelStyles["center"], GUILayout.ExpandWidth(true));  
   
_content.text = "►";  
_content.tooltip = "Select next skin";  
if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))  
{  
this._skinIdx++;  
if (this._skinIdx >= skin_list.Count) this._skinIdx = 0;  
Tools.PostDebugMessage (string.Format (  
"{0}: new this._skinIdx = {1} :: skin_list.Count = {2}",  
this.GetType().Name,  
this._skinIdx,  
this.skin_list.Count  
));  
}  
   
if (this.Skin.name != this.defaultSkin)  
{  
this.defaultSkin = this.Skin.name;  
}  
   
GUILayout.EndHorizontal();  
   
foreach (IVOID_Module mod in this.Modules)  
{  
mod.DrawConfigurables ();  
}  
   
this._factoryReset = GUILayout.Toggle (this._factoryReset, "Factory Reset");  
}  
   
public void OnGUI()  
{  
if (Event.current.type == EventType.Repaint)  
{  
return;  
}  
   
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"Event.current.type: {0}" + "Event.current.type: {0}" +
"\nthis.VOIDIconLocked: {1}" + "\nthis.VOIDIconLocked: {1}" +
"\nEvent.current.mousePosition: {2}" + "\nEvent.current.mousePosition: {2}" +
"\nVOIDIconPos: ({3}, {4}),({5}, {6})", "\nVOIDIconPos: ({3}, {4}),({5}, {6})",
Event.current.type, Event.current.type,
this.VOIDIconLocked, this.VOIDIconLocked,
Event.current.mousePosition, Event.current.mousePosition,
this.VOIDIconPos.value.xMin, this.VOIDIconPos.value.xMin,
this.VOIDIconPos.value.yMin, this.VOIDIconPos.value.yMin,
this.VOIDIconPos.value.xMax, this.VOIDIconPos.value.xMax,
this.VOIDIconPos.value.yMax this.VOIDIconPos.value.yMax
)); ));
  */
   
if (!this.VOIDIconLocked && if (!this.VOIDIconLocked &&
VOIDIconPos.value.Contains(Event.current.mousePosition) VOIDIconPos.value.Contains(Event.current.mousePosition)
&& Event.current.type == EventType.mouseDrag && Event.current.type == EventType.mouseDrag)
)  
{ {
Tools.PostDebugMessage(string.Format( Tools.PostDebugMessage(string.Format(
"Event.current.type: {0}" + "Event.current.type: {0}" +
"\ndelta.x: {1}; delta.y: {2}", "\ndelta.x: {1}; delta.y: {2}",
Event.current.type, Event.current.type,
Event.current.delta.x, Event.current.delta.x,
Event.current.delta.y Event.current.delta.y
)); ));
   
Rect tmp = new Rect(VOIDIconPos); Rect tmp = new Rect(VOIDIconPos);
   
tmp.x = Event.current.mousePosition.x - tmp.width / 2; tmp.x = Event.current.mousePosition.x - tmp.width / 2;
tmp.y = Event.current.mousePosition.y - tmp.height / 2; tmp.y = Event.current.mousePosition.y - tmp.height / 2;
   
if (tmp.x > Screen.width - tmp.width) if (tmp.x > Screen.width - tmp.width)
{ {
tmp.x = Screen.width - tmp.width; tmp.x = Screen.width - tmp.width;
} }
   
if (tmp.y > Screen.height - tmp.height) if (tmp.y > Screen.height - tmp.height)
{ {
tmp.y = Screen.height - tmp.height; tmp.y = Screen.height - tmp.height;
} }
   
VOIDIconPos = tmp; VOIDIconPos = tmp;
} }
} }
   
public override void DrawGUI() public void Update()
{ {
if (!this._modulesLoaded) this.LoadBeforeUpdate();
{  
this.LoadModulesOfType<IVOID_Module> (); if (this.vessel != null)
} {
  SimManager.Instance.Gravity = VOID_Core.Instance.vessel.mainBody.gravParameter /
this._windowID = this.windowBaseID; Math.Pow(VOID_Core.Instance.vessel.Radius(), 2);
  SimManager.Instance.TryStartSimulation();
if (!this.skinsLoaded) }
{  
this.LoadSkins(); if (!this.guiRunning)
} {
  this.StartGUI();
GUI.skin = this.Skin; }
   
if (!this.GUIStylesLoaded) if (!HighLogic.LoadedSceneIsFlight && this.guiRunning)
{ {
this.LoadGUIStyles (); this.StopGUI();
} }
   
this.VOIDIconTexture = this.VOIDIconOff; //icon off default foreach (IVOID_Module module in this.Modules)
if (this.togglePower) this.VOIDIconTexture = this.VOIDIconOn; //or on if power_toggle==true {
if (GUI.Button(VOIDIconPos, VOIDIconTexture, new GUIStyle()) && this.VOIDIconLocked) if (!module.guiRunning && module.toggleActive)
{ {
this.mainGuiMinimized = !this.mainGuiMinimized; module.StartGUI();
} }
  if (module.guiRunning && !module.toggleActive ||
if (!this.mainGuiMinimized) !this.togglePower ||
{ !HighLogic.LoadedSceneIsFlight ||
Rect _mainWindowPos = this.mainWindowPos; this.factoryReset)
  {
_mainWindowPos = GUILayout.Window ( module.StopGUI();
this.windowID, }
_mainWindowPos,  
this.VOIDMainWindow, if (module is IVOID_BehaviorModule)
string.Join (" ", new string[] {this.VoidName, this.VoidVersion}), {
GUILayout.Width (250), ((IVOID_BehaviorModule)module).Update();
GUILayout.Height (50) }
  }
   
  this.CheckAndSave();
  this._updateTimer += Time.deltaTime;
  }
   
  public void FixedUpdate()
  {
  bool newPowerState = this.powerAvailable;
   
  if (this.togglePower && this.consumeResource &&
  this.vessel.vesselType != VesselType.EVA &&
  TimeWarp.deltaTime != 0)
  {
  float powerReceived = this.vessel.rootPart.RequestResource(
  this.resourceName,
  this.resourceRate * TimeWarp.fixedDeltaTime
); );
   
_mainWindowPos = Tools.ClampRectToScreen (_mainWindowPos); if (powerReceived > 0)
  {
if (_mainWindowPos != this.mainWindowPos) newPowerState = true;
{ }
this.mainWindowPos = _mainWindowPos; else
} {
} newPowerState = false;
  }
if (!this.configWindowMinimized)  
{ if (this.powerAvailable != newPowerState)
Rect _configWindowPos = this.configWindowPos; {
  this.powerAvailable = newPowerState;
_configWindowPos = GUILayout.Window ( this.SetIconTexture(this.powerState | this.activeState);
this.windowID, }
_configWindowPos, }
this.VOIDConfigWindow,  
string.Join (" ", new string[] {this.VoidName, "Configuration"}), foreach (IVOID_BehaviorModule module in
GUILayout.Width (250), this._modules.OfType<IVOID_BehaviorModule>().Where(m => !m.GetType().IsAbstract))
GUILayout.Height (50) {
  module.FixedUpdate();
  }
  }
   
  public void ResetGUI()
  {
  this.StopGUI();
   
  foreach (IVOID_Module module in this.Modules)
  {
  module.StopGUI();
  module.StartGUI();
  }
   
  this.StartGUI();
  }
   
  public void VOIDMainWindow(int _)
  {
  GUILayout.BeginVertical();
   
  if (this.powerAvailable || HighLogic.LoadedSceneIsEditor)
  {
  if (!HighLogic.LoadedSceneIsEditor)
  {
  string str = string.Intern("ON");
  if (togglePower)
  str = string.Intern("OFF");
  if (GUILayout.Button("Power " + str))
  {
  togglePower.value = !togglePower;
  this.SetIconTexture(this.powerState | this.activeState);
  }
  }
   
  if (togglePower || HighLogic.LoadedSceneIsEditor)
  {
  foreach (IVOID_Module module in this.Modules)
  {
  module.toggleActive = GUILayout.Toggle(module.toggleActive, module.Name);
  }
  }
  }
  else
  {
  GUILayout.Label("-- POWER LOST --", this.LabelStyles["red"]);
  }
   
  this.configWindowMinimized.value = !GUILayout.Toggle(!this.configWindowMinimized, "Configuration");
   
  GUILayout.EndVertical();
  GUI.DragWindow();
  }
   
  public void VOIDConfigWindow(int _)
  {
  GUILayout.BeginVertical();
   
  this.DrawConfigurables();
   
  GUILayout.EndVertical();
  GUI.DragWindow();
  }
   
  public override void DrawConfigurables()
  {
  int skinIdx;
   
  GUIContent _content;
   
  if (HighLogic.LoadedSceneIsFlight)
  {
  this.consumeResource.value = GUILayout.Toggle(this.consumeResource, "Consume Resources");
   
  this.VOIDIconLocked = GUILayout.Toggle(this.VOIDIconLocked, "Lock Icon Position");
  }
   
  this.UseToolbarManager = GUILayout.Toggle(this.UseToolbarManager, "Use Blizzy's Toolbar If Available");
   
  GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
   
  GUILayout.Label("Skin:", GUILayout.ExpandWidth(false));
   
  _content = new GUIContent();
   
  if (skinNames.Contains(this._skinName))
  {
  skinIdx = skinNames.IndexOf(this._skinName);
  }
  else if (skinNames.Contains(this.defaultSkin))
  {
  skinIdx = skinNames.IndexOf(this.defaultSkin);
  }
  else
  {
  skinIdx = 0;
  }
   
  _content.text = "◄";
  _content.tooltip = "Select previous skin";
  if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))
  {
  this.GUIStylesLoaded = false;
  skinIdx--;
  if (skinIdx < 0)
  skinIdx = skinNames.Count - 1;
  Tools.PostDebugMessage(string.Format(
  "{0}: new this._skinIdx = {1} :: skin_list.Count = {2}",
  this.GetType().Name,
  this._skinName,
  this.skin_list.Count
  ));
  }
   
  _content.text = this.Skin.name;
  _content.tooltip = "Current skin";
  GUILayout.Label(_content, this.LabelStyles["center"], GUILayout.ExpandWidth(true));
   
  _content.text = "►";
  _content.tooltip = "Select next skin";
  if (GUILayout.Button(_content, GUILayout.ExpandWidth(true)))
  {
  this.GUIStylesLoaded = false;
  skinIdx++;
  if (skinIdx >= skinNames.Count)
  skinIdx = 0;
  Tools.PostDebugMessage(string.Format(
  "{0}: new this._skinIdx = {1} :: skin_list.Count = {2}",
  this.GetType().Name,
  this._skinName,
  this.skin_list.Count
  ));
  }
   
  if (this._skinName != skinNames[skinIdx])
  {
  this._skinName = skinNames[skinIdx];
  }
   
  GUILayout.EndHorizontal();
   
  GUILayout.BeginHorizontal();
  GUILayout.Label("Update Rate (Hz):");
  if (this.stringFrequency == null)
  {
  this.stringFrequency = (1f / this.updatePeriod).ToString();
  }
  this.stringFrequency = GUILayout.TextField(this.stringFrequency.ToString(), 5, GUILayout.ExpandWidth(true));
  // GUILayout.FlexibleSpace();
  if (GUILayout.Button("Apply"))
  {
  double updateFreq = 1f / this.updatePeriod;
  double.TryParse(stringFrequency, out updateFreq);
  this._updatePeriod = 1 / updateFreq;
  }
  GUILayout.EndHorizontal();
   
  foreach (IVOID_Module mod in this.Modules)
  {
  mod.DrawConfigurables();
  }
   
  this._factoryReset = GUILayout.Toggle(this._factoryReset, "Factory Reset");
  }
   
  protected void LoadModulesOfType<T>()
  {
  var types = AssemblyLoader.loadedAssemblies
  .Select(a => a.assembly.GetExportedTypes())
  .SelectMany(t => t)
  .Where(v => typeof(T).IsAssignableFrom(v)
  && !(v.IsInterface || v.IsAbstract) &&
  !typeof(VOID_Core).IsAssignableFrom(v)
); );
   
_configWindowPos = Tools.ClampRectToScreen (_configWindowPos); Tools.PostDebugMessage(string.Format(
  "{0}: Found {1} modules to check.",
if (_configWindowPos != this.configWindowPos) this.GetType().Name,
{ types.Count()
this.configWindowPos = _configWindowPos; ));
} foreach (var voidType in types)
} {
} if (!HighLogic.LoadedSceneIsEditor &&
  typeof(IVOID_EditorModule).IsAssignableFrom(voidType))
public void ResetGUI() {
{ continue;
this.StopGUI (); }
   
  Tools.PostDebugMessage(string.Format(
  "{0}: found Type {1}",
  this.GetType().Name,
  voidType.Name
  ));
   
  this.LoadModule(voidType);
  }
   
  this._modulesLoaded = true;
   
  Tools.PostDebugMessage(string.Format(
  "{0}: Loaded {1} modules.",
  this.GetType().Name,
  this.Modules.Count
  ));
  }
   
  protected void LoadModule(Type T)
  {
  var existingModules = this._modules.Where(mod => mod.GetType().Name == T.Name);
  if (existingModules.Any())
  {
  Tools.PostDebugMessage(string.Format(
  "{0}: refusing to load {1}: already loaded",
  this.GetType().Name,
  T.Name
  ));
  return;
  }
  IVOID_Module module = Activator.CreateInstance(T) as IVOID_Module;
  module.LoadConfig();
  this._modules.Add(module);
   
  Tools.PostDebugMessage(string.Format(
  "{0}: loaded module {1}.",
  this.GetType().Name,
  T.Name
  ));
  }
   
  protected void LoadSkins()
  {
  Tools.PostDebugMessage("AssetBase has skins: \n" +
  string.Join("\n\t",
  Resources.FindObjectsOfTypeAll(typeof(GUISkin))
  .Select(s => s.ToString())
  .ToArray()
  )
  );
   
  this.skin_list = Resources.FindObjectsOfTypeAll(typeof(GUISkin))
  .Where(s => !this.forbiddenSkins.Contains(s.name))
  .Select(s => s as GUISkin)
  .GroupBy(s => s.name)
  .Select(g => g.First())
  .ToDictionary(s => s.name);
   
  Tools.PostDebugMessage(string.Format(
  "{0}: loaded {1} GUISkins.",
  this.GetType().Name,
  this.skin_list.Count
  ));
   
  this.skinNames = this.skin_list.Keys.ToList();
  this.skinNames.Sort();
   
  if (this._skinName == null || !this.skinNames.Contains(this._skinName))
  {
  this._skinName = this.defaultSkin;
  Tools.PostDebugMessage(string.Format(
  "{0}: resetting _skinIdx to default.",
  this.GetType().Name
  ));
  }
   
  Tools.PostDebugMessage(string.Format(
  "{0}: _skinIdx = {1}.",
  this.GetType().Name,
  this._skinName.ToString()
  ));
   
  this.skinsLoaded = true;
  }
   
  protected void LoadGUIStyles()
  {
  this.LabelStyles["link"] = new GUIStyle(GUI.skin.label);
  this.LabelStyles["link"].fontStyle = FontStyle.Bold;
   
  this.LabelStyles["center"] = new GUIStyle(GUI.skin.label);
  this.LabelStyles["center"].normal.textColor = Color.white;
  this.LabelStyles["center"].alignment = TextAnchor.UpperCenter;
   
  this.LabelStyles["center_bold"] = new GUIStyle(GUI.skin.label);
  this.LabelStyles["center_bold"].normal.textColor = Color.white;
  this.LabelStyles["center_bold"].alignment = TextAnchor.UpperCenter;
  this.LabelStyles["center_bold"].fontStyle = FontStyle.Bold;
   
  this.LabelStyles["right"] = new GUIStyle(GUI.skin.label);
  this.LabelStyles["right"].normal.textColor = Color.white;
  this.LabelStyles["right"].alignment = TextAnchor.UpperRight;
   
  this.LabelStyles["red"] = new GUIStyle(GUI.skin.label);
  this.LabelStyles["red"].normal.textColor = Color.red;
  this.LabelStyles["red"].alignment = TextAnchor.MiddleCenter;
   
  this.iconStyle = new GUIStyle(GUI.skin.button);
  this.iconStyle.padding = new RectOffset(0, 0, 0, 0);
  // this.iconStyle.margin = new RectOffset(0, 0, 0, 0);
  // this.iconStyle.contentOffset = new Vector2(0, 0);
  this.iconStyle.overflow = new RectOffset(0, 0, 0, 0);
  // this.iconStyle.border = new RectOffset(0, 0, 0, 0);
   
  this.GUIStylesLoaded = true;
  }
   
  protected void LoadVesselTypes()
  {
  this._allVesselTypes = Enum.GetValues(typeof(VesselType)).OfType<VesselType>().ToList();
  this.vesselTypesLoaded = true;
  }
   
  protected void LoadBeforeUpdate()
  {
  if (!this.vesselTypesLoaded)
  {
  this.LoadVesselTypes();
  }
  }
   
  protected void InitializeToolbarButton()
  {
  this.ToolbarButton = ToolbarManager.Instance.add(this.VoidName, "coreToggle");
  this.ToolbarButton.Text = this.VoidName;
  this.SetIconTexture(this.powerState | this.activeState);
   
  this.ToolbarButton.Visibility = new GameScenesVisibility(GameScenes.EDITOR, GameScenes.FLIGHT, GameScenes.SPH);
   
  this.ToolbarButton.OnClick +=
  (e) =>
  {
  this.ToggleMainWindow();
  };
  }
   
  protected void ToggleMainWindow()
  {
  this.mainGuiMinimized = !this.mainGuiMinimized;
  this.SetIconTexture(this.powerState | this.activeState);
  }
   
  protected void SetIconTexture(IconState state)
  {
  switch (state)
  {
  case (IconState.PowerOff | IconState.Inactive):
  this.SetIconTexture(this.VOIDIconOffInactivePath);
  break;
  case (IconState.PowerOff | IconState.Active):
  this.SetIconTexture(this.VOIDIconOffActivePath);
  break;
  case (IconState.PowerOn | IconState.Inactive):
  this.SetIconTexture(this.VOIDIconOnInactivePath);
  break;
  case (IconState.PowerOn | IconState.Active):
  this.SetIconTexture(this.VOIDIconOnActivePath);
  break;
  default:
  throw new NotImplementedException();
  }
  }
   
  protected void SetIconTexture(string texturePath)
  {
  if (this.UseToolbarManager && this.ToolbarButton != null)
  {
  this.ToolbarButton.TexturePath = texturePath;
  }
  else
  {
  this.VOIDIconTexture = GameDatabase.Instance.GetTexture(texturePath, false);
  }
  }
   
  protected void CheckAndSave()
  {
  this.saveTimer += Time.deltaTime;
   
  if (this.saveTimer > 2f)
  {
  if (!this.configDirty)
  {
  return;
  }
   
  Tools.PostDebugMessage(string.Format(
  "{0}: Time to save, checking if configDirty: {1}",
  this.GetType().Name,
  this.configDirty
  ));
   
  this.SaveConfig();
  this.saveTimer = 0;
  }
  }
   
  public override void LoadConfig()
  {
  base.LoadConfig();
   
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
module.StopGUI (); module.LoadConfig();
module.StartGUI (); }
} }
   
this.StartGUI (); public void SaveConfig()
} {
  var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core>();
public override void LoadConfig() config.load();
{  
base.LoadConfig (); this._SaveToConfig(config);
   
foreach (IVOID_Module module in this.Modules) foreach (IVOID_Module module in this.Modules)
{ {
module.LoadConfig (); module._SaveToConfig(config);
}  
}  
   
public void SaveConfig()  
{  
var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core> ();  
config.load ();  
   
this._SaveToConfig(config);  
   
foreach (IVOID_Module module in this.Modules)  
{  
module._SaveToConfig (config);  
} }
   
config.save(); config.save();
   
this.configDirty = false; this.configDirty = false;
  }
   
  protected VOID_Core()
  {
  this._Name = "VOID Core";
   
  this._Active.value = true;
   
  this._skinName = this.defaultSkin;
   
  this.VOIDIconOnActivePath = "VOID/Textures/void_icon_light_glow";
  this.VOIDIconOnInactivePath = "VOID/Textures/void_icon_dark_glow";
  this.VOIDIconOffActivePath = "VOID/Textures/void_icon_light";
  this.VOIDIconOffInactivePath = "VOID/Textures/void_icon_dark";
   
  this.UseToolbarManager = false;
   
  this.LoadConfig();
   
  this.SetIconTexture(this.powerState | this.activeState);
  }
   
  protected enum IconState
  {
  PowerOff = 1,
  PowerOn = 2,
  Inactive = 4,
  Active = 8
} }
} }
} }
   
   
// //
// VOID_Orbital.cs // VOID_Orbital.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using KSP; using KSP;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_DataLogger : VOID_WindowModule, IVOID_BehaviorModule public class VOID_DataLogger : VOID_WindowModule, IVOID_BehaviorModule
{ {
/* /*
* Fields * Fields
* */ * */
protected bool stopwatch1_running = false; protected bool stopwatch1_running;
   
protected bool csv_logging = false; protected bool csv_logging;
protected bool first_write = true; protected bool first_write;
   
protected double stopwatch1 = 0; protected double stopwatch1;
   
protected string csv_log_interval_str = "0.5"; protected string csv_log_interval_str;
   
protected float csv_log_interval; protected float csv_log_interval;
   
protected double csvWriteTimer = 0; protected double csvWriteTimer;
protected double csvCollectTimer = 0; protected double csvCollectTimer;
   
protected List<string> csvList = new List<string>(); protected List<string> csvList = new List<string>();
   
/* /*
* Properties * Properties
* */ * */
   
   
/* /*
* Methods * Methods
* */ * */
public VOID_DataLogger() public VOID_DataLogger()
{ {
this._Name = "CSV Data Logger"; this._Name = "CSV Data Logger";
   
  this.stopwatch1_running = false;
   
  this.csv_logging = false;
  this.first_write = true;
   
  this.stopwatch1 = 0;
  this.csv_log_interval_str = "0.5";
   
  this.csvWriteTimer = 0;
  this.csvCollectTimer = 0;
   
this.WindowPos.x = Screen.width - 520; this.WindowPos.x = Screen.width - 520;
this.WindowPos.y = 85; this.WindowPos.y = 85;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
GUIStyle txt_white = new GUIStyle(GUI.skin.label); GUIStyle txt_white = new GUIStyle(GUI.skin.label);
txt_white.normal.textColor = txt_white.focused.textColor = Color.white; txt_white.normal.textColor = txt_white.focused.textColor = Color.white;
txt_white.alignment = TextAnchor.UpperRight; txt_white.alignment = TextAnchor.UpperRight;
GUIStyle txt_green = new GUIStyle(GUI.skin.label); GUIStyle txt_green = new GUIStyle(GUI.skin.label);
txt_green.normal.textColor = txt_green.focused.textColor = Color.green; txt_green.normal.textColor = txt_green.focused.textColor = Color.green;
txt_green.alignment = TextAnchor.UpperRight; txt_green.alignment = TextAnchor.UpperRight;
GUIStyle txt_yellow = new GUIStyle(GUI.skin.label); GUIStyle txt_yellow = new GUIStyle(GUI.skin.label);
txt_yellow.normal.textColor = txt_yellow.focused.textColor = Color.yellow; txt_yellow.normal.textColor = txt_yellow.focused.textColor = Color.yellow;
txt_yellow.alignment = TextAnchor.UpperRight; txt_yellow.alignment = TextAnchor.UpperRight;
   
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
GUILayout.Label("System time: " + DateTime.Now.ToString("HH:mm:ss")); GUILayout.Label("System time: " + DateTime.Now.ToString("HH:mm:ss"));
GUILayout.Label(Tools.ConvertInterval(stopwatch1)); GUILayout.Label(Tools.ConvertInterval(stopwatch1));
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button("Start")) if (GUILayout.Button("Start"))
{ {
if (stopwatch1_running == false) stopwatch1_running = true; if (stopwatch1_running == false) stopwatch1_running = true;
} }
if (GUILayout.Button("Stop")) if (GUILayout.Button("Stop"))
{ {
if (stopwatch1_running == true) stopwatch1_running = false; if (stopwatch1_running == true) stopwatch1_running = false;
} }
if (GUILayout.Button("Reset")) if (GUILayout.Button("Reset"))
{ {
if (stopwatch1_running == true) stopwatch1_running = false; if (stopwatch1_running == true) stopwatch1_running = false;
stopwatch1 = 0; stopwatch1 = 0;
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUIStyle label_style = txt_white; GUIStyle label_style = txt_white;
string log_label = "Inactive"; string log_label = "Inactive";
if (csv_logging && vessel.situation.ToString() == "PRELAUNCH") if (csv_logging && vessel.situation.ToString() == "PRELAUNCH")
{ {
log_label = "Awaiting launch"; log_label = "Awaiting launch";
label_style = txt_yellow; label_style = txt_yellow;
} }
if (csv_logging && vessel.situation.ToString() != "PRELAUNCH") if (csv_logging && vessel.situation.ToString() != "PRELAUNCH")
{ {
log_label = "Active"; log_label = "Active";
label_style = txt_green; label_style = txt_green;
} }
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
csv_logging = GUILayout.Toggle(csv_logging, "Data logging: ", GUILayout.ExpandWidth(false)); csv_logging = GUILayout.Toggle(csv_logging, "Data logging: ", GUILayout.ExpandWidth(false));
GUILayout.Label(log_label, label_style, GUILayout.ExpandWidth(true)); GUILayout.Label(log_label, label_style, GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Interval: ", GUILayout.ExpandWidth(false)); GUILayout.Label("Interval: ", GUILayout.ExpandWidth(false));
csv_log_interval_str = GUILayout.TextField(csv_log_interval_str, GUILayout.ExpandWidth(true)); csv_log_interval_str = GUILayout.TextField(csv_log_interval_str, GUILayout.ExpandWidth(true));
GUILayout.Label("s", GUILayout.ExpandWidth(false)); GUILayout.Label("s", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
float new_log_interval; float new_log_interval;
if (Single.TryParse(csv_log_interval_str, out new_log_interval)) csv_log_interval = new_log_interval; if (Single.TryParse(csv_log_interval_str, out new_log_interval)) csv_log_interval = new_log_interval;
   
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
   
public void Update() public void Update()
{ {
// CSV Logging // CSV Logging
// from ISA MapSat // from ISA MapSat
if (csv_logging) if (csv_logging)
{ {
//data logging is on //data logging is on
//increment timers //increment timers
csvWriteTimer += Time.deltaTime; csvWriteTimer += Time.deltaTime;
csvCollectTimer += Time.deltaTime; csvCollectTimer += Time.deltaTime;
   
if (csvCollectTimer >= csv_log_interval && vessel.situation != Vessel.Situations.PRELAUNCH) if (csvCollectTimer >= csv_log_interval && vessel.situation != Vessel.Situations.PRELAUNCH)
{ {
//data logging is on, vessel is not prelaunch, and interval has passed //data logging is on, vessel is not prelaunch, and interval has passed
//write a line to the list //write a line to the list
line_to_csvList(); //write to the csv line_to_csvList(); //write to the csv
} }
   
if (csvList.Count != 0 && csvWriteTimer >= 15f) if (csvList.Count != 0 && csvWriteTimer >= 15f)
{ {
// csvList is not empty and interval between writings to file has elapsed // csvList is not empty and interval between writings to file has elapsed
//write it //write it
string[] csvData; string[] csvData;
csvData = (string[])csvList.ToArray(); csvData = (string[])csvList.ToArray();
Innsewerants_writeData(csvData); Innsewerants_writeData(csvData);
csvList.Clear(); csvList.Clear();
csvWriteTimer = 0f; csvWriteTimer = 0f;
} }
} }
else else
{ {
//data logging is off //data logging is off
//reset any timers and clear anything from csvList //reset any timers and clear anything from csvList
csvWriteTimer = 0f; csvWriteTimer = 0f;
csvCollectTimer = 0f; csvCollectTimer = 0f;
if (csvList.Count > 0) csvList.Clear(); if (csvList.Count > 0) csvList.Clear();
} }
   
if (stopwatch1_running) if (stopwatch1_running)
{ {
stopwatch1 += Time.deltaTime; stopwatch1 += Time.deltaTime;
} }
} }
   
public void FixedUpdate() {} public void FixedUpdate() {}
   
private void Innsewerants_writeData(string[] csvArray) private void Innsewerants_writeData(string[] csvArray)
{ {
var efile = KSP.IO.File.AppendText<VOID_Core>(vessel.vesselName + "_data.csv", null); var efile = KSP.IO.File.AppendText<VOID_Core>(vessel.vesselName + "_data.csv", null);
foreach (string line in csvArray) foreach (string line in csvArray)
{ {
efile.Write(line); efile.Write(line);
} }
efile.Close(); efile.Close();
} }
   
private void line_to_csvList() private void line_to_csvList()
{ {
//called if logging is on and interval has passed //called if logging is on and interval has passed
//writes one line to the csvList //writes one line to the csvList
   
string line = ""; string line = "";
if (first_write && !KSP.IO.File.Exists<VOID_Core>(vessel.vesselName + "_data.csv", null)) if (first_write && !KSP.IO.File.Exists<VOID_Core>(vessel.vesselName + "_data.csv", null))
{ {
first_write = false; first_write = false;
line += "Mission Elapsed Time (s);Altitude ASL (m);Altitude above terrain (m);Orbital Velocity (m/s);Surface Velocity (m/s);Vertical Speed (m/s);Horizontal Speed (m/s);Gee Force (gees);Temperature (°C);Gravity (m/s²);Atmosphere Density (g/m³);\n"; line += "Mission Elapsed Time (s);Altitude ASL (m);Altitude above terrain (m);Orbital Velocity (m/s);Surface Velocity (m/s);Vertical Speed (m/s);Horizontal Speed (m/s);Gee Force (gees);Temperature (°C);Gravity (m/s²);Atmosphere Density (g/m³);\n";
} }
//Mission time //Mission time
line += vessel.missionTime.ToString("F3") + ";"; line += vessel.missionTime.ToString("F3") + ";";
//Altitude ASL //Altitude ASL
line += vessel.orbit.altitude.ToString("F3") + ";"; line += vessel.orbit.altitude.ToString("F3") + ";";
//Altitude (true) //Altitude (true)
double alt_true = vessel.orbit.altitude - vessel.terrainAltitude; double alt_true = vessel.orbit.altitude - vessel.terrainAltitude;
if (vessel.terrainAltitude < 0) alt_true = vessel.orbit.altitude; if (vessel.terrainAltitude < 0) alt_true = vessel.orbit.altitude;
line += alt_true.ToString("F3") + ";"; line += alt_true.ToString("F3") + ";";
//Orbital velocity //Orbital velocity
line += vessel.orbit.vel.magnitude.ToString("F3") + ";"; line += vessel.orbit.vel.magnitude.ToString("F3") + ";";
//surface velocity //surface velocity
line += vessel.srf_velocity.magnitude.ToString("F3") + ";"; line += vessel.srf_velocity.magnitude.ToString("F3") + ";";
//vertical speed //vertical speed
line += vessel.verticalSpeed.ToString("F3") + ";"; line += vessel.verticalSpeed.ToString("F3") + ";";
//horizontal speed //horizontal speed
line += vessel.horizontalSrfSpeed.ToString("F3") + ";"; line += vessel.horizontalSrfSpeed.ToString("F3") + ";";
//gee force //gee force
line += vessel.geeForce.ToString("F3") + ";"; line += vessel.geeForce.ToString("F3") + ";";
//temperature //temperature
line += vessel.flightIntegrator.getExternalTemperature().ToString("F2") + ";"; line += vessel.flightIntegrator.getExternalTemperature().ToString("F2") + ";";
//gravity //gravity
double r_vessel = vessel.mainBody.Radius + vessel.mainBody.GetAltitude(vessel.findWorldCenterOfMass()); double r_vessel = vessel.mainBody.Radius + vessel.mainBody.GetAltitude(vessel.findWorldCenterOfMass());
double g_vessel = (VOID_Core.Constant_G * vessel.mainBody.Mass) / Math.Pow(r_vessel, 2); double g_vessel = (VOID_Core.Constant_G * vessel.mainBody.Mass) / Math.Pow(r_vessel, 2);
line += g_vessel.ToString("F3") + ";"; line += g_vessel.ToString("F3") + ";";
//atm density //atm density
line += (vessel.atmDensity * 1000).ToString("F3") + ";"; line += (vessel.atmDensity * 1000).ToString("F3") + ";";
line += "\n"; line += "\n";
if (csvList.Contains(line) == false) csvList.Add(line); if (csvList.Contains(line) == false) csvList.Add(line);
csvCollectTimer = 0f; csvCollectTimer = 0f;
} }
} }
} }
file:b/VOID_DataValue.cs (new)
  //
  // VOID_DataValue.cs
  //
  // Author:
  // toadicus <>
  //
  // Copyright (c) 2013 toadicus
  //
  // This program is free software: you can redistribute it and/or modify
  // it under the terms of the GNU General Public License as published by
  // the Free Software Foundation, either version 3 of the License, or
  // (at your option) any later version.
  //
  // This program is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  // GNU General Public License for more details.
  //
  // You should have received a copy of the GNU General Public License
  // along with this program. If not, see <http://www.gnu.org/licenses/>.
  using System;
  using UnityEngine;
 
  namespace VOID
  {
  public interface IVOID_DataValue
  {
  void Refresh();
  string ValueUnitString();
  void DoGUIHorizontal();
  }
 
  public class VOID_DataValue<T> : IVOID_DataValue
  {
  /*
  * Static Members
  * */
  public static implicit operator T(VOID_DataValue<T> v)
  {
  return (T)v.Value;
  }
 
  /*
  * Instance Members
  * */
  /*
  * Fields
  * */
  protected T cache;
  protected Func<T> ValueFunc;
 
  /*
  * Properties
  * */
  public string Label { get; protected set; }
  public string Units { get; protected set; }
 
  public T Value {
  get {
  return (T)this.cache;
  }
  }
 
  /*
  * Methods
  * */
  public VOID_DataValue(string Label, Func<T> ValueFunc, string Units = "")
  {
  this.Label = Label;
  this.Units = Units;
  this.ValueFunc = ValueFunc;
  }
 
  public void Refresh()
  {
  this.cache = this.ValueFunc.Invoke ();
  }
 
  public T GetFreshValue()
  {
  this.Refresh ();
  return (T)this.cache;
  }
 
  public string ValueUnitString() {
  return this.Value.ToString() + this.Units;
  }
 
  public virtual void DoGUIHorizontal()
  {
  GUILayout.BeginHorizontal (GUILayout.ExpandWidth (true));
  GUILayout.Label (this.Label + ":");
  GUILayout.FlexibleSpace ();
  GUILayout.Label (this.ValueUnitString(), GUILayout.ExpandWidth (false));
  GUILayout.EndHorizontal ();
  }
 
  public override string ToString()
  {
  return string.Format (
  "{0}: {1}{2}",
  this.Label,
  this.Value.ToString (),
  this.Units
  );
  }
  }
 
  internal interface IVOID_NumericValue
  {
  double ToDouble();
  string ToString(string format);
  string ToSIString(int digits, int MinMagnitude, int MaxMagnitude);
  }
 
  public abstract class VOID_NumValue<T> : VOID_DataValue<T>, IVOID_NumericValue
  {
  public VOID_NumValue(string Label, Func<T> ValueFunc, string Units = "") : base(Label, ValueFunc, Units) {}
 
  public abstract double ToDouble();
  public abstract string ToString(string Format);
  public abstract string ToSIString(int digits = 3, int MinMagnitude = 0, int MaxMagnitude = int.MaxValue);
 
  public abstract string ValueUnitString(string format);
 
  public virtual string ValueUnitString(int digits) {
  return Tools.MuMech_ToSI(this.ToDouble(), digits) + this.Units;
  }
 
  public virtual string ValueUnitString(int digits, int MinMagnitude, int MaxMagnitude)
  {
  return Tools.MuMech_ToSI(this.ToDouble(), digits, MinMagnitude, MaxMagnitude) + this.Units;
  }
 
  public virtual void DoGUIHorizontal(string format)
  {
  GUILayout.BeginHorizontal (GUILayout.ExpandWidth (true));
  GUILayout.Label (this.Label + ":");
  GUILayout.FlexibleSpace ();
  GUILayout.Label (this.ValueUnitString(format), GUILayout.ExpandWidth (false));
  GUILayout.EndHorizontal ();
  }
 
  public virtual int DoGUIHorizontal(int digits, bool precisionButton = true)
  {
  if (precisionButton)
  {
  return this.DoGUIHorizontalPrec(digits);
  }
 
  GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
  GUILayout.Label(this.Label + ":", GUILayout.ExpandWidth(true));
  GUILayout.FlexibleSpace();
  GUILayout.Label(this.ValueUnitString(digits), GUILayout.ExpandWidth(false));
  GUILayout.EndHorizontal();
 
  return digits;
  }
 
  public virtual int DoGUIHorizontalPrec(int digits)
  {
  float magnitude;
  float magLimit;
 
  magnitude = (float)Math.Log10(Math.Abs(this.ToDouble()));
 
  magLimit = Mathf.Max(magnitude, 6f);
  magLimit = Mathf.Round((float)Math.Ceiling(magLimit / 3f) * 3f);
 
  GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
  GUILayout.Label(this.Label + "ⁱ:", GUILayout.ExpandWidth(true));
  GUILayout.FlexibleSpace();
 
  GUILayout.Label(this.ValueUnitString(3, int.MinValue, (int)magnitude - digits), GUILayout.ExpandWidth(false));
  GUILayout.EndHorizontal();
 
  if (Event.current.type == EventType.mouseUp)
  {
  Rect lastRect = GUILayoutUtility.GetLastRect();
  if (lastRect.Contains(Event.current.mousePosition))
  {
  if (Event.current.button == 0)
  {
  digits = (digits + 3) % (int)magLimit;
  }
  else if (Event.current.button == 1)
  {
  digits = (digits - 3) % (int)magLimit;
  if (digits < 0)
  {
  digits = (int)magLimit - 3;
  }
  }
  }
  }
 
  return digits;
  }
  }
 
  public class VOID_DoubleValue : VOID_NumValue<double>, IVOID_NumericValue
  {
  public VOID_DoubleValue(string Label, Func<double> ValueFunc, string Units) : base(Label, ValueFunc, Units) {}
 
  public override double ToDouble ()
  {
  return this.Value;
  }
 
  public override string ToString(string format)
  {
  return string.Format (
  "{0}: {1}{2}",
  this.Label,
  this.Value.ToString (format),
  this.Units
  );
  }
 
  public override string ValueUnitString(string format) {
  return this.Value.ToString(format) + this.Units;
  }
 
  public override string ToSIString(int digits = 3, int MinMagnitude = 0, int MaxMagnitude = int.MaxValue)
  {
  return string.Format (
  "{0}{1}",
  Tools.MuMech_ToSI (this.Value, digits, MinMagnitude, MaxMagnitude),
  this.Units
  );
  }
  }
  public class VOID_FloatValue : VOID_NumValue<float>, IVOID_NumericValue
  {
  public VOID_FloatValue(string Label, Func<float> ValueFunc, string Units) : base(Label, ValueFunc, Units) {}
 
  public override double ToDouble ()
  {
  return (double)this.Value;
  }
 
  public override string ValueUnitString(string format) {
  return this.Value.ToString(format) + this.Units;
  }
 
  public override string ToString(string format)
  {
  return string.Format (
  "{0}: {1}{2}",
  this.Label,
  this.Value.ToString (format),
  this.Units
  );
  }
 
  public override string ToSIString(int digits = 3, int MinMagnitude = 0, int MaxMagnitude = int.MaxValue)
  {
  return string.Format (
  "{0}{1}",
  Tools.MuMech_ToSI ((double)this.Value, digits, MinMagnitude, MaxMagnitude),
  this.Units
  );
  }
  }
  public class VOID_IntValue : VOID_NumValue<int>, IVOID_NumericValue
  {
  public VOID_IntValue(string Label, Func<int> ValueFunc, string Units) : base(Label, ValueFunc, Units) {}
 
  public override double ToDouble ()
  {
  return (double)this.Value;
  }
 
  public override string ValueUnitString(string format) {
  return this.Value.ToString(format) + this.Units;
  }
 
  public override string ToString(string format)
  {
  return string.Format (
  "{0}: {1}{2}",
  this.Label,
  this.Value.ToString (format),
  this.Units
  );
  }
 
  public override string ToSIString(int digits = 3, int MinMagnitude = 0, int MaxMagnitude = int.MaxValue)
  {
  return string.Format (
  "{0}{1}",
  Tools.MuMech_ToSI ((double)this.Value, digits, MinMagnitude, MaxMagnitude),
  this.Units
  );
  }
  }
 
 
  public class VOID_StrValue : VOID_DataValue<string>
  {
  public VOID_StrValue(string Label, Func<string> ValueFunc) : base(Label, ValueFunc, "") {}
  }
  }
 
 
// //
// VOID_EditorCore.cs // VOID_EditorCore.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using Engineer.VesselSimulator; using Engineer.VesselSimulator;
using KSP; using KSP;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_EditorCore : VOID_Core public class VOID_EditorCore : VOID_Core
{ {
/* /*
* Static Members * Static Members
* */ * */
protected new static bool _initialized = false; protected new static bool _initialized = false;
public new static bool Initialized public new static bool Initialized
{ {
get get
{ {
return _initialized; return _initialized;
} }
} }
   
protected new static VOID_EditorCore _instance; protected new static VOID_EditorCore _instance;
public new static VOID_EditorCore Instance public new static VOID_EditorCore Instance
{ {
get get
{ {
if (_instance == null) if (_instance == null)
{ {
_instance = new VOID_EditorCore(); _instance = new VOID_EditorCore();
_initialized = true; _initialized = true;
} }
return _instance; return _instance;
} }
} }
   
public new static void Reset() public new static void Reset()
{ {
if (_initialized) if (_initialized)
{ {
_instance.StopGUI(); _instance.StopGUI();
_instance = null; _instance = null;
_initialized = false; _initialized = false;
} }
} }
   
public VOID_EditorCore() : base() public VOID_EditorCore() : base()
{ {
this._Name = "VOID Editor Core"; this._Name = "VOID Editor Core";
} }
   
public new void OnGUI() {} public new void OnGUI() {}
   
public override void DrawGUI() public override void DrawGUI()
{ {
if (!this._modulesLoaded) if (!this._modulesLoaded)
{ {
this.LoadModulesOfType<IVOID_EditorModule>(); this.LoadModulesOfType<IVOID_EditorModule>();
} }
   
Rect _iconPos = Tools.DockToWindow (this.VOIDIconPos, this.mainWindowPos); Rect _iconPos = Tools.DockToWindow (this.VOIDIconPos, this.mainWindowPos);
   
_iconPos = Tools.ClampRectToScreen (_iconPos, (int)_iconPos.width, (int)_iconPos.height); _iconPos = Tools.ClampRectToScreen (_iconPos, (int)_iconPos.width, (int)_iconPos.height);
   
if (_iconPos != this.VOIDIconPos) if (_iconPos != this.VOIDIconPos)
{ {
this.VOIDIconPos = _iconPos; this.VOIDIconPos = _iconPos;
} }
   
base.DrawGUI(); base.DrawGUI();
} }
   
public new void Update() public new void Update()
{ {
foreach (IVOID_EditorModule module in this.Modules) foreach (IVOID_EditorModule module in this.Modules)
{ {
if (EditorLogic.startPod == null) if (EditorLogic.startPod == null)
{ {
module.StopGUI(); module.StopGUI();
continue; continue;
} }
if (HighLogic.LoadedSceneIsEditor && module.toggleActive && EditorLogic.SortedShipList.Any()) if (HighLogic.LoadedSceneIsEditor && module.toggleActive && EditorLogic.SortedShipList.Any())
{ {
module.StartGUI(); module.StartGUI();
} }
if (!HighLogic.LoadedSceneIsEditor || !module.toggleActive || !EditorLogic.SortedShipList.Any()) if (!HighLogic.LoadedSceneIsEditor || !module.toggleActive || !EditorLogic.SortedShipList.Any())
{ {
module.StopGUI(); module.StopGUI();
} }
} }
   
if (EditorLogic.startPod == null || !HighLogic.LoadedSceneIsEditor) if (EditorLogic.startPod == null || !HighLogic.LoadedSceneIsEditor)
{ {
this.StopGUI(); this.StopGUI();
return; return;
} }
else if (!this.guiRunning && HighLogic.LoadedSceneIsEditor) else if (!this.guiRunning && HighLogic.LoadedSceneIsEditor)
{ {
this.StartGUI(); this.StartGUI();
} }
   
if (EditorLogic.SortedShipList.Count > 0) if (EditorLogic.SortedShipList.Count > 0)
{ {
SimManager.Instance.Gravity = 9.08665; SimManager.Instance.Gravity = this.Kerbin.gravParameter /
  Math.Pow(this.Kerbin.Radius, 2);
SimManager.Instance.TryStartSimulation(); SimManager.Instance.TryStartSimulation();
} }
   
this.CheckAndSave (); this.CheckAndSave ();
} }
   
public new void FixedUpdate() {} public new void FixedUpdate() {}
} }
} }
   
   
// //
// VOID_Hud.cs // VOID_Hud.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
   
using Engineer.VesselSimulator; using Engineer.VesselSimulator;
using KSP; using KSP;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
  using System.Linq;
  using System.Text;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_EditorHUD : VOID_Module, IVOID_EditorModule public class VOID_EditorHUD : VOID_Module, IVOID_EditorModule
{ {
/* /*
* Fields * Fields
* */ * */
[AVOID_SaveValue("colorIndex")] [AVOID_SaveValue("colorIndex")]
protected VOID_SaveValue<int> _colorIndex = 0; protected VOID_SaveValue<int> _colorIndex = 0;
   
protected List<Color> textColors = new List<Color>(); protected List<Color> textColors = new List<Color>();
   
protected GUIStyle labelStyle; protected GUIStyle labelStyle;
   
  protected EditorVesselOverlays _vesselOverlays;
   
/* /*
* Properties * Properties
* */ * */
public int ColorIndex public int ColorIndex
{ {
get get
{ {
return this._colorIndex; return this._colorIndex;
} }
set set
{ {
if (this._colorIndex >= this.textColors.Count - 1) if (this._colorIndex >= this.textColors.Count - 1)
{ {
this._colorIndex = 0; this._colorIndex = 0;
return; return;
} }
   
this._colorIndex = value; this._colorIndex = value;
} }
} }
   
  protected EditorVesselOverlays vesselOverlays
  {
  get
  {
  if (this._vesselOverlays == null)
  {
  this._vesselOverlays = (EditorVesselOverlays)Resources
  .FindObjectsOfTypeAll(typeof(EditorVesselOverlays))
  .FirstOrDefault();
  }
   
  return this._vesselOverlays;
  }
  }
   
  protected EditorMarker_CoM CoMmarker
  {
  get
  {
  if (this.vesselOverlays == null)
  {
  return null;
  }
   
  return this.vesselOverlays.CoMmarker;
  }
  }
   
  protected EditorMarker_CoT CoTmarker
  {
  get
  {
  if (this.vesselOverlays == null)
  {
  return null;
  }
   
  return this.vesselOverlays.CoTmarker;
  }
  }
   
/* /*
* Methods * Methods
* */ * */
public VOID_EditorHUD() : base() public VOID_EditorHUD() : base()
{ {
this._Name = "Heads-Up Display"; this._Name = "Heads-Up Display";
   
this._Active = true; this._Active.value = true;
   
this.textColors.Add(Color.green); this.textColors.Add(Color.green);
this.textColors.Add(Color.black); this.textColors.Add(Color.black);
this.textColors.Add(Color.white); this.textColors.Add(Color.white);
this.textColors.Add(Color.red); this.textColors.Add(Color.red);
this.textColors.Add(Color.blue); this.textColors.Add(Color.blue);
this.textColors.Add(Color.yellow); this.textColors.Add(Color.yellow);
this.textColors.Add(Color.gray); this.textColors.Add(Color.gray);
this.textColors.Add(Color.cyan); this.textColors.Add(Color.cyan);
this.textColors.Add(Color.magenta); this.textColors.Add(Color.magenta);
   
this.labelStyle = new GUIStyle (); this.labelStyle = new GUIStyle ();
// this.labelStyle.alignment = TextAnchor.UpperRight; // this.labelStyle.alignment = TextAnchor.UpperRight;
this.labelStyle.normal.textColor = this.textColors [this.ColorIndex]; this.labelStyle.normal.textColor = this.textColors [this.ColorIndex];
   
Tools.PostDebugMessage (this.GetType().Name + ": Constructed."); Tools.PostDebugMessage (this.GetType().Name + ": Constructed.");
} }
   
public override void DrawGUI() public override void DrawGUI()
{ {
SimManager.Instance.RequestSimulation(); SimManager.Instance.RequestSimulation();
   
if (SimManager.Instance.LastStage == null) if (SimManager.Instance.LastStage == null)
{ {
return; return;
} }
   
float hudLeft; float hudLeft;
  StringBuilder hudString;
   
if (EditorLogic.fetch.editorScreen == EditorLogic.EditorScreen.Parts) if (EditorLogic.fetch.editorScreen == EditorLogic.EditorScreen.Parts)
{ {
hudLeft = EditorPanels.Instance.partsPanelWidth + 10; hudLeft = EditorPanels.Instance.partsPanelWidth + 10;
} }
else if (EditorLogic.fetch.editorScreen == EditorLogic.EditorScreen.Actions) else if (EditorLogic.fetch.editorScreen == EditorLogic.EditorScreen.Actions)
{ {
hudLeft = EditorPanels.Instance.actionsPanelWidth + 10; hudLeft = EditorPanels.Instance.actionsPanelWidth + 10;
} }
else else
{ {
return; return;
} }
   
Rect hudPos = new Rect (hudLeft, 48, 300, 32); Rect hudPos = new Rect (hudLeft, 48, 300, 32);
   
  hudString = new StringBuilder();
   
// GUI.skin = AssetBase.GetGUISkin("KSP window 2"); // GUI.skin = AssetBase.GetGUISkin("KSP window 2");
   
labelStyle.normal.textColor = textColors [ColorIndex]; labelStyle.normal.textColor = textColors [ColorIndex];
   
  hudString.Append("Total Mass: ");
  hudString.Append(SimManager.Instance.LastStage.totalMass.ToString("F3"));
  hudString.Append('t');
   
  hudString.Append(' ');
   
  hudString.Append("Part Count: ");
  hudString.Append(EditorLogic.SortedShipList.Count);
   
  hudString.Append('\n');
   
  hudString.Append("Total Delta-V: ");
  hudString.Append(Tools.MuMech_ToSI(SimManager.Instance.LastStage.totalDeltaV));
  hudString.Append("m/s");
   
  hudString.Append('\n');
   
  hudString.Append("Bottom Stage Delta-V");
  hudString.Append(Tools.MuMech_ToSI(SimManager.Instance.LastStage.deltaV));
  hudString.Append("m/s");
   
  hudString.Append('\n');
   
  hudString.Append("Bottom Stage T/W Ratio: ");
  hudString.Append(SimManager.Instance.LastStage.thrustToWeight.ToString("F3"));
   
  if (this.CoMmarker.gameObject.activeInHierarchy && this.CoTmarker.gameObject.activeInHierarchy)
  {
  hudString.Append('\n');
   
  hudString.Append("Thrust Offset: ");
  hudString.Append(
  Vector3.Cross(
  this.CoTmarker.dirMarkerObject.transform.forward,
  this.CoMmarker.posMarkerObject.transform.position - this.CoTmarker.posMarkerObject.transform.position
  ).ToString("F3"));
  }
   
GUI.Label ( GUI.Label (
hudPos, hudPos,
"Total Mass: " + SimManager.Instance.LastStage.totalMass.ToString("F3") + "t" + hudString.ToString(),
" Part Count: " + EditorLogic.SortedShipList.Count +  
"\nTotal Delta-V: " + Tools.MuMech_ToSI(SimManager.Instance.LastStage.totalDeltaV) + "m/s" +  
"\nBottom Stage Delta-V: " + Tools.MuMech_ToSI(SimManager.Instance.LastStage.deltaV) + "m/s" +  
"\nBottom Stage T/W Ratio: " + SimManager.Instance.LastStage.thrustToWeight.ToString("F3"),  
labelStyle); labelStyle);
} }
   
public override void DrawConfigurables() public override void DrawConfigurables()
{ {
if (GUILayout.Button ("Change HUD color", GUILayout.ExpandWidth (false))) if (GUILayout.Button ("Change HUD color", GUILayout.ExpandWidth (false)))
{ {
++this.ColorIndex; ++this.ColorIndex;
} }
} }
} }
} }
   
// //
// VOID_Hud.cs // VOID_Hud.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
   
using KSP; using KSP;
using UnityEngine; using UnityEngine;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
   
namespace VOID namespace VOID
{ {
public class VOID_HUD : VOID_Module, IVOID_Module public class VOID_HUD : VOID_Module, IVOID_Module
{ {
/* /*
* Fields * Fields
* */ * */
[AVOID_SaveValue("colorIndex")] [AVOID_SaveValue("colorIndex")]
protected VOID_SaveValue<int> _colorIndex = 0; protected VOID_SaveValue<int> _colorIndex = 0;
   
protected List<Color> textColors = new List<Color>(); protected List<Color> textColors = new List<Color>();
   
protected GUIStyle labelStyle;  
   
/* /*
* Properties * Properties
* */ * */
public int ColorIndex public int ColorIndex
{ {
get get
{ {
return this._colorIndex; return this._colorIndex;
} }
set set
{ {
if (this._colorIndex >= this.textColors.Count - 1) if (this._colorIndex >= this.textColors.Count - 1)
{ {
this._colorIndex = 0; this._colorIndex = 0;
return; return;
} }
   
this._colorIndex = value; this._colorIndex = value;
} }
} }
   
/* /*
* Methods * Methods
* */ * */
public VOID_HUD() : base() public VOID_HUD() : base()
{ {
this._Name = "Heads-Up Display"; this._Name = "Heads-Up Display";
   
this._Active = true; this._Active.value = true;
   
this.textColors.Add(Color.green); this.textColors.Add(Color.green);
this.textColors.Add(Color.black); this.textColors.Add(Color.black);
this.textColors.Add(Color.white); this.textColors.Add(Color.white);
this.textColors.Add(Color.red); this.textColors.Add(Color.red);
this.textColors.Add(Color.blue); this.textColors.Add(Color.blue);
this.textColors.Add(Color.yellow); this.textColors.Add(Color.yellow);
this.textColors.Add(Color.gray); this.textColors.Add(Color.gray);
this.textColors.Add(Color.cyan); this.textColors.Add(Color.cyan);
this.textColors.Add(Color.magenta); this.textColors.Add(Color.magenta);
   
this.labelStyle = new GUIStyle (); VOID_Core.Instance.LabelStyles["hud"] = new GUIStyle();
this.labelStyle.normal.textColor = this.textColors [this.ColorIndex]; VOID_Core.Instance.LabelStyles["hud"].normal.textColor = this.textColors [this.ColorIndex];
   
Tools.PostDebugMessage ("VOID_HUD: Constructed."); Tools.PostDebugMessage ("VOID_HUD: Constructed.");
} }
   
public override void DrawGUI() public override void DrawGUI()
{ {
GUI.skin = VOID_Core.Instance.Skin; GUI.skin = VOID_Core.Instance.Skin;
   
if (VOID_Core.Instance.powerAvailable) if (VOID_Core.Instance.powerAvailable)
{ {
labelStyle.normal.textColor = textColors [ColorIndex]; VOID_Core.Instance.LabelStyles["hud"].normal.textColor = textColors [ColorIndex];
   
GUI.Label ( GUI.Label (
new Rect ((Screen.width * .2083f), 0, 300f, 70f), new Rect ((Screen.width * .2083f), 0, 300f, 70f),
"Obt Alt: " + Tools.MuMech_ToSI (vessel.orbit.altitude) + "m" + "Obt Alt: " + Tools.MuMech_ToSI (vessel.orbit.altitude) + "m" +
" Obt Vel: " + Tools.MuMech_ToSI (vessel.orbit.vel.magnitude) + "m/s" + " Obt Vel: " + Tools.MuMech_ToSI (vessel.orbit.vel.magnitude) + "m/s" +
"\nAp: " + Tools.MuMech_ToSI (vessel.orbit.ApA) + "m" + "\nAp: " + Tools.MuMech_ToSI (vessel.orbit.ApA) + "m" +
" ETA " + Tools.ConvertInterval (vessel.orbit.timeToAp) + " ETA " + Tools.ConvertInterval (vessel.orbit.timeToAp) +
"\nPe: " + Tools.MuMech_ToSI (vessel.orbit.PeA) + "m" + "\nPe: " + Tools.MuMech_ToSI (vessel.orbit.PeA) + "m" +
" ETA " + Tools.ConvertInterval (vessel.orbit.timeToPe) + " ETA " + Tools.ConvertInterval (vessel.orbit.timeToPe) +
"\nInc: " + vessel.orbit.inclination.ToString ("F3") + "°", "\nInc: " + vessel.orbit.inclination.ToString ("F3") + "°" +
labelStyle); "\nPrimary: " + vessel.mainBody.bodyName,
  VOID_Core.Instance.LabelStyles["hud"]);
// Toadicus edit: Added "Biome: " line to surf/atmo HUD // Toadicus edit: Added "Biome: " line to surf/atmo HUD
GUI.Label ( GUI.Label (
new Rect ((Screen.width * .625f), 0, 300f, 90f), new Rect ((Screen.width * .625f), 0, 300f, 90f),
"Srf Alt: " + Tools.MuMech_ToSI (Tools.TrueAltitude (vessel)) + "m" + "Srf Alt: " + Tools.MuMech_ToSI (Tools.TrueAltitude (vessel)) + "m" +
" Srf Vel: " + Tools.MuMech_ToSI (vessel.srf_velocity.magnitude) + "m/s" + " Srf Vel: " + Tools.MuMech_ToSI (vessel.srf_velocity.magnitude) + "m/s" +
"\nVer: " + Tools.MuMech_ToSI (vessel.verticalSpeed) + "m/s" + "\nVer: " + Tools.MuMech_ToSI (vessel.verticalSpeed) + "m/s" +
" Hor: " + Tools.MuMech_ToSI (vessel.horizontalSrfSpeed) + "m/s" + " Hor: " + Tools.MuMech_ToSI (vessel.horizontalSrfSpeed) + "m/s" +
"\nLat: " + Tools.GetLatitudeString (vessel, "F3") + "\nLat: " + Tools.GetLatitudeString (vessel, "F3") +
" Lon: " + Tools.GetLongitudeString (vessel, "F3") + " Lon: " + Tools.GetLongitudeString (vessel, "F3") +
"\nHdg: " + Tools.MuMech_get_heading (vessel).ToString ("F2") + "° " + "\nHdg: " + Tools.MuMech_get_heading (vessel).ToString ("F2") + "° " +
Tools.get_heading_text (Tools.MuMech_get_heading (vessel)) + Tools.get_heading_text (Tools.MuMech_get_heading (vessel)) +
"\nBiome: " + Tools.Toadicus_GetAtt (vessel).name, "\nBiome: " + Tools.Toadicus_GetAtt (vessel).name +
labelStyle); " Sit: " + vessel.GetExperimentSituation().HumanString(),
  VOID_Core.Instance.LabelStyles["hud"]);
} }
else else
{ {
labelStyle.normal.textColor = Color.red; VOID_Core.Instance.LabelStyles["hud"].normal.textColor = Color.red;
GUI.Label (new Rect ((Screen.width * .2083f), 0, 300f, 70f), "-- POWER LOST --", labelStyle); GUI.Label (new Rect ((Screen.width * .2083f), 0, 300f, 70f), "-- POWER LOST --", VOID_Core.Instance.LabelStyles["hud"]);
GUI.Label (new Rect ((Screen.width * .625f), 0, 300f, 70f), "-- POWER LOST --", labelStyle); GUI.Label (new Rect ((Screen.width * .625f), 0, 300f, 70f), "-- POWER LOST --", VOID_Core.Instance.LabelStyles["hud"]);
} }
} }
   
public override void DrawConfigurables() public override void DrawConfigurables()
{ {
if (GUILayout.Button ("Change HUD color", GUILayout.ExpandWidth (false))) if (GUILayout.Button ("Change HUD color", GUILayout.ExpandWidth (false)))
{ {
++this.ColorIndex; ++this.ColorIndex;
} }
} }
} }
} }
   
// //
// VOID_Module.cs // VOID_Module.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public abstract class VOID_Module : IVOID_Module public abstract class VOID_Module : IVOID_Module
{ {
/* /*
* Fields * Fields
* */ * */
[AVOID_SaveValue("Active")] [AVOID_SaveValue("Active")]
protected VOID_SaveValue<bool> _Active = false; protected VOID_SaveValue<bool> _Active = false;
protected bool _Running = false; protected bool _Running = false;
   
protected string _Name; protected string _Name;
   
  protected float lastUpdate = 0;
   
/* /*
* Properties * Properties
* */ * */
public virtual bool toggleActive public virtual bool toggleActive
{ {
get get
{ {
return this._Active; return this._Active;
} }
set set
{ {
this._Active = value; this._Active.value = value;
} }
} }
   
public virtual bool guiRunning public virtual bool guiRunning
{ {
get get
{ {
return this._Running; return this._Running;
} }
} }
   
public virtual string Name public virtual string Name
{ {
get get
{ {
return this._Name; return this._Name;
} }
} }
   
public virtual Vessel vessel public virtual Vessel vessel
{ {
get get
{ {
return FlightGlobals.ActiveVessel; return FlightGlobals.ActiveVessel;
} }
} }
   
/* /*
* Methods * Methods
* */ * */
public void StartGUI() public void StartGUI()
{ {
if (!this.toggleActive || this.guiRunning) if (!this.toggleActive || this.guiRunning)
{ {
return; return;
} }
   
Tools.PostDebugMessage (string.Format("Adding {0} to the draw queue.", this.GetType().Name)); Tools.PostDebugMessage (string.Format("Adding {0} to the draw queue.", this.GetType().Name));
RenderingManager.AddToPostDrawQueue (3, this.DrawGUI); RenderingManager.AddToPostDrawQueue (3, this.DrawGUI);
this._Running = true; this._Running = true;
} }
   
public void StopGUI() public void StopGUI()
{ {
if (!this.guiRunning) if (!this.guiRunning)
{ {
return; return;
} }
Tools.PostDebugMessage (string.Format("Removing {0} from the draw queue.", this.GetType().Name)); Tools.PostDebugMessage (string.Format("Removing {0} from the draw queue.", this.GetType().Name));
RenderingManager.RemoveFromPostDrawQueue (3, this.DrawGUI); RenderingManager.RemoveFromPostDrawQueue (3, this.DrawGUI);
this._Running = false; this._Running = false;
} }
   
public abstract void DrawGUI(); public abstract void DrawGUI();
   
public virtual void DrawConfigurables() {} public virtual void DrawConfigurables() {}
   
public virtual void LoadConfig() public virtual void LoadConfig()
{ {
var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core> (); var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core> ();
config.load (); config.load ();
   
foreach (var field in this.GetType().GetFields( foreach (var field in this.GetType().GetFields(
BindingFlags.NonPublic | BindingFlags.NonPublic |
BindingFlags.Public | BindingFlags.Public |
BindingFlags.Instance | BindingFlags.Instance |
BindingFlags.FlattenHierarchy BindingFlags.FlattenHierarchy
)) ))
{ {
object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false); object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false);
   
if (attrs.Length == 0) { if (attrs.Length == 0) {
continue; continue;
} }
   
AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue; AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue;
   
string fieldName = string.Format("{0}_{1}", this.GetType().Name, attr.Name); string fieldName = string.Format("{0}_{1}", this.GetType().Name, attr.Name);
   
  Tools.PostDebugMessage(string.Format("{0}: Loading field {1}.", this.GetType().Name, fieldName));
   
object fieldValue = field.GetValue(this); object fieldValue = field.GetValue(this);
   
bool convertBack = false; bool convertBack = false;
if (fieldValue is IVOID_SaveValue) if (fieldValue is IVOID_SaveValue)
{ {
fieldValue = (fieldValue as IVOID_SaveValue).AsType; fieldValue = (fieldValue as IVOID_SaveValue).AsType;
convertBack = true; convertBack = true;
} }
   
fieldValue = config.GetValue(fieldName, fieldValue); fieldValue = config.GetValue(fieldName, fieldValue);
   
if (convertBack) if (convertBack)
{ {
Type type = typeof(VOID_SaveValue<>).MakeGenericType (fieldValue.GetType ()); Type type = typeof(VOID_SaveValue<>).MakeGenericType (fieldValue.GetType ());
IVOID_SaveValue convertValue = Activator.CreateInstance (type) as IVOID_SaveValue; IVOID_SaveValue convertValue = Activator.CreateInstance (type) as IVOID_SaveValue;
convertValue.SetValue (fieldValue); convertValue.SetValue (fieldValue);
fieldValue = convertValue; fieldValue = convertValue;
} }
   
field.SetValue (this, fieldValue); field.SetValue (this, fieldValue);
   
Tools.PostDebugMessage(string.Format("{0}: Loaded field {1}.", this.GetType().Name, fieldName)); Tools.PostDebugMessage(string.Format("{0}: Loaded field {1}.", this.GetType().Name, fieldName));
} }
} }
   
public virtual void _SaveToConfig(KSP.IO.PluginConfiguration config) public virtual void _SaveToConfig(KSP.IO.PluginConfiguration config)
{ {
foreach (var field in this.GetType().GetFields( foreach (var field in this.GetType().GetFields(
BindingFlags.Instance | BindingFlags.Instance |
BindingFlags.NonPublic | BindingFlags.NonPublic |
BindingFlags.Public | BindingFlags.Public |
BindingFlags.FlattenHierarchy BindingFlags.FlattenHierarchy
)) ))
{ {
object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false); object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false);
   
if (attrs.Length == 0) { if (attrs.Length == 0) {
continue; continue;
} }
   
AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue; AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue;
   
string fieldName = string.Format("{0}_{1}", this.GetType().Name, attr.Name); string fieldName = string.Format("{0}_{1}", this.GetType().Name, attr.Name);
   
object fieldValue = field.GetValue(this); object fieldValue = field.GetValue(this);
   
if (fieldValue is IVOID_SaveValue) if (fieldValue is IVOID_SaveValue)
{ {
fieldValue = (fieldValue as IVOID_SaveValue).AsType; fieldValue = (fieldValue as IVOID_SaveValue).AsType;
} }
   
config.SetValue(fieldName, fieldValue); config.SetValue(fieldName, fieldValue);
   
Tools.PostDebugMessage(string.Format("{0}: Saved field {1}.", this.GetType().Name, fieldName)); Tools.PostDebugMessage(string.Format("{0}: Saved field {1}.", this.GetType().Name, fieldName));
} }
} }
} }
   
public abstract class VOID_WindowModule : VOID_Module public abstract class VOID_WindowModule : VOID_Module
{ {
[AVOID_SaveValue("WindowPos")] [AVOID_SaveValue("WindowPos")]
protected Rect WindowPos = new Rect(Screen.width / 2, Screen.height / 2, 250f, 50f); protected Rect WindowPos = new Rect(Screen.width / 2, Screen.height / 2, 250f, 50f);
protected float defWidth = 250f; protected float defWidth = 250f;
protected float defHeight = 50f; protected float defHeight = 50f;
   
public abstract void ModuleWindow(int _); public virtual void ModuleWindow(int _)
  {
  if (VOID_Core.Instance.updateTimer - this.lastUpdate > VOID_Core.Instance.updatePeriod) {
  foreach (var fieldinfo in this.GetType().GetFields(
  BindingFlags.Instance |
  BindingFlags.NonPublic |
  BindingFlags.Public |
  BindingFlags.FlattenHierarchy
  ))
  {
  object field = null;
   
  try
  {
  field = fieldinfo.GetValue (this);
  }
  catch (NullReferenceException) {
  Tools.PostDebugMessage(string.Format(
  "{0}: caught NullReferenceException, could not get value for field {1}.",
  this.GetType().Name,
  fieldinfo.Name
  ));
  }
   
  if (field == null) {
  continue;
  }
   
  if (typeof(IVOID_DataValue).IsAssignableFrom (field.GetType ())) {
  (field as IVOID_DataValue).Refresh ();
  }
  }
   
  this.lastUpdate = VOID_Core.Instance.updateTimer;
  }
  }
   
public override void DrawGUI() public override void DrawGUI()
{ {
  GUI.skin = VOID_Core.Instance.Skin;
   
Rect _Pos = this.WindowPos; Rect _Pos = this.WindowPos;
   
_Pos = GUILayout.Window( _Pos = GUILayout.Window(
VOID_Core.Instance.windowID, VOID_Core.Instance.windowID,
_Pos, _Pos,
this.ModuleWindow, this.ModuleWindow,
this.Name, this.Name,
GUILayout.Width(this.defWidth), GUILayout.Width(this.defWidth),
GUILayout.Height(this.defHeight) GUILayout.Height(this.defHeight)
); );
   
_Pos = Tools.ClampRectToScreen (_Pos); _Pos = Tools.ClampRectToScreen (_Pos);
   
if (_Pos != this.WindowPos) if (_Pos != this.WindowPos)
{ {
this.WindowPos = _Pos; this.WindowPos = _Pos;
VOID_Core.Instance.configDirty = true; VOID_Core.Instance.configDirty = true;
} }
} }
} }
} }
   
   
// //
// VOID_Orbital.cs // VOID_Orbital.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using KSP; using KSP;
using System; using System;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_Orbital : VOID_WindowModule public class VOID_Orbital : VOID_WindowModule
{ {
[AVOID_SaveValue("toggleExtended")] [AVOID_SaveValue("toggleExtended")]
protected VOID_SaveValue<bool> toggleExtended = false; protected VOID_SaveValue<bool> toggleExtended = false;
   
  [AVOID_SaveValue("precisionValues")]
  protected long _precisionValues = 230584300921369395;
  protected IntCollection precisionValues;
   
  protected VOID_StrValue primaryName = new VOID_StrValue (
  VOIDLabels.void_primary,
  new Func<string> (() => VOID_Core.Instance.vessel.mainBody.name)
  );
   
  protected VOID_DoubleValue orbitAltitude = new VOID_DoubleValue (
  "Altitude (ASL)",
  new Func<double> (() => VOID_Core.Instance.vessel.orbit.altitude),
  "m"
  );
   
  protected VOID_DoubleValue orbitVelocity = new VOID_DoubleValue (
  VOIDLabels.void_velocity,
  new Func<double> (() => VOID_Core.Instance.vessel.orbit.vel.magnitude),
  "m/s"
  );
   
  protected VOID_DoubleValue orbitApoAlt = new VOID_DoubleValue(
  VOIDLabels.void_apoapsis,
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.ApA),
  "m"
  );
   
  protected VOID_DoubleValue oribtPeriAlt = new VOID_DoubleValue(
  VOIDLabels.void_periapsis,
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.PeA),
  "m"
  );
   
  protected VOID_StrValue timeToApo = new VOID_StrValue(
  "Time to Apoapsis",
  new Func<string>(() => Tools.ConvertInterval(VOID_Core.Instance.vessel.orbit.timeToAp))
  );
   
  protected VOID_StrValue timeToPeri = new VOID_StrValue(
  "Time to Periapsis",
  new Func<string>(() => Tools.ConvertInterval(VOID_Core.Instance.vessel.orbit.timeToPe))
  );
   
  protected VOID_DoubleValue orbitInclination = new VOID_DoubleValue(
  "Inclination",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.inclination),
  "°"
  );
   
  protected VOID_DoubleValue gravityAccel = new VOID_DoubleValue(
  "Gravity",
  delegate()
  {
  double orbitRadius = VOID_Core.Instance.vessel.mainBody.Radius +
  VOID_Core.Instance.vessel.mainBody.GetAltitude(VOID_Core.Instance.vessel.findWorldCenterOfMass());
  return (VOID_Core.Constant_G * VOID_Core.Instance.vessel.mainBody.Mass) /
  Math.Pow(orbitRadius, 2);
  },
  "m/s²"
  );
   
  protected VOID_StrValue orbitPeriod = new VOID_StrValue(
  "Period",
  new Func<string>(() => Tools.ConvertInterval(VOID_Core.Instance.vessel.orbit.period))
  );
   
  protected VOID_DoubleValue semiMajorAxis = new VOID_DoubleValue(
  "Semi-Major Axis",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.semiMajorAxis),
  "m"
  );
   
  protected VOID_DoubleValue eccentricity = new VOID_DoubleValue(
  "Eccentricity",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.eccentricity),
  ""
  );
   
  protected VOID_DoubleValue meanAnomaly = new VOID_DoubleValue(
  "Mean Anomaly",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.meanAnomaly * 180d / Math.PI),
  "°"
  );
   
  protected VOID_DoubleValue trueAnomaly = new VOID_DoubleValue(
  "True Anomaly",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.trueAnomaly),
  "°"
  );
   
  protected VOID_DoubleValue eccAnomaly = new VOID_DoubleValue(
  "Eccentric Anomaly",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.eccentricAnomaly * 180d / Math.PI),
  "°"
  );
   
  protected VOID_DoubleValue longitudeAscNode = new VOID_DoubleValue(
  "Long. Ascending Node",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.LAN),
  "°"
  );
   
  protected VOID_DoubleValue argumentPeriapsis = new VOID_DoubleValue(
  "Argument of Periapsis",
  new Func<double>(() => VOID_Core.Instance.vessel.orbit.argumentOfPeriapsis),
  "°"
  );
   
  protected VOID_DoubleValue localSiderealLongitude = new VOID_DoubleValue(
  "Local Sidereal Longitude",
  new Func<double>(() => Tools.FixDegreeDomain(
  VOID_Core.Instance.vessel.longitude + VOID_Core.Instance.vessel.orbit.referenceBody.rotationAngle)),
  "°"
  );
   
public VOID_Orbital() public VOID_Orbital()
{ {
this._Name = "Orbital Information"; this._Name = "Orbital Information";
   
this.WindowPos.x = Screen.width - 520f; this.WindowPos.x = Screen.width - 520f;
this.WindowPos.y = 250f; this.WindowPos.y = 250f;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
// Toadicus edit: added local sidereal longitude. base.ModuleWindow (_);
double LSL = vessel.longitude + vessel.orbit.referenceBody.rotationAngle;  
LSL = Tools.FixDegreeDomain (LSL); int idx = 0;
   
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.primaryName.DoGUIHorizontal ();
GUILayout.Label(VOIDLabels.void_primary + ":");  
GUILayout.Label(vessel.mainBody.bodyName, GUILayout.ExpandWidth(false)); this.precisionValues [idx]= (ushort)this.orbitAltitude.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.EndHorizontal(); idx++;
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.orbitVelocity.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label(VOIDLabels.void_altitude_asl + ":"); idx++;
GUILayout.Label(Tools.MuMech_ToSI(vessel.orbit.altitude) + "m", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal(); this.precisionValues [idx]= (ushort)this.orbitApoAlt.DoGUIHorizontal (this.precisionValues [idx]);
  idx++;
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label(VOIDLabels.void_velocity + ":"); this.timeToApo.DoGUIHorizontal();
GUILayout.Label(Tools.MuMech_ToSI(vessel.orbit.vel.magnitude) + "m/s", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal(); this.precisionValues [idx]= (ushort)this.oribtPeriAlt.DoGUIHorizontal (this.precisionValues [idx]);
  idx++;
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label(VOIDLabels.void_apoapsis + ":"); this.timeToPeri.DoGUIHorizontal();
GUILayout.Label(Tools.MuMech_ToSI(vessel.orbit.ApA) + "m", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal(); this.orbitInclination.DoGUIHorizontal("F3");
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.gravityAccel.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Time to Ap:"); idx++;
GUILayout.Label(Tools.ConvertInterval(vessel.orbit.timeToAp), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal(); this.toggleExtended.value = GUILayout.Toggle(this.toggleExtended, "Extended info");
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label(VOIDLabels.void_periapsis + ":");  
GUILayout.Label(Tools.MuMech_ToSI(vessel.orbit.PeA) + "m", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Time to Pe:");  
GUILayout.Label(Tools.ConvertInterval(vessel.orbit.timeToPe), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Inclination:");  
GUILayout.Label(vessel.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
double r_vessel = vessel.mainBody.Radius + vessel.mainBody.GetAltitude(vessel.findWorldCenterOfMass());  
double g_vessel = (VOID_Core.Constant_G * vessel.mainBody.Mass) / Math.Pow(r_vessel, 2);  
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Gravity:");  
GUILayout.Label(Tools.MuMech_ToSI(g_vessel) + "m/s²", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
this.toggleExtended = GUILayout.Toggle(this.toggleExtended, "Extended info");  
   
if (this.toggleExtended) if (this.toggleExtended)
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.orbitPeriod.DoGUIHorizontal();
GUILayout.Label("Period:");  
GUILayout.Label(Tools.ConvertInterval(vessel.orbit.period), GUILayout.ExpandWidth(false)); this.precisionValues [idx]= (ushort)this.semiMajorAxis.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.EndHorizontal(); idx++;
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.eccentricity.DoGUIHorizontal("F4");
GUILayout.Label("Semi-major axis:");  
GUILayout.Label((vessel.orbit.semiMajorAxis / 1000).ToString("##,#") + "km", GUILayout.ExpandWidth(false)); this.meanAnomaly.DoGUIHorizontal("F3");
GUILayout.EndHorizontal();  
  this.trueAnomaly.DoGUIHorizontal("F3");
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Eccentricity:"); this.eccAnomaly.DoGUIHorizontal("F3");
GUILayout.Label(vessel.orbit.eccentricity.ToString("F4"), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal(); this.longitudeAscNode.DoGUIHorizontal("F3");
   
// Toadicus edit: convert mean anomaly into degrees. this.argumentPeriapsis.DoGUIHorizontal("F3");
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Mean anomaly:"); this.localSiderealLongitude.DoGUIHorizontal("F3");
GUILayout.Label((vessel.orbit.meanAnomaly * 180d / Math.PI).ToString("F3") + "°", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("True anomaly:");  
GUILayout.Label(vessel.orbit.trueAnomaly.ToString("F3") + "°", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
// Toadicus edit: convert eccentric anomaly into degrees.  
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Eccentric anomaly:");  
GUILayout.Label((vessel.orbit.eccentricAnomaly * 180d / Math.PI).ToString("F3") + "°", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Long. ascending node:");  
GUILayout.Label(vessel.orbit.LAN.ToString("F3") + "°", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Arg. of periapsis:");  
GUILayout.Label(vessel.orbit.argumentOfPeriapsis.ToString("F3") + "°", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
// Toadicus edit: added local sidereal longitude.  
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Local Sidereal Longitude:");  
GUILayout.Label(LSL.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["txt_right"]);  
GUILayout.EndHorizontal();  
} }
   
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
   
  public override void LoadConfig ()
  {
  base.LoadConfig ();
   
  this.precisionValues = new IntCollection (4, this._precisionValues);
  }
   
  public override void _SaveToConfig (KSP.IO.PluginConfiguration config)
  {
  this._precisionValues = this.precisionValues.collection;
   
  base._SaveToConfig (config);
  }
} }
} }
   
   
// //
// VOID_Orbital.cs // VOID_Orbital.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using KSP; using KSP;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_Rendezvous : VOID_WindowModule public class VOID_Rendezvous : VOID_WindowModule
{ {
[AVOID_SaveValue("untoggleRegisterInfo")] [AVOID_SaveValue("untoggleRegisterInfo")]
protected VOID_SaveValue<bool> untoggleRegisterInfo = false; protected VOID_SaveValue<bool> untoggleRegisterInfo = false;
   
[AVOID_SaveValue("toggleExtendedOrbital")] [AVOID_SaveValue("toggleExtendedOrbital")]
protected VOID_SaveValue<bool> toggleExtendedOrbital = false; protected VOID_SaveValue<bool> toggleExtendedOrbital = false;
   
protected VOID_VesselRegister RegisterModule; protected VOID_VesselRegister RegisterModule;
   
public VOID_Rendezvous() public VOID_Rendezvous()
{ {
this._Name = "Rendezvous Information"; this._Name = "Rendezvous Information";
   
this.WindowPos.x = 845; this.WindowPos.x = 845;
this.WindowPos.y = 85; this.WindowPos.y = 85;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
Vessel rendezvessel = new Vessel(); Vessel rendezvessel = new Vessel();
CelestialBody rendezbody = new CelestialBody(); CelestialBody rendezbody = new CelestialBody();
   
this.RegisterModule = VOID_Core.Instance.Modules.Where(m => typeof(VOID_VesselRegister).IsAssignableFrom(m.GetType())).FirstOrDefault() as VOID_VesselRegister; this.RegisterModule = VOID_Core.Instance.Modules.Where(m => typeof(VOID_VesselRegister).IsAssignableFrom(m.GetType())).FirstOrDefault() as VOID_VesselRegister;
   
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
//display both //display both
//Show Target Info //Show Target Info
GUILayout.Label("Target:", VOID_Core.Instance.LabelStyles["center_bold"]); GUILayout.Label("Target:", VOID_Core.Instance.LabelStyles["center_bold"]);
if (FlightGlobals.fetch.VesselTarget != null) if (FlightGlobals.fetch.VesselTarget != null)
{ {
//a KSP Target (body or vessel) is selected //a KSP Target (body or vessel) is selected
if (FlightGlobals.fetch.vesselTargetMode == FlightGlobals.VesselTargetModes.Direction) if (FlightGlobals.fetch.vesselTargetMode == FlightGlobals.VesselTargetModes.Direction)
{ {
//a Body is selected //a Body is selected
rendezbody = vessel.patchedConicSolver.targetBody; rendezbody = vessel.patchedConicSolver.targetBody;
display_rendezvous_info(null, rendezbody); display_rendezvous_info(null, rendezbody);
} }
else if (FlightGlobals.fetch.vesselTargetMode == FlightGlobals.VesselTargetModes.DirectionAndVelocity) else if (FlightGlobals.fetch.vesselTargetMode == FlightGlobals.VesselTargetModes.DirectionAndVelocity)
{ {
//a Vessel is selected //a Vessel is selected
rendezvessel = FlightGlobals.fetch.VesselTarget.GetVessel(); rendezvessel = FlightGlobals.fetch.VesselTarget.GetVessel();
display_rendezvous_info(rendezvessel, null); display_rendezvous_info(rendezvessel, null);
} }
//Show Unset button for both options above //Show Unset button for both options above
if (GUILayout.Button("Unset Target", GUILayout.ExpandWidth(false))) if (GUILayout.Button("Unset Target", GUILayout.ExpandWidth(false)))
{ {
FlightGlobals.fetch.SetVesselTarget(null); FlightGlobals.fetch.SetVesselTarget(null);
Tools.PostDebugMessage("VOID_Rendezvous: KSP Target set to null"); Tools.PostDebugMessage("VOID_Rendezvous: KSP Target set to null");
} }
   
} }
else else
{ {
//no KSP Target selected //no KSP Target selected
GUILayout.Label("No Target Selected", VOID_Core.Instance.LabelStyles["center_bold"]); GUILayout.Label("No Target Selected", VOID_Core.Instance.LabelStyles["center_bold"]);
} }
   
//Show Vessel Register vessel info //Show Vessel Register vessel info
if (untoggleRegisterInfo == false && this.RegisterModule != default(IVOID_Module)) if (untoggleRegisterInfo == false && this.RegisterModule != default(IVOID_Module))
{ {
GUILayout.Label("Vessel Register:", VOID_Core.Instance.LabelStyles["center_bold"]); GUILayout.Label("Vessel Register:", VOID_Core.Instance.LabelStyles["center_bold"]);
if (this.RegisterModule.selectedVessel != null) if (this.RegisterModule.selectedVessel != null)
{ {
rendezvessel = this.RegisterModule.selectedVessel; rendezvessel = this.RegisterModule.selectedVessel;
display_rendezvous_info(rendezvessel, null); display_rendezvous_info(rendezvessel, null);
   
//show set/unset buttons //show set/unset buttons
if (FlightGlobals.fetch.VesselTarget == null || (FlightGlobals.fetch.VesselTarget != null && FlightGlobals.fetch.VesselTarget.GetVessel() != this.RegisterModule.selectedVessel)) if (FlightGlobals.fetch.VesselTarget == null || (FlightGlobals.fetch.VesselTarget != null && FlightGlobals.fetch.VesselTarget.GetVessel() != this.RegisterModule.selectedVessel))
{ {
//no Tgt set or Tgt is not this vessel //no Tgt set or Tgt is not this vessel
//show a Set button //show a Set button
if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false))) if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false)))
{ {
FlightGlobals.fetch.SetVesselTarget(rendezvessel); FlightGlobals.fetch.SetVesselTarget(rendezvessel);
Tools.PostDebugMessage("[VOID] KSP Target set to " + rendezvessel.vesselName); Tools.PostDebugMessage("[VOID] KSP Target set to " + rendezvessel.vesselName);
} }
} }
} }
else else
{ {
//vesreg Vessel is null //vesreg Vessel is null
//targ = null; //targ = null;
GUILayout.Label("No Vessel Selected", VOID_Core.Instance.LabelStyles["center_bold"]); GUILayout.Label("No Vessel Selected", VOID_Core.Instance.LabelStyles["center_bold"]);
} }
} }
   
untoggleRegisterInfo = GUILayout.Toggle(untoggleRegisterInfo, "Hide Vessel Register Info"); untoggleRegisterInfo.value = GUILayout.Toggle(untoggleRegisterInfo, "Hide Vessel Register Info");
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label(" ", GUILayout.ExpandWidth(true)); GUILayout.Label(" ", GUILayout.ExpandWidth(true));
if (GUILayout.Button("Close", GUILayout.ExpandWidth(false))) this._Active = false; if (GUILayout.Button("Close", GUILayout.ExpandWidth(false))) this._Active = false;
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
   
private void display_rendezvous_info(Vessel v, CelestialBody cb) private void display_rendezvous_info(Vessel v, CelestialBody cb)
{ {
if (cb == null && v != null) if (cb == null && v != null)
{ {
//Display vessel rendezvous info //Display vessel rendezvous info
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label(v.vesselName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); GUILayout.Label(v.vesselName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
if (v.situation == Vessel.Situations.ESCAPING || v.situation == Vessel.Situations.FLYING || v.situation == Vessel.Situations.ORBITING || v.situation == Vessel.Situations.SUB_ORBITAL) if (v.situation == Vessel.Situations.ESCAPING || v.situation == Vessel.Situations.FLYING || v.situation == Vessel.Situations.ORBITING || v.situation == Vessel.Situations.SUB_ORBITAL)
{ {
// Toadicus edit: added local sidereal longitude. // Toadicus edit: added local sidereal longitude.
// Toadicus edit: added local sidereal longitude. // Toadicus edit: added local sidereal longitude.
double LSL = vessel.longitude + vessel.orbit.referenceBody.rotationAngle; double LSL = v.longitude + v.orbit.referenceBody.rotationAngle;
LSL = Tools.FixDegreeDomain (LSL); LSL = Tools.FixDegreeDomain (LSL);
   
//display orbital info for orbiting/flying/suborbital/escaping vessels only //display orbital info for orbiting/flying/suborbital/escaping vessels only
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Ap/Pe:"); GUILayout.Label("Ap/Pe:");
GUILayout.Label(Tools.MuMech_ToSI(v.orbit.ApA) + "m / " + Tools.MuMech_ToSI(v.orbit.PeA) + "m", GUILayout.ExpandWidth(false)); GUILayout.Label(Tools.MuMech_ToSI(v.orbit.ApA) + "m / " + Tools.MuMech_ToSI(v.orbit.PeA) + "m", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Altitude:"); GUILayout.Label("Altitude:");
GUILayout.Label(Tools.MuMech_ToSI(v.orbit.altitude) + "m", GUILayout.ExpandWidth(false)); GUILayout.Label(Tools.MuMech_ToSI(v.orbit.altitude) + "m", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Inclination:"); GUILayout.Label("Inclination:");
GUILayout.Label(v.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(v.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
if (vessel.mainBody == v.mainBody) if (vessel.mainBody == v.mainBody)
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Relative inclination:"); GUILayout.Label("Relative inclination:");
GUILayout.Label(Vector3d.Angle(vessel.orbit.GetOrbitNormal(), v.orbit.GetOrbitNormal()).ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(Vector3d.Angle(vessel.orbit.GetOrbitNormal(), v.orbit.GetOrbitNormal()).ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
//if (debugging) Debug.Log("[CHATR] v -> v relative incl OK"); //if (debugging) Debug.Log("[CHATR] v -> v relative incl OK");
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Velocity:"); GUILayout.Label("Velocity:");
GUILayout.Label(Tools.MuMech_ToSI(v.orbit.vel.magnitude) + "m/s", GUILayout.ExpandWidth(false)); GUILayout.Label(Tools.MuMech_ToSI(v.orbit.vel.magnitude) + "m/s", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Relative velocity:"); GUILayout.Label("Relative velocity:");
GUILayout.Label(Tools.MuMech_ToSI(v.orbit.vel.magnitude - vessel.orbit.vel.magnitude) + "m/s", GUILayout.ExpandWidth(false)); GUILayout.Label(Tools.MuMech_ToSI(v.orbit.vel.magnitude - vessel.orbit.vel.magnitude) + "m/s", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Distance:"); GUILayout.Label("Distance:");
GUILayout.Label(Tools.MuMech_ToSI((vessel.findWorldCenterOfMass() - v.findWorldCenterOfMass()).magnitude) + "m", GUILayout.ExpandWidth(false)); GUILayout.Label(Tools.MuMech_ToSI((vessel.findWorldCenterOfMass() - v.findWorldCenterOfMass()).magnitude) + "m", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
//target_vessel_extended_orbital_info = GUILayout.Toggle(target_vessel_extended_orbital_info, "Extended info"); //target_vessel_extended_orbital_info = GUILayout.Toggle(target_vessel_extended_orbital_info, "Extended info");
   
if (toggleExtendedOrbital) if (toggleExtendedOrbital)
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Period:"); GUILayout.Label("Period:");
GUILayout.Label(Tools.ConvertInterval(v.orbit.period), GUILayout.ExpandWidth(false)); GUILayout.Label(Tools.ConvertInterval(v.orbit.period), GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Semi-major axis:"); GUILayout.Label("Semi-major axis:");
GUILayout.Label((v.orbit.semiMajorAxis / 1000).ToString("##,#") + "km", GUILayout.ExpandWidth(false)); GUILayout.Label((v.orbit.semiMajorAxis / 1000).ToString("##,#") + "km", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Eccentricity:"); GUILayout.Label("Eccentricity:");
GUILayout.Label(v.orbit.eccentricity.ToString("F4"), GUILayout.ExpandWidth(false)); GUILayout.Label(v.orbit.eccentricity.ToString("F4"), GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
// Toadicus edit: convert mean anomaly into degrees. // Toadicus edit: convert mean anomaly into degrees.
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Mean anomaly:"); GUILayout.Label("Mean anomaly:");
GUILayout.Label((v.orbit.meanAnomaly * 180d / Math.PI).ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label((v.orbit.meanAnomaly * 180d / Math.PI).ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("True anomaly:"); GUILayout.Label("True anomaly:");
GUILayout.Label(v.orbit.trueAnomaly.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(v.orbit.trueAnomaly.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
// Toadicus edit: convert eccentric anomaly into degrees. // Toadicus edit: convert eccentric anomaly into degrees.
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Eccentric anomaly:"); GUILayout.Label("Eccentric anomaly:");
GUILayout.Label((v.orbit.eccentricAnomaly * 180d / Math.PI).ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label((v.orbit.eccentricAnomaly * 180d / Math.PI).ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Long. ascending node:"); GUILayout.Label("Long. ascending node:");
GUILayout.Label(v.orbit.LAN.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(v.orbit.LAN.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Arg. of periapsis:"); GUILayout.Label("Arg. of periapsis:");
GUILayout.Label(v.orbit.argumentOfPeriapsis.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(v.orbit.argumentOfPeriapsis.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
// Toadicus edit: added local sidereal longitude. // Toadicus edit: added local sidereal longitude.
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Local Sidereal Longitude:"); GUILayout.Label("Local Sidereal Longitude:");
GUILayout.Label(LSL.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["txt_right"]); GUILayout.Label(LSL.ToString("F3") + "°", VOID_Core.Instance.LabelStyles["right"]);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
} }
else else
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Latitude:"); GUILayout.Label("Latitude:");
GUILayout.Label(Tools.GetLatitudeString(vessel), GUILayout.ExpandWidth(false)); GUILayout.Label(Tools.GetLatitudeString(vessel), GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Longitude:"); GUILayout.Label("Longitude:");
GUILayout.Label(Tools.GetLongitudeString(vessel), GUILayout.ExpandWidth(false)); GUILayout.Label(Tools.GetLongitudeString(vessel), GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Distance:"); GUILayout.Label("Distance:");
GUILayout.Label(Tools.MuMech_ToSI((vessel.findWorldCenterOfMass() - v.findWorldCenterOfMass()).magnitude) + "m", GUILayout.ExpandWidth(false)); GUILayout.Label(Tools.MuMech_ToSI((vessel.findWorldCenterOfMass() - v.findWorldCenterOfMass()).magnitude) + "m", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
} }
else if (cb != null && v == null) else if (cb != null && v == null)
{ {
//Display CelstialBody rendezvous info //Display CelstialBody rendezvous info
GUILayout.Label(cb.bodyName, VOID_Core.Instance.LabelStyles["center_bold"]); GUILayout.Label(cb.bodyName, VOID_Core.Instance.LabelStyles["center_bold"]);
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Ap/Pe:"); GUILayout.Label("Ap/Pe:");
GUILayout.Label(Tools.MuMech_ToSI(cb.orbit.ApA) + "m / " + Tools.MuMech_ToSI(cb.orbit.PeA) + "m", GUILayout.ExpandWidth(false)); GUILayout.Label(Tools.MuMech_ToSI(cb.orbit.ApA) + "m / " + Tools.MuMech_ToSI(cb.orbit.PeA) + "m", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
//if (debugging) Debug.Log("[VOID] Ap/Pe OK"); //if (debugging) Debug.Log("[VOID] Ap/Pe OK");
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Inclination:"); GUILayout.Label("Inclination:");
GUILayout.Label(cb.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(cb.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
//if (debugging) Debug.Log("[VOID] Inclination OK"); //if (debugging) Debug.Log("[VOID] Inclination OK");
   
if (cb.referenceBody == vessel.mainBody) if (cb.referenceBody == vessel.mainBody)
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Relative inclination:"); GUILayout.Label("Relative inclination:");
GUILayout.Label(Vector3d.Angle(vessel.orbit.GetOrbitNormal(), cb.orbit.GetOrbitNormal()).ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label(Vector3d.Angle(vessel.orbit.GetOrbitNormal(), cb.orbit.GetOrbitNormal()).ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
//if (debugging) Debug.Log("[VOID] cb Relative inclination OK"); //if (debugging) Debug.Log("[VOID] cb Relative inclination OK");
} }
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label("Distance:"); GUILayout.Label("Distance:");
GUILayout.Label(Tools.MuMech_ToSI((vessel.mainBody.position - cb.position).magnitude) + "m", GUILayout.ExpandWidth(false)); GUILayout.Label(Tools.MuMech_ToSI((vessel.mainBody.position - cb.position).magnitude) + "m", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
//if (debugging) Debug.Log("[VOID] Distance OK"); //if (debugging) Debug.Log("[VOID] Distance OK");
   
//SUN2PLANET: //SUN2PLANET:
if (vessel.mainBody.bodyName == "Sun" && cb.referenceBody == vessel.mainBody) if (vessel.mainBody.bodyName == "Sun" && cb.referenceBody == vessel.mainBody)
{ {
Tools.display_transfer_angles_SUN2PLANET(cb, vessel); Tools.display_transfer_angles_SUN2PLANET(cb, vessel);
//if (debugging) Debug.Log("[VOID] SUN2PLANET OK"); //if (debugging) Debug.Log("[VOID] SUN2PLANET OK");
} }
   
//PLANET2PLANET //PLANET2PLANET
else if (vessel.mainBody.referenceBody.bodyName == "Sun" && cb.referenceBody == vessel.mainBody.referenceBody) else if (vessel.mainBody.referenceBody.bodyName == "Sun" && cb.referenceBody == vessel.mainBody.referenceBody)
{ {
Tools.display_transfer_angles_PLANET2PLANET(cb, vessel); Tools.display_transfer_angles_PLANET2PLANET(cb, vessel);
//if (debugging) Debug.Log("[VOID] PLANET2PLANET OK"); //if (debugging) Debug.Log("[VOID] PLANET2PLANET OK");
} }
   
//PLANET2MOON //PLANET2MOON
else if (vessel.mainBody.referenceBody.bodyName == "Sun" && cb.referenceBody == vessel.mainBody) else if (vessel.mainBody.referenceBody.bodyName == "Sun" && cb.referenceBody == vessel.mainBody)
{ {
Tools.display_transfer_angles_PLANET2MOON(cb, vessel); Tools.display_transfer_angles_PLANET2MOON(cb, vessel);
//if (debugging) Debug.Log("[VOID] PLANET2MOON OK"); //if (debugging) Debug.Log("[VOID] PLANET2MOON OK");
} }
   
//MOON2MOON //MOON2MOON
else if (vessel.mainBody.referenceBody.referenceBody.bodyName == "Sun" && cb.referenceBody == vessel.mainBody.referenceBody) else if (vessel.mainBody.referenceBody.referenceBody.bodyName == "Sun" && cb.referenceBody == vessel.mainBody.referenceBody)
{ {
Tools.display_transfer_angles_MOON2MOON(cb, vessel); Tools.display_transfer_angles_MOON2MOON(cb, vessel);
//if (debugging) Debug.Log("[VOID] MOON2MOON OK"); //if (debugging) Debug.Log("[VOID] MOON2MOON OK");
} }
   
//else GUILayout.Label("Transfer angle information\nunavailable for this target"); //else GUILayout.Label("Transfer angle information\nunavailable for this target");
   
} }
} }
} }
} }
// //
// VOID_Config.cs // VOID_Config.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using KSP; using KSP;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public struct VOID_SaveValue<T> : IVOID_SaveValue public struct VOID_SaveValue<T> : IVOID_SaveValue
{ {
private T _value; private T _value;
private Type _type; private Type _type;
   
  private VOID_Core Core
  {
  get
  {
  if (HighLogic.LoadedSceneIsEditor)
  {
  if (VOID_EditorCore.Initialized)
  {
  return VOID_EditorCore.Instance;
  }
  }
  else if (HighLogic.LoadedSceneIsFlight)
  {
  if (VOID_Core.Initialized)
  {
  return VOID_Core.Instance;
  }
  }
  return null;
  }
  }
   
public T value public T value
{ {
get get
{ {
return this._value; return this._value;
} }
set set
{ {
  if (this.Core != null && !System.Object.Equals(this._value, value))
  {
  Tools.PostDebugMessage (string.Format (
  "VOID: Dirtying config for type {0} in method {1}." +
  "\n\t Old Value: {2}, New Value: {3}" +
  "\n\t Object.Equals(New, Old): {4}",
  this._type,
  new System.Diagnostics.StackTrace().GetFrame(1).GetMethod(),
  this._value,
  value,
  System.Object.Equals(this._value, value)
  ));
  this.Core.configDirty = true;
  }
this._value = value; this._value = value;
} }
} }
   
public Type type public Type type
{ {
get get
{ {
  if (this._type == null && this._value != null)
  {
  this._type = this._value.GetType ();
  }
return this._type; return this._type;
} }
set set
{ {
this._type = value; this._type = value;
} }
} }
   
public object AsType public object AsType
{ {
get get
{ {
return (T)this._value; return (T)this._value;
} }
} }
   
public void SetValue(object v) public void SetValue(object v)
{ {
this._value = (T)v; this.value = (T)v;
} }
   
public static implicit operator T(VOID_SaveValue<T> v) public static implicit operator T(VOID_SaveValue<T> v)
{ {
return v.value; return (T)v.value;
} }
   
public static implicit operator VOID_SaveValue<T>(T v) public static implicit operator VOID_SaveValue<T>(T v)
{ {
VOID_SaveValue<T> r = new VOID_SaveValue<T>(); VOID_SaveValue<T> r = new VOID_SaveValue<T>();
  r.type = v.GetType();
r.value = v; r.value = v;
r.type = v.GetType();  
   
if (VOID_Core.Initialized)  
{  
VOID_Core.Instance.configDirty = true;  
}  
   
if (VOID_EditorCore.Initialized)  
{  
VOID_EditorCore.Instance.configDirty = true;  
}  
   
return r; return r;
} }
   
public new string ToString() public override string ToString()
{ {
return this.value.ToString(); return this.value.ToString();
} }
} }
   
public interface IVOID_SaveValue public interface IVOID_SaveValue
{ {
Type type { get; } Type type { get; }
object AsType { get; } object AsType { get; }
void SetValue(object v); void SetValue(object v);
} }
   
[AttributeUsage(AttributeTargets.Field)] [AttributeUsage(AttributeTargets.Field)]
public class AVOID_SaveValue : Attribute public class AVOID_SaveValue : Attribute
{ {
protected string _name; protected string _name;
   
public string Name public string Name
{ {
get get
{ {
return this._name; return this._name;
} }
} }
   
public AVOID_SaveValue(string fieldName) public AVOID_SaveValue(string fieldName)
{ {
this._name = fieldName; this._name = fieldName;
} }
} }
} }
   
   
// //
// VOID_Orbital.cs // VOID_Orbital.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using KSP; using KSP;
using System; using System;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_SurfAtmo : VOID_WindowModule public class VOID_SurfAtmo : VOID_WindowModule
{ {
  [AVOID_SaveValue("precisionValues")]
  protected long _precisionValues = 230584300921369395;
  protected IntCollection precisionValues;
   
  protected VOID_DoubleValue trueAltitude = new VOID_DoubleValue(
  "Altitude (true)",
  delegate()
  {
  double alt_true = VOID_Core.Instance.vessel.orbit.altitude - VOID_Core.Instance.vessel.terrainAltitude;
  // HACK: This assumes that on worlds with oceans, all water is fixed at 0 m,
  // and water covers the whole surface at 0 m.
  if (VOID_Core.Instance.vessel.terrainAltitude < 0 && VOID_Core.Instance.vessel.mainBody.ocean )
  alt_true = VOID_Core.Instance.vessel.orbit.altitude;
  return alt_true;
  },
  "m"
  );
   
  protected VOID_StrValue surfLatitude = new VOID_StrValue(
  "Latitude",
  new Func<string> (() => Tools.GetLatitudeString(VOID_Core.Instance.vessel))
  );
   
  protected VOID_StrValue surfLongitude = new VOID_StrValue(
  "Longitude",
  new Func<string> (() => Tools.GetLongitudeString(VOID_Core.Instance.vessel))
  );
   
  protected VOID_StrValue vesselHeading = new VOID_StrValue(
  "Heading",
  delegate()
  {
  double heading = Tools.MuMech_get_heading(VOID_Core.Instance.vessel);
  string cardinal = Tools.get_heading_text(heading);
   
  return string.Format(
  "{0}° {1}",
  heading.ToString("F2"),
  cardinal
  );
  }
  );
   
  protected VOID_DoubleValue terrainElevation = new VOID_DoubleValue(
  "Terrain elevation",
  new Func<double> (() => VOID_Core.Instance.vessel.terrainAltitude),
  "m"
  );
   
  protected VOID_DoubleValue surfVelocity = new VOID_DoubleValue(
  "Surface velocity",
  new Func<double> (() => VOID_Core.Instance.vessel.srf_velocity.magnitude),
  "m/s"
  );
   
  protected VOID_DoubleValue vertVelocity = new VOID_DoubleValue(
  "Vertical speed",
  new Func<double> (() => VOID_Core.Instance.vessel.verticalSpeed),
  "m/s"
  );
   
  protected VOID_DoubleValue horzVelocity = new VOID_DoubleValue(
  "Horizontal speed",
  new Func<double> (() => VOID_Core.Instance.vessel.horizontalSrfSpeed),
  "m/s"
  );
   
  protected VOID_FloatValue temperature = new VOID_FloatValue(
  "Temperature",
  new Func<float> (() => VOID_Core.Instance.vessel.flightIntegrator.getExternalTemperature()),
  "°C"
  );
   
  protected VOID_DoubleValue atmDensity = new VOID_DoubleValue (
  "Atmosphere Density",
  new Func<double> (() => VOID_Core.Instance.vessel.atmDensity * 1000f),
  "g/m³"
  );
   
  protected VOID_DoubleValue atmPressure = new VOID_DoubleValue (
  "Pressure",
  new Func<double> (() => VOID_Core.Instance.vessel.staticPressure),
  "atm"
  );
   
  protected VOID_FloatValue atmLimit = new VOID_FloatValue(
  "Atmosphere Limit",
  new Func<float> (() => VOID_Core.Instance.vessel.mainBody.maxAtmosphereAltitude),
  "m"
  );
   
  protected VOID_StrValue currBiome = new VOID_StrValue(
  "Biome",
  new Func<string> (() => Tools.Toadicus_GetAtt(VOID_Core.Instance.vessel).name)
  );
   
public VOID_SurfAtmo() public VOID_SurfAtmo()
{ {
this._Name = "Surface & Atmospheric Information"; this._Name = "Surface & Atmospheric Information";
   
this.WindowPos.x = Screen.width - 260f; this.WindowPos.x = Screen.width - 260f;
this.WindowPos.y = 85; this.WindowPos.y = 85;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
  base.ModuleWindow (_);
   
  int idx = 0;
   
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.trueAltitude.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Altitude (true):"); idx++;
double alt_true = vessel.orbit.altitude - vessel.terrainAltitude;  
// HACK: This assumes that on worlds with oceans, all water is fixed at 0 m, and water covers the whole surface at 0 m.  
if (vessel.terrainAltitude < 0 && vessel.mainBody.ocean ) alt_true = vessel.orbit.altitude;  
GUILayout.Label(Tools.MuMech_ToSI(alt_true) + "m", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal ();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.surfLatitude.DoGUIHorizontal ();
GUILayout.Label("Latitude:");  
GUILayout.Label(Tools.GetLatitudeString(vessel), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.surfLongitude.DoGUIHorizontal ();
GUILayout.Label("Longitude:");  
GUILayout.Label(Tools.GetLongitudeString(vessel), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.vesselHeading.DoGUIHorizontal ();
GUILayout.Label("Heading:");  
GUILayout.Label(Tools.MuMech_get_heading(vessel).ToString("F2") + "° " + Tools.get_heading_text(Tools.MuMech_get_heading(vessel)), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.terrainElevation.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Terrain elevation:"); idx++;
GUILayout.Label(Tools.MuMech_ToSI(vessel.terrainAltitude) + "m", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.surfVelocity.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Surface velocity:"); idx++;
GUILayout.Label(Tools.MuMech_ToSI(vessel.srf_velocity.magnitude) + "m/s", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.vertVelocity.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Vertical speed:"); idx++;
GUILayout.Label(Tools.MuMech_ToSI(vessel.verticalSpeed) + "m/s", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.horzVelocity.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Horizontal speed:"); idx++;
GUILayout.Label(Tools.MuMech_ToSI(vessel.horizontalSrfSpeed) + "m/s", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.temperature.DoGUIHorizontal ("F2");
GUILayout.Label("Temperature:");  
GUILayout.Label(vessel.flightIntegrator.getExternalTemperature().ToString("F2") + "° C", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.atmDensity.DoGUIHorizontal (3);
GUILayout.Label("Atmosphere density:");  
GUILayout.Label(Tools.MuMech_ToSI(vessel.atmDensity * 1000) + "g/m³", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.atmPressure.DoGUIHorizontal ("F2");
GUILayout.Label("Pressure:");  
GUILayout.Label(vessel.staticPressure.ToString("F2") + " atms", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.precisionValues [idx]= (ushort)this.atmLimit.DoGUIHorizontal (this.precisionValues [idx]);
GUILayout.Label("Atmosphere limit:"); idx++;
GUILayout.Label("≈ " + Tools.MuMech_ToSI(vessel.mainBody.maxAtmosphereAltitude) + "m", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
// Toadicus edit: added Biome // Toadicus edit: added Biome
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); this.currBiome.DoGUIHorizontal ();
GUILayout.Label("Biome:");  
GUILayout.Label(Tools.Toadicus_GetAtt(vessel).name, VOID_Core.Instance.LabelStyles["txt_right"]);  
GUILayout.EndHorizontal();  
   
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
   
  public override void LoadConfig ()
  {
  base.LoadConfig ();
   
  this.precisionValues = new IntCollection (4, this._precisionValues);
  }
   
  public override void _SaveToConfig (KSP.IO.PluginConfiguration config)
  {
  this._precisionValues = this.precisionValues.collection;
   
  base._SaveToConfig (config);
  }
} }
} }
// //
// VOID_Orbital.cs // VOID_Orbital.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using KSP; using KSP;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_Transfer : VOID_WindowModule public class VOID_Transfer : VOID_WindowModule
{ {
[AVOID_SaveValue("toggleExtended")]  
protected VOID_SaveValue<bool> toggleExtended = false;  
   
protected List<CelestialBody> selectedBodies = new List<CelestialBody>(); protected List<CelestialBody> selectedBodies = new List<CelestialBody>();
   
public VOID_Transfer() public VOID_Transfer()
{ {
this._Name = "Transfer Angle Information"; this._Name = "Transfer Angle Information";
   
this.WindowPos.x = 475; this.WindowPos.x = 475;
this.WindowPos.y = 85; this.WindowPos.y = 85;
this.defWidth = 315; this.defWidth = 315;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
if (vessel.mainBody.name == "Sun") //Vessel is orbiting the Sun if (vessel.mainBody.name == "Sun") //Vessel is orbiting the Sun
{ {
foreach (CelestialBody body in vessel.mainBody.orbitingBodies) foreach (CelestialBody body in vessel.mainBody.orbitingBodies)
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button(body.bodyName)) if (GUILayout.Button(body.bodyName))
{ {
//add or remove this body to this list of bodies to display more info on //add or remove this body to this list of bodies to display more info on
if (selectedBodies.Contains(body)) selectedBodies.Remove(body); if (selectedBodies.Contains(body)) selectedBodies.Remove(body);
else selectedBodies.Add(body); else selectedBodies.Add(body);
} }
GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
if (selectedBodies.Contains(body)) if (selectedBodies.Contains(body))
{ {
Tools.display_transfer_angles_SUN2PLANET(body, vessel); //show phase angles for each selected body Tools.display_transfer_angles_SUN2PLANET(body, vessel); //show phase angles for each selected body
tad_targeting(body); //display Set/Unset Target button for each selected body tad_targeting(body); //display Set/Unset Target button for each selected body
} }
} }
} }
else if (vessel.mainBody.referenceBody.name == "Sun") //Vessel is orbiting a planet else if (vessel.mainBody.referenceBody.name == "Sun") //Vessel is orbiting a planet
{ {
foreach (CelestialBody body in vessel.mainBody.referenceBody.orbitingBodies) foreach (CelestialBody body in vessel.mainBody.referenceBody.orbitingBodies)
{ {
if (body.name != vessel.mainBody.name) // show other planets if (body.name != vessel.mainBody.name) // show other planets
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button(body.bodyName)) if (GUILayout.Button(body.bodyName))
{ {
//add or remove this body to this list of bodies to display more info on //add or remove this body to this list of bodies to display more info on
if (selectedBodies.Contains(body)) selectedBodies.Remove(body); if (selectedBodies.Contains(body)) selectedBodies.Remove(body);
else selectedBodies.Add(body); else selectedBodies.Add(body);
} }
GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
if (selectedBodies.Contains(body)) if (selectedBodies.Contains(body))
{ {
Tools.display_transfer_angles_PLANET2PLANET(body, vessel); Tools.display_transfer_angles_PLANET2PLANET(body, vessel);
tad_targeting(body); //display Set/Unset Target button tad_targeting(body); //display Set/Unset Target button
} }
} }
} }
foreach (CelestialBody body in vessel.mainBody.orbitingBodies) // show moons foreach (CelestialBody body in vessel.mainBody.orbitingBodies) // show moons
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button(body.bodyName)) if (GUILayout.Button(body.bodyName))
{ {
//add or remove this body to this list of bodies to display more info on //add or remove this body to this list of bodies to display more info on
if (selectedBodies.Contains(body)) selectedBodies.Remove(body); if (selectedBodies.Contains(body)) selectedBodies.Remove(body);
else selectedBodies.Add(body); else selectedBodies.Add(body);
} }
GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
if (selectedBodies.Contains(body)) if (selectedBodies.Contains(body))
{ {
Tools.display_transfer_angles_PLANET2MOON(body, vessel); Tools.display_transfer_angles_PLANET2MOON(body, vessel);
tad_targeting(body); //display Set/Unset Target button tad_targeting(body); //display Set/Unset Target button
} }
} }
} }
else if (vessel.mainBody.referenceBody.referenceBody.name == "Sun") // Vessel is orbiting a moon else if (vessel.mainBody.referenceBody.referenceBody.name == "Sun") // Vessel is orbiting a moon
{ {
foreach (CelestialBody body in vessel.mainBody.referenceBody.orbitingBodies) foreach (CelestialBody body in vessel.mainBody.referenceBody.orbitingBodies)
{ {
if (body.name != vessel.mainBody.name) // show other moons if (body.name != vessel.mainBody.name) // show other moons
{ {
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button(body.bodyName)) if (GUILayout.Button(body.bodyName))
{ {
//add or remove this body to this list of bodies to display more info on //add or remove this body to this list of bodies to display more info on
if (selectedBodies.Contains(body)) selectedBodies.Remove(body); if (selectedBodies.Contains(body)) selectedBodies.Remove(body);
else selectedBodies.Add(body); else selectedBodies.Add(body);
} }
GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false)); GUILayout.Label("Inclined " + body.orbit.inclination.ToString("F3") + "°", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
if (selectedBodies.Contains(body)) if (selectedBodies.Contains(body))
{ {
Tools.display_transfer_angles_MOON2MOON(body, vessel); Tools.display_transfer_angles_MOON2MOON(body, vessel);
tad_targeting(body); //display Set/Unset Target button tad_targeting(body); //display Set/Unset Target button
} }
} }
} }
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
   
private void tad_targeting(CelestialBody body) private void tad_targeting(CelestialBody body)
{ {
//Target Set/Unset buttons //Target Set/Unset buttons
if (FlightGlobals.fetch.VesselTarget == null || (FlightGlobals.fetch.VesselTarget != null && FlightGlobals.fetch.VesselTarget.GetVessel() == null)) if (FlightGlobals.fetch.VesselTarget == null || (FlightGlobals.fetch.VesselTarget != null && FlightGlobals.fetch.VesselTarget.GetVessel() == null))
{ {
//No TGT set or TGT is a Body //No TGT set or TGT is a Body
if ((CelestialBody)FlightGlobals.fetch.VesselTarget != body) if ((CelestialBody)FlightGlobals.fetch.VesselTarget != body)
{ {
if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false))) if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false)))
{ {
FlightGlobals.fetch.SetVesselTarget(body); FlightGlobals.fetch.SetVesselTarget(body);
Tools.PostDebugMessage("[VOID] KSP Target set to CelestialBody " + body.bodyName); Tools.PostDebugMessage("[VOID] KSP Target set to CelestialBody " + body.bodyName);
} }
} }
else if ((CelestialBody)FlightGlobals.fetch.VesselTarget == body) else if ((CelestialBody)FlightGlobals.fetch.VesselTarget == body)
{ {
if (GUILayout.Button("Unset Target", GUILayout.ExpandWidth(false))) if (GUILayout.Button("Unset Target", GUILayout.ExpandWidth(false)))
{ {
FlightGlobals.fetch.SetVesselTarget(null); FlightGlobals.fetch.SetVesselTarget(null);
Tools.PostDebugMessage("[VOID] KSP Target set to null"); Tools.PostDebugMessage("[VOID] KSP Target set to null");
} }
} }
} }
else if (FlightGlobals.fetch.VesselTarget == null || (FlightGlobals.fetch.VesselTarget != null && FlightGlobals.fetch.VesselTarget.GetVessel() != null)) else if (FlightGlobals.fetch.VesselTarget == null || (FlightGlobals.fetch.VesselTarget != null && FlightGlobals.fetch.VesselTarget.GetVessel() != null))
{ {
//No TGT or TGT is a vessel //No TGT or TGT is a vessel
if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false))) if (GUILayout.Button("Set Target", GUILayout.ExpandWidth(false)))
{ {
FlightGlobals.fetch.SetVesselTarget(body); FlightGlobals.fetch.SetVesselTarget(body);
Tools.PostDebugMessage("[VOID] KSP Target set to CelestialBody " + body.bodyName); Tools.PostDebugMessage("[VOID] KSP Target set to CelestialBody " + body.bodyName);
} }
} }
} }
} }
} }
   
   
// //
// VOID_Orbital.cs // VOID_Orbital.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using KSP; using KSP;
using System; using System;
  using System.Collections.Generic;
using UnityEngine; using UnityEngine;
  using Engineer.VesselSimulator;
  using Engineer.Extensions;
   
namespace VOID namespace VOID
{ {
public class VOID_VesselInfo : VOID_WindowModule public class VOID_VesselInfo : VOID_WindowModule
{ {
[AVOID_SaveValue("toggleExtended")] protected VOID_DoubleValue geeForce = new VOID_DoubleValue(
protected VOID_SaveValue<bool> toggleExtended = false; "G-force",
  new Func<double>(() => VOID_Core.Instance.vessel.geeForce),
public VOID_VesselInfo() "gees"
  );
   
  protected VOID_IntValue partCount = new VOID_IntValue(
  "Parts",
  new Func<int>(() => VOID_Core.Instance.vessel.Parts.Count),
  ""
  );
   
  protected VOID_DoubleValue totalMass = new VOID_DoubleValue(
  "Total Mass",
  new Func<double> (() => SimManager.Instance.TryGetLastMass()),
  "tons"
  );
   
  protected VOID_DoubleValue resourceMass = new VOID_DoubleValue(
  "Resource Mass",
  delegate()
  {
  double rscMass = 0;
  foreach (Part part in VOID_Core.Instance.vessel.Parts)
  {
  rscMass += part.GetResourceMass();
  }
  return rscMass;
  },
  "tons"
  );
   
  protected VOID_DoubleValue stageDeltaV = new VOID_DoubleValue(
  "DeltaV (Current Stage)",
  delegate()
  {
  if (SimManager.Instance.Stages == null ||
  SimManager.Instance.Stages.Length <= Staging.lastStage
  )
  return double.NaN;
  return SimManager.Instance.Stages[Staging.lastStage].deltaV;
  },
  "m/s"
  );
   
  protected VOID_DoubleValue totalDeltaV = new VOID_DoubleValue(
  "DeltaV (Total)",
  delegate()
  {
  if (SimManager.Instance.Stages == null)
  return double.NaN;
  return SimManager.Instance.LastStage.totalDeltaV;
  },
  "m/s"
  );
   
  protected VOID_FloatValue mainThrottle = new VOID_FloatValue(
  "Throttle",
  new Func<float>(() => VOID_Core.Instance.vessel.ctrlState.mainThrottle * 100f),
  "%"
  );
   
  protected VOID_StrValue currmaxThrust = new VOID_StrValue(
  "Thrust (curr/max)",
  delegate()
  {
  if (SimManager.Instance.Stages == null)
  return "N/A";
   
  double currThrust = SimManager.Instance.LastStage.actualThrust;
  double maxThrust = SimManager.Instance.LastStage.thrust;
   
  return string.Format(
  "{0} / {1}",
  currThrust.ToString("F1"),
  maxThrust.ToString("F1")
  );
  }
  );
   
  protected VOID_StrValue currmaxThrustWeight = new VOID_StrValue(
  "T:W (curr/max)",
  delegate()
  {
  if (SimManager.Instance.Stages == null)
  return "N/A";
   
  double currThrust = SimManager.Instance.LastStage.actualThrust;
  double maxThrust = SimManager.Instance.LastStage.thrust;
  double mass = SimManager.Instance.TryGetLastMass();
  double gravity = VOID_Core.Instance.vessel.mainBody.gravParameter /
  Math.Pow(
  VOID_Core.Instance.vessel.mainBody.Radius + VOID_Core.Instance.vessel.altitude,
  2
  );
  double weight = mass * gravity;
   
  return string.Format(
  "{0} / {1}",
  (currThrust / weight).ToString("F2"),
  (maxThrust / weight).ToString("F2")
  );
  }
  );
   
  protected VOID_DoubleValue surfaceThrustWeight = new VOID_DoubleValue(
  "Max T:W @ surface",
  delegate()
  {
  if (SimManager.Instance.Stages == null)
  return double.NaN;
   
  double maxThrust = SimManager.Instance.LastStage.thrust;
  double mass = SimManager.Instance.TryGetLastMass();
  double gravity = (VOID_Core.Constant_G * VOID_Core.Instance.vessel.mainBody.Mass) /
  Math.Pow(VOID_Core.Instance.vessel.mainBody.Radius, 2);
  double weight = mass * gravity;
   
  return maxThrust / weight;
  },
  ""
  );
   
  protected VOID_StrValue intakeAirStatus = new VOID_StrValue(
  "Intake Air (Curr / Req)",
  delegate()
  {
  double currentAmount;
  double currentRequirement;
   
  currentAmount = 0d;
  currentRequirement = 0d;
   
  foreach (Part part in VOID_Core.Instance.vessel.Parts)
  {
  if (part.HasModule<ModuleEngines>() && part.enabled)
  {
  foreach (Propellant propellant in part.GetModule<ModuleEngines>().propellants)
  {
  if (propellant.name == "IntakeAir")
  {
  // currentAmount += propellant.currentAmount;
  currentRequirement += propellant.currentRequirement / TimeWarp.fixedDeltaTime;
  break;
  }
  }
  }
   
  if (part.HasModule<ModuleResourceIntake>() && part.enabled)
  {
  ModuleResourceIntake intakeModule = part.GetModule<ModuleResourceIntake>();
   
  if (intakeModule.resourceName == "IntakeAir")
  {
  currentAmount += intakeModule.airFlow;
  }
  }
  }
   
  if (currentAmount == 0 && currentRequirement == 0)
  {
  return "N/A";
  }
   
  return string.Format("{0:F3} / {1:F3}", currentAmount, currentRequirement);
  }
  );
   
  public VOID_VesselInfo() : base()
{ {
this._Name = "Vessel Information"; this._Name = "Vessel Information";
   
this.WindowPos.x = Screen.width - 260; this.WindowPos.x = Screen.width - 260;
this.WindowPos.y = 450; this.WindowPos.y = 450;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
  base.ModuleWindow (_);
   
if ((TimeWarp.WarpMode == TimeWarp.Modes.LOW) || (TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate)) if ((TimeWarp.WarpMode == TimeWarp.Modes.LOW) || (TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate))
{ {
Engineer.VesselSimulator.SimManager.Instance.RequestSimulation(); SimManager.Instance.RequestSimulation();
} }
   
Engineer.VesselSimulator.Stage[] stages = Engineer.VesselSimulator.SimManager.Instance.Stages;  
   
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
GUILayout.Label(vessel.vesselName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); GUILayout.Label(
  vessel.vesselName,
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); VOID_Core.Instance.LabelStyles["center_bold"],
GUILayout.Label("G-force:"); GUILayout.ExpandWidth(true));
GUILayout.Label(vessel.geeForce.ToString("F2") + " gees", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal(); this.geeForce.DoGUIHorizontal ("F2");
   
int num_parts = 0; this.partCount.DoGUIHorizontal ();
double total_mass = vessel.GetTotalMass();  
double resource_mass = 0; this.totalMass.DoGUIHorizontal ("F1");
double max_thrust = 0;  
double final_thrust = 0; this.resourceMass.DoGUIHorizontal ("F1");
   
foreach (Part p in vessel.parts) this.stageDeltaV.DoGUIHorizontal (3, false);
{  
num_parts++; this.totalDeltaV.DoGUIHorizontal (3, false);
resource_mass += p.GetResourceMass();  
  this.mainThrottle.DoGUIHorizontal ("F0");
foreach (PartModule pm in p.Modules)  
{ this.currmaxThrust.DoGUIHorizontal ();
if ((pm.moduleName == "ModuleEngines") && ((p.State == PartStates.ACTIVE) || ((Staging.CurrentStage > Staging.lastStage) && (p.inverseStage == Staging.lastStage))))  
{ this.currmaxThrustWeight.DoGUIHorizontal ();
max_thrust += ((ModuleEngines)pm).maxThrust;  
final_thrust += ((ModuleEngines)pm).finalThrust; this.surfaceThrustWeight.DoGUIHorizontal ("F2");
}  
} this.intakeAirStatus.DoGUIHorizontal();
}  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Parts:");  
GUILayout.Label(num_parts.ToString("F0"), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Total mass:");  
GUILayout.Label(total_mass.ToString("F1") + " tons", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Resource mass:");  
GUILayout.Label(resource_mass.ToString("F1") + " tons", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
if (stages.Length > Staging.lastStage)  
{  
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("DeltaV (Current Stage):");  
GUILayout.Label(Tools.MuMech_ToSI(stages[Staging.lastStage].deltaV).ToString() + "m/s", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
}  
   
if (stages.Length > 0)  
{  
double totalDeltaV = 0d;  
   
for (int i = 0; i < stages.Length; ++i)  
{  
totalDeltaV += stages [i].deltaV;  
}  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("DeltaV (Total):");  
GUILayout.Label(Tools.MuMech_ToSI(totalDeltaV).ToString() + "m/s", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
}  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Throttle:");  
GUILayout.Label((vessel.ctrlState.mainThrottle * 100f).ToString("F0") + "%", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Thrust (curr/max):");  
GUILayout.Label(final_thrust.ToString("F1") + " / " + max_thrust.ToString("F1") + " kN", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
double gravity = vessel.mainBody.gravParameter / Math.Pow(vessel.mainBody.Radius + vessel.altitude, 2);  
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("T:W (curr/max):");  
GUILayout.Label((final_thrust / (total_mass * gravity)).ToString("F2") + " / " + (max_thrust / (total_mass * gravity)).ToString("F2"), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
double g_ASL = (VOID_Core.Constant_G * vessel.mainBody.Mass) / Math.Pow(vessel.mainBody.Radius, 2);  
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));  
GUILayout.Label("Max T:W @ surface:");  
GUILayout.Label((max_thrust / (total_mass * g_ASL)).ToString("F2"), GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal();  
   
GUILayout.EndVertical(); GUILayout.EndVertical();
GUI.DragWindow(); GUI.DragWindow();
} }
} }
} }
   
   
// //
// VOID_Orbital.cs // VOID_Orbital.cs
// //
// Author: // Author:
// toadicus <> // toadicus <>
// //
// Copyright (c) 2013 toadicus // Copyright (c) 2013 toadicus
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using KSP; using KSP;
using System; using System;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_VesselRegister : VOID_WindowModule public class VOID_VesselRegister : VOID_WindowModule
{ {
[AVOID_SaveValue("selectedBodyIdx")] [AVOID_SaveValue("selectedBodyIdx")]
protected VOID_SaveValue<int> selectedBodyIdx = 0; protected VOID_SaveValue<int> selectedBodyIdx = 0;
protected CelestialBody seletedBody; protected CelestialBody seletedBody;
   
[AVOID_SaveValue("selectedVesselTypeIdx")] [AVOID_SaveValue("selectedVesselTypeIdx")]
protected VOID_SaveValue<int> selectedVesselTypeIdx = 0; protected VOID_SaveValue<int> selectedVesselTypeIdx = 0;
protected VesselType selectedVesselType; protected VesselType selectedVesselType;
   
protected string vesselSituation = "Orbiting"; protected string vesselSituation = "Orbiting";
   
protected Vector2 selectorScrollPos = new Vector2(); protected Vector2 selectorScrollPos = new Vector2();
   
protected Vessel _selectedVessel; protected Vessel _selectedVessel;
   
public Vessel selectedVessel public Vessel selectedVessel
{ {
get get
{ {
return this._selectedVessel; return this._selectedVessel;
} }
} }
   
public VOID_VesselRegister() public VOID_VesselRegister()
{ {
this._Name = "Vessel Register"; this._Name = "Vessel Register";
   
this.WindowPos.x = 845; this.WindowPos.x = 845;
this.WindowPos.y = 275; this.WindowPos.y = 275;
this.defHeight = 375; this.defHeight = 375;
} }
   
public override void ModuleWindow(int _) public override void ModuleWindow(int _)
{ {
if (!VOID_Core.Instance.allVesselTypes.Any()) if (!VOID_Core.Instance.allVesselTypes.Any())
{ {
return; return;
} }
   
GUILayout.BeginVertical(); GUILayout.BeginVertical();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button("<")) if (GUILayout.Button("<"))
{ {
selectedBodyIdx--; selectedBodyIdx--;
if (selectedBodyIdx < 0) selectedBodyIdx = VOID_Core.Instance.allBodies.Count - 1; if (selectedBodyIdx < 0) selectedBodyIdx = VOID_Core.Instance.allBodies.Count - 1;
} }
GUILayout.Label(VOID_Core.Instance.allBodies[selectedBodyIdx].bodyName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); GUILayout.Label(VOID_Core.Instance.allBodies[selectedBodyIdx].bodyName, VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true));
if (GUILayout.Button(">")) if (GUILayout.Button(">"))
{ {
selectedBodyIdx++; selectedBodyIdx++;
if (selectedBodyIdx > VOID_Core.Instance.allBodies.Count - 1) selectedBodyIdx = 0; if (selectedBodyIdx > VOID_Core.Instance.allBodies.Count - 1) selectedBodyIdx = 0;
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
seletedBody = VOID_Core.Instance.allBodies[selectedBodyIdx]; seletedBody = VOID_Core.Instance.allBodies[selectedBodyIdx];
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button("<")) if (GUILayout.Button("<"))
{ {
selectedVesselTypeIdx--; selectedVesselTypeIdx--;
if (selectedVesselTypeIdx < 0) selectedVesselTypeIdx = VOID_Core.Instance.allVesselTypes.Count - 1; if (selectedVesselTypeIdx < 0) selectedVesselTypeIdx = VOID_Core.Instance.allVesselTypes.Count - 1;
} }
GUILayout.Label(VOID_Core.Instance.allVesselTypes[selectedVesselTypeIdx].ToString(), VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true)); GUILayout.Label(VOID_Core.Instance.allVesselTypes[selectedVesselTypeIdx].ToString(), VOID_Core.Instance.LabelStyles["center_bold"], GUILayout.ExpandWidth(true));
if (GUILayout.Button(">")) if (GUILayout.Button(">"))
{ {
selectedVesselTypeIdx++; selectedVesselTypeIdx++;
if (selectedVesselTypeIdx > VOID_Core.Instance.allVesselTypes.Count - 1) selectedVesselTypeIdx = 0; if (selectedVesselTypeIdx > VOID_Core.Instance.allVesselTypes.Count - 1) selectedVesselTypeIdx = 0;
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
selectedVesselType = VOID_Core.Instance.allVesselTypes[selectedVesselTypeIdx]; selectedVesselType = VOID_Core.Instance.allVesselTypes[selectedVesselTypeIdx];
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (GUILayout.Button("Landed", GUILayout.ExpandWidth(true))) vesselSituation = "Landed"; if (GUILayout.Button("Landed", GUILayout.ExpandWidth(true))) vesselSituation = "Landed";
if (GUILayout.Button("Orbiting", GUILayout.ExpandWidth(true))) vesselSituation = "Orbiting"; if (GUILayout.Button("Orbiting", GUILayout.ExpandWidth(true))) vesselSituation = "Orbiting";
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
GUILayout.Label( GUILayout.Label(
Tools.UppercaseFirst(vesselSituation) + " " + selectedVesselType.ToString() + "s @ " + seletedBody.bodyName, Tools.UppercaseFirst(vesselSituation) + " " + selectedVesselType.ToString() + "s @ " + seletedBody.bodyName,
VOID_Core.Instance.LabelStyles["center"], VOID_Core.Instance.LabelStyles["center"],
GUILayout.ExpandWidth(true)); GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
   
selectorScrollPos = GUILayout.BeginScrollView(selectorScrollPos, false, false); selectorScrollPos = GUILayout.BeginScrollView(selectorScrollPos, false, false);
   
foreach (Vessel v in FlightGlobals.Vessels) foreach (Vessel v in FlightGlobals.Vessels)
{ {
if (v != vessel && v.vesselType == selectedVesselType && v.mainBody == seletedBody) if (v != vessel && v.vesselType == selectedVesselType && v.mainBody == seletedBody)
{ {
if ((vesselSituation == "Landed" && if ((vesselSituation == "Landed" &&
(v.situation == Vessel.Situations.LANDED || (v.situation == Vessel.Situations.LANDED ||
v.situation == Vessel.Situations.PRELAUNCH || v.situation == Vessel.Situations.PRELAUNCH ||
v.situation == Vessel.Situations.SPLASHED)) || v.situation == Vessel.Situations.SPLASHED)) ||
(vesselSituation == "Orbiting" && (vesselSituation == "Orbiting" &&
(v.situation == Vessel.Situations.ESCAPING || (v.situation == Vessel.Situations.ESCAPING ||
v.situation == Vessel.Situations.FLYING || v.situation == Vessel.Situations.FLYING ||
v.situation == Vessel.Situations.ORBITING || v.situation == Vessel.Situations.ORBITING ||
v.situation == Vessel.Situations.SUB_ORBITAL)) v.situation == Vessel.Situations.SUB_ORBITAL))
) )
{ {
if (GUILayout.Button(v.vesselName, GUILayout.ExpandWidth(true))) if (GUILayout.Button(v.vesselName, GUILayout.ExpandWidth(true)))
{ {
if (_selectedVessel != v) if (_selectedVessel != v)
{ {
_selectedVessel = v; //set clicked vessel as selected_vessel _selectedVessel = v; //set clicked vessel as selected_vessel
this._Active = true; //turn bool on to open the window if closed this._Active.value = true; //turn bool on to open the window if closed
} }
else else
{ {
_selectedVessel = null; _selectedVessel = null;
} }
} }
} }
} }
} }
   
GUILayout.EndScrollView(); GUILayout.EndScrollView();
   
GUILayout.EndVertical(); GUILayout.EndVertical();
   
GUI.DragWindow(); GUI.DragWindow();
} }
} }
} }
  using System.Reflection;
  using System.Runtime.CompilerServices;
  using System.Runtime.InteropServices;
 
  // Allgemeine Informationen über eine Assembly werden über die folgenden
  // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
  // die mit einer Assembly verknüpft sind.
  [assembly: AssemblyTitle("Toolbar Wrapper for Kerbal Space Program")]
  [assembly: AssemblyDescription("")]
  [assembly: AssemblyConfiguration("")]
  [assembly: AssemblyCompany("")]
  [assembly: AssemblyProduct("ToolbarWrapper")]
  [assembly: AssemblyCopyright("Copyright © 2013-2014 Maik Schreiber")]
  [assembly: AssemblyTrademark("")]
  [assembly: AssemblyCulture("")]
 
  // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
  // für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
  // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
  [assembly: ComVisible(false)]
 
  // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
  [assembly: Guid("bfd95a60-6335-4a59-a29e-438d806d8f2d")]
 
  // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
  //
  // Hauptversion
  // Nebenversion
  // Buildnummer
  // Revision
  //
  // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
  // übernehmen, indem Sie "*" eingeben:
  // [assembly: AssemblyVersion("1.0.*")]
  [assembly: AssemblyVersion("1.0.0.0")]
  [assembly: AssemblyFileVersion("1.0.0.0")]
 
  /*
  Copyright (c) 2013-2014, Maik Schreiber
  All rights reserved.
 
  Redistribution and use in source and binary forms, with or without modification,
  are permitted provided that the following conditions are met:
 
  1. Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.
 
  2. Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
 
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Reflection;
  using System.Text;
  using UnityEngine;
 
 
  namespace VOID {
 
 
 
  /**********************************************************\
  * --- DO NOT EDIT BELOW THIS COMMENT --- *
  * *
  * This file contains classes and interfaces to use the *
  * Toolbar Plugin without creating a hard dependency on it. *
  * *
  * There is nothing in this file that needs to be edited *
  * by hand. *
  * *
  * --- DO NOT EDIT BELOW THIS COMMENT --- *
  \**********************************************************/
 
 
 
  /// <summary>
  /// The global tool bar manager.
  /// </summary>
  public partial class ToolbarManager : IToolbarManager {
  /// <summary>
  /// Whether the Toolbar Plugin is available.
  /// </summary>
  public static bool ToolbarAvailable {
  get {
  if (toolbarAvailable == null) {
  toolbarAvailable = Instance != null;
  }
  return (bool) toolbarAvailable;
  }
  }
 
  /// <summary>
  /// The global tool bar manager instance.
  /// </summary>
  public static IToolbarManager Instance {
  get {
  if ((toolbarAvailable != false) && (instance_ == null)) {
  Type type = ToolbarTypes.getType("Toolbar.ToolbarManager");
  if (type != null) {
  object realToolbarManager = ToolbarTypes.getStaticProperty(type, "Instance").GetValue(null, null);
  instance_ = new ToolbarManager(realToolbarManager);
  }
  }
  return instance_;
  }
  }
  }
 
  #region interfaces
 
  /// <summary>
  /// A toolbar manager.
  /// </summary>
  public interface IToolbarManager {
  /// <summary>
  /// Adds a new button.
  /// </summary>
  /// <remarks>
  /// To replace an existing button, just add a new button using the old button's namespace and ID.
  /// Note that the new button will inherit the screen position of the old button.
  /// </remarks>
  /// <param name="ns">The new button's namespace. This is usually the plugin's name. Must not include special characters like '.'</param>
  /// <param name="id">The new button's ID. This ID must be unique across all buttons in the namespace. Must not include special characters like '.'</param>
  /// <returns>The button created.</returns>
  IButton add(string ns, string id);
  }
 
  /// <summary>
  /// Represents a clickable button.
  /// </summary>
  public interface IButton {
  /// <summary>
  /// The text displayed on the button. Set to null to hide text.
  /// </summary>
  /// <remarks>
  /// The text can be changed at any time to modify the button's appearance. Note that since this will also
  /// modify the button's size, this feature should be used sparingly, if at all.
  /// </remarks>
  /// <seealso cref="TexturePath"/>
  string Text {
  set;
  get;
  }
 
  /// <summary>
  /// The color the button text is displayed with. Defaults to Color.white.
  /// </summary>
  /// <remarks>
  /// The text color can be changed at any time to modify the button's appearance.
  /// </remarks>
  Color TextColor {
  set;
  get;
  }
 
  /// <summary>
  /// The path of a texture file to display an icon on the button. Set to null to hide icon.
  /// </summary>
  /// <remarks>
  /// <para>
  /// A texture path on a button will have precedence over text. That is, if both text and texture path
  /// have been set on a button, the button will show the texture, not the text.
  /// </para>
  /// <para>
  /// The texture size must not exceed 24x24 pixels.
  /// </para>
  /// <para>
  /// The texture path must be relative to the "GameData" directory, and must not specify a file name suffix.
  /// Valid example: MyAddon/Textures/icon_mybutton
  /// </para>
  /// <para>
  /// The texture path can be changed at any time to modify the button's appearance.
  /// </para>
  /// </remarks>
  /// <seealso cref="Text"/>
  string TexturePath {
  set;
  get;
  }
 
  /// <summary>
  /// The button's tool tip text. Set to null if no tool tip is desired.
  /// </summary>
  /// <remarks>
  /// Tool Tip Text Should Always Use Headline Style Like This.
  /// </remarks>
  string ToolTip {
  set;
  get;
  }
 
  /// <summary>
  /// Whether this button is currently visible or not. Can be used in addition to or as a replacement for <see cref="Visibility"/>.
  /// </summary>
  /// <remarks>
  /// Setting this property to true does not affect the player's ability to hide the button using the configuration.
  /// Conversely, setting this property to false does not enable the player to show the button using the configuration.
  /// </remarks>
  bool Visible {
  set;
  get;
  }
 
  /// <summary>
  /// Determines this button's visibility. Can be used in addition to or as a replacement for <see cref="Visible"/>.
  /// </summary>
  /// <remarks>
  /// The return value from IVisibility.Visible is subject to the same rules as outlined for
  /// <see cref="Visible"/>.
  /// </remarks>
  IVisibility Visibility {
  set;
  get;
  }
 
  /// <summary>
  /// Whether this button is currently effectively visible or not. This is a combination of
  /// <see cref="Visible"/> and <see cref="Visibility"/>.
  /// </summary>
  /// <remarks>
  /// Note that the toolbar is not visible in certain game scenes, for example the loading screens. This property
  /// does not reflect button invisibility in those scenes. In addition, this property does not reflect the
  /// player's configuration of the button's visibility.
  /// </remarks>
  bool EffectivelyVisible {
  get;
  }
 
  /// <summary>
  /// Whether this button is currently enabled (clickable) or not. This does not affect the player's ability to
  /// position the button on their toolbar.
  /// </summary>
  bool Enabled {
  set;
  get;
  }
 
  /// <summary>
  /// Whether this button is currently "important." Set to false to return to normal button behaviour.
  /// </summary>
  /// <remarks>
  /// <para>
  /// This can be used to temporarily force the button to be shown on screen regardless of the toolbar being
  /// currently in auto-hidden mode. For example, a button that signals the arrival of a private message in
  /// a chat room could mark itself as "important" as long as the message has not been read.
  /// </para>
  /// <para>
  /// Setting this property does not change the appearance of the button. Use <see cref="TexturePath"/> to
  /// change the button's icon.
  /// </para>
  /// <para>
  /// Setting this property to true does not affect the player's ability to hide the button using the
  /// configuration.
  /// </para>
  /// <para>
  /// This feature should be used only sparingly, if at all, since it forces the button to be displayed on
  /// screen even when it normally wouldn't.
  /// </para>
  /// </remarks>
  bool Important {
  set;
  get;
  }
 
  /// <summary>
  /// A drawable that is tied to the current button. This can be anything from a popup menu to
  /// an informational window. Set to null to hide the drawable.
  /// </summary>
  IDrawable Drawable {
  set;
  get;
  }
 
  /// <summary>
  /// Event handler that can be registered with to receive "on click" events.
  /// </summary>
  /// <example>
  /// <code>
  /// IButton button = ...
  /// button.OnClick += (e) => {
  /// Debug.Log("button clicked, mouseButton: " + e.MouseButton);
  /// };
  /// </code>
  /// </example>
  event ClickHandler OnClick;
 
  /// <summary>
  /// Event handler that can be registered with to receive "on mouse enter" events.
  /// </summary>
  /// <example>
  /// <code>
  /// IButton button = ...
  /// button.OnMouseEnter += (e) => {
  /// Debug.Log("mouse entered button");
  /// };
  /// </code>
  /// </example>
  event MouseEnterHandler OnMouseEnter;
 
  /// <summary>
  /// Event handler that can be registered with to receive "on mouse leave" events.
  /// </summary>
  /// <example>
  /// <code>
  /// IButton button = ...
  /// button.OnMouseLeave += (e) => {
  /// Debug.Log("mouse left button");
  /// };
  /// </code>
  /// </example>
  event MouseLeaveHandler OnMouseLeave;
 
  /// <summary>
  /// Permanently destroys this button so that it is no longer displayed.
  /// Should be used when a plugin is stopped to remove leftover buttons.
  /// </summary>
  void Destroy();
  }
 
  /// <summary>
  /// A drawable that is tied to a particular button. This can be anything from a popup menu
  /// to an informational window.
  /// </summary>
  public interface IDrawable {
  /// <summary>
  /// Update any information. This is called once per frame.
  /// </summary>
  void Update();
 
  /// <summary>
  /// Draws GUI widgets for this drawable. This is the equivalent to the OnGUI() message in
  /// <see cref="MonoBehaviour"/>.
  /// </summary>
  /// <remarks>
  /// The drawable will be positioned near its parent toolbar according to the drawable's current
  /// width/height.
  /// </remarks>
  /// <param name="position">The left/top position of where to draw this drawable.</param>
  /// <returns>The current width/height of this drawable.</returns>
  Vector2 Draw(Vector2 position);
  }
 
  #endregion
 
  #region events
 
  /// <summary>
  /// Event describing a click on a button.
  /// </summary>
  public partial class ClickEvent : EventArgs {
  /// <summary>
  /// The button that has been clicked.
  /// </summary>
  public readonly IButton Button;
 
  /// <summary>
  /// The mouse button which the button was clicked with.
  /// </summary>
  /// <remarks>
  /// Is 0 for left mouse button, 1 for right mouse button, and 2 for middle mouse button.
  /// </remarks>
  public readonly int MouseButton;
  }
 
  /// <summary>
  /// An event handler that is invoked whenever a button has been clicked.
  /// </summary>
  /// <param name="e">An event describing the button click.</param>
  public delegate void ClickHandler(ClickEvent e);
 
  /// <summary>
  /// Event describing the mouse pointer moving about a button.
  /// </summary>
  public abstract partial class MouseMoveEvent {
  /// <summary>
  /// The button in question.
  /// </summary>
  public readonly IButton button;
  }
 
  /// <summary>
  /// Event describing the mouse pointer entering a button's area.
  /// </summary>
  public partial class MouseEnterEvent : MouseMoveEvent {
  }
 
  /// <summary>
  /// Event describing the mouse pointer leaving a button's area.
  /// </summary>
  public partial class MouseLeaveEvent : MouseMoveEvent {
  }
 
  /// <summary>
  /// An event handler that is invoked whenever the mouse pointer enters a button's area.
  /// </summary>
  /// <param name="e">An event describing the mouse pointer entering.</param>
  public delegate void MouseEnterHandler(MouseEnterEvent e);
 
  /// <summary>
  /// An event handler that is invoked whenever the mouse pointer leaves a button's area.
  /// </summary>
  /// <param name="e">An event describing the mouse pointer leaving.</param>
  public delegate void MouseLeaveHandler(MouseLeaveEvent e);
 
  #endregion
 
  #region visibility
 
  /// <summary>
  /// Determines visibility of a button.
  /// </summary>
  /// <seealso cref="IButton.Visibility"/>
  public interface IVisibility {
  /// <summary>
  /// Whether a button is currently visible or not.
  /// </summary>
  /// <seealso cref="IButton.Visible"/>
  bool Visible {
  get;
  }
  }
 
  /// <summary>
  /// Determines visibility of a button in relation to the currently running game scene.
  /// </summary>
  /// <example>
  /// <code>
  /// IButton button = ...
  /// button.Visibility = new GameScenesVisibility(GameScenes.EDITOR, GameScenes.SPH);
  /// </code>
  /// </example>
  /// <seealso cref="IButton.Visibility"/>
  public class GameScenesVisibility : IVisibility {
  private GameScenes[] gameScenes;
 
  public bool Visible {
  get {
  return (bool) visibleProperty.GetValue(realGameScenesVisibility, null);
  }
  }
 
  private object realGameScenesVisibility;
  private PropertyInfo visibleProperty;
 
  public GameScenesVisibility(params GameScenes[] gameScenes) {
  Type gameScenesVisibilityType = ToolbarTypes.getType("Toolbar.GameScenesVisibility");
  realGameScenesVisibility = Activator.CreateInstance(gameScenesVisibilityType, new object[] { gameScenes });
  visibleProperty = ToolbarTypes.getProperty(gameScenesVisibilityType, "Visible");
  this.gameScenes = gameScenes;
  }
  }
 
  #endregion
 
  #region drawable
 
  /// <summary>
  /// A drawable that draws a popup menu.
  /// </summary>
  public partial class PopupMenuDrawable : IDrawable {
  /// <summary>
  /// Event handler that can be registered with to receive "any menu option clicked" events.
  /// </summary>
  public event Action OnAnyOptionClicked {
  add {
  onAnyOptionClickedEvent.AddEventHandler(realPopupMenuDrawable, value);
  }
  remove {
  onAnyOptionClickedEvent.RemoveEventHandler(realPopupMenuDrawable, value);
  }
  }
 
  private object realPopupMenuDrawable;
  private MethodInfo updateMethod;
  private MethodInfo drawMethod;
  private MethodInfo addOptionMethod;
  private MethodInfo addSeparatorMethod;
  private MethodInfo destroyMethod;
  private EventInfo onAnyOptionClickedEvent;
 
  public PopupMenuDrawable() {
  Type popupMenuDrawableType = ToolbarTypes.getType("Toolbar.PopupMenuDrawable");
  realPopupMenuDrawable = Activator.CreateInstance(popupMenuDrawableType, null);
  updateMethod = ToolbarTypes.getMethod(popupMenuDrawableType, "Update");
  drawMethod = ToolbarTypes.getMethod(popupMenuDrawableType, "Draw");
  addOptionMethod = ToolbarTypes.getMethod(popupMenuDrawableType, "AddOption");
  addSeparatorMethod = ToolbarTypes.getMethod(popupMenuDrawableType, "AddSeparator");
  destroyMethod = ToolbarTypes.getMethod(popupMenuDrawableType, "Destroy");
  onAnyOptionClickedEvent = ToolbarTypes.getEvent(popupMenuDrawableType, "OnAnyOptionClicked");
  }
 
  public void Update() {
  updateMethod.Invoke(realPopupMenuDrawable, null);
  }
 
  public Vector2 Draw(Vector2 position) {
  return (Vector2) drawMethod.Invoke(realPopupMenuDrawable, new object[] { position });
  }
 
  /// <summary>
  /// Adds a new option to the popup menu.
  /// </summary>
  /// <param name="text">The text of the option.</param>
  /// <returns>A button that can be used to register clicks on the menu option.</returns>
  public IButton AddOption(string text) {
  object realButton = addOptionMethod.Invoke(realPopupMenuDrawable, new object[] { text });
  return new Button(realButton, new ToolbarTypes());
  }
 
  /// <summary>
  /// Adds a separator to the popup menu.
  /// </summary>
  public void AddSeparator() {
  addSeparatorMethod.Invoke(realPopupMenuDrawable, null);
  }
 
  /// <summary>
  /// Destroys this drawable. This must always