Added sane window start positions and states. 0.9.9
[VOID.git] / VOID_VesselInfo.cs
blob:a/VOID_VesselInfo.cs -> blob:b/VOID_VesselInfo.cs
// // VOID
// VOID_Orbital.cs //
// // VOID_VesselInfo.cs
// Author: //
// toadicus <> // Copyright © 2014, toadicus
// // All rights reserved.
// Copyright (c) 2013 toadicus //
// // Redistribution and use in source and binary forms, with or without modification,
// This program is free software: you can redistribute it and/or modify // are permitted provided that the following conditions are met:
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation, either version 3 of the License, or // 1. Redistributions of source code must retain the above copyright notice,
// (at your option) any later version. // this list of conditions and the following disclaimer.
// //
// This program is distributed in the hope that it will be useful, // 2. Redistributions in binary form must reproduce the above copyright notice,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // this list of conditions and the following disclaimer in the documentation and/or other
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // materials provided with the distribution.
// GNU General Public License for more details. //
// // 3. Neither the name of the copyright holder nor the names of its contributors may be used
// You should have received a copy of the GNU General Public License // to endorse or promote products derived from this software without specific prior written permission.
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
  // 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 Engineer.VesselSimulator;
  using Engineer.Extensions;
using KSP; using KSP;
using System; using System;
  using System.Collections.Generic;
  using ToadicusTools;
using UnityEngine; using UnityEngine;
   
namespace VOID namespace VOID
{ {
public class VOID_VesselInfo : VOID_WindowModule public class VOID_VesselInfo : VOID_WindowModule
{ {
[AVOID_SaveValue("toggleExtended")] public VOID_VesselInfo() : base()
protected VOID_SaveValue<bool> toggleExtended = false;  
   
public VOID_VesselInfo()  
{ {
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 _)
{ {
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.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)); core.LabelStyles["center_bold"],
GUILayout.Label("G-force:"); GUILayout.ExpandWidth(true));
GUILayout.Label(vessel.geeForce.ToString("F2") + " gees", GUILayout.ExpandWidth(false));  
GUILayout.EndHorizontal(); VOID_Data.geeForce.DoGUIHorizontal ("F2");
   
int num_parts = 0; VOID_Data.partCount.DoGUIHorizontal ();
double total_mass = vessel.GetTotalMass();  
double resource_mass = 0; VOID_Data.totalMass.DoGUIHorizontal ("F3");
double max_thrust = 0;  
double final_thrust = 0; VOID_Data.stageResourceMass.DoGUIHorizontal("F2");
   
foreach (Part p in vessel.parts) VOID_Data.resourceMass.DoGUIHorizontal("F2");
{  
num_parts++; VOID_Data.stageDeltaV.DoGUIHorizontal (3, false);
resource_mass += p.GetResourceMass();  
  VOID_Data.totalDeltaV.DoGUIHorizontal (3, false);
foreach (PartModule pm in p.Modules)  
{ VOID_Data.mainThrottle.DoGUIHorizontal ("F0");
if ((pm.moduleName == "ModuleEngines") && ((p.State == PartStates.ACTIVE) || ((Staging.CurrentStage > Staging.lastStage) && (p.inverseStage == Staging.lastStage))))  
{ VOID_Data.currmaxThrust.DoGUIHorizontal ();
max_thrust += ((ModuleEngines)pm).maxThrust;  
final_thrust += ((ModuleEngines)pm).finalThrust; VOID_Data.currmaxThrustWeight.DoGUIHorizontal ();
}  
} VOID_Data.surfaceThrustWeight.DoGUIHorizontal ("F2");
}  
  VOID_Data.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();
} }
} }
   
  public static partial class VOID_Data
  {
  public static readonly VOID_DoubleValue geeForce = new VOID_DoubleValue(
  "G-force",
  new Func<double>(() => core.vessel.geeForce),
  "gees"
  );
   
  public static readonly VOID_IntValue partCount = new VOID_IntValue(
  "Parts",
  new Func<int>(() => core.vessel.Parts.Count),
  ""
  );
   
  public static readonly VOID_DoubleValue totalMass = new VOID_DoubleValue(
  "Total Mass",
  delegate()
  {
  if (core.Stages == null || core.LastStage == null)
  {
  return double.NaN;
  }
   
  return core.LastStage.totalMass;
  },
  "tons"
  );
   
  public static readonly VOID_DoubleValue resourceMass = new VOID_DoubleValue(
  "Resource Mass",
  delegate()
  {
  if (core.Stages == null || core.LastStage == null)
  {
  return double.NaN;
  }
   
  return core.LastStage.totalMass - core.LastStage.totalBaseMass;
  },
  "tons"
  );
   
  public static readonly VOID_DoubleValue stageResourceMass = new VOID_DoubleValue(
  "Resource Mass (Stage)",
  delegate()
  {
  if (core.LastStage == null)
  {
  return double.NaN;
  }
   
  return core.LastStage.mass - core.LastStage.baseMass;
  },
  "tons"
  );
   
  public static readonly VOID_StrValue comboResourceMass = new VOID_StrValue(
  "Resource Mass (curr / total)",
  delegate()
  {
  return string.Format("{0} / {1}",
  stageResourceMass.ValueUnitString("F3"),
  resourceMass.ValueUnitString("F3")
  );
  }
  );
   
  public static readonly VOID_DoubleValue stageDeltaV = new VOID_DoubleValue(
  "DeltaV (Current Stage)",
  delegate()
  {
  if (core.Stages == null || core.LastStage == null)
  return double.NaN;
  return core.LastStage.deltaV;
  },
  "m/s"
  );
   
  public static readonly VOID_DoubleValue totalDeltaV = new VOID_DoubleValue(
  "DeltaV (Total)",
  delegate()
  {
  if (core.Stages == null || core.LastStage == null)
  return double.NaN;
  return core.LastStage.totalDeltaV;
  },
  "m/s"
  );
   
  public static readonly VOID_FloatValue mainThrottle = new VOID_FloatValue(
  "Throttle",
  new Func<float>(() => core.vessel.ctrlState.mainThrottle * 100f),
  "%"
  );
   
  public static readonly VOID_StrValue currmaxThrust = new VOID_StrValue(
  "Thrust (curr/max)",
  delegate()
  {
  if (core.Stages == null || core.LastStage == null)
  return "N/A";
   
  double currThrust = core.LastStage.actualThrust;
  double maxThrust = core.LastStage.thrust;
   
  return string.Format(
  "{0} / {1}",
  currThrust.ToString("F1"),
  maxThrust.ToString("F1")
  );
  }
  );
   
  public static readonly VOID_DoubleValue currThrustWeight = new VOID_DoubleValue(
  "T:W Ratio",
  delegate()
  {
  if (core.LastStage == null)
  {
  return double.NaN;
  }
   
  return core.LastStage.actualThrustToWeight;
  },
  ""
  );
   
  public static readonly VOID_DoubleValue maxThrustWeight = new VOID_DoubleValue(
  "T:W Ratio",
  delegate()
  {
  if (core.LastStage == null)
  {
  return double.NaN;
  }
   
  return core.LastStage.thrustToWeight;
  },
  ""
  );
   
  public static readonly VOID_StrValue currmaxThrustWeight = new VOID_StrValue(
  "T:W (curr/max)",
  delegate()
  {
  if (core.Stages == null || core.LastStage == null)
  return "N/A";
   
  return string.Format(
  "{0} / {1}",
  (VOID_Data.currThrustWeight.Value).ToString("F2"),
  (VOID_Data.maxThrustWeight.Value).ToString("F2")
  );
  }
  );
   
  public static readonly VOID_DoubleValue surfaceThrustWeight = new VOID_DoubleValue(
  "Max T:W @ surface",
  delegate()
  {
  if (core.Stages == null || core.LastStage == null)
  return double.NaN;
   
  double maxThrust = core.LastStage.thrust;
  double mass = core.LastStage.totalMass;
  double gravity = (VOID_Core.Constant_G * core.vessel.mainBody.Mass) /
  (core.vessel.mainBody.Radius * core.vessel.mainBody.Radius);
  double weight = mass * gravity;
   
  return maxThrust / weight;
  },
  ""
  );
   
  public static readonly VOID_StrValue intakeAirStatus = new VOID_StrValue(
  "Intake Air (Curr / Req)",
  delegate()
  {
  double currentAmount;
  double currentRequirement;
   
  currentAmount = 0d;
  currentRequirement = 0d;
   
  foreach (Part part in core.vessel.Parts)
  {
  if (part.enabled)
  {
  ModuleEngines engineModule;
  ModuleEnginesFX enginesFXModule;
  List<Propellant> propellantList = null;
   
  if (part.tryGetFirstModuleOfType<ModuleEngines>(out engineModule))
  {
  propellantList = engineModule.propellants;
  }
  else if (part.tryGetFirstModuleOfType<ModuleEnginesFX>(out enginesFXModule))
  {
  propellantList = enginesFXModule.propellants;
  }
   
  if (propellantList != null)
  {
  foreach (Propellant propellant in propellantList)
  {
  if (propellant.name == "IntakeAir")
  {
  currentRequirement += propellant.currentRequirement / TimeWarp.fixedDeltaTime;
  break;
  }
  }
  }
  }
   
  ModuleResourceIntake intakeModule;
   
  if (part.enabled && part.tryGetFirstModuleOfType<ModuleResourceIntake>(out intakeModule))
  {
  if (intakeModule.resourceName == "IntakeAir")
  {
  currentAmount += intakeModule.airFlow;
  }
  }
  }
   
  if (currentAmount == 0 && currentRequirement == 0)
  {
  return "N/A";
  }
   
  return string.Format("{0:F3} / {1:F3}", currentAmount, currentRequirement);
  }
  );
  }
} }