Show part info tooltips for highlighted parts.
Show part info tooltips for highlighted parts.

// //
// Kerbal Engineer Redux // Kerbal Engineer Redux
// //
// Copyright (C) 2016 CYBUTEK // Copyright (C) 2016 CYBUTEK
// //
// 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/>.
// //
   
namespace KerbalEngineer.Editor namespace KerbalEngineer.Editor
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Extensions; using Extensions;
using Helpers; using Helpers;
using UnityEngine; using UnityEngine;
   
public class BuildOverlayPartInfo : MonoBehaviour public class BuildOverlayPartInfo : MonoBehaviour
{ {
private static bool clickToOpen = true; private static bool clickToOpen = true;
private static ModuleResource generatorResource; private static ModuleResource generatorResource;
private static ModuleAlternator moduleAlternator; private static ModuleAlternator moduleAlternator;
private static ModuleDataTransmitter moduleDataTransmitter; private static ModuleDataTransmitter moduleDataTransmitter;
private static ModuleDeployableSolarPanel moduleDeployableSolarPanel; private static ModuleDeployableSolarPanel moduleDeployableSolarPanel;
private static ModuleGenerator moduleGenerator; private static ModuleGenerator moduleGenerator;
private static ModuleGimbal moduleGimbal; private static ModuleGimbal moduleGimbal;
private static ModuleParachute moduleParachute; private static ModuleParachute moduleParachute;
private static ModuleRCS moduleRcs; private static ModuleRCS moduleRcs;
private static ModuleReactionWheel moduleReactionWheel; private static ModuleReactionWheel moduleReactionWheel;
private static ModuleResource moduleResource; private static ModuleResource moduleResource;
private static ModuleScienceExperiment moduleScienceExperiment; private static ModuleScienceExperiment moduleScienceExperiment;
private static bool namesOnly; private static bool namesOnly;
private static Part part; private static Part part;
private static PartInfoItem partInfoItem; private static PartInfoItem partInfoItem;
private static PartResource partResource; private static PartResource partResource;
private static Propellant propellant; private static Propellant propellant;
private static PartExtensions.ProtoModuleDecoupler protoModuleDecoupler; private static PartExtensions.ProtoModuleDecoupler protoModuleDecoupler;
private static PartExtensions.ProtoModuleEngine protoModuleEngine; private static PartExtensions.ProtoModuleEngine protoModuleEngine;
private static bool visible = true; private static bool visible = true;
   
private readonly List<PartInfoItem> infoItems = new List<PartInfoItem>(); private readonly List<PartInfoItem> infoItems = new List<PartInfoItem>();
   
private Rect position; private Rect position;
private Part selectedPart; private Part selectedPart;
private bool showInfo; private bool showInfo;
private bool skipFrame; private bool skipFrame;
   
public static bool ClickToOpen public static bool ClickToOpen
{ {
get get
{ {
return clickToOpen; return clickToOpen;
} }
set set
{ {
clickToOpen = value; clickToOpen = value;
} }
} }
   
public static bool Hidden { get; set; } public static bool Hidden { get; set; }
   
public static bool NamesOnly public static bool NamesOnly
{ {
get get
{ {
return namesOnly; return namesOnly;
} }
set set
{ {
namesOnly = value; namesOnly = value;
} }
} }
   
public static bool Visible public static bool Visible
{ {
get get
{ {
return visible; return visible;
} }
set set
{ {
visible = value; visible = value;
} }
} }
   
protected void OnGUI() protected void OnGUI()
{ {
try try
{ {
if (!Visible || Hidden || selectedPart == null) if (!Visible || Hidden || selectedPart == null)
{ {
return; return;
} }
   
position = GUILayout.Window(GetInstanceID(), position, Window, string.Empty, BuildOverlay.WindowStyle); position = GUILayout.Window(GetInstanceID(), position, Window, string.Empty, BuildOverlay.WindowStyle);
} }
catch (Exception ex) catch (Exception ex)
   
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
protected void Update() protected void Update()
{ {
try try
{ {
if (!Visible || Hidden || EditorLogic.RootPart == null || EditorLogic.fetch.editorScreen != EditorScreen.Parts) if (!Visible || Hidden || EditorLogic.RootPart == null || EditorLogic.fetch.editorScreen != EditorScreen.Parts)
{ {
return; return;
} }
   
position.x = Mathf.Clamp(Input.mousePosition.x + 16.0f, 0.0f, Screen.width - position.width); position.x = Mathf.Clamp(Input.mousePosition.x + 16.0f, 0.0f, Screen.width - position.width);
position.y = Mathf.Clamp(Screen.height - Input.mousePosition.y, 0.0f, Screen.height - position.height); position.y = Mathf.Clamp(Screen.height - Input.mousePosition.y, 0.0f, Screen.height - position.height);
if (position.x < Input.mousePosition.x + 20.0f) if (position.x < Input.mousePosition.x + 20.0f)
{ {
position.y = Mathf.Clamp(position.y + 20.0f, 0.0f, Screen.height - position.height); position.y = Mathf.Clamp(position.y + 20.0f, 0.0f, Screen.height - position.height);
} }
if (position.x < Input.mousePosition.x + 16.0f && position.y < Screen.height - Input.mousePosition.y) if (position.x < Input.mousePosition.x + 16.0f && position.y < Screen.height - Input.mousePosition.y)
{ {
position.x = Input.mousePosition.x - 3 - position.width; position.x = Input.mousePosition.x - 3 - position.width;
} }
   
RaycastHit rayHit; RaycastHit rayHit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out rayHit)) if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out rayHit))
{ {
part = rayHit.transform.GetComponent<Part>(); part = rayHit.transform.GetComponent<Part>();
} }
else else
{ {
part = null; part = EditorLogic.fetch.ship.parts.Find(p => p.highlighter.highlighted) ?? EditorLogic.SelectedPart;
}  
   
if (part == null)  
{  
part = EditorLogic.SelectedPart;  
} }
   
if (part != null) if (part != null)
{ {
if (!part.Equals(selectedPart)) if (!part.Equals(selectedPart))
{ {
selectedPart = part; selectedPart = part;
ResetInfo(); ResetInfo();
} }
if (NamesOnly || skipFrame) if (NamesOnly || skipFrame)
{ {
skipFrame = false; skipFrame = false;
return; return;
} }
   
if (!showInfo && Input.GetMouseButtonDown(2)) if (!showInfo && Input.GetMouseButtonDown(2))
{ {
showInfo = true; showInfo = true;
} }
else if (ClickToOpen && showInfo && Input.GetMouseButtonDown(2)) else if (ClickToOpen && showInfo && Input.GetMouseButtonDown(2))
{ {
ResetInfo(); ResetInfo();
} }
   
if (showInfo) if (showInfo)
{ {
PartInfoItem.Release(infoItems); PartInfoItem.Release(infoItems);
infoItems.Clear(); infoItems.Clear();
SetCostInfo(); SetCostInfo();
SetMassItems(); SetMassItems();
SetResourceItems(); SetResourceItems();
SetEngineInfo(); SetEngineInfo();
SetAlternatorInfo(); SetAlternatorInfo();
SetGimbalInfo(); SetGimbalInfo();
SetRcsInfo(); SetRcsInfo();
SetParachuteInfo(); SetParachuteInfo();
SetSasInfo(); SetSasInfo();
SetReactionWheelInfo(); SetReactionWheelInfo();
SetSolarPanelInfo(); SetSolarPanelInfo();
SetGeneratorInfo(); SetGeneratorInfo();
SetDecouplerInfo(); SetDecouplerInfo();
SetTransmitterInfo(); SetTransmitterInfo();
SetScienceExperimentInfo(); SetScienceExperimentInfo();
SetScienceContainerInfo(); SetScienceContainerInfo();
SetSingleActivationInfo(); SetSingleActivationInfo();
} }
} }
else else
{ {
selectedPart = null; selectedPart = null;
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
   
private void ResetInfo() private void ResetInfo()
{ {
showInfo = !clickToOpen; showInfo = !clickToOpen;
skipFrame = true; skipFrame = true;
position.width = namesOnly || clickToOpen ? 0.0f : 200.0f; position.width = namesOnly || clickToOpen ? 0.0f : 200.0f;
position.height = 0.0f; position.height = 0.0f;
} }
   
private void SetAlternatorInfo() private void SetAlternatorInfo()
{ {
moduleAlternator = selectedPart.GetModule<ModuleAlternator>(); moduleAlternator = selectedPart.GetModule<ModuleAlternator>();
if (moduleAlternator != null) if (moduleAlternator != null)
{ {
infoItems.Add(PartInfoItem.Create("Alternator")); infoItems.Add(PartInfoItem.Create("Alternator"));
for (int i = 0; i < moduleAlternator.outputResources.Count; ++i) for (int i = 0; i < moduleAlternator.outputResources.Count; ++i)
{ {
moduleResource = moduleAlternator.outputResources[i]; moduleResource = moduleAlternator.outputResources[i];
infoItems.Add(PartInfoItem.Create("\t" + moduleResource.name, moduleResource.rate.ToRate())); infoItems.Add(PartInfoItem.Create("\t" + moduleResource.name, moduleResource.rate.ToRate()));
} }
} }
} }
   
private void SetCostInfo() private void SetCostInfo()
{ {
infoItems.Add(PartInfoItem.Create("Cost", Units.ConcatF(selectedPart.GetCostDry(), selectedPart.GetCostWet()))); infoItems.Add(PartInfoItem.Create("Cost", Units.ConcatF(selectedPart.GetCostDry(), selectedPart.GetCostWet())));
} }
   
private void SetDecouplerInfo() private void SetDecouplerInfo()
{ {
protoModuleDecoupler = selectedPart.GetProtoModuleDecoupler(); protoModuleDecoupler = selectedPart.GetProtoModuleDecoupler();
if (protoModuleDecoupler != null) if (protoModuleDecoupler != null)
{ {
infoItems.Add(PartInfoItem.Create("Ejection Force", protoModuleDecoupler.EjectionForce.ToForce())); infoItems.Add(PartInfoItem.Create("Ejection Force", protoModuleDecoupler.EjectionForce.ToForce()));
if (protoModuleDecoupler.IsOmniDecoupler) if (protoModuleDecoupler.IsOmniDecoupler)
{ {
infoItems.Add(PartInfoItem.Create("Omni-directional")); infoItems.Add(PartInfoItem.Create("Omni-directional"));
} }
} }
} }
   
private void SetEngineInfo() private void SetEngineInfo()
{ {
protoModuleEngine = selectedPart.GetProtoModuleEngine(); protoModuleEngine = selectedPart.GetProtoModuleEngine();
if (protoModuleEngine != null) if (protoModuleEngine != null)
{ {
infoItems.Add(PartInfoItem.Create("Thrust", Units.ToForce(protoModuleEngine.MinimumThrust, protoModuleEngine.MaximumThrust))); infoItems.Add(PartInfoItem.Create("Thrust", Units.ToForce(protoModuleEngine.MinimumThrust, protoModuleEngine.MaximumThrust)));
infoItems.Add(PartInfoItem.Create("Isp", Units.ConcatF(protoModuleEngine.GetSpecificImpulse(1.0f), protoModuleEngine.GetSpecificImpulse(0.0f)) + "s")); infoItems.Add(PartInfoItem.Create("Isp", Units.ConcatF(protoModuleEngine.GetSpecificImpulse(1.0f), protoModuleEngine.GetSpecificImpulse(0.0f)) + "s"));
if (protoModuleEngine.Propellants.Count > 0) if (protoModuleEngine.Propellants.Count > 0)
{ {
infoItems.Add(PartInfoItem.Create("Propellants")); infoItems.Add(PartInfoItem.Create("Propellants"));
   
float totalRatio = 0.0f; float totalRatio = 0.0f;
for (int i = 0; i < protoModuleEngine.Propellants.Count; ++i) for (int i = 0; i < protoModuleEngine.Propellants.Count; ++i)
{ {
totalRatio = totalRatio + protoModuleEngine.Propellants[i].ratio; totalRatio = totalRatio + protoModuleEngine.Propellants[i].ratio;
} }
   
for (int i = 0; i < protoModuleEngine.Propellants.Count; ++i) for (int i = 0; i < protoModuleEngine.Propellants.Count; ++i)
{ {
propellant = protoModuleEngine.Propellants[i]; propellant = protoModuleEngine.Propellants[i];
infoItems.Add(PartInfoItem.Create("\t" + propellant.name, (propellant.ratio / totalRatio).ToPercent())); infoItems.Add(PartInfoItem.Create("\t" + propellant.name, (propellant.ratio / totalRatio).ToPercent()));
} }
} }
} }
} }
   
private void SetGeneratorInfo() private void SetGeneratorInfo()
{ {
moduleGenerator = selectedPart.GetModule<ModuleGenerator>(); moduleGenerator = selectedPart.GetModule<ModuleGenerator>();
if (moduleGenerator != null) if (moduleGenerator != null)
{ {
if (moduleGenerator.inputList.Count > 0) if (moduleGenerator.inputList.Count > 0)
{ {
infoItems.Add(PartInfoItem.Create("Generator Input")); infoItems.Add(PartInfoItem.Create("Generator Input"));
for (int i = 0; i < moduleGenerator.inputList.Count; ++i) for (int i = 0; i < moduleGenerator.inputList.Count; ++i)
{ {
generatorResource = moduleGenerator.inputList[i]; generatorResource = moduleGenerator.inputList[i];
infoItems.Add(PartInfoItem.Create("\t" + generatorResource.name, generatorResource.rate.ToRate())); infoItems.Add(PartInfoItem.Create("\t" + generatorResource.name, generatorResource.rate.ToRate()));
} }
} }
if (moduleGenerator.outputList.Count > 0) if (moduleGenerator.outputList.Count > 0)
{ {
infoItems.Add(PartInfoItem.Create("Generator Output")); infoItems.Add(PartInfoItem.Create("Generator Output"));
for (int i = 0; i < moduleGenerator.outputList.Count; ++i) for (int i = 0; i < moduleGenerator.outputList.Count; ++i)
{ {
generatorResource = moduleGenerator.outputList[i]; generatorResource = moduleGenerator.outputList[i];
infoItems.Add(PartInfoItem.Create("\t" + generatorResource.name, generatorResource.rate.ToRate())); infoItems.Add(PartInfoItem.Create("\t" + generatorResource.name, generatorResource.rate.ToRate()));
} }
} }
if (moduleGenerator.isAlwaysActive) if (moduleGenerator.isAlwaysActive)
{ {
infoItems.Add(PartInfoItem.Create("Generator is Always Active")); infoItems.Add(PartInfoItem.Create("Generator is Always Active"));
} }
} }
} }
   
private void SetGimbalInfo() private void SetGimbalInfo()
{ {
moduleGimbal = selectedPart.GetModule<ModuleGimbal>(); moduleGimbal = selectedPart.GetModule<ModuleGimbal>();
if (moduleGimbal != null) if (moduleGimbal != null)
{ {
infoItems.Add(PartInfoItem.Create("Thrust Vectoring", moduleGimbal.gimbalRange.ToString("F2"))); infoItems.Add(PartInfoItem.Create("Thrust Vectoring", moduleGimbal.gimbalRange.ToString("F2")));
} }
} }
   
private void SetMassItems() private void SetMassItems()
{ {
if (selectedPart.physicalSignificance == Part.PhysicalSignificance.FULL) if (selectedPart.physicalSignificance == Part.PhysicalSignificance.FULL)
{ {
infoItems.Add(PartInfoItem.Create("Mass", Units.ToMass(selectedPart.GetDryMass(), selectedPart.GetWetMass()))); infoItems.Add(PartInfoItem.Create("Mass", Units.ToMass(selectedPart.GetDryMass(), selectedPart.GetWetMass())));
} }
} }
   
private void SetParachuteInfo() private void SetParachuteInfo()
{ {
moduleParachute = selectedPart.GetModule<ModuleParachute>(); moduleParachute = selectedPart.GetModule<ModuleParachute>();
if (moduleParachute != null) if (moduleParachute != null)
{ {
infoItems.Add(PartInfoItem.Create("Deployed Drag", Units.ConcatF(moduleParachute.semiDeployedDrag, moduleParachute.fullyDeployedDrag))); infoItems.Add(PartInfoItem.Create("Deployed Drag", Units.ConcatF(moduleParachute.semiDeployedDrag, moduleParachute.fullyDeployedDrag)));
infoItems.Add(PartInfoItem.Create("Deployment Altitude", moduleParachute.deployAltitude.ToDistance())); infoItems.Add(PartInfoItem.Create("Deployment Altitude", moduleParachute.deployAltitude.ToDistance()));
infoItems.Add(PartInfoItem.Create("Deployment Pressure", moduleParachute.minAirPressureToOpen.ToString("F2"))); infoItems.Add(PartInfoItem.Create("Deployment Pressure", moduleParachute.minAirPressureToOpen.ToString("F2")));
} }
} }
   
private void SetRcsInfo() private void SetRcsInfo()
{ {
moduleRcs = selectedPart.GetModule<ModuleRCS>(); moduleRcs = selectedPart.GetModule<ModuleRCS>();
if (moduleRcs != null) if (moduleRcs != null)
{ {
infoItems.Add(PartInfoItem.Create("Thruster Power", moduleRcs.thrusterPower.ToForce())); infoItems.Add(PartInfoItem.Create("Thruster Power", moduleRcs.thrusterPower.ToForce()));
infoItems.Add(PartInfoItem.Create("Specific Impulse", Units.ConcatF(moduleRcs.atmosphereCurve.Evaluate(1.0f), moduleRcs.atmosphereCurve.Evaluate(0.0f)) + "s")); infoItems.Add(PartInfoItem.Create("Specific Impulse", Units.ConcatF(moduleRcs.atmosphereCurve.Evaluate(1.0f), moduleRcs.atmosphereCurve.Evaluate(0.0f)) + "s"));
} }
} }
   
private void SetReactionWheelInfo() private void SetReactionWheelInfo()
{ {
moduleReactionWheel = selectedPart.GetModule<ModuleReactionWheel>(); moduleReactionWheel = selectedPart.GetModule<ModuleReactionWheel>();
if (moduleReactionWheel != null) if (moduleReactionWheel != null)
{ {
infoItems.Add(PartInfoItem.Create("Reaction Wheel Torque")); infoItems.Add(PartInfoItem.Create("Reaction Wheel Torque"));
infoItems.Add(PartInfoItem.Create("\tPitch", moduleReactionWheel.PitchTorque.ToTorque())); infoItems.Add(PartInfoItem.Create("\tPitch", moduleReactionWheel.PitchTorque.ToTorque()));
infoItems.Add(PartInfoItem.Create("\tRoll", moduleReactionWheel.RollTorque.ToTorque())); infoItems.Add(PartInfoItem.Create("\tRoll", moduleReactionWheel.RollTorque.ToTorque()));
infoItems.Add(PartInfoItem.Create("\tYaw", moduleReactionWheel.YawTorque.ToTorque())); infoItems.Add(PartInfoItem.Create("\tYaw", moduleReactionWheel.YawTorque.ToTorque()));
for (int i = 0; i < moduleReactionWheel.inputResources.Count; ++i) for (int i = 0; i < moduleReactionWheel.inputResources.Count; ++i)
{ {
moduleResource = moduleReactionWheel.inputResources[i]; moduleResource = moduleReactionWheel.inputResources[i];
infoItems.Add(PartInfoItem.Create("\t" + moduleResource.name, moduleResource.rate.ToRate())); infoItems.Add(PartInfoItem.Create("\t" + moduleResource.name, moduleResource.rate.ToRate()));
} }
} }
} }
   
private void SetResourceItems() private void SetResourceItems()
{ {
bool visibleResources = false; bool visibleResources = false;
for (int i = 0; i < selectedPart.Resources.list.Count; ++i) for (int i = 0; i < selectedPart.Resources.list.Count; ++i)
{ {
if (selectedPart.Resources.list[i].hideFlow == false) if (selectedPart.Resources.list[i].hideFlow == false)
{ {
visibleResources = true; visibleResources = true;
break; break;
} }
} }
if (visibleResources) if (visibleResources)
{ {
infoItems.Add(PartInfoItem.Create("Resources")); infoItems.Add(PartInfoItem.Create("Resources"));
for (int i = 0; i < selectedPart.Resources.list.Count; ++i) for (int i = 0; i < selectedPart.Resources.list.Count; ++i)
{ {
partResource = selectedPart.Resources.list[i]; partResource = selectedPart.Resources.list[i];
   
if (partResource.hideFlow == false) if (partResource.hideFlow == false)
{ {
infoItems.Add(partResource.GetDensity() > 0 infoItems.Add(partResource.GetDensity() > 0
? PartInfoItem.Create("\t" + partResource.info.name, "(" + partResource.GetMass().ToMass() + ") " + partResource.amount.ToString("F1")) ? PartInfoItem.Create("\t" + partResource.info.name, "(" + partResource.GetMass().ToMass() + ") " + partResource.amount.ToString("F1"))
: PartInfoItem.Create("\t" + partResource.info.name, partResource.amount.ToString("F1"))); : PartInfoItem.Create("\t" + partResource.info.name, partResource.amount.ToString("F1")));
} }
} }
} }
} }
   
private void SetSasInfo() private void SetSasInfo()
{ {
if (selectedPart.HasModule<ModuleSAS>()) if (selectedPart.HasModule<ModuleSAS>())
{ {
infoItems.Add(PartInfoItem.Create("SAS Equiped")); infoItems.Add(PartInfoItem.Create("SAS Equiped"));
} }
} }
   
private void SetScienceContainerInfo() private void SetScienceContainerInfo()
{ {
if (selectedPart.HasModule<ModuleScienceContainer>()) if (selectedPart.HasModule<ModuleScienceContainer>())
{ {
infoItems.Add(PartInfoItem.Create("Science Container")); infoItems.Add(PartInfoItem.Create("Science Container"));
} }
} }
   
private void SetScienceExperimentInfo() private void SetScienceExperimentInfo()
{ {
moduleScienceExperiment = selectedPart.GetModule<ModuleScienceExperiment>(); moduleScienceExperiment = selectedPart.GetModule<ModuleScienceExperiment>();
if (moduleScienceExperiment != null) if (moduleScienceExperiment != null)
{ {
infoItems.Add(PartInfoItem.Create("Science Experiment", moduleScienceExperiment.experimentActionName)); infoItems.Add(PartInfoItem.Create("Science Experiment", moduleScienceExperiment.experimentActionName));
infoItems.Add(PartInfoItem.Create("\tTransmit Efficiency", moduleScienceExperiment.xmitDataScalar.ToPercent())); infoItems.Add(PartInfoItem.Create("\tTransmit Efficiency", moduleScienceExperiment.xmitDataScalar.ToPercent()));
if (moduleScienceExperiment.rerunnable == false) if (moduleScienceExperiment.rerunnable == false)
{ {
infoItems.Add(PartInfoItem.Create("\tSingle Usage")); infoItems.Add(PartInfoItem.Create("\tSingle Usage"));
} }
} }
} }
   
private void SetSingleActivationInfo() private void SetSingleActivationInfo()
{ {
if (selectedPart.HasModule<ModuleAnimateGeneric>(m => m.isOneShot)) if (selectedPart.HasModule<ModuleAnimateGeneric>(m => m.isOneShot))
{ {
infoItems.Add(PartInfoItem.Create("Single Activation")); infoItems.Add(PartInfoItem.Create("Single Activation"));
} }
} }
   
private void SetSolarPanelInfo() private void SetSolarPanelInfo()
{ {
moduleDeployableSolarPanel = selectedPart.GetModule<ModuleDeployableSolarPanel>(); moduleDeployableSolarPanel = selectedPart.GetModule<ModuleDeployableSolarPanel>();
if (moduleDeployableSolarPanel != null) if (moduleDeployableSolarPanel != null)
{ {
infoItems.Add(PartInfoItem.Create("Charge Rate", moduleDeployableSolarPanel.chargeRate.ToRate())); infoItems.Add(PartInfoItem.Create("Charge Rate", moduleDeployableSolarPanel.chargeRate.ToRate()));
if (moduleDeployableSolarPanel.isBreakable) if (moduleDeployableSolarPanel.isBreakable)
{ {
infoItems.Add(PartInfoItem.Create("Breakable")); infoItems.Add(PartInfoItem.Create("Breakable"));
} }
if (moduleDeployableSolarPanel.sunTracking) if (moduleDeployableSolarPanel.sunTracking)
{ {
infoItems.Add(PartInfoItem.Create("Sun Tracking")); infoItems.Add(PartInfoItem.Create("Sun Tracking"));
} }
} }
} }
   
private void SetTransmitterInfo() private void SetTransmitterInfo()
{ {
moduleDataTransmitter = selectedPart.GetModule<ModuleDataTransmitter>(); moduleDataTransmitter = selectedPart.GetModule<ModuleDataTransmitter>();
if (moduleDataTransmitter != null) if (moduleDataTransmitter != null)
{ {
infoItems.Add(PartInfoItem.Create("Packet Size", moduleDataTransmitter.packetSize.ToString("F2") + " Mits")); infoItems.Add(PartInfoItem.Create("Packet Size", moduleDataTransmitter.packetSize.ToString("F2") + " Mits"));
infoItems.Add(PartInfoItem.Create("Bandwidth", (moduleDataTransmitter.packetInterval * moduleDataTransmitter.packetSize).ToString("F2") + "Mits/sec")); infoItems.Add(PartInfoItem.Create("Bandwidth", (moduleDataTransmitter.packetInterval * moduleDataTransmitter.packetSize).ToString("F2") + "Mits/sec"));
infoItems.Add(PartInfoItem.Create(moduleDataTransmitter.requiredResource, moduleDataTransmitter.packetResourceCost.ToString("F2") + "/Packet")); infoItems.Add(PartInfoItem.Create(moduleDataTransmitter.requiredResource, moduleDataTransmitter.packetResourceCost.ToString("F2") + "/Packet"));
} }
} }
   
private void Window(int windowId) private void Window(int windowId)
{ {
try try
{ {
GUILayout.Label(selectedPart.partInfo.title, BuildOverlay.TitleStyle); GUILayout.Label(selectedPart.partInfo.title, BuildOverlay.TitleStyle);
if (showInfo) if (showInfo)
{ {
for (int i = 0; i < infoItems.Count; ++i) for (int i = 0; i < infoItems.Count; ++i)
{ {
partInfoItem = infoItems[i]; partInfoItem = infoItems[i];
GUILayout.Space(2.0f); GUILayout.Space(2.0f);
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
if (partInfoItem.Value != null) if (partInfoItem.Value != null)
{ {
GUILayout.Label(partInfoItem.Name + ":", BuildOverlay.NameStyle); GUILayout.Label(partInfoItem.Name + ":", BuildOverlay.NameStyle);
GUILayout.Space(25.0f); GUILayout.Space(25.0f);
GUILayout.Label(partInfoItem.Value, BuildOverlay.ValueStyle); GUILayout.Label(partInfoItem.Value, BuildOverlay.ValueStyle);
} }
else else
{ {
GUILayout.Label(partInfoItem.Name, BuildOverlay.NameStyle); GUILayout.Label(partInfoItem.Name, BuildOverlay.NameStyle);
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
} }
else if (clickToOpen && namesOnly == false) else if (clickToOpen && namesOnly == false)
{ {
GUILayout.Space(2.0f); GUILayout.Space(2.0f);
GUILayout.Label("Click middle mouse to show more info...", BuildOverlay.NameStyle); GUILayout.Label("Click middle mouse to show more info...", BuildOverlay.NameStyle);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Exception(ex); Logger.Exception(ex);
} }
} }
} }
} }
// //
// Kerbal Engineer Redux // Kerbal Engineer Redux
// //
// Copyright (C) 2014 CYBUTEK // Copyright (C) 2014 CYBUTEK
// //
// 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/>.
// //
   
#region Using Directives #region Using Directives
   
using System;  
using System.Collections;  
using System.Collections.Generic;  
using System.IO;  
using System.Reflection;  
   
using UnityEngine;  
   
#endregion #endregion
   
namespace KerbalEngineer namespace KerbalEngineer
{ {
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.IO;
  using System.Reflection;
  using UnityEngine;
   
[KSPAddon(KSPAddon.Startup.Instantly, false)] [KSPAddon(KSPAddon.Startup.Instantly, false)]
public class Logger : MonoBehaviour public class Logger : MonoBehaviour
{ {
  #region Fields
   
  private static readonly List<string[]> messages = new List<string[]>();
   
  #endregion
   
#region Constants #region Constants
   
private static readonly string fileName; private static readonly string fileName;
private static readonly AssemblyName assemblyName; private static readonly AssemblyName assemblyName;
   
#endregion  
   
#region Fields  
   
private static readonly List<string[]> messages = new List<string[]>();  
   
#endregion #endregion
   
#region Initialisation #region Initialisation
   
static Logger() static Logger()
{ {
assemblyName = Assembly.GetExecutingAssembly().GetName(); assemblyName = Assembly.GetExecutingAssembly().GetName();
fileName = Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, "log"); fileName = Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, "log");
File.Delete(fileName); File.Delete(fileName);
   
lock (messages) lock (messages)
{ {
messages.Add(new[] {"Executing: " + assemblyName.Name + " - " + assemblyName.Version}); messages.Add(new[] {"Executing: " + assemblyName.Name + " - " + assemblyName.Version});
messages.Add(new[] {"Assembly: " + Assembly.GetExecutingAssembly().Location}); messages.Add(new[] {"Assembly: " + Assembly.GetExecutingAssembly().Location});
} }
Blank(); Blank();
} }
   
private void Awake() private void Awake()
{ {
DontDestroyOnLoad(this); DontDestroyOnLoad(this);
} }
   
#endregion #endregion
   
#region Printing #region Printing
   
public static void Blank() public static void Blank()
{ {
lock (messages) lock (messages)
{ {
messages.Add(new string[] {}); messages.Add(new string[] {});
} }
} }
   
public static void Log(object obj) public static void Log(object obj)
{ {
lock (messages) lock (messages)
{ {
try try
{ {
if (obj is IEnumerable) messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, GetObjString(obj)});
  }
  catch (Exception ex)
  {
  Exception(ex);
  }
  }
  }
   
  public static void Log(string name, object obj)
  {
  lock (messages)
  {
  try
  {
  messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, name + "\n" + GetObjString(obj)});
  }
  catch (Exception ex)
  {
  Exception(ex);
  }
  }
  }
   
  private static string GetObjString(object obj, int tabs = 0)
  {
  string objString;
  string tabString = string.Empty;
  for (int i = 0; i < tabs; i++)
  {
  tabString += " ";
  }
   
  if (obj != null)
  {
  objString = tabString + obj;
   
  IEnumerable items = obj as IEnumerable;
  if (items != null)
  {
  foreach (object item in items)
{ {
messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, obj.ToString()}); objString += "\n" + GetObjString(item, tabs + 1);
foreach (var o in obj as IEnumerable)  
{  
messages.Add(new[] {"\t", o.ToString()});  
}  
} }
else if (obj != null) }
{ }
messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, obj.ToString()}); else
} {
else objString = "Null";
{ }
messages.Add(new[] { "Log " + DateTime.Now.TimeOfDay, "Null" });  
} return objString;
}  
catch (Exception ex)  
{  
Exception(ex);  
}  
}  
}  
   
public static void Log(string name, object obj)  
{  
lock (messages)  
{  
try  
{  
if (obj is IEnumerable)  
{  
messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, name});  
foreach (var o in obj as IEnumerable)  
{  
messages.Add(new[] {"\t", o.ToString()});  
}  
}  
else if (obj != null)  
{  
messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, obj.ToString()});  
}  
else  
{  
messages.Add(new[] { "Log " + DateTime.Now.TimeOfDay, "Null" });  
}  
}  
catch (Exception ex)  
{  
Exception(ex);  
}  
}  
} }
   
public static void Log(string message) public static void Log(string message)
{ {
lock (messages) lock (messages)
{ {
messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, message}); messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, message});
} }
} }
   
public static void Warning(string message) public static void Warning(string message)
{ {
lock (messages) lock (messages)
{ {
messages.Add(new[] {"Warning " + DateTime.Now.TimeOfDay, message}); messages.Add(new[] {"Warning " + DateTime.Now.TimeOfDay, message});
} }
} }
   
public static void Error(string message) public static void Error(string message)
{ {
lock (messages) lock (messages)
{ {
messages.Add(new[] {"Error " + DateTime.Now.TimeOfDay, message}); messages.Add(new[] {"Error " + DateTime.Now.TimeOfDay, message});
} }
} }
   
public static void Exception(Exception ex) public static void Exception(Exception ex)
{ {
lock (messages) lock (messages)
{ {
messages.Add(new[] {"Exception " + DateTime.Now.TimeOfDay, ex.Message}); messages.Add(new[] {"Exception " + DateTime.Now.TimeOfDay, ex.Message});
messages.Add(new[] {string.Empty, ex.StackTrace}); messages.Add(new[] {string.Empty, ex.StackTrace});
Blank(); Blank();
} }
} }
   
public static void Exception(Exception ex, string location) public static void Exception(Exception ex, string location)
{ {
lock (messages) lock (messages)
{ {
messages.Add(new[] {"Exception " + DateTime.Now.TimeOfDay, location + " // " + ex.Message}); messages.Add(new[] {"Exception " + DateTime.Now.TimeOfDay, location + " // " + ex.Message});
messages.Add(new[] {string.Empty, ex.StackTrace}); messages.Add(new[] {string.Empty, ex.StackTrace});
Blank(); Blank();
} }
} }
   
#endregion #endregion
   
#region Flushing #region Flushing
   
public static void Flush() public static void Flush()
{ {
lock (messages) lock (messages)
{ {
if (messages.Count > 0) if (messages.Count > 0)
{ {
using (var file = File.AppendText(fileName)) using (StreamWriter file = File.AppendText(fileName))
{ {
foreach (var message in messages) foreach (string[] message in messages)
{ {
file.WriteLine(message.Length > 0 ? message.Length > 1 ? "[" + message[0] + "]: " + message[1] : message[0] : string.Empty); file.WriteLine(message.Length > 0 ? message.Length > 1 ? "[" + message[0] + "]: " + message[1] : message[0] : string.Empty);
if (message.Length > 0) if (message.Length > 0)
{ {
print(message.Length > 1 ? assemblyName.Name + " -> " + message[1] : assemblyName.Name + " -> " + message[0]); print(message.Length > 1 ? assemblyName.Name + " -> " + message[1] : assemblyName.Name + " -> " + message[0]);
} }
} }
} }
messages.Clear(); messages.Clear();
} }
} }
} }
   
private void LateUpdate() private void LateUpdate()
{ {
Flush(); Flush();
} }
   
#endregion #endregion
   
#region Destruction #region Destruction
   
private void OnDestroy() private void OnDestroy()
{ {
Flush(); Flush();
} }
   
~Logger() ~Logger()
{ {
Flush(); Flush();
} }
   
#endregion #endregion
} }
} }