Reverted changes to VOID_Core.cs so we can find the bad one.
--- /dev/null
+++ b/.gitattributes
@@ -1,1 +1,3 @@
+* text=auto
+* eol=lf
--- a/AVOID_ConfigValue.cs
+++ /dev/null
@@ -1,28 +1,1 @@
-//
-// AVOID_ConfigValue.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
-{
-
-}
-
-
--- a/IVOID_Module.cs
+++ b/IVOID_Module.cs
@@ -24,13 +24,15 @@
{
public interface IVOID_Module
{
- bool hasGUIConfig { get; }
- bool toggleActive { get; }
+ string Name { get; }
+ bool toggleActive { get; set; }
bool guiRunning { get; }
void DrawGUI();
void StartGUI();
void StopGUI();
+
+ void DrawConfigurables();
void LoadConfig();
--- a/Tools.cs
+++ b/Tools.cs
@@ -1,618 +1,618 @@
-//
-// Tools.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/>.
-//
-// This software uses VesselSimulator and Engineer.Extensions from Engineer Redux.
-// Engineer Redux (c) 2013 cybutek
-// Used by permission.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-
-using System;
-using System.Collections.Generic;
-using UnityEngine;
-
-namespace VOID
-{
- public class VOIDLabels
- {
- public string void_primary;
- public string void_altitude_asl;
- public string void_velocity;
- public string void_apoapsis;
- public string void_periapsis;
- }
-
- 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.
- public static CBAttributeMap.MapAttribute Toadicus_GetAtt(Vessel vessel)
- {
- CBAttributeMap.MapAttribute mapAttribute;
-
- try
- {
- CBAttributeMap BiomeMap = vessel.mainBody.BiomeMap;
- double lat = vessel.latitude * Math.PI / 180d;
- double lon = vessel.longitude * Math.PI / 180d;
-
- lon -= Math.PI / 2d;
-
- if (lon < 0d)
- {
- lon += 2d * Math.PI;
- }
-
- float v = (float)(lat / Math.PI) + 0.5f;
- float u = (float)(lon / (2d * Math.PI));
-
- Color pixelBilinear = BiomeMap.Map.GetPixelBilinear (u, v);
- mapAttribute = BiomeMap.defaultAttribute;
-
- if (BiomeMap.Map != null)
- {
- if (BiomeMap.exactSearch)
- {
- for (int i = 0; i < BiomeMap.Attributes.Length; ++i)
- {
- if (pixelBilinear == BiomeMap.Attributes[i].mapColor)
- {
- mapAttribute = BiomeMap.Attributes[i];
- }
- }
- }
- else
- {
- float zero = 0;
- float num = 1 / zero;
- for (int j = 0; j < BiomeMap.Attributes.Length; ++j)
- {
- Color mapColor = BiomeMap.Attributes [j].mapColor;
- float sqrMagnitude = ((Vector4)(mapColor - pixelBilinear)).sqrMagnitude;
- if (sqrMagnitude < num)
- {
- bool testCase = true;
- if (BiomeMap.nonExactThreshold != -1)
- {
- testCase = (sqrMagnitude < BiomeMap.nonExactThreshold);
- }
- if (testCase)
- {
- mapAttribute = BiomeMap.Attributes[j];
- num = sqrMagnitude;
- }
- }
- }
- }
- }
- }
- catch (NullReferenceException)
- {
- mapAttribute = new CBAttributeMap.MapAttribute();
- mapAttribute.name = "N/A";
- }
-
- return mapAttribute;
- }
-
- public static string GetLongitudeString(Vessel vessel, string format="F4")
- {
- string dir_long = "W";
- double v_long = vessel.longitude;
-
- v_long = FixDegreeDomain(v_long);
-
- if (v_long < -180d)
- {
- v_long += 360d;
- }
- if (v_long >= 180)
- {
- v_long -= 360d;
- }
-
- if (v_long > 0) dir_long = "E";
-
- return string.Format("{0}° {1}", Math.Abs(v_long).ToString(format), dir_long);
- }
-
- public static string GetLatitudeString(Vessel vessel, string format="F4")
- {
- string dir_lat = "S";
- double v_lat = vessel.latitude;
- if (v_lat > 0) dir_lat = "N";
-
- return string.Format("{0}° {1}", Math.Abs(v_lat).ToString(format), dir_lat);
- }
-
- ///////////////////////////////////////////////////////////////////////////////
-
- //For MuMech_get_heading()
- public class MuMech_MovingAverage
- {
- private double[] store;
- private int storeSize;
- private int nextIndex = 0;
-
- public double value
- {
- get
- {
- double tmp = 0;
- foreach (double i in store)
- {
- tmp += i;
- }
- return tmp / storeSize;
- }
- set
- {
- store[nextIndex] = value;
- nextIndex = (nextIndex + 1) % storeSize;
- }
- }
-
- public MuMech_MovingAverage(int size = 10, double startingValue = 0)
- {
- storeSize = size;
- store = new double[size];
- force(startingValue);
- }
-
- public void force(double newValue)
- {
- for (int i = 0; i < storeSize; i++)
- {
- store[i] = newValue;
- }
- }
-
- public static implicit operator double(MuMech_MovingAverage v)
- {
- return v.value;
- }
-
- public override string ToString()
- {
- return value.ToString();
- }
-
- public string ToString(string format)
- {
- return value.ToString(format);
- }
- }
-
- //From http://svn.mumech.com/KSP/trunk/MuMechLib/VOID.vesselState.cs
- public static double MuMech_get_heading(Vessel vessel)
- {
- Vector3d CoM = vessel.findWorldCenterOfMass();
- Vector3d up = (CoM - vessel.mainBody.position).normalized;
- Vector3d north = Vector3d.Exclude(up, (vessel.mainBody.position + vessel.mainBody.transform.up * (float)vessel.mainBody.Radius) - CoM).normalized;
-
- Quaternion rotationSurface = Quaternion.LookRotation(north, up);
- Quaternion rotationvesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vessel.transform.rotation) * rotationSurface);
- MuMech_MovingAverage vesselHeading = new MuMech_MovingAverage();
- vesselHeading.value = rotationvesselSurface.eulerAngles.y;
- return vesselHeading.value * 10; // *10 by me
- }
-
- //From http://svn.mumech.com/KSP/trunk/MuMechLib/MuUtils.cs
- public static string MuMech_ToSI(double d)
- {
- int digits = 2;
- double exponent = Math.Log10(Math.Abs(d));
- if (Math.Abs(d) >= 1)
- {
- switch ((int)Math.Floor(exponent))
- {
- case 0:
- case 1:
- case 2:
- return d.ToString("F" + digits);
- case 3:
- case 4:
- case 5:
- return (d / 1e3).ToString("F" + digits) + "k";
- case 6:
- case 7:
- case 8:
- return (d / 1e6).ToString("F" + digits) + "M";
- case 9:
- case 10:
- case 11:
- return (d / 1e9).ToString("F" + digits) + "G";
- case 12:
- case 13:
- case 14:
- return (d / 1e12).ToString("F" + digits) + "T";
- case 15:
- case 16:
- case 17:
- return (d / 1e15).ToString("F" + digits) + "P";
- case 18:
- case 19:
- case 20:
- return (d / 1e18).ToString("F" + digits) + "E";
- case 21:
- case 22:
- case 23:
- return (d / 1e21).ToString("F" + digits) + "Z";
- default:
- return (d / 1e24).ToString("F" + digits) + "Y";
- }
- }
- else if (Math.Abs(d) > 0)
- {
- switch ((int)Math.Floor(exponent))
- {
- case -1:
- case -2:
- case -3:
- return (d * 1e3).ToString("F" + digits) + "m";
- case -4:
- case -5:
- case -6:
- return (d * 1e6).ToString("F" + digits) + "μ";
- case -7:
- case -8:
- case -9:
- return (d * 1e9).ToString("F" + digits) + "n";
- case -10:
- case -11:
- case -12:
- return (d * 1e12).ToString("F" + digits) + "p";
- case -13:
- case -14:
- case -15:
- return (d * 1e15).ToString("F" + digits) + "f";
- case -16:
- case -17:
- case -18:
- return (d * 1e18).ToString("F" + digits) + "a";
- case -19:
- 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;
-
- try
- {
- interval = TimeSpan.FromSeconds(seconds);
- }
- catch (OverflowException)
- {
- return "NaN";
- }
-
- int years = interval.Days / 365;
-
- string output;
- if (years > 0)
- {
- output = string.Format(format_1,
- years,
- interval.Days - (years * 365), // subtract years * 365 for accurate day count
- interval.Hours,
- interval.Minutes,
- interval.Seconds,
- interval.Milliseconds.ToString().Substring(0, 1));
- }
- else if (interval.Days > 0)
- {
- output = string.Format(format_2,
- interval.Days,
- interval.Hours,
- interval.Minutes,
- interval.Seconds,
- interval.Milliseconds.ToString().Substring(0, 1));
- }
- else
- {
- output = string.Format(format_3,
- interval.Hours,
- interval.Minutes,
- interval.Seconds,
- interval.Milliseconds.ToString().Substring(0, 1));
- }
- return output;
- }
-
- public static string UppercaseFirst(string s)
- {
- if (string.IsNullOrEmpty(s))
- {
- return string.Empty;
- }
- char[] a = s.ToCharArray();
- a[0] = char.ToUpper(a[0]);
- return new string(a);
- }
-
- //transfer angles
-
- 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));
- return 360 * (0.5 - (T_transfer / (2 * T_target)));
- }
-
- public static double Younata_DeltaVToGetToOtherBody(double mu, double r1, double r2)
- {
- /*
- def deltaVToGetToOtherBody(mu, r1, r2):
- # mu = gravity param of common orbiting body of r1 and r2
- # (e.g. for mun to minmus, mu is kerbin's gravity param
- # r1 = initial body's orbit radius
- # r2 = target body's orbit radius
-
- # return value is km/s
- sur1 = math.sqrt(mu / r1)
- sr1r2 = math.sqrt(float(2*r2)/float(r1+r2))
- mult = sr1r2 - 1
- return sur1 * mult
- */
- double sur1, sr1r2, mult;
- sur1 = Math.Sqrt(mu / r1);
- sr1r2 = Math.Sqrt((2 * r2) / (r1 + r2));
- mult = sr1r2 - 1;
- return sur1 * mult;
- }
-
- public static double Younata_DeltaVToExitSOI(double mu, double r1, double r2, double v)
- {
- /*
- def deltaVToExitSOI(mu, r1, r2, v):
- # mu = gravity param of current body
- # r1 = current orbit radius
- # r2 = SOI radius
- # v = SOI exit velocity
- foo = r2 * (v**2) - 2 * mu
- bar = r1 * foo + (2 * r2 * mu)
- r = r1*r2
- return math.sqrt(bar / r)
- */
- double foo = r2 * Math.Pow(v, 2) - 2 * mu;
- double bar = r1 * foo + (2 * r2 * mu);
- double r = r1 * r2;
- return Math.Sqrt(bar / r);
- }
-
- public static double Younata_TransferBurnPoint(double r, double v, double angle, double mu)
- {
- /*
- def transferBurnPoint(r, v, angle, mu):
- # r = parking orbit radius
- # v = ejection velocity
- # angle = phase angle (from function phaseAngle())
- # mu = gravity param of current body.
- epsilon = ((v**2)/2) - (mu / r)
- h = r * v * math.sin(angle)
- e = math.sqrt(1 + ((2 * epsilon * h**2)/(mu**2)))
- theta = math.acos(1.0 / e)
- degrees = theta * (180.0 / math.pi)
- return 180 - degrees
- */
- double epsilon, h, ee, theta, degrees;
- epsilon = (Math.Pow(v, 2) / 2) - (mu / r);
- h = r * v * Math.Sin(angle);
- ee = Math.Sqrt(1 + ((2 * epsilon * Math.Pow(h, 2)) / Math.Pow(mu, 2)));
- theta = Math.Acos(1.0 / ee);
- degrees = theta * (180.0 / Math.PI);
- return 180 - degrees;
- // returns the ejection angle
- }
-
- public static double Adammada_CurrrentPhaseAngle(double body_LAN, double body_orbitPct, double origin_LAN, double origin_orbitPct)
- {
- double angle = (body_LAN / 360 + body_orbitPct) - (origin_LAN / 360 + origin_orbitPct);
- if (angle > 1) angle = angle - 1;
- if (angle < 0) angle = angle + 1;
- if (angle > 0.5) angle = angle - 1;
- angle = angle * 360;
- return angle;
- }
-
- public static double Adammada_CurrentEjectionAngle(double vessel_long, double origin_rotAngle, double origin_LAN, double origin_orbitPct)
- {
- //double eangle = ((FlightGlobals.ActiveVOID.vessel.longitude + orbiting.rotationAngle) - (orbiting.orbit.LAN / 360 + orbiting.orbit.orbitPercent) * 360);
- double eangle = ((vessel_long + origin_rotAngle) - (origin_LAN / 360 + origin_orbitPct) * 360);
-
- while (eangle < 0) eangle = eangle + 360;
- while (eangle > 360) eangle = eangle - 360;
- if (eangle < 270) eangle = 90 - eangle;
- else eangle = 450 - eangle;
- return eangle;
- }
-
- public static double mrenigma03_calcphase(Vessel vessel, CelestialBody target) //calculates phase angle between the current body and target body
- {
- Vector3d vecthis = new Vector3d();
- Vector3d vectarget = new Vector3d();
- vectarget = target.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime());
-
- if ((vessel.mainBody.name == "Sun") || (vessel.mainBody.referenceBody.referenceBody.name == "Sun"))
- {
- 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)
- {
- double Extent = 2d * Math.PI;
- if (Degrees) {
- Extent = 360d;
- }
-
- Angle = Angle % (Extent);
- if (Angle < 0d)
- {
- Angle += Extent;
- }
-
- return Angle;
- }
-
- public static double FixDegreeDomain(double Angle)
- {
- return FixAngleDomain (Angle, true);
- }
-
- public static double adjustCurrPhaseAngle(double transfer_angle, double curr_phase)
- {
- if (transfer_angle < 0)
- {
- if (curr_phase > 0) return (-1 * (360 - curr_phase));
- else if (curr_phase < 0) return curr_phase;
- }
- else if (transfer_angle > 0)
- {
- if (curr_phase > 0) return curr_phase;
- else if (curr_phase < 0) return (360 + curr_phase);
- }
- return curr_phase;
- }
-
- public static double adjust_current_ejection_angle(double curr_ejection)
- {
- //curr_ejection WILL need to be adjusted once for all transfers as it returns values ranging -180 to 180
- // need 0-360 instead
- //
- // ie i have -17 in the screenshot
- // need it to show 343
- //
- // do this
- //
- // if < 0, add curr to 360 // 360 + (-17) = 343
- // else its good as it is
-
- if (curr_ejection < 0) return 360 + curr_ejection;
- else return curr_ejection;
-
- }
-
- public static double adjust_transfer_ejection_angle(double trans_ejection, double trans_phase)
- {
- // if transfer_phase_angle < 0 its a lower transfer
- //180 + curr_ejection
- // else if transfer_phase_angle > 0 its good as it is
-
- 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;
-
- // 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 )
- {
- trueAltitude = vessel.orbit.altitude;
- }
-
- return trueAltitude;
- }
-
- public static string get_heading_text(double heading)
- {
- if (heading > 348.75 || heading <= 11.25) return "N";
- else if (heading > 11.25 && heading <= 33.75) return "NNE";
- else if (heading > 33.75 && heading <= 56.25) return "NE";
- else if (heading > 56.25 && heading <= 78.75) return "ENE";
- else if (heading > 78.75 && heading <= 101.25) return "E";
- else if (heading > 101.25 && heading <= 123.75) return "ESE";
- else if (heading > 123.75 && heading <= 146.25) return "SE";
- else if (heading > 146.25 && heading <= 168.75) return "SSE";
- 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 double[] ParseXYString(string s)
- {
- string[] xy = s.Split (',');
- if (xy.Length != 2)
- {
- throw new ArgumentException ("Argument must be of the format 'x,y'.");
- }
-
- double x = double.Parse (xy [0].Trim ());
- double y = double.Parse (xy [1].Trim ());
-
- return new double[] { x, y };
- }
-
- private static ScreenMessage debugmsg = new ScreenMessage("", 2f, ScreenMessageStyle.UPPER_RIGHT);
-
- [System.Diagnostics.Conditional("DEBUG")]
- public static void PostDebugMessage(string Msg)
- {
- if (HighLogic.LoadedScene > GameScenes.SPACECENTER)
- {
- debugmsg.message = Msg;
- ScreenMessages.PostScreenMessage(debugmsg, true);
- }
-
- KSPLog.print(Msg);
- }
- }
+//
+// Tools.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/>.
+//
+// This software uses VesselSimulator and Engineer.Extensions from Engineer Redux.
+// Engineer Redux (c) 2013 cybutek
+// Used by permission.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace VOID
+{
+ public static class VOIDLabels
+ {
+ public static string void_primary = "Primary";
+ public static string void_altitude_asl = "Altitude (ASL)";
+ public static string void_velocity = "Velocity";
+ public static string void_apoapsis = "Apoapsis";
+ public static string void_periapsis = "Periapsis";
+ }
+
+ 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.
+ public static CBAttributeMap.MapAttribute Toadicus_GetAtt(Vessel vessel)
+ {
+ CBAttributeMap.MapAttribute mapAttribute;
+
+ try
+ {
+ CBAttributeMap BiomeMap = vessel.mainBody.BiomeMap;
+ double lat = vessel.latitude * Math.PI / 180d;
+ double lon = vessel.longitude * Math.PI / 180d;
+
+ lon -= Math.PI / 2d;
+
+ if (lon < 0d)
+ {
+ lon += 2d * Math.PI;
+ }
+
+ float v = (float)(lat / Math.PI) + 0.5f;
+ float u = (float)(lon / (2d * Math.PI));
+
+ Color pixelBilinear = BiomeMap.Map.GetPixelBilinear (u, v);
+ mapAttribute = BiomeMap.defaultAttribute;
+
+ if (BiomeMap.Map != null)
+ {
+ if (BiomeMap.exactSearch)
+ {
+ for (int i = 0; i < BiomeMap.Attributes.Length; ++i)
+ {
+ if (pixelBilinear == BiomeMap.Attributes[i].mapColor)
+ {
+ mapAttribute = BiomeMap.Attributes[i];
+ }
+ }
+ }
+ else
+ {
+ float zero = 0;
+ float num = 1 / zero;
+ for (int j = 0; j < BiomeMap.Attributes.Length; ++j)
+ {
+ Color mapColor = BiomeMap.Attributes [j].mapColor;
+ float sqrMagnitude = ((Vector4)(mapColor - pixelBilinear)).sqrMagnitude;
+ if (sqrMagnitude < num)
+ {
+ bool testCase = true;
+ if (BiomeMap.nonExactThreshold != -1)
+ {
+ testCase = (sqrMagnitude < BiomeMap.nonExactThreshold);
+ }
+ if (testCase)
+ {
+ mapAttribute = BiomeMap.Attributes[j];
+ num = sqrMagnitude;
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (NullReferenceException)
+ {
+ mapAttribute = new CBAttributeMap.MapAttribute();
+ mapAttribute.name = "N/A";
+ }
+
+ return mapAttribute;
+ }
+
+ public static string GetLongitudeString(Vessel vessel, string format="F4")
+ {
+ string dir_long = "W";
+ double v_long = vessel.longitude;
+
+ v_long = FixDegreeDomain(v_long);
+
+ if (v_long < -180d)
+ {
+ v_long += 360d;
+ }
+ if (v_long >= 180)
+ {
+ v_long -= 360d;
+ }
+
+ if (v_long > 0) dir_long = "E";
+
+ return string.Format("{0}° {1}", Math.Abs(v_long).ToString(format), dir_long);
+ }
+
+ public static string GetLatitudeString(Vessel vessel, string format="F4")
+ {
+ string dir_lat = "S";
+ double v_lat = vessel.latitude;
+ if (v_lat > 0) dir_lat = "N";
+
+ return string.Format("{0}° {1}", Math.Abs(v_lat).ToString(format), dir_lat);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ //For MuMech_get_heading()
+ public class MuMech_MovingAverage
+ {
+ private double[] store;
+ private int storeSize;
+ private int nextIndex = 0;
+
+ public double value
+ {
+ get
+ {
+ double tmp = 0;
+ foreach (double i in store)
+ {
+ tmp += i;
+ }
+ return tmp / storeSize;
+ }
+ set
+ {
+ store[nextIndex] = value;
+ nextIndex = (nextIndex + 1) % storeSize;
+ }
+ }
+
+ public MuMech_MovingAverage(int size = 10, double startingValue = 0)
+ {
+ storeSize = size;
+ store = new double[size];
+ force(startingValue);
+ }
+
+ public void force(double newValue)
+ {
+ for (int i = 0; i < storeSize; i++)
+ {
+ store[i] = newValue;
+ }
+ }
+
+ public static implicit operator double(MuMech_MovingAverage v)
+ {
+ return v.value;
+ }
+
+ public override string ToString()
+ {
+ return value.ToString();
+ }
+
+ public string ToString(string format)
+ {
+ return value.ToString(format);
+ }
+ }
+
+ //From http://svn.mumech.com/KSP/trunk/MuMechLib/VOID.vesselState.cs
+ public static double MuMech_get_heading(Vessel vessel)
+ {
+ Vector3d CoM = vessel.findWorldCenterOfMass();
+ Vector3d up = (CoM - vessel.mainBody.position).normalized;
+ Vector3d north = Vector3d.Exclude(up, (vessel.mainBody.position + vessel.mainBody.transform.up * (float)vessel.mainBody.Radius) - CoM).normalized;
+
+ Quaternion rotationSurface = Quaternion.LookRotation(north, up);
+ Quaternion rotationvesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vessel.transform.rotation) * rotationSurface);
+ MuMech_MovingAverage vesselHeading = new MuMech_MovingAverage();
+ vesselHeading.value = rotationvesselSurface.eulerAngles.y;
+ return vesselHeading.value * 10; // *10 by me
+ }
+
+ //From http://svn.mumech.com/KSP/trunk/MuMechLib/MuUtils.cs
+ public static string MuMech_ToSI(double d)
+ {
+ int digits = 2;
+ double exponent = Math.Log10(Math.Abs(d));
+ if (Math.Abs(d) >= 1)
+ {
+ switch ((int)Math.Floor(exponent))
+ {
+ case 0:
+ case 1:
+ case 2:
+ return d.ToString("F" + digits);
+ case 3:
+ case 4:
+ case 5:
+ return (d / 1e3).ToString("F" + digits) + "k";
+ case 6:
+ case 7:
+ case 8:
+ return (d / 1e6).ToString("F" + digits) + "M";
+ case 9:
+ case 10:
+ case 11:
+ return (d / 1e9).ToString("F" + digits) + "G";
+ case 12:
+ case 13:
+ case 14:
+ return (d / 1e12).ToString("F" + digits) + "T";
+ case 15:
+ case 16:
+ case 17:
+ return (d / 1e15).ToString("F" + digits) + "P";
+ case 18:
+ case 19:
+ case 20:
+ return (d / 1e18).ToString("F" + digits) + "E";
+ case 21:
+ case 22:
+ case 23:
+ return (d / 1e21).ToString("F" + digits) + "Z";
+ default:
+ return (d / 1e24).ToString("F" + digits) + "Y";
+ }
+ }
+ else if (Math.Abs(d) > 0)
+ {
+ switch ((int)Math.Floor(exponent))
+ {
+ case -1:
+ case -2:
+ case -3:
+ return (d * 1e3).ToString("F" + digits) + "m";
+ case -4:
+ case -5:
+ case -6:
+ return (d * 1e6).ToString("F" + digits) + "μ";
+ case -7:
+ case -8:
+ case -9:
+ return (d * 1e9).ToString("F" + digits) + "n";
+ case -10:
+ case -11:
+ case -12:
+ return (d * 1e12).ToString("F" + digits) + "p";
+ case -13:
+ case -14:
+ case -15:
+ return (d * 1e15).ToString("F" + digits) + "f";
+ case -16:
+ case -17:
+ case -18:
+ return (d * 1e18).ToString("F" + digits) + "a";
+ case -19:
+ 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;
+
+ try
+ {
+ interval = TimeSpan.FromSeconds(seconds);
+ }
+ catch (OverflowException)
+ {
+ return "NaN";
+ }
+
+ int years = interval.Days / 365;
+
+ string output;
+ if (years > 0)
+ {
+ output = string.Format(format_1,
+ years,
+ interval.Days - (years * 365), // subtract years * 365 for accurate day count
+ interval.Hours,
+ interval.Minutes,
+ interval.Seconds,
+ interval.Milliseconds.ToString().Substring(0, 1));
+ }
+ else if (interval.Days > 0)
+ {
+ output = string.Format(format_2,
+ interval.Days,
+ interval.Hours,
+ interval.Minutes,
+ interval.Seconds,
+ interval.Milliseconds.ToString().Substring(0, 1));
+ }
+ else
+ {
+ output = string.Format(format_3,
+ interval.Hours,
+ interval.Minutes,
+ interval.Seconds,
+ interval.Milliseconds.ToString().Substring(0, 1));
+ }
+ return output;
+ }
+
+ public static string UppercaseFirst(string s)
+ {
+ if (string.IsNullOrEmpty(s))
+ {
+ return string.Empty;
+ }
+ char[] a = s.ToCharArray();
+ a[0] = char.ToUpper(a[0]);
+ return new string(a);
+ }
+
+ //transfer angles
+
+ 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));
+ return 360 * (0.5 - (T_transfer / (2 * T_target)));
+ }
+
+ public static double Younata_DeltaVToGetToOtherBody(double mu, double r1, double r2)
+ {
+ /*
+ def deltaVToGetToOtherBody(mu, r1, r2):
+ # mu = gravity param of common orbiting body of r1 and r2
+ # (e.g. for mun to minmus, mu is kerbin's gravity param
+ # r1 = initial body's orbit radius
+ # r2 = target body's orbit radius
+
+ # return value is km/s
+ sur1 = math.sqrt(mu / r1)
+ sr1r2 = math.sqrt(float(2*r2)/float(r1+r2))
+ mult = sr1r2 - 1
+ return sur1 * mult
+ */
+ double sur1, sr1r2, mult;
+ sur1 = Math.Sqrt(mu / r1);
+ sr1r2 = Math.Sqrt((2 * r2) / (r1 + r2));
+ mult = sr1r2 - 1;
+ return sur1 * mult;
+ }
+
+ public static double Younata_DeltaVToExitSOI(double mu, double r1, double r2, double v)
+ {
+ /*
+ def deltaVToExitSOI(mu, r1, r2, v):
+ # mu = gravity param of current body
+ # r1 = current orbit radius
+ # r2 = SOI radius
+ # v = SOI exit velocity
+ foo = r2 * (v**2) - 2 * mu
+ bar = r1 * foo + (2 * r2 * mu)
+ r = r1*r2
+ return math.sqrt(bar / r)
+ */
+ double foo = r2 * Math.Pow(v, 2) - 2 * mu;
+ double bar = r1 * foo + (2 * r2 * mu);
+ double r = r1 * r2;
+ return Math.Sqrt(bar / r);
+ }
+
+ public static double Younata_TransferBurnPoint(double r, double v, double angle, double mu)
+ {
+ /*
+ def transferBurnPoint(r, v, angle, mu):
+ # r = parking orbit radius
+ # v = ejection velocity
+ # angle = phase angle (from function phaseAngle())
+ # mu = gravity param of current body.
+ epsilon = ((v**2)/2) - (mu / r)
+ h = r * v * math.sin(angle)
+ e = math.sqrt(1 + ((2 * epsilon * h**2)/(mu**2)))
+ theta = math.acos(1.0 / e)
+ degrees = theta * (180.0 / math.pi)
+ return 180 - degrees
+ */
+ double epsilon, h, ee, theta, degrees;
+ epsilon = (Math.Pow(v, 2) / 2) - (mu / r);
+ h = r * v * Math.Sin(angle);
+ ee = Math.Sqrt(1 + ((2 * epsilon * Math.Pow(h, 2)) / Math.Pow(mu, 2)));
+ theta = Math.Acos(1.0 / ee);
+ degrees = theta * (180.0 / Math.PI);
+ return 180 - degrees;
+ // returns the ejection angle
+ }
+
+ public static double Adammada_CurrrentPhaseAngle(double body_LAN, double body_orbitPct, double origin_LAN, double origin_orbitPct)
+ {
+ double angle = (body_LAN / 360 + body_orbitPct) - (origin_LAN / 360 + origin_orbitPct);
+ if (angle > 1) angle = angle - 1;
+ if (angle < 0) angle = angle + 1;
+ if (angle > 0.5) angle = angle - 1;
+ angle = angle * 360;
+ return angle;
+ }
+
+ public static double Adammada_CurrentEjectionAngle(double vessel_long, double origin_rotAngle, double origin_LAN, double origin_orbitPct)
+ {
+ //double eangle = ((FlightGlobals.ActiveVOID.vessel.longitude + orbiting.rotationAngle) - (orbiting.orbit.LAN / 360 + orbiting.orbit.orbitPercent) * 360);
+ double eangle = ((vessel_long + origin_rotAngle) - (origin_LAN / 360 + origin_orbitPct) * 360);
+
+ while (eangle < 0) eangle = eangle + 360;
+ while (eangle > 360) eangle = eangle - 360;
+ if (eangle < 270) eangle = 90 - eangle;
+ else eangle = 450 - eangle;
+ return eangle;
+ }
+
+ public static double mrenigma03_calcphase(Vessel vessel, CelestialBody target) //calculates phase angle between the current body and target body
+ {
+ Vector3d vecthis = new Vector3d();
+ Vector3d vectarget = new Vector3d();
+ vectarget = target.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime());
+
+ if ((vessel.mainBody.name == "Sun") || (vessel.mainBody.referenceBody.referenceBody.name == "Sun"))
+ {
+ 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)
+ {
+ double Extent = 2d * Math.PI;
+ if (Degrees) {
+ Extent = 360d;
+ }
+
+ Angle = Angle % (Extent);
+ if (Angle < 0d)
+ {
+ Angle += Extent;
+ }
+
+ return Angle;
+ }
+
+ public static double FixDegreeDomain(double Angle)
+ {
+ return FixAngleDomain (Angle, true);
+ }
+
+ public static double adjustCurrPhaseAngle(double transfer_angle, double curr_phase)
+ {
+ if (transfer_angle < 0)
+ {
+ if (curr_phase > 0) return (-1 * (360 - curr_phase));
+ else if (curr_phase < 0) return curr_phase;
+ }
+ else if (transfer_angle > 0)
+ {
+ if (curr_phase > 0) return curr_phase;
+ else if (curr_phase < 0) return (360 + curr_phase);
+ }
+ return curr_phase;
+ }
+
+ public static double adjust_current_ejection_angle(double curr_ejection)
+ {
+ //curr_ejection WILL need to be adjusted once for all transfers as it returns values ranging -180 to 180
+ // need 0-360 instead
+ //
+ // ie i have -17 in the screenshot
+ // need it to show 343
+ //
+ // do this
+ //
+ // if < 0, add curr to 360 // 360 + (-17) = 343
+ // else its good as it is
+
+ if (curr_ejection < 0) return 360 + curr_ejection;
+ else return curr_ejection;
+
+ }
+
+ public static double adjust_transfer_ejection_angle(double trans_ejection, double trans_phase)
+ {
+ // if transfer_phase_angle < 0 its a lower transfer
+ //180 + curr_ejection
+ // else if transfer_phase_angle > 0 its good as it is
+
+ 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;
+
+ // 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 )
+ {
+ trueAltitude = vessel.orbit.altitude;
+ }
+
+ return trueAltitude;
+ }
+
+ public static string get_heading_text(double heading)
+ {
+ if (heading > 348.75 || heading <= 11.25) return "N";
+ else if (heading > 11.25 && heading <= 33.75) return "NNE";
+ else if (heading > 33.75 && heading <= 56.25) return "NE";
+ else if (heading > 56.25 && heading <= 78.75) return "ENE";
+ else if (heading > 78.75 && heading <= 101.25) return "E";
+ else if (heading > 101.25 && heading <= 123.75) return "ESE";
+ else if (heading > 123.75 && heading <= 146.25) return "SE";
+ else if (heading > 146.25 && heading <= 168.75) return "SSE";
+ 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 double[] ParseXYString(string s)
+ {
+ string[] xy = s.Split (',');
+ if (xy.Length != 2)
+ {
+ throw new ArgumentException ("Argument must be of the format 'x,y'.");
+ }
+
+ double x = double.Parse (xy [0].Trim ());
+ double y = double.Parse (xy [1].Trim ());
+
+ return new double[] { x, y };
+ }
+
+ private static ScreenMessage debugmsg = new ScreenMessage("", 2f, ScreenMessageStyle.UPPER_RIGHT);
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void PostDebugMessage(string Msg)
+ {
+ if (HighLogic.LoadedScene > GameScenes.SPACECENTER)
+ {
+ debugmsg.message = Msg;
+ ScreenMessages.PostScreenMessage(debugmsg, true);
+ }
+
+ KSPLog.print(Msg);
+ }
+ }
}
--- a/VOIDFlightMaster.cs
+++ b/VOIDFlightMaster.cs
@@ -48,22 +48,7 @@
{
Tools.PostDebugMessage ("VOIDLightMaster: Waking up.");
this.Core = (VOID_Core)VOID_Core.Instance;
- foreach (Type T in System.Reflection.Assembly.GetExecutingAssembly().GetTypes())
- {
- Tools.PostDebugMessage (string.Format ("VOIDFlightMaster: Testing type {0}", T.Name));
- if (typeof(IVOID_Module).IsAssignableFrom(T) &&
- !T.IsAbstract &&
- !typeof(VOID_Core).IsAssignableFrom(T))
- {
- this.Core.LoadModule (T);
- Tools.PostDebugMessage(string.Format("VOIDFlightMaster: Found module {0}.", T.Name));
- }
- }
-
- Tools.PostDebugMessage (string.Format ("VOIDFlightMaster: Loaded {0} modules.", this.Core.Modules.Count));
-
- this.Core.LoadConfig ();
-
+ this.Core.StartGUI ();
Tools.PostDebugMessage ("VOIDFlightMaster: Awake.");
}
--- a/VOID_ConfigValue.cs
+++ /dev/null
@@ -1,97 +1,1 @@
-//
-// VOID_Config.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 System.Collections.Generic;
-using KSP;
-using UnityEngine;
-namespace VOID
-{
- public struct VOID_ConfigValue<T> : IVOID_ConfigValue
- {
- private T _value;
- private Type _type;
-
- public T value
- {
- get
- {
- return this._value;
- }
- set
- {
- this._value = value;
- }
- }
-
- public Type type
- {
- get
- {
- return this._type;
- }
- set
- {
- this._type = value;
- }
- }
-
- public static implicit operator T(VOID_ConfigValue<T> v)
- {
- return v.value;
- }
-
- public static implicit operator VOID_ConfigValue<T>(T v)
- {
- VOID_ConfigValue<T> r = new VOID_ConfigValue<T>();
- r.value = v;
- r.type = v.GetType();
- VOID_Core.Instance.configDirty = true;
- return r;
- }
- }
-
- public interface IVOID_ConfigValue
- {
- Type type { get; }
- }
-
- [AttributeUsage(AttributeTargets.Field)]
- public class AVOID_ConfigValue : Attribute
- {
- protected string _name;
-
- public string Name
- {
- get
- {
- return this._name;
- }
- }
-
- public AVOID_ConfigValue(string fieldName)
- {
- this._name = fieldName;
- }
- }
-}
-
-
--- a/VOID_Core.cs
+++ b/VOID_Core.cs
@@ -21,6 +21,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection;
using KSP;
using UnityEngine;
@@ -31,6 +32,15 @@
/*
* Static Members
* */
+ protected static bool _initialized = false;
+ public static bool Initialized
+ {
+ get
+ {
+ return _initialized;
+ }
+ }
+
protected static VOID_Core _instance;
public static VOID_Core Instance
{
@@ -39,6 +49,7 @@
if (_instance == null)
{
_instance = new VOID_Core();
+ _initialized = true;
}
return _instance;
}
@@ -50,25 +61,28 @@
protected string VoidName = "VOID";
protected string VoidVersion = "0.9.9";
- [AVOID_ConfigValue("configValue")]
- protected VOID_ConfigValue<int> configVersion = 1;
-
- protected List<VOID_Module> _modules = new List<VOID_Module>();
-
- [AVOID_ConfigValue("mainWindowPos")]
- protected VOID_ConfigValue<Rect> mainWindowPos = new Rect(Screen.width / 2, Screen.height / 2, 10f, 10f);
-
- [AVOID_ConfigValue("mainGuiMinimized")]
- protected VOID_ConfigValue<bool> mainGuiMinimized = false;
-
- [AVOID_ConfigValue("configWindowPos")]
- protected VOID_ConfigValue<Rect> configWindowPos = new Rect(Screen.width / 2, Screen.height /2, 10f, 10f);
-
- [AVOID_ConfigValue("configWindowMinimized")]
- protected VOID_ConfigValue<bool> configWindowMinimized = true;
-
- [AVOID_ConfigValue("VOIDIconPos")]
- protected VOID_ConfigValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 30, 30f, 30f);
+ [AVOID_SaveValue("configValue")]
+ protected VOID_SaveValue<int> configVersion = 1;
+
+ protected List<IVOID_Module> _modules = new List<IVOID_Module>();
+ protected bool _modulesLoaded = false;
+
+ protected List<Callback> _configurableCallbacks = new List<Callback>();
+
+ [AVOID_SaveValue("mainWindowPos")]
+ protected VOID_SaveValue<Rect> mainWindowPos = new Rect(Screen.width / 2, Screen.height / 2, 10f, 10f);
+
+ [AVOID_SaveValue("mainGuiMinimized")]
+ protected VOID_SaveValue<bool> mainGuiMinimized = false;
+
+ [AVOID_SaveValue("configWindowPos")]
+ protected VOID_SaveValue<Rect> configWindowPos = new Rect(Screen.width / 2, Screen.height /2, 10f, 10f);
+
+ [AVOID_SaveValue("configWindowMinimized")]
+ protected VOID_SaveValue<bool> configWindowMinimized = true;
+
+ [AVOID_SaveValue("VOIDIconPos")]
+ protected VOID_SaveValue<Rect> VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 30, 30f, 30f);
protected Texture2D VOIDIconOff = new Texture2D(30, 30, TextureFormat.ARGB32, false);
protected Texture2D VOIDIconOn = new Texture2D(30, 30, TextureFormat.ARGB32, false);
protected Texture2D VOIDIconTexture;
@@ -77,23 +91,31 @@
protected int windowBaseID = -96518722;
- public VOID_ConfigValue<bool> togglePower = true;
+ [AVOID_SaveValue("togglePower")]
+ public VOID_SaveValue<bool> togglePower = true;
+
public bool powerAvailable = true;
- protected VOID_ConfigValue<bool> consumeResource = false;
- protected VOID_ConfigValue<string> resourceName = "ElectricCharge";
- protected VOID_ConfigValue<float> resourceRate = 0.2f;
+
+ [AVOID_SaveValue("consumeResource")]
+ protected VOID_SaveValue<bool> consumeResource = false;
+
+ [AVOID_SaveValue("resourceName")]
+ protected VOID_SaveValue<string> resourceName = "ElectricCharge";
+
+ [AVOID_SaveValue("resourceRate")]
+ protected VOID_SaveValue<float> resourceRate = 0.2f;
public float saveTimer = 0;
protected string defaultSkin = "KSP window 2";
- protected VOID_ConfigValue<string> _skin;
+ protected VOID_SaveValue<string> _skin;
public bool configDirty;
/*
* Properties
* */
- public List<VOID_Module> Modules
+ public List<IVOID_Module> Modules
{
get
{
@@ -130,11 +152,62 @@
this.VOIDIconOn = GameDatabase.Instance.GetTexture (this.VOIDIconOnPath, false);
this.VOIDIconOff = GameDatabase.Instance.GetTexture (this.VOIDIconOffPath, false);
- }
-
- public void LoadModule(Type T)
- {
- this._modules.Add (Activator.CreateInstance (T) as VOID_Module);
+
+ this.LoadConfig ();
+ }
+
+ protected void LoadModules()
+ {
+ var types = AssemblyLoader.loadedAssemblies
+ .Select (a => a.assembly.GetExportedTypes ())
+ .SelectMany (t => t)
+ .Where (v => typeof(IVOID_Module).IsAssignableFrom (v)
+ && !(v.IsInterface || v.IsAbstract) &&
+ !typeof(VOID_Core).IsAssignableFrom (v)
+ );
+
+ Tools.PostDebugMessage (string.Format (
+ "{0}: Found {1} modules to check.",
+ this.GetType ().Name,
+ types.Count ()
+ ));
+ foreach (var voidType in types)
+ {
+ Tools.PostDebugMessage (string.Format (
+ "{0}: found Type {1}",
+ this.GetType ().Name,
+ voidType.Name
+ ));
+
+ this.LoadModule(voidType);
+ }
+
+ this._modulesLoaded = true;
+
+ Tools.PostDebugMessage (string.Format ("VOID_Core: Loaded {0} modules.", 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
+ ));
}
public void Update()
@@ -146,13 +219,18 @@
this.StartGUI ();
}
- foreach (VOID_Module module in this.Modules)
+ 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)
+ if (module.guiRunning && !module.toggleActive || !this.togglePower || !HighLogic.LoadedSceneIsFlight)
{
module.StopGUI();
}
@@ -196,7 +274,7 @@
if (GUILayout.Button("Power " + str)) togglePower = !togglePower;
if (togglePower)
{
- foreach (VOID_Module module in this.Modules)
+ foreach (IVOID_Module module in this.Modules)
{
module.toggleActive = GUILayout.Toggle (module.toggleActive, module.Name);
}
@@ -220,19 +298,34 @@
{
GUILayout.BeginVertical ();
- this.consumeResource = GUILayout.Toggle (this.consumeResource, "Consume Resources");
+ this.DrawConfigurables ();
GUILayout.EndVertical ();
GUI.DragWindow ();
}
+ public override void DrawConfigurables()
+ {
+ this.consumeResource = GUILayout.Toggle (this.consumeResource, "Consume Resources");
+
+ foreach (IVOID_Module mod in this.Modules)
+ {
+ mod.DrawConfigurables ();
+ }
+ }
+
public override void DrawGUI()
{
+ if (!this._modulesLoaded)
+ {
+ this.LoadModules ();
+ }
+
GUI.skin = this.Skin;
int windowID = this.windowBaseID;
- this.VOIDIconTexture = this.VOIDIconOff; //icon off default
+ this.VOIDIconTexture = this.VOIDIconOff; //icon off default
if (this.togglePower) this.VOIDIconTexture = this.VOIDIconOn; //or on if power_toggle==true
if (GUI.Button(new Rect(VOIDIconPos), VOIDIconTexture, new GUIStyle()))
{
@@ -241,81 +334,48 @@
if (!this.mainGuiMinimized)
{
- this.mainWindowPos = GUILayout.Window (
+ Rect _mainWindowPos = this.mainWindowPos;
+
+ _mainWindowPos = GUILayout.Window (
++windowID,
- this.mainWindowPos,
+ _mainWindowPos,
this.VOIDMainWindow,
- string.Join (" ", this.VoidName, this.VoidVersion),
+ string.Join (" ", new string[] {this.VoidName, this.VoidVersion}),
GUILayout.Width (250),
GUILayout.Height (50)
);
+
+ if (_mainWindowPos != this.mainWindowPos)
+ {
+ this.mainWindowPos = _mainWindowPos;
+ }
}
if (!this.configWindowMinimized)
{
- this.configWindowPos = GUILayout.Window (
+ Rect _configWindowPos = this.configWindowPos;
+
+ _configWindowPos = GUILayout.Window (
++windowID,
- this.configWindowPos,
+ _configWindowPos,
this.VOIDConfigWindow,
- string.Join (" ", this.VoidName, "Configuration"),
+ string.Join (" ", new string[] {this.VoidName, "Configuration"}),
GUILayout.Width (250),
GUILayout.Height (50)
);
- }
- }
-
- public new void StartGUI()
- {
- base.StartGUI ();
- foreach (var module in this._modules)
- {
- if (module.toggleActive)
- {
- module.StartGUI ();
- }
- }
-
- this._Running = true;
- }
-
- public new void StopGUI()
- {
- base.StopGUI ();
- foreach (var module in this._modules)
- {
- if (module.guiRunning)
- {
- module.StopGUI ();
- }
- }
-
- this._Running = false;
+
+ if (_configWindowPos != this.configWindowPos)
+ {
+ this.configWindowPos = _configWindowPos;
+ }
+ }
}
public override void LoadConfig()
{
- var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core>();
- config.load();
-
- if (this.configVersion > config.GetValue("configVersion", 0))
- {
- // TODO: Config update stuff.
- }
-
- foreach (var field in this.GetType().GetFields().Where(f => f.IsDefined(typeof(AVOID_ConfigValue), false)))
- {
- var attr = field.GetCustomAttributes(typeof(AVOID_ConfigValue), false)[0];
- string fieldName = (attr as AVOID_ConfigValue).Name;
-
- var fieldValue = field.GetValue(this);
-
- field.SetValue(
- this,
- config.GetValue(fieldName, fieldValue)
- );
- }
-
- foreach (VOID_Module module in this.Modules)
+ base.LoadConfig ();
+
+ foreach (IVOID_Module module in this.Modules)
{
module.LoadConfig ();
}
@@ -323,23 +383,14 @@
public override void SaveConfig()
{
- var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core> ();
- config.load ();
-
- foreach (var field in this.GetType().GetFields().Where(f => f.IsDefined(typeof(AVOID_ConfigValue), false)))
- {
- var attr = field.GetCustomAttributes(typeof(AVOID_ConfigValue), false)[0];
- string fieldName = (attr as AVOID_ConfigValue).Name;
-
- object fieldValue = field.GetValue(this);
- Type T = (fieldValue as IVOID_ConfigValue).type;
-
- config.SetValue(fieldName, fieldValue);
- }
-
- config.save ();
-
- foreach (VOID_Module module in this.Modules)
+ if (!this.configDirty)
+ {
+ return;
+ }
+
+ base.SaveConfig ();
+
+ foreach (IVOID_Module module in this.Modules)
{
module.SaveConfig ();
}
--- a/VOID_HUD.cs
+++ b/VOID_HUD.cs
@@ -32,13 +32,16 @@
/*
* Fields
* */
+ protected string _Name = "Heads-Up Display";
+
+ protected new bool _hasConfigurables = true;
+
+ [AVOID_SaveValue("colorIndex")]
+ protected VOID_SaveValue<int> _colorIndex = 0;
+
protected List<Color> textColors = new List<Color>();
protected GUIStyle labelStyle;
-
- protected int _counterTextColor = 0;
-
- protected Vessel vessel = null;
/*
* Properties
@@ -47,17 +50,17 @@
{
get
{
- return this._counterTextColor;
+ return this._colorIndex;
}
set
{
- if (this._counterTextColor >= this.textColors.Count - 1)
+ if (this._colorIndex >= this.textColors.Count - 1)
{
- this._counterTextColor = 0;
+ this._colorIndex = 0;
return;
}
- this._counterTextColor = value;
+ this._colorIndex = value;
}
}
@@ -66,7 +69,6 @@
* */
public VOID_HUD() : base()
{
- this._Name = "Heads-Up Display";
this.textColors.Add(Color.green);
this.textColors.Add(Color.black);
this.textColors.Add(Color.white);
@@ -89,14 +91,9 @@
GUI.skin = VOID_Core.Instance.Skin;
- if (vessel == null)
+ if (this.vessel == null)
{
- vessel = FlightGlobals.ActiveVessel;
- }
-
- if (vessel != FlightGlobals.ActiveVessel)
- {
- vessel = FlightGlobals.ActiveVessel;
+ return;
}
if (VOID_Core.Instance.powerAvailable)
@@ -105,26 +102,26 @@
GUI.Label (
new Rect ((Screen.width * .2083f), 0, 300f, 70f),
- "Obt Alt: " + Tools.MuMech_ToSI (vessel.orbit.altitude) + "m" +
- " Obt Vel: " + Tools.MuMech_ToSI (vessel.orbit.vel.magnitude) + "m/s" +
- "\nAp: " + Tools.MuMech_ToSI (vessel.orbit.ApA) + "m" +
- " ETA " + Tools.ConvertInterval (vessel.orbit.timeToAp) +
- "\nPe: " + Tools.MuMech_ToSI (vessel.orbit.PeA) + "m" +
- " ETA " + Tools.ConvertInterval (vessel.orbit.timeToPe) +
- "\nInc: " + vessel.orbit.inclination.ToString ("F3") + "°",
+ "Obt Alt: " + Tools.MuMech_ToSI (this.vessel.orbit.altitude) + "m" +
+ " Obt Vel: " + Tools.MuMech_ToSI (this.vessel.orbit.vel.magnitude) + "m/s" +
+ "\nAp: " + Tools.MuMech_ToSI (this.vessel.orbit.ApA) + "m" +
+ " ETA " + Tools.ConvertInterval (this.vessel.orbit.timeToAp) +
+ "\nPe: " + Tools.MuMech_ToSI (this.vessel.orbit.PeA) + "m" +
+ " ETA " + Tools.ConvertInterval (this.vessel.orbit.timeToPe) +
+ "\nInc: " + this.vessel.orbit.inclination.ToString ("F3") + "°",
labelStyle);
// Toadicus edit: Added "Biome: " line to surf/atmo HUD
GUI.Label (
new Rect ((Screen.width * .625f), 0, 300f, 90f),
- "Srf Alt: " + Tools.MuMech_ToSI (Tools.TrueAltitude (vessel)) + "m" +
- " Srf Vel: " + Tools.MuMech_ToSI (vessel.srf_velocity.magnitude) + "m/s" +
- "\nVer: " + Tools.MuMech_ToSI (vessel.verticalSpeed) + "m/s" +
- " Hor: " + Tools.MuMech_ToSI (vessel.horizontalSrfSpeed) + "m/s" +
- "\nLat: " + Tools.GetLatitudeString (vessel, "F3") +
- " Lon: " + Tools.GetLongitudeString (vessel, "F3") +
- "\nHdg: " + Tools.MuMech_get_heading (vessel).ToString ("F2") + "° " +
- Tools.get_heading_text (Tools.MuMech_get_heading (vessel)) +
- "\nBiome: " + Tools.Toadicus_GetAtt (vessel).name,
+ "Srf Alt: " + Tools.MuMech_ToSI (Tools.TrueAltitude (this.vessel)) + "m" +
+ " Srf Vel: " + Tools.MuMech_ToSI (this.vessel.srf_velocity.magnitude) + "m/s" +
+ "\nVer: " + Tools.MuMech_ToSI (this.vessel.verticalSpeed) + "m/s" +
+ " Hor: " + Tools.MuMech_ToSI (this.vessel.horizontalSrfSpeed) + "m/s" +
+ "\nLat: " + Tools.GetLatitudeString (this.vessel, "F3") +
+ " Lon: " + Tools.GetLongitudeString (this.vessel, "F3") +
+ "\nHdg: " + Tools.MuMech_get_heading (this.vessel).ToString ("F2") + "° " +
+ Tools.get_heading_text (Tools.MuMech_get_heading (this.vessel)) +
+ "\nBiome: " + Tools.Toadicus_GetAtt (this.vessel).name,
labelStyle);
}
else
@@ -135,21 +132,12 @@
}
}
- public override void SaveConfig()
+ public override void DrawConfigurables()
{
- Tools.PostDebugMessage ("VOID_HUD: Saving Config.");
- var config = KSP.IO.PluginConfiguration.CreateForType<VOID_HUD> ();
- config.load ();
- config.SetValue ("ColorIndex", this.ColorIndex);
- config.save ();
- }
-
- public override void LoadConfig()
- {
- Tools.PostDebugMessage ("VOID_HUD: Loading Config.");
- var config = KSP.IO.PluginConfiguration.CreateForType<VOID_HUD> ();
- config.load ();
- this.ColorIndex = config.GetValue ("ColorIndex", 0);
+ if (GUILayout.Button ("Change HUD color", GUILayout.ExpandWidth (false)))
+ {
+ ++this.ColorIndex;
+ }
}
}
}
--- a/VOID_Module.cs
+++ b/VOID_Module.cs
@@ -19,31 +19,26 @@
// 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 System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
namespace VOID
{
- public abstract class VOID_Module
+ public abstract class VOID_Module : IVOID_Module
{
/*
* Fields
* */
- protected bool _Active = true;
+ [AVOID_SaveValue("Active")]
+ protected VOID_SaveValue<bool> _Active = true;
protected bool _Running = false;
- protected bool _hasGUICfg = false;
protected string _Name;
/*
* Properties
* */
- public virtual bool hasGUIConfig
- {
- get
- {
- return this._hasGUICfg;
- }
- }
-
public virtual bool toggleActive
{
get
@@ -72,11 +67,24 @@
}
}
+ public virtual Vessel vessel
+ {
+ get
+ {
+ return FlightGlobals.ActiveVessel;
+ }
+ }
+
/*
* Methods
* */
public void StartGUI()
{
+ if (!this.toggleActive)
+ {
+ return;
+ }
+
Tools.PostDebugMessage (string.Format("Adding {0} to the draw queue.", this.GetType().Name));
RenderingManager.AddToPostDrawQueue (3, this.DrawGUI);
this._Running = true;
@@ -91,13 +99,93 @@
public abstract void DrawGUI();
- public abstract void LoadConfig();
+ public virtual void DrawConfigurables() {}
- public abstract void SaveConfig();
+ public virtual void LoadConfig()
+ {
+ var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core> ();
+ config.load ();
- ~VOID_Module()
+ foreach (var field in this.GetType().GetFields(
+ BindingFlags.NonPublic |
+ BindingFlags.Public |
+ BindingFlags.Instance
+ ))
+ {
+ object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false);
+
+ if (attrs.Length == 0) {
+ return;
+ }
+
+ AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue;
+
+ string fieldName = string.Format("{0}_{1}", this.GetType().Name, attr.Name);
+
+ object fieldValue = field.GetValue(this);
+
+ bool convertBack = false;
+ if (fieldValue is IVOID_SaveValue)
+ {
+ fieldValue = (fieldValue as IVOID_SaveValue).AsType;
+ convertBack = true;
+ }
+
+ fieldValue = config.GetValue(fieldName, fieldValue);
+
+ if (convertBack)
+ {
+ Type type = typeof(VOID_SaveValue<>).MakeGenericType (fieldValue.GetType ());
+ IVOID_SaveValue convertValue = Activator.CreateInstance (type) as IVOID_SaveValue;
+ convertValue.SetValue (fieldValue);
+ fieldValue = convertValue;
+ }
+
+ field.SetValue (this, fieldValue);
+
+ Tools.PostDebugMessage(string.Format("{0}: Loaded field {1}.", this.GetType().Name, fieldName));
+ }
+ }
+
+ public virtual void SaveConfig()
{
- this.SaveConfig ();
+ if (!VOID_Core.Instance.configDirty)
+ {
+ return;
+ }
+
+ var config = KSP.IO.PluginConfiguration.CreateForType<VOID_Core> ();
+ config.load ();
+
+ foreach (var field in this.GetType().GetFields(
+ BindingFlags.NonPublic |
+ BindingFlags.Public |
+ BindingFlags.Instance
+ ))
+ {
+ object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false);
+
+ if (attrs.Length == 0) {
+ return;
+ }
+
+ AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue;
+
+ string fieldName = string.Format("{0}_{1}", this.GetType().Name, attr.Name);
+
+ object fieldValue = field.GetValue(this);
+
+ if (fieldValue is IVOID_SaveValue)
+ {
+ fieldValue = (fieldValue as IVOID_SaveValue).AsType;
+ }
+
+ config.SetValue(fieldName, fieldValue);
+
+ Tools.PostDebugMessage(string.Format("{0}: Saved field {1}.", this.GetType().Name, fieldName));
+ }
+
+ config.save ();
}
}
}
--- /dev/null
+++ b/VOID_Orbital.cs
@@ -1,1 +1,161 @@
+//
+// VOID_Orbital.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 KSP;
+using System;
+using UnityEngine;
+namespace VOID
+{
+ public class VOID_Orbital : VOID_Module
+ {
+ protected new string _Name = "Orbital Information";
+
+ [AVOID_SaveValue("OrbitalWindowPos")]
+ protected Rect OrbitalWindowPos = new Rect(Screen.width / 2, Screen.height / 2, 10f, 10f);
+
+ [AVOID_SaveValue("toggleExtendedOribtal")]
+ protected bool toggleExtendedOribtal = false;
+
+ public void OrbitalWindow(int _)
+ {
+ // Toadicus edit: added local sidereal longitude.
+ double LSL = vessel.longitude + vessel.orbit.referenceBody.rotationAngle;
+ LSL = Tools.FixDegreeDomain (LSL);
+
+ GUILayout.BeginVertical();
+
+ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
+ GUILayout.Label(VOIDLabels.void_primary + ":");
+ GUILayout.Label(vessel.mainBody.bodyName, GUILayout.ExpandWidth(false));
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
+ GUILayout.Label(VOIDLabels.void_altitude_asl + ":");
+ GUILayout.Label(Tools.MuMech_ToSI(vessel.orbit.altitude) + "m", GUILayout.ExpandWidth(false));
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
+ GUILayout.Label(VOIDLabels.void_velocity + ":");
+ GUILayout.Label(Tools.MuMech_ToSI(vessel.orbit.vel.magnitude) + "m/s", GUILayout.ExpandWidth(false));
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
+ GUILayout.Label(VOIDLabels.void_apoapsis + ":");
+ GUILayout.Label(Tools.MuMech_ToSI(vessel.orbit.ApA) + "m", GUILayout.ExpandWidth(false));
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
+ GUILayout.Label("Time to Ap:");
+ GUILayout.Label(Tools.ConvertInterval(vessel.orbit.timeToAp), GUILayout.ExpandWidth(false));
+ GUILayout.EndHorizontal();
+
+ 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();
+
+ toggleExtendedOribtal = GUILayout.Toggle(toggleExtendedOribtal, "Extended info");
+
+ if (toggleExtendedOribtal)
+ {
+ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
+ GUILayout.Label("Period:");
+ GUILayout.Label(Tools.ConvertInterval(vessel.orbit.period), GUILayout.ExpandWidth(false));
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
+ GUILayout.Label("Semi-major axis:");
+ GUILayout.Label((vessel.orbit.semiMajorAxis / 1000).ToString("##,#") + "km", GUILayout.ExpandWidth(false));
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
+ GUILayout.Label("Eccentricity:");
+ GUILayout.Label(vessel.orbit.eccentricity.ToString("F4"), GUILayout.ExpandWidth(false));
+ GUILayout.EndHorizontal();
+
+ // Toadicus edit: convert mean anomaly into degrees.
+ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
+ GUILayout.Label("Mean anomaly:");
+ 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();
+ GUI.DragWindow();
+ }
+
+ public override void DrawGUI()
+ {
+ OrbitalWindowPos = GUILayout.Window(
+ ++VOID_Core.Instance.windowID,
+ OrbitalWindowPos,
+ this.OrbitalWindow,
+ this.Name, GUILayout.Width(250),
+ GUILayout.Height(50));
+ }
+ }
+}
+
+
--- /dev/null
+++ b/VOID_SaveValue.cs
@@ -1,1 +1,115 @@
+//
+// VOID_Config.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 System.Collections.Generic;
+using KSP;
+using UnityEngine;
+namespace VOID
+{
+ public struct VOID_SaveValue<T> : IVOID_SaveValue
+ {
+ private T _value;
+ private Type _type;
+
+ public T value
+ {
+ get
+ {
+ return this._value;
+ }
+ set
+ {
+ this._value = value;
+ }
+ }
+
+ public Type type
+ {
+ get
+ {
+ return this._type;
+ }
+ set
+ {
+ this._type = value;
+ }
+ }
+
+ public object AsType
+ {
+ get
+ {
+ return (T)this._value;
+ }
+ }
+
+ public void SetValue(object v)
+ {
+ this._value = (T)v;
+ }
+
+ public static implicit operator T(VOID_SaveValue<T> v)
+ {
+ return v.value;
+ }
+
+ public static implicit operator VOID_SaveValue<T>(T v)
+ {
+ VOID_SaveValue<T> r = new VOID_SaveValue<T>();
+ r.value = v;
+ r.type = v.GetType();
+ if (VOID_Core.Initialized)
+ {
+ VOID_Core.Instance.configDirty = true;
+ }
+ return r;
+ }
+ }
+
+ public interface IVOID_SaveValue
+ {
+ Type type { get; }
+ object AsType { get; }
+ void SetValue(object v);
+ }
+
+ [AttributeUsage(AttributeTargets.Field)]
+ public class AVOID_SaveValue : Attribute
+ {
+ protected string _name;
+
+ public string Name
+ {
+ get
+ {
+ return this._name;
+ }
+ }
+
+ public AVOID_SaveValue(string fieldName)
+ {
+ this._name = fieldName;
+ }
+ }
+}
+
+