diff --git a/Distribution/DeepFreeze.zip b/Distribution/DeepFreeze.zip deleted file mode 100644 index 2457ad5..0000000 Binary files a/Distribution/DeepFreeze.zip and /dev/null differ diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Assets/Cry-0300RInternals.mu b/Distribution/GameData/REPOSoftTech/DeepFreeze/Assets/Cry-0300RInternals.mu deleted file mode 100644 index 0f5ecb8..0000000 Binary files a/Distribution/GameData/REPOSoftTech/DeepFreeze/Assets/Cry-0300RInternals.mu and /dev/null differ diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/DeepFreezeContinued.version b/Distribution/GameData/REPOSoftTech/DeepFreeze/DeepFreezeContinued.version deleted file mode 100644 index 9ed583c..0000000 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/DeepFreezeContinued.version +++ /dev/null @@ -1,9 +0,0 @@ -{ -"NAME":"DeepFreeze Continued...", -"URL":"http://ksp-avc.cybutek.net/version.php?id=183", -"DOWNLOAD":"http://spacedock.info/mod/142/DeepFreeze%20Continued...", -"VERSION":{"MAJOR":0,"MINOR":20,"PATCH":4,"BUILD":0}, -"KSP_VERSION":{"MAJOR":1,"MINOR":0,"PATCH":5}, -"KSP_VERSION_MIN":{"MAJOR":1,"MINOR":0,"PATCH":5}, -"KSP_VERSION_MAX":{"MAJOR":1,"MINOR":0,"PATCH":5} -} \ No newline at end of file diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RPMInternalsMM.cfg b/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RPMInternalsMM.cfg deleted file mode 100644 index 3059b20..0000000 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RPMInternalsMM.cfg +++ /dev/null @@ -1,8 +0,0 @@ -@PART[CRY-0300Freezer]:FOR[DeepFreeze]:NEEDS[RasterPropMonitor] -{ -@MODULE[DeepFreezer] - MODULE - { - name = JSITransparentPod - } -} \ No newline at end of file diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RRPMInternalsMM.cfg b/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RRPMInternalsMM.cfg deleted file mode 100644 index 37cf022..0000000 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RRPMInternalsMM.cfg +++ /dev/null @@ -1,8 +0,0 @@ -@PART[CRY-0300RFreezer]:FOR[DeepFreeze]:NEEDS[RasterPropMonitor] -{ -@MODULE[DeepFreezer] - MODULE - { - name = JSITransparentPod - } -} \ No newline at end of file diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY2300partDepricated.cfg b/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY2300partDepricated.cfg deleted file mode 100644 index b3e0ebb..0000000 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY2300partDepricated.cfg +++ /dev/null @@ -1,8 +0,0 @@ -PART[CRY-2300Freezer] -{ - @name = cryofreezer - @TechRequired = hidden - @category = -1 - @title ^= :$: [DEPRECATED]: - @description = REPOSoftTech has Deprecated this Duplicate Part Definition. CONVERT CRAFT to use NEW CRY-2300 part AND DELETE this one. REPOSoftTech_DEPRECATED -} \ No newline at end of file diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/DeepFreeze.dll b/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/DeepFreeze.dll deleted file mode 100644 index f0fbdf7..0000000 Binary files a/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/DeepFreeze.dll and /dev/null differ diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/DeepFreeze.dll.mdb b/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/DeepFreeze.dll.mdb deleted file mode 100644 index c59696f..0000000 Binary files a/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/DeepFreeze.dll.mdb and /dev/null differ diff --git a/Source/APIs/DFWrapper.cs b/Source/APIs/DFWrapper.cs index 38df152..6f40d4a 100644 --- a/Source/APIs/DFWrapper.cs +++ b/Source/APIs/DFWrapper.cs @@ -301,8 +301,14 @@ internal DeepFreezer(Object a) FreezerOutofEC = getFreezerOutofEC; FrzrTmpMethod = DeepFreezerType.GetMethod("get_DFIFrzrTmp", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); FrzrTmp = getFrzrTmp; + FrznChargeUsageMethod = DeepFreezerType.GetMethod("get_DFIFrznChargeUsage", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); + FrznChargeUsage = getFrznChargeUsage; StoredCrewListMethod = DeepFreezerType.GetMethod("get_DFIStoredCrewList", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); actualStoredCrewList = StoredCrewListMethod.Invoke(actualDeepFreezer, null); + ECReqdMethod = DeepFreezerType.GetMethod("get_DFIECReqd", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); + ECReqd = getECReqd; + FrznChargeRequiredMethod = DeepFreezerType.GetMethod("get_DFIFrznChargeRequired", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); + FrznChargeRequired = getFrznChargeRequired; //Methods //LogFormatted("Getting beginFreezeKerbalMethod Method"); @@ -438,6 +444,42 @@ private FrzrTmpStatus getFrzrTmp get { return (FrzrTmpStatus)FrzrTmpMethod.Invoke(actualDeepFreezer, null); } } + /// + /// True if this DeepFreezer requires Electric Charge for frozen Kerbals + /// + public bool ECReqd; + + private MethodInfo ECReqdMethod; + + private bool getECReqd + { + get { return (bool)ECReqdMethod.Invoke(actualDeepFreezer, null); } + } + + /// + /// The current EC Usage of this DeepFreezer + /// + public float FrznChargeUsage; + + private MethodInfo FrznChargeUsageMethod; + + private float getFrznChargeUsage + { + get { return (float)FrznChargeUsageMethod.Invoke(actualDeepFreezer, null); } + } + + /// + /// The EC Usage of this DeepFreezer Per Kerbal per minute + /// + public int FrznChargeRequired; + + private MethodInfo FrznChargeRequiredMethod; + + private int getFrznChargeRequired + { + get { return (int)FrznChargeRequiredMethod.Invoke(actualDeepFreezer, null); } + } + private Object actualStoredCrewList; private MethodInfo StoredCrewListMethod; diff --git a/Source/APIs/KACWrapper.cs b/Source/APIs/KACWrapper.cs index 367801b..1835bdc 100644 --- a/Source/APIs/KACWrapper.cs +++ b/Source/APIs/KACWrapper.cs @@ -73,7 +73,7 @@ public static Boolean InitKACWrapper() _KACWrapped = false; actualKAC = null; KAC = null; - LogFormatted("Attempting to Grab KAC Types..."); + LogFormatted_DebugOnly("Attempting to Grab KAC Types..."); //find the base type KACType = AssemblyLoader.loadedAssemblies @@ -105,7 +105,7 @@ public static Boolean InitKACWrapper() } //now grab the running instance - LogFormatted("Got Assembly Types, grabbing Instance"); + LogFormatted_DebugOnly("Got Assembly Types, grabbing Instance"); try { @@ -124,7 +124,7 @@ public static Boolean InitKACWrapper() } //If we get this far we can set up the local object and its methods/functions - LogFormatted("Got Instance, Creating Wrapper Objects"); + LogFormatted_DebugOnly("Got Instance, Creating Wrapper Objects"); KAC = new KACAPI(actualKAC); //} _KACWrapped = true; @@ -143,33 +143,33 @@ internal KACAPI(Object KAC) //these sections get and store the reflection info and actual objects where required. Later in the properties we then read the values from the actual objects //for events we also add a handler - LogFormatted("Getting APIReady Object"); + LogFormatted_DebugOnly("Getting APIReady Object"); APIReadyField = KACType.GetField("APIReady", BindingFlags.Public | BindingFlags.Static); - LogFormatted("Success: " + (APIReadyField != null)); + LogFormatted_DebugOnly("Success: " + (APIReadyField != null)); //WORK OUT THE STUFF WE NEED TO HOOK FOR PEOPEL HERE - LogFormatted("Getting Alarms Object"); + LogFormatted_DebugOnly("Getting Alarms Object"); AlarmsField = KACType.GetField("alarms", BindingFlags.Public | BindingFlags.Static); actualAlarms = AlarmsField.GetValue(actualKAC); - LogFormatted("Success: " + (actualAlarms != null)); + LogFormatted_DebugOnly("Success: " + (actualAlarms != null)); //Events - LogFormatted("Getting Alarm State Change Event"); + LogFormatted_DebugOnly("Getting Alarm State Change Event"); onAlarmStateChangedEvent = KACType.GetEvent("onAlarmStateChanged", BindingFlags.Public | BindingFlags.Instance); LogFormatted_DebugOnly("Success: " + (onAlarmStateChangedEvent != null)); LogFormatted_DebugOnly("Adding Handler"); AddHandler(onAlarmStateChangedEvent, actualKAC, AlarmStateChanged); //Methods - LogFormatted("Getting Create Method"); + LogFormatted_DebugOnly("Getting Create Method"); CreateAlarmMethod = KACType.GetMethod("CreateAlarm", BindingFlags.Public | BindingFlags.Instance); LogFormatted_DebugOnly("Success: " + (CreateAlarmMethod != null)); - LogFormatted("Getting Delete Method"); + LogFormatted_DebugOnly("Getting Delete Method"); DeleteAlarmMethod = KACType.GetMethod("DeleteAlarm", BindingFlags.Public | BindingFlags.Instance); LogFormatted_DebugOnly("Success: " + (DeleteAlarmMethod != null)); - LogFormatted("Getting DrawAlarmAction"); + LogFormatted_DebugOnly("Getting DrawAlarmAction"); DrawAlarmActionChoiceMethod = KACType.GetMethod("DrawAlarmActionChoiceAPI", BindingFlags.Public | BindingFlags.Instance); LogFormatted_DebugOnly("Success: " + (DrawAlarmActionChoiceMethod != null)); @@ -237,9 +237,9 @@ private KACAlarmList ExtractAlarmList(Object actualAlarmList) ListToReturn.Add(r1); } } - catch (Exception) + catch (Exception ex) { - //LogFormatted("Arrggg: {0}", ex.Message); + LogFormatted("ExtractAlarmList failed: {0}", ex.Message); //throw ex; // } @@ -627,10 +627,11 @@ public class KACAlarmList : List /// /// Text to be printed - can be formatted as per String.format /// Objects to feed into a String.format - [Conditional("DEBUG")] + internal static void LogFormatted_DebugOnly(String Message, params Object[] strParams) { - LogFormatted(Message, strParams); + if (RSTUtils.Utilities.debuggingOn) + LogFormatted(Message, strParams); } /// diff --git a/Source/APIs/KBWrapper.cs b/Source/APIs/KBWrapper.cs new file mode 100644 index 0000000..6b64c7a --- /dev/null +++ b/Source/APIs/KBWrapper.cs @@ -0,0 +1,174 @@ +/** + * DeepFreeze Continued... + * (C) Copyright 2015, Jamie Leighton + * + * Kerbal Space Program is Copyright (C) 2013 Squad. See http://kerbalspaceprogram.com/. This + * project is in no way associated with nor endorsed by Squad. + * + * This file is part of JPLRepo's DeepFreeze (continued...) - a Fork of DeepFreeze. Original Author of DeepFreeze is 'scottpaladin' on the KSP Forums. + * This File was not part of the original Deepfreeze but was written by Jamie Leighton based of code and concepts from the Kerbal Alarm Clock Mod. Which was licensed under the MIT license. + * (C) Copyright 2015, Jamie Leighton + * + * Continues to be licensed under the Attribution-NonCommercial-ShareAlike 3.0 (CC BY-NC-SA 4.0) + * creative commons license. See + * for full details. + * + */ + +using System; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using Debug = UnityEngine.Debug; + +namespace DF +{ + /// + /// The Wrapper class to access KB LS + /// + public class KBWrapper + { + protected static Type KBType; + protected static Object actualKB; + + /// + /// This is the KB LS Actual object + /// + /// SET AFTER INIT + /// + public static KBAPI KBActualAPI; + + /// + /// Whether we found the KB LS assembly in the loadedassemblies. + /// + /// SET AFTER INIT + /// + public static Boolean AssemblyExists { get { return KBType != null; } } + + /// + /// Whether we managed to hook the running Instance from the assembly. + /// + /// SET AFTER INIT + /// + public static Boolean InstanceExists { get { return KBActualAPI != null; } } + + /// + /// Whether we managed to wrap all the methods/functions from the instance. + /// + /// SET AFTER INIT + /// + private static Boolean _KBWrapped; + + /// + /// Whether the object has been wrapped + /// + public static Boolean APIReady { get { return _KBWrapped; } } + + /// + /// This method will set up the KB LS object and wrap all the methods/functions + /// + /// + public static Boolean InitKBWrapper() + { + //reset the internal objects + _KBWrapped = false; + actualKB = null; + LogFormatted_DebugOnly("Attempting to Grab KB LS Types..."); + + //find the base type + KBType = AssemblyLoader.loadedAssemblies + .Select(a => a.assembly.GetExportedTypes()) + .SelectMany(t => t) + .FirstOrDefault(t => t.FullName == "KERBALISM.Kerbalism"); + + if (KBType == null) + { + return false; + } + + LogFormatted("KB LS Version:{0}", KBType.Assembly.GetName().Version.ToString()); + + //If we get this far we can set up the local object and its methods/functions + LogFormatted_DebugOnly("Got Instance, Creating Wrapper Objects"); + KBActualAPI = new KBAPI(); + //KBIsKerbalTracked = new KBIsKerbalTrackedAPI(actualKBIsKerbalTracked); + + _KBWrapped = true; + return true; + } + + /// + /// The Type that is an analogue of the real KB LS. This lets you access all the API-able properties and Methods of KB LS + public class KBAPI + { + internal KBAPI() + { + //these sections get and store the reflection info and actual objects where required. Later in the properties we then read the values from the actual objects + //for events we also add a handler + //LogFormatted("Getting APIReady Object"); + //APIReadyField = TRType.GetField("APIReady", BindingFlags.Public | BindingFlags.Static); + //LogFormatted("Success: " + (APIReadyField != null).ToString()); + + //WORK OUT THE STUFF WE NEED TO HOOK FOR PEOPLE HERE + //Methods + LogFormatted_DebugOnly("Getting hook_DisableKerbal Method"); + KBhook_DisableKerbalMethod = KBType.GetMethod("hook_DisableKerbal", BindingFlags.Public | BindingFlags.Static); + LogFormatted_DebugOnly("Success: " + (KBhook_DisableKerbalMethod != null)); + } + + #region Methods + + private MethodInfo KBhook_DisableKerbalMethod; + + /// + /// Un/track a kerbal in KB LS + /// + /// A string containing the kerbal's name + /// A bool to disable or enable + internal void DisableKerbal(string kerbal, bool disabled) + { + try + { + KBhook_DisableKerbalMethod.Invoke(null, new System.Object[] { kerbal, disabled }); + } + catch (Exception ex) + { + LogFormatted("Unable to invoke KB LS DisableKerbal Method"); + LogFormatted("Exception: {0}", ex); + //throw; + } + } + #endregion Methods + } + + + #region Logging Stuff + + /// + /// Some Structured logging to the debug file - ONLY RUNS WHEN DLL COMPILED IN DEBUG MODE + /// + /// Text to be printed - can be formatted as per String.format + /// Objects to feed into a String.format + internal static void LogFormatted_DebugOnly(String Message, params Object[] strParams) + { + if (RSTUtils.Utilities.debuggingOn) + LogFormatted(Message, strParams); + } + + /// + /// Some Structured logging to the debug file + /// + /// Text to be printed - can be formatted as per String.format + /// Objects to feed into a String.format + internal static void LogFormatted(String Message, params Object[] strParams) + { + Message = String.Format(Message, strParams); + String strMessageLine = String.Format("{0},{2}-{3},{1}", + DateTime.Now, Message, Assembly.GetExecutingAssembly().GetName().Name, + MethodBase.GetCurrentMethod().DeclaringType.Name); + Debug.Log(strMessageLine); + } + + #endregion Logging Stuff + } +} \ No newline at end of file diff --git a/Source/APIs/RTWrapper.cs b/Source/APIs/RTWrapper.cs index a6798ea..7ac650b 100644 --- a/Source/APIs/RTWrapper.cs +++ b/Source/APIs/RTWrapper.cs @@ -74,7 +74,7 @@ public static Boolean InitTRWrapper() //reset the internal objects _RTWrapped = false; actualRTAPI = null; - LogFormatted("Attempting to Grab Remote Tech Types..."); + LogFormatted_DebugOnly("Attempting to Grab Remote Tech Types..."); //find the base type RTAPIType = AssemblyLoader.loadedAssemblies @@ -90,7 +90,7 @@ public static Boolean InitTRWrapper() LogFormatted("Remote Tech Version:{0}", RTAPIType.Assembly.GetName().Version.ToString()); //now grab the running instance - LogFormatted("Got Assembly Types, grabbing Instances"); + LogFormatted_DebugOnly("Got Assembly Types, grabbing Instances"); try { actualRTAPI = RTAPIType.GetMember("HasLocalControl", BindingFlags.Public | BindingFlags.Static); @@ -108,7 +108,7 @@ public static Boolean InitTRWrapper() } //If we get this far we can set up the local object and its methods/functions - LogFormatted("Got Instance, Creating Wrapper Objects"); + LogFormatted_DebugOnly("Got Instance, Creating Wrapper Objects"); RTactualAPI = new RTAPI(actualRTAPI); _RTWrapped = true; @@ -130,15 +130,15 @@ internal RTAPI(Object actualRT) //WORK OUT THE STUFF WE NEED TO HOOK FOR PEOPLE HERE //Methods - LogFormatted("Getting HasLocalControl Method"); + LogFormatted_DebugOnly("Getting HasLocalControl Method"); HasLocalControlMethod = RTAPIType.GetMethod("HasLocalControl", BindingFlags.Public | BindingFlags.Static); LogFormatted_DebugOnly("Success: " + (HasLocalControlMethod != null)); - LogFormatted("Getting HasAnyConnection Method"); + LogFormatted_DebugOnly("Getting HasAnyConnection Method"); HasAnyConnectionMethod = RTAPIType.GetMethod("HasAnyConnection", BindingFlags.Public | BindingFlags.Static); LogFormatted_DebugOnly("Success: " + (HasAnyConnectionMethod != null)); - LogFormatted("Getting GetShortestSignalDelay Method"); + LogFormatted_DebugOnly("Getting GetShortestSignalDelay Method"); GetShortestSignalDelayMethod = RTAPIType.GetMethod("GetShortestSignalDelay", BindingFlags.Public | BindingFlags.Static); LogFormatted_DebugOnly("Success: " + (GetShortestSignalDelayMethod != null)); } @@ -223,10 +223,10 @@ internal double GetShortestSignalDelay(Guid id) /// /// Text to be printed - can be formatted as per String.format /// Objects to feed into a String.format - [Conditional("DEBUG")] internal static void LogFormatted_DebugOnly(String Message, params Object[] strParams) { - LogFormatted(Message, strParams); + if (RSTUtils.Utilities.debuggingOn) + LogFormatted(Message, strParams); } /// diff --git a/Source/APIs/SMwrapper.cs b/Source/APIs/SMwrapper.cs index 18dbe6d..0ed1cda 100644 --- a/Source/APIs/SMwrapper.cs +++ b/Source/APIs/SMwrapper.cs @@ -4,9 +4,6 @@ using System.Reflection; using Debug = UnityEngine.Debug; -// TODO: Change this namespace to something specific to your plugin here. -//EG: -// namespace MyPlugin_ShipManifestWrapper namespace DF { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -69,7 +66,7 @@ public static Boolean InitSMWrapper() _SMWrapped = false; actualSM = null; ShipManifestAPI = null; - LogFormatted("Attempting to Grab ShipManifest Types..."); + LogFormatted_DebugOnly("Attempting to Grab ShipManifest Types..."); //find the base type SMType = AssemblyLoader.loadedAssemblies @@ -96,7 +93,7 @@ public static Boolean InitSMWrapper() } //now grab the running instance - LogFormatted("Got Assembly Types, grabbing Instance"); + LogFormatted_DebugOnly("Got Assembly Types, grabbing Instance"); try { actualSM = SMType.GetField("Instance", BindingFlags.Public | BindingFlags.Static).GetValue(null); @@ -111,9 +108,9 @@ public static Boolean InitSMWrapper() LogFormatted("Failed grabbing SMAddon Instance"); return false; } - + //If we get this far we can set up the local object and its methods/functions - LogFormatted("Got Instance, Creating Wrapper Objects"); + LogFormatted_DebugOnly("Got Instance, Creating Wrapper Objects"); ShipManifestAPI = new SMAPI(actualSM); _SMWrapped = true; return true; @@ -142,61 +139,61 @@ internal SMAPI(Object a) //these sections get and store the reflection info and actual objects where required. Later in the properties we then read the values from the actual objects //for events we also add a handler - LogFormatted("Getting TransferCrew Instance"); + LogFormatted_DebugOnly("Getting TransferCrew Instance"); TransferCrewMethod = SMType.GetMethod("get_CrewTransferProcess", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); actualCrewTransfer = getCrewTransferProcess; - LogFormatted("Success: " + (TransferCrewMethod != null)); - LogFormatted("Getting CrewProcessOn Instance"); + LogFormatted_DebugOnly("Success: " + (TransferCrewMethod != null)); + LogFormatted_DebugOnly("Getting CrewProcessOn Instance"); CrewProcessOnMethod = SMType.GetMethod("get_CrewProcessOn", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (CrewProcessOnMethod != null)); - LogFormatted("Getting getCrewXferActiveMethod"); + LogFormatted_DebugOnly("Success: " + (CrewProcessOnMethod != null)); + LogFormatted_DebugOnly("Getting getCrewXferActiveMethod"); getCrewXferActiveMethod = TransferCrewType.GetMethod("get_CrewXferActive", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getCrewXferActiveMethod != null)); - LogFormatted("Getting setCrewXferActiveMethod"); + LogFormatted_DebugOnly("Success: " + (getCrewXferActiveMethod != null)); + LogFormatted_DebugOnly("Getting setCrewXferActiveMethod"); setCrewXferActiveMethod = TransferCrewType.GetMethod("set_CrewXferActive", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (setCrewXferActiveMethod != null)); - LogFormatted("Getting getIsStockXferMethod"); + LogFormatted_DebugOnly("Success: " + (setCrewXferActiveMethod != null)); + LogFormatted_DebugOnly("Getting getIsStockXferMethod"); getIsStockXferMethod = TransferCrewType.GetMethod("get_IsStockXfer", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getIsStockXferMethod != null)); - LogFormatted("Getting getOverrideStockCrewXferMethod"); + LogFormatted_DebugOnly("Success: " + (getIsStockXferMethod != null)); + LogFormatted_DebugOnly("Getting getOverrideStockCrewXferMethod"); getOverrideStockCrewXferMethod = TransferCrewType.GetMethod("get_OverrideStockCrewXfer", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getOverrideStockCrewXferMethod != null)); - LogFormatted("Getting getCrewXferDelaySecMethod"); + LogFormatted_DebugOnly("Success: " + (getOverrideStockCrewXferMethod != null)); + LogFormatted_DebugOnly("Getting getCrewXferDelaySecMethod"); getCrewXferDelaySecMethod = TransferCrewType.GetMethod("get_CrewXferDelaySec", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getCrewXferDelaySecMethod != null)); - LogFormatted("Getting getIsSeat2SeatXferMethod"); + LogFormatted_DebugOnly("Success: " + (getCrewXferDelaySecMethod != null)); + LogFormatted_DebugOnly("Getting getIsSeat2SeatXferMethod"); getIsSeat2SeatXferMethod = TransferCrewType.GetMethod("get_IsSeat2SeatXfer", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getIsSeat2SeatXferMethod != null)); - LogFormatted("Getting getSeat2SeatXferDelaySecMethod"); + LogFormatted_DebugOnly("Success: " + (getIsSeat2SeatXferMethod != null)); + LogFormatted_DebugOnly("Getting getSeat2SeatXferDelaySecMethod"); getSeat2SeatXferDelaySecMethod = TransferCrewType.GetMethod("get_Seat2SeatXferDelaySec", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getSeat2SeatXferDelaySecMethod != null)); - LogFormatted("Getting getFromSeatMethod"); + LogFormatted_DebugOnly("Success: " + (getSeat2SeatXferDelaySecMethod != null)); + LogFormatted_DebugOnly("Getting getFromSeatMethod"); getFromSeatMethod = TransferCrewType.GetMethod("get_FromSeat", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getFromSeatMethod != null)); - LogFormatted("Getting getToSeatMethod"); + LogFormatted_DebugOnly("Success: " + (getFromSeatMethod != null)); + LogFormatted_DebugOnly("Getting getToSeatMethod"); getToSeatMethod = TransferCrewType.GetMethod("get_ToSeat", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getToSeatMethod != null)); - LogFormatted("Getting getXferVesselIdMethod"); + LogFormatted_DebugOnly("Success: " + (getToSeatMethod != null)); + LogFormatted_DebugOnly("Getting getXferVesselIdMethod"); getXferVesselIdMethod = TransferCrewType.GetMethod("get_XferVesselId", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getXferVesselIdMethod != null)); - LogFormatted("Getting getIvaDelayActiveMethod"); + LogFormatted_DebugOnly("Success: " + (getXferVesselIdMethod != null)); + LogFormatted_DebugOnly("Getting getIvaDelayActiveMethod"); getIvaDelayActiveMethod = TransferCrewType.GetMethod("get_IvaDelayActive", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getIvaDelayActiveMethod != null)); - LogFormatted("Getting getIvaPortraitDelayMethod"); + LogFormatted_DebugOnly("Success: " + (getIvaDelayActiveMethod != null)); + LogFormatted_DebugOnly("Getting getIvaPortraitDelayMethod"); getIvaPortraitDelayMethod = TransferCrewType.GetMethod("get_IvaPortraitDelay", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getIvaPortraitDelayMethod != null)); - LogFormatted("Getting getFromPartMethod"); + LogFormatted_DebugOnly("Success: " + (getIvaPortraitDelayMethod != null)); + LogFormatted_DebugOnly("Getting getFromPartMethod"); getFromPartMethod = TransferCrewType.GetMethod("get_FromPart", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getFromPartMethod != null)); - LogFormatted("Getting getToPartMethod"); + LogFormatted_DebugOnly("Success: " + (getFromPartMethod != null)); + LogFormatted_DebugOnly("Getting getToPartMethod"); getToPartMethod = TransferCrewType.GetMethod("get_ToPart", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getToPartMethod != null)); - LogFormatted("Getting getFromCrewMemberMethod"); + LogFormatted_DebugOnly("Success: " + (getToPartMethod != null)); + LogFormatted_DebugOnly("Getting getFromCrewMemberMethod"); getFromCrewMemberMethod = TransferCrewType.GetMethod("get_FromCrewMember", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getFromCrewMemberMethod != null)); - LogFormatted("Getting getToCrewMemberMethod"); + LogFormatted_DebugOnly("Success: " + (getFromCrewMemberMethod != null)); + LogFormatted_DebugOnly("Getting getToCrewMemberMethod"); getToCrewMemberMethod = TransferCrewType.GetMethod("get_ToCrewMember", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); - LogFormatted("Success: " + (getToCrewMemberMethod != null)); + LogFormatted_DebugOnly("Success: " + (getToCrewMemberMethod != null)); } catch (Exception ex) @@ -514,10 +511,10 @@ public ProtoCrewMember ToCrewMember /// /// Text to be printed - can be formatted as per String.format /// Objects to feed into a String.format - [Conditional("DEBUG")] internal static void LogFormatted_DebugOnly(String Message, params Object[] strParams) { - LogFormatted(Message, strParams); + if (RSTUtils.Utilities.debuggingOn) + LogFormatted(Message, strParams); } /// diff --git a/Source/APIs/TRWrapper.cs b/Source/APIs/TRWrapper.cs index 7b2fd18..7b2e272 100644 --- a/Source/APIs/TRWrapper.cs +++ b/Source/APIs/TRWrapper.cs @@ -78,7 +78,7 @@ public static Boolean InitTRWrapper() _TRWrapped = false; actualTR = null; TexRepPersonaliser = null; - LogFormatted("Attempting to Grab TextureReplacer Types..."); + LogFormatted_DebugOnly("Attempting to Grab TextureReplacer Types..."); //find the base type TRType = AssemblyLoader.loadedAssemblies @@ -105,7 +105,7 @@ public static Boolean InitTRWrapper() } //now grab the running instance - LogFormatted("Got Assembly Types, grabbing Instances"); + LogFormatted_DebugOnly("Got Assembly Types, grabbing Instances"); try { actualTR = TRType.GetField("isInitialised", BindingFlags.Public | BindingFlags.Static).GetValue(null); @@ -131,7 +131,7 @@ public static Boolean InitTRWrapper() } //If we get this far we can set up the local object and its methods/functions - LogFormatted("Got Instance, Creating Wrapper Objects"); + LogFormatted_DebugOnly("Got Instance, Creating Wrapper Objects"); TexRepPersonaliser = new TRPersonaliserAPI(actualTRPersonaliser); _TRWrapped = true; @@ -156,7 +156,7 @@ internal TRPersonaliserAPI(Object TexRepPersonaliser) //WORK OUT THE STUFF WE NEED TO HOOK FOR PEOPLE HERE //Methods - LogFormatted("Getting personalise Method"); + LogFormatted_DebugOnly("Getting personalise Method"); personaliseIvaMethod = TRPersonaliserType.GetMethod("personaliseIva", BindingFlags.Public | BindingFlags.Instance); LogFormatted_DebugOnly("Success: " + (personaliseIvaMethod != null)); } @@ -196,10 +196,10 @@ internal void personaliseIva(Kerbal kerbal) /// /// Text to be printed - can be formatted as per String.format /// Objects to feed into a String.format - [Conditional("DEBUG")] internal static void LogFormatted_DebugOnly(String Message, params Object[] strParams) { - LogFormatted(Message, strParams); + if (RSTUtils.Utilities.debuggingOn) + LogFormatted(Message, strParams); } /// diff --git a/Source/APIs/USIWrapper.cs b/Source/APIs/USIWrapper.cs index beb6065..1eb3e92 100644 --- a/Source/APIs/USIWrapper.cs +++ b/Source/APIs/USIWrapper.cs @@ -75,7 +75,7 @@ public static Boolean InitUSIWrapper() //reset the internal objects _USIWrapped = false; actualUSI = null; - LogFormatted("Attempting to Grab USI LS Types..."); + LogFormatted_DebugOnly("Attempting to Grab USI LS Types..."); //find the base type USIType = AssemblyLoader.loadedAssemblies @@ -103,7 +103,7 @@ public static Boolean InitUSIWrapper() //now grab the running instance - LogFormatted("Got Assembly Types, grabbing Instances"); + LogFormatted_DebugOnly("Got Assembly Types, grabbing Instances"); try { @@ -123,7 +123,7 @@ public static Boolean InitUSIWrapper() //If we get this far we can set up the local object and its methods/functions - LogFormatted("Got Instance, Creating Wrapper Objects"); + LogFormatted_DebugOnly("Got Instance, Creating Wrapper Objects"); USIActualAPI = new USIAPI(actualUSI); //USIIsKerbalTracked = new USIIsKerbalTrackedAPI(actualUSIIsKerbalTracked); @@ -148,19 +148,19 @@ internal USIAPI(Object a) //WORK OUT THE STUFF WE NEED TO HOOK FOR PEOPLE HERE //Methods - LogFormatted("Getting UntrackKerbal Method"); + LogFormatted_DebugOnly("Getting UntrackKerbal Method"); USIUntrackKerbalMethod = USILifeSupportMgrType.GetMethod("UntrackKerbal", BindingFlags.Public | BindingFlags.Instance); LogFormatted_DebugOnly("Success: " + (USIUntrackKerbalMethod != null)); - LogFormatted("Getting IsKerbalTracked Method"); + LogFormatted_DebugOnly("Getting IsKerbalTracked Method"); USIIsKerbalTrackedMethod = USILifeSupportMgrType.GetMethod("IsKerbalTracked", BindingFlags.Public | BindingFlags.Instance); LogFormatted_DebugOnly("Success: " + (USIIsKerbalTrackedMethod != null)); - LogFormatted("Getting UntrackVessel Method"); + LogFormatted_DebugOnly("Getting UntrackVessel Method"); USIUntrackVesselMethod = USILifeSupportMgrType.GetMethod("UntrackVessel", BindingFlags.Public | BindingFlags.Instance); LogFormatted_DebugOnly("Success: " + (USIUntrackVesselMethod != null)); - LogFormatted("Getting IsVesselTracked Method"); + LogFormatted_DebugOnly("Getting IsVesselTracked Method"); USIIsVesselTrackedTrackedMethod = USILifeSupportMgrType.GetMethod("IsVesselTracked", BindingFlags.Public | BindingFlags.Instance); LogFormatted_DebugOnly("Success: " + (USIIsVesselTrackedTrackedMethod != null)); } @@ -262,10 +262,10 @@ internal void UntrackVessel(string vesselId) /// /// Text to be printed - can be formatted as per String.format /// Objects to feed into a String.format - [Conditional("DEBUG")] internal static void LogFormatted_DebugOnly(String Message, params Object[] strParams) { - LogFormatted(Message, strParams); + if (RSTUtils.Utilities.debuggingOn) + LogFormatted(Message, strParams); } /// diff --git a/Source/DFAlarmInfo.cs b/Source/DFAlarmInfo.cs index 41bbeaa..4f90403 100644 --- a/Source/DFAlarmInfo.cs +++ b/Source/DFAlarmInfo.cs @@ -56,15 +56,23 @@ internal AlarmInfo(string Name, Guid vesselID) internal static AlarmInfo Load(ConfigNode node) { Guid vesselID = Utilities.GetNodeValue(node, "vesselID"); - string Name = Utilities.GetNodeValue(node, "Name", string.Empty); + string Name = ""; + node.TryGetValue("Name", ref Name); + AlarmInfo info = new AlarmInfo(Name, vesselID); + info.AlarmType = Utilities.GetNodeValue(node, "AlarmType", KACWrapper.KACAPI.AlarmTypeEnum.Raw); - info.Notes = Utilities.GetNodeValue(node, "Notes", string.Empty); - info.AlarmTime = Utilities.GetNodeValue(node, "AlarmTime", 0d); - info.AlarmMargin = Utilities.GetNodeValue(node, "AlarmMargin", 0d); - info.AlarmExecute = Utilities.GetNodeValue(node, "AlarmExecute", false); - string frzkbllst = Utilities.GetNodeValue(node, "FrzKerbals", string.Empty); - string thwkbllst = Utilities.GetNodeValue(node, "ThwKerbals", string.Empty); + node.TryGetValue("Notes", ref info.Notes); + node.TryGetValue("AlarmTime", ref info.AlarmTime); + node.TryGetValue("AlarmMargin", ref info.AlarmMargin); + node.TryGetValue("AlarmExecute", ref info.AlarmExecute); + + + string frzkbllst = ""; + node.TryGetValue("FrzKerbals", ref frzkbllst); + string thwkbllst = ""; + node.TryGetValue("ThwKerbals", ref thwkbllst); + string[] frzStrings = frzkbllst.Split(','); if (frzStrings.Length > 0) { diff --git a/Source/DFEditorFilter.cs b/Source/DFEditorFilter.cs index fde15ad..ce6ee3b 100644 --- a/Source/DFEditorFilter.cs +++ b/Source/DFEditorFilter.cs @@ -17,6 +17,7 @@ using System.Collections.Generic; using System.IO; +using KSP.UI.Screens; using RUI.Icons.Selectable; using UnityEngine; @@ -36,7 +37,7 @@ public class DFEditorFilter : MonoBehaviour //internal string iconName = "R&D_node_icon_evatech"; //create and the icons - private Texture2D icon_DeepFreeze_Editor = new Texture2D(32, 32); + private Texture2D icon_DeepFreeze_Editor = new Texture2D(32, 32, TextureFormat.ARGB32, false); internal string iconName = "DeepFreezeEditor"; internal bool filter = true; @@ -83,9 +84,9 @@ private void SubCategories() Icon filterDeepFreeze = new Icon("DeepFreezeEditor", icon_DeepFreeze_Editor, icon_DeepFreeze_Editor, true); PartCategorizer.Category Filter = PartCategorizer.Instance.filters.Find(f => f.button.categoryName == category); PartCategorizer.AddCustomSubcategoryFilter(Filter, subCategoryTitle, filterDeepFreeze, p => EditorItemsFilter(p)); - RUIToggleButtonTyped button = Filter.button.activeButton; - button.SetFalse(button, RUIToggleButtonTyped.ClickType.FORCED); - button.SetTrue(button, RUIToggleButtonTyped.ClickType.FORCED); + //RUIToggleButtonTyped button = Filter.button.activeButton; + //button.SetFalse(button, RUIToggleButtonTyped.ClickType.FORCED); + //button.SetTrue(button, RUIToggleButtonTyped.ClickType.FORCED); } } } \ No newline at end of file diff --git a/Source/DFGameSettings.cs b/Source/DFGameSettings.cs index 954b4a2..05387d2 100644 --- a/Source/DFGameSettings.cs +++ b/Source/DFGameSettings.cs @@ -57,7 +57,7 @@ internal void Load(ConfigNode node) if (node.HasNode(configNodeName)) { ConfigNode DFsettingsNode = node.GetNode(configNodeName); - Enabled = Utilities.GetNodeValue(DFsettingsNode, "Enabled", Enabled); + DFsettingsNode.TryGetValue("Enabled", ref Enabled); KnownFrozenKerbals.Clear(); var kerbalNodes = DFsettingsNode.GetNodes(KerbalInfo.ConfigNodeName); diff --git a/Source/DFInstalledMods.cs b/Source/DFInstalledMods.cs index 8911a2a..03de039 100644 --- a/Source/DFInstalledMods.cs +++ b/Source/DFInstalledMods.cs @@ -76,6 +76,14 @@ internal static bool IsRPMInstalled } } + internal static bool IsJSITransparentPodsInstalled + { + get + { + return IsModInstalled("JSIAdvTransparentPods"); + } + } + internal static bool IsBGPInstalled { get @@ -92,6 +100,14 @@ internal static bool IsTexReplacerInstalled } } + internal static bool IskerbalismInstalled + { + get + { + return IsModInstalled("Kerbalism"); + } + } + internal static bool IsModInstalled(string assemblyName) { try diff --git a/Source/DFIntMemory.cs b/Source/DFIntMemory.cs index 69d0f35..3834052 100644 --- a/Source/DFIntMemory.cs +++ b/Source/DFIntMemory.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Linq; +using KSP.UI.Screens; using PreFlightTests; using RSTUtils; using UnityEngine; @@ -29,6 +30,7 @@ internal class DFIntMemory : MonoBehaviour // The DeepFreeze Internal memory class. // this class maintains the information in the knownVessels, knownFreezerParts and knownKACalarms dictionaries. // It also Executes KAC Alarms when they occur and have DeepFreeze events to execute. + // and controls the Alternate DeepFreeze IVA cameras and Messages when in IVA. public static DFIntMemory Instance { get; private set; } public class VslFrzrCams @@ -108,22 +110,25 @@ private void Start() ChkActiveFrozenKerbals(); DeepFreeze.Instance.DFgameSettings.DmpKnownFznKerbals(); resetFreezerCams(); - if (DFInstalledMods.IsTexReplacerInstalled) + if (Utilities.GameModeisFlight) { - TRWrapper.InitTRWrapper(); - } - if (DFInstalledMods.IsUSILSInstalled) - { - USIWrapper.InitUSIWrapper(); + if (DFInstalledMods.IsTexReplacerInstalled) + { + TRWrapper.InitTRWrapper(); + } + if (DFInstalledMods.IsUSILSInstalled) + { + USIWrapper.InitUSIWrapper(); + } + if (DFInstalledMods.IsSMInstalled) + { + SMWrapper.InitSMWrapper(); + } } if (DFInstalledMods.IsRTInstalled) { RTWrapper.InitTRWrapper(); } - if (DFInstalledMods.IsSMInstalled) - { - SMWrapper.InitSMWrapper(); - } } private void OnDestroy() @@ -137,14 +142,14 @@ private void OnDestroy() GameEvents.onVesselLoaded.Remove(onVesselLoad); GameEvents.onVesselCreate.Remove(onVesselCreate); GameEvents.onPartCouple.Remove(onPartCouple); - GameEvents.onGUIEngineersReportReady.Remove(AddTests); + GameEvents.onGUIEngineersReportReady.Remove(AddTests); } private void Update() { //For some reason when we Freeze a Kerbal and switch to the Internal camera (if in IVA mode) the cameramanager gets stuck. //If the user hits the camera mode key while in Internal camera mode this will kick them out to flight - if (GameSettings.CAMERA_MODE.GetKeyDown() && Utilities.IsInInternal()) + if (GameSettings.CAMERA_MODE.GetKeyDown() && Utilities.IsInInternal) { CameraManager.Instance.SetCameraFlight(); } @@ -160,27 +165,49 @@ private void Update() if (HighLogic.LoadedSceneIsFlight && ActVslHasDpFrezr) { + /* Not required from KSP 1.1 as RefreskFrozenKerbals in each PartModule will remove the portraits for frozen kerbals. //Check if Refresh Portraits Cam is required after two vessels are docked if (refreshPortraits) { if (Planetarium.GetUniversalTime() - refreshPortraitsTimer > 3) { - Utilities.CheckPortraitCams(FlightGlobals.ActiveVessel); + foreach (Part part in FlightGlobals.ActiveVessel.parts) + { + if (part.internalModel != null) + { + foreach (InternalSeat seat in part.internalModel.seats) + { + if (seat.kerbalRef != null) + { + try + { + KerbalPortraitGallery.Instance.UnregisterActiveCrew(seat.kerbalRef); + if (!DeepFreeze.Instance.DFgameSettings.KnownFrozenKerbals.ContainsKey(seat.kerbalRef.crewMemberName)) + KerbalPortraitGallery.Instance.RegisterActiveCrew(seat.kerbalRef); + } + catch (Exception) + { + Utilities.Log_Debug("Unregister Portrait on inactive part failed {0}", seat.kerbalRef.crewMemberName); + } + } + } + } + } refreshPortraits = false; } - } + }*/ //If user hits Modifier Key - D switch to freezer cams. - if (GameSettings.MODIFIER_KEY.GetKey() && Input.GetKeyDown(keyFrzrCam) && ActFrzrCams.Count > 0) + if (GameSettings.MODIFIER_KEY.GetKey() && Input.GetKeyDown(keyFrzrCam) && ActFrzrCams.Count > 0 && !Utilities.StockOverlayCamIsOn) { Utilities.Log_Debug("User hit InternalCamera modifier keys lastFrzrCam=" + lastFrzrCam); - if (Utilities.IsInIVA()) + if (Utilities.IsInIVA) { Utilities.Log_Debug("Vessel is in IVA, looking for active kerbal"); Kerbal activeKerbal; foreach (DeepFreezer frzr in DpFrzrActVsl) { - activeKerbal = frzr.part.FindCurrentKerbal(); + activeKerbal = CameraManager.Instance.IVACameraActiveKerbal;// frzr.part.FindCurrentKerbal(); if (activeKerbal != null) { int CamIndex = -1; @@ -223,7 +250,7 @@ private void Update() } //If user hits n while we are in internal camera mode switch to the next freezer camera. - if (Input.GetKeyDown(keyNxtFrzrCam) && Utilities.IsInInternal()) + if (Input.GetKeyDown(keyNxtFrzrCam) && Utilities.IsInInternal) { Utilities.Log_Debug("User hit InternalCamera nextCamera key lastFrzrCam=" + lastFrzrCam); if ((lastFrzrCam == ActFrzrCams.Count - 1) || (lastFrzrCam > ActFrzrCams.Count)) @@ -259,7 +286,7 @@ private void Update() } //If user hits b while we are in internal camera mode switch to the previous freezer camera. - if (Input.GetKeyDown(keyPrvFrzrCam) && Utilities.IsInInternal()) + if (Input.GetKeyDown(keyPrvFrzrCam) && Utilities.IsInInternal) { Utilities.Log_Debug("User hit InternalCamera prevCamera key lastFrzrCam=" + lastFrzrCam); if (lastFrzrCam <= 0) @@ -293,28 +320,48 @@ private void Update() CameraManager.Instance.SetCameraFlight(); } } - ScreenMessages.RemoveMessage(IVAKerbalName); - ScreenMessages.RemoveMessage(IVAkerbalPart); - ScreenMessages.RemoveMessage(IVAkerbalPod); - if (Utilities.IsInInternal() && ActFrzrCams.Count > 0) + + if (IVAKerbalName != null) ScreenMessages.RemoveMessage(IVAKerbalName); + if (IVAkerbalPart != null) ScreenMessages.RemoveMessage(IVAkerbalPart); + if (IVAkerbalPod != null) ScreenMessages.RemoveMessage(IVAkerbalPod); + if (Utilities.IsInInternal && ActFrzrCams.Count > 0) { - // Set Bottom right messages for FreezerCam mode + // Set Top Left messages for FreezerCam mode // See if there is a kerbal seated/frozen in that seat get their reference - - IVAkerbalPod = ScreenMessages.PostScreenMessage("Pod:" + ActFrzrCams[lastFrzrCam].FrzrCamSeatIndex); - IVAkerbalPart = ScreenMessages.PostScreenMessage(ActFrzrCams[lastFrzrCam].FrzrCamPartName); + IVAkerbalPod = new ScreenMessage("Pod:" + ActFrzrCams[lastFrzrCam].FrzrCamSeatIndex, 1, ScreenMessageStyle.UPPER_LEFT); + IVAkerbalPod.color = Color.white; + ScreenMessages.PostScreenMessage(IVAkerbalPod); + IVAkerbalPart = new ScreenMessage(ActFrzrCams[lastFrzrCam].FrzrCamPartName, 1, ScreenMessageStyle.UPPER_LEFT); + IVAkerbalPart.color = Color.white; + ScreenMessages.PostScreenMessage(IVAkerbalPart); + string kerbalname; try { - kerbalname = ActFrzrCams[lastFrzrCam].FrzrCamPart.part.internalModel.seats[lastFrzrCam].kerbalRef.name; + Utilities.Log("FrzrCamPart InternalModelName {0}", ActFrzrCams[lastFrzrCam].FrzrCamPart.part.internalModel.internalName); + Utilities.Log("FrzrCamPart InternalSeatTransformName {0}", ActFrzrCams[lastFrzrCam].FrzrCamPart.part.internalModel.seats[lastFrzrCam].seatTransformName); + if (ActFrzrCams[lastFrzrCam].FrzrCamPart.part.internalModel.seats[lastFrzrCam].kerbalRef != null) + { + Utilities.Log("KerbalRef is not null"); + Utilities.Log("Seats Kerbalref {0}", ActFrzrCams[lastFrzrCam].FrzrCamPart.part.internalModel.seats[lastFrzrCam].kerbalRef.protoCrewMember.name); + Utilities.Log("Seats Kerbalref {0}", ActFrzrCams[lastFrzrCam].FrzrCamPart.part.internalModel.seats[lastFrzrCam].kerbalRef.crewMemberName); + } + else + { + Utilities.Log("Kerbalref is null"); + } + + kerbalname = ActFrzrCams[lastFrzrCam].FrzrCamPart.part.internalModel.seats[lastFrzrCam].kerbalRef.crewMemberName; } catch (Exception) { kerbalname = string.Empty; } - List activecrew = FlightGlobals.ActiveVessel.GetVesselCrew(); - IVAKerbalName = ScreenMessages.PostScreenMessage(kerbalname); + //List activecrew = FlightGlobals.ActiveVessel.GetVesselCrew(); + IVAKerbalName = new ScreenMessage(kerbalname, 1, ScreenMessageStyle.UPPER_LEFT); + IVAKerbalName.color = Color.white; + ScreenMessages.PostScreenMessage(IVAKerbalName); } } } @@ -577,8 +624,8 @@ internal void onPartCouple(GameEvents.FromToAction fromToAction) { frzr.resetFrozenKerbals(); } - refreshPortraits = true; - refreshPortraitsTimer = Planetarium.GetUniversalTime(); + //refreshPortraits = true; + //refreshPortraitsTimer = Planetarium.GetUniversalTime(); } } @@ -768,7 +815,7 @@ private void CheckVslUpdate() DpFrzrLoadedVsl = vessel.FindPartModulesImplementing(); foreach (DeepFreezer frzr in DpFrzrLoadedVsl) { - if (frzr.hasExternalDoor || frzr.isPodExternal) + if (frzr.ExternalDoorActive || frzr.isPodExternal) { Utilities.Log_Debug("chkvslupdate loaded freezer with door or external pod, reset the cryopods"); frzr.resetCryopods(false); @@ -846,7 +893,7 @@ private void UpdateVesselInfo(VesselInfo vesselInfo, Vessel vessel, double curre { Utilities.Log("New Freezer Part: " + frzr.name + "(" + frzr.part.flightID + ")" + " (" + vessel.id + ")"); partInfo = new PartInfo(vessel.id, frzr.name, currentTime); - partInfo.hasextDoor = frzr.hasExternalDoor; + partInfo.hasextDoor = frzr.ExternalDoorActive; partInfo.hasextPod = frzr.isPodExternal; partInfo.numSeats = frzr.FreezerSize; partInfo.timeLastElectricity = frzr.timeSinceLastECtaken; @@ -867,7 +914,7 @@ private void UpdateVesselInfo(VesselInfo vesselInfo, Vessel vessel, double curre } else // Update existing entry { - partInfo.hasextDoor = frzr.hasExternalDoor; + partInfo.hasextDoor = frzr.ExternalDoorActive; partInfo.hasextPod = frzr.isPodExternal; partInfo.numSeats = frzr.FreezerSize; partInfo.timeLastElectricity = frzr.timeSinceLastECtaken; @@ -887,7 +934,7 @@ private void UpdateVesselInfo(VesselInfo vesselInfo, Vessel vessel, double curre } } //now update the knownfreezerpart and any related vesselinfo field - if (frzr.hasExternalDoor) + if (frzr.ExternalDoorActive) vesselInfo.hasextDoor = true; if (frzr.isPodExternal) vesselInfo.hasextPod = true; diff --git a/Source/DFSettings.cs b/Source/DFSettings.cs index 90672c6..fc32dfe 100644 --- a/Source/DFSettings.cs +++ b/Source/DFSettings.cs @@ -24,39 +24,40 @@ internal class DFSettings // this class stores the DeepFreeze Settings from the config file. private const string configNodeName = "DFSettings"; - internal float DFwindowPosX { get; set; } - internal float DFwindowPosY { get; set; } - internal float CFwindowPosX { get; set; } - internal float CFwindowPosY { get; set; } - internal float DFKACwindowPosX { get; set; } - internal float DFKACwindowPosY { get; set; } - internal bool UseAppLauncher { get; set; } - internal bool debugging { get; set; } - internal bool ECreqdForFreezer { get; set; } - internal bool fatalOption { get; set; } - internal float comatoseTime { get; set; } - internal bool AutoRecoverFznKerbals { get; set; } - internal float KSCcostToThawKerbal { get; set; } - internal int ECReqdToFreezeThaw { get; set; } - internal int GlykerolReqdToFreeze { get; set; } - internal bool RegTempReqd { get; set; } - internal double RegTempFreeze { get; set; } - internal double RegTempMonitor { get; set; } - internal double heatamtMonitoringFrznKerbals { get; set; } - internal double heatamtThawFreezeKerbal { get; set; } - internal bool TempinKelvin { get; set; } - internal double defaultTimeoutforCrewXfer { get; set; } - internal double cryopodResettimeDelay { get; set; } - internal float DFWindowWidth { get; set; } - internal float CFWindowWidth { get; set; } - internal float KACWindowWidth { get; set; } - internal float WindowbaseHeight { get; set; } - internal float ECLowWarningTime { get; set; } - internal float EClowCriticalTime { get; set; } - internal bool StripLightsActive { get; set; } - internal int internalFrzrCamCode { get; set; } - internal int internalNxtFrzrCamCode { get; set; } - internal int internalPrvFrzrCamCode { get; set; } + internal float DFwindowPosX ; + internal float DFwindowPosY ; + internal float CFwindowPosX ; + internal float CFwindowPosY ; + internal float DFKACwindowPosX ; + internal float DFKACwindowPosY ; + internal bool UseAppLauncher ; + internal bool debugging ; + internal bool ECreqdForFreezer ; + internal bool fatalOption ; + internal float comatoseTime ; + internal bool AutoRecoverFznKerbals ; + internal float KSCcostToThawKerbal ; + internal int ECReqdToFreezeThaw ; + internal int GlykerolReqdToFreeze ; + internal bool RegTempReqd ; + internal double RegTempFreeze ; + internal double RegTempMonitor ; + internal double heatamtMonitoringFrznKerbals ; + internal double heatamtThawFreezeKerbal ; + internal bool TempinKelvin ; + internal double defaultTimeoutforCrewXfer ; + internal double cryopodResettimeDelay ; + internal float DFWindowWidth ; + internal float CFWindowWidth ; + internal float KACWindowWidth ; + internal float WindowbaseHeight ; + internal float ECLowWarningTime ; + internal float EClowCriticalTime ; + internal bool StripLightsActive ; + internal int internalFrzrCamCode ; + internal int internalNxtFrzrCamCode ; + internal int internalPrvFrzrCamCode ; + internal bool ToolTips ; internal DFSettings() { @@ -82,7 +83,7 @@ internal DFSettings() heatamtThawFreezeKerbal = 100f; TempinKelvin = true; defaultTimeoutforCrewXfer = 30; - cryopodResettimeDelay = 5; + cryopodResettimeDelay = 2; DFWindowWidth = 560f; CFWindowWidth = 340f; KACWindowWidth = 485f; @@ -92,6 +93,7 @@ internal DFSettings() internalFrzrCamCode = 100; internalNxtFrzrCamCode = 110; internalPrvFrzrCamCode = 98; + ToolTips = true; } //Settings Functions Follow @@ -102,38 +104,39 @@ internal void Load(ConfigNode node) { ConfigNode DFsettingsNode = node.GetNode(configNodeName); - DFwindowPosX = Utilities.GetNodeValue(DFsettingsNode, "DFwindowPosX", DFwindowPosX); - DFwindowPosY = Utilities.GetNodeValue(DFsettingsNode, "DFwindowPosY", DFwindowPosY); - CFwindowPosX = Utilities.GetNodeValue(DFsettingsNode, "CFwindowPosX", CFwindowPosX); - CFwindowPosY = Utilities.GetNodeValue(DFsettingsNode, "CFwindowPosY", CFwindowPosY); - DFKACwindowPosX = Utilities.GetNodeValue(DFsettingsNode, "DFKACwindowPosX", DFKACwindowPosX); - DFKACwindowPosY = Utilities.GetNodeValue(DFsettingsNode, "DFKACwindowPosY", DFKACwindowPosY); - ECreqdForFreezer = Utilities.GetNodeValue(DFsettingsNode, "ECreqdForFreezer", ECreqdForFreezer); - fatalOption = Utilities.GetNodeValue(DFsettingsNode, "fatalOption", fatalOption); - comatoseTime = Utilities.GetNodeValue(DFsettingsNode, "comatoseTime", comatoseTime); - UseAppLauncher = Utilities.GetNodeValue(DFsettingsNode, "UseAppLauncher", UseAppLauncher); - debugging = Utilities.GetNodeValue(DFsettingsNode, "debugging", debugging); - AutoRecoverFznKerbals = Utilities.GetNodeValue(DFsettingsNode, "AutoRecoverFznKerbals", AutoRecoverFznKerbals); - KSCcostToThawKerbal = Utilities.GetNodeValue(DFsettingsNode, "KSCcostToThawKerbal", KSCcostToThawKerbal); - ECReqdToFreezeThaw = Utilities.GetNodeValue(DFsettingsNode, "ECReqdToFreezeThaw", ECReqdToFreezeThaw); - GlykerolReqdToFreeze = Utilities.GetNodeValue(DFsettingsNode, "GlykerolReqdToFreeze", GlykerolReqdToFreeze); - RegTempReqd = Utilities.GetNodeValue(DFsettingsNode, "RegTempReqd", RegTempReqd); - RegTempFreeze = Utilities.GetNodeValue(DFsettingsNode, "RegTempFreeze", RegTempFreeze); - RegTempMonitor = Utilities.GetNodeValue(DFsettingsNode, "RegTempMonitor", RegTempMonitor); - heatamtMonitoringFrznKerbals = Utilities.GetNodeValue(DFsettingsNode, "heatamtMonitoringFrznKerbals", heatamtMonitoringFrznKerbals); - heatamtThawFreezeKerbal = Utilities.GetNodeValue(DFsettingsNode, "heatamtThawFreezeKerbal", heatamtThawFreezeKerbal); - TempinKelvin = Utilities.GetNodeValue(DFsettingsNode, "TempinKelvin", TempinKelvin); - defaultTimeoutforCrewXfer = Utilities.GetNodeValue(DFsettingsNode, "defaultTimeoutforCrewXfer", defaultTimeoutforCrewXfer); - cryopodResettimeDelay = Utilities.GetNodeValue(DFsettingsNode, "cryopodResettimeDelay", cryopodResettimeDelay); - DFWindowWidth = Utilities.GetNodeValue(DFsettingsNode, "DFWindowWidth", DFWindowWidth); - CFWindowWidth = Utilities.GetNodeValue(DFsettingsNode, "CFWindowWidth", CFWindowWidth); - KACWindowWidth = Utilities.GetNodeValue(DFsettingsNode, "KACWindowWidth", KACWindowWidth); - ECLowWarningTime = Utilities.GetNodeValue(DFsettingsNode, "ECLowWarningTime", ECLowWarningTime); - EClowCriticalTime = Utilities.GetNodeValue(DFsettingsNode, "EClowCriticalTime", EClowCriticalTime); - StripLightsActive = Utilities.GetNodeValue(DFsettingsNode, "StripLightsActive", StripLightsActive); - internalFrzrCamCode = Utilities.GetNodeValue(DFsettingsNode, "internalFrzrCamCode", internalFrzrCamCode); - internalNxtFrzrCamCode = Utilities.GetNodeValue(DFsettingsNode, "internalNxtFrzrCamCode", internalNxtFrzrCamCode); - internalPrvFrzrCamCode = Utilities.GetNodeValue(DFsettingsNode, "internalPrvFrzrCamCode", internalPrvFrzrCamCode); + DFsettingsNode.TryGetValue("DFwindowPosX", ref DFwindowPosX); + DFsettingsNode.TryGetValue("DFwindowPosY", ref DFwindowPosY); + DFsettingsNode.TryGetValue("CFwindowPosX", ref CFwindowPosX); + DFsettingsNode.TryGetValue("CFwindowPosY", ref CFwindowPosY); + DFsettingsNode.TryGetValue("DFKACwindowPosX", ref DFKACwindowPosX); + DFsettingsNode.TryGetValue("DFKACwindowPosY", ref DFKACwindowPosY); + DFsettingsNode.TryGetValue("ECreqdForFreezer", ref ECreqdForFreezer); + DFsettingsNode.TryGetValue("fatalOption", ref fatalOption); + DFsettingsNode.TryGetValue("comatoseTime", ref comatoseTime); + DFsettingsNode.TryGetValue("UseAppLauncher", ref UseAppLauncher); + DFsettingsNode.TryGetValue("debugging", ref debugging); + DFsettingsNode.TryGetValue("ToolTips", ref ToolTips); + DFsettingsNode.TryGetValue("AutoRecoverFznKerbals", ref AutoRecoverFznKerbals); + DFsettingsNode.TryGetValue("KSCcostToThawKerbal", ref KSCcostToThawKerbal); + DFsettingsNode.TryGetValue("ECReqdToFreezeThaw", ref ECReqdToFreezeThaw); + DFsettingsNode.TryGetValue("GlykerolReqdToFreeze", ref GlykerolReqdToFreeze); + DFsettingsNode.TryGetValue("RegTempReqd", ref RegTempReqd); + DFsettingsNode.TryGetValue("RegTempFreeze", ref RegTempFreeze); + DFsettingsNode.TryGetValue("RegTempMonitor", ref RegTempMonitor); + DFsettingsNode.TryGetValue("heatamtMonitoringFrznKerbals", ref heatamtMonitoringFrznKerbals); + DFsettingsNode.TryGetValue("heatamtThawFreezeKerbal", ref heatamtThawFreezeKerbal); + DFsettingsNode.TryGetValue("TempinKelvin", ref TempinKelvin); + DFsettingsNode.TryGetValue("defaultTimeoutforCrewXfer", ref defaultTimeoutforCrewXfer); + DFsettingsNode.TryGetValue("cryopodResettimeDelay", ref cryopodResettimeDelay); + DFsettingsNode.TryGetValue("DFWindowWidth", ref DFWindowWidth); + DFsettingsNode.TryGetValue("CFWindowWidth", ref CFWindowWidth); + DFsettingsNode.TryGetValue("KACWindowWidth", ref KACWindowWidth); + DFsettingsNode.TryGetValue("ECLowWarningTime", ref ECLowWarningTime); + DFsettingsNode.TryGetValue("EClowCriticalTime", ref EClowCriticalTime); + DFsettingsNode.TryGetValue("StripLightsActive", ref StripLightsActive); + DFsettingsNode.TryGetValue("internalFrzrCamCode", ref internalFrzrCamCode); + DFsettingsNode.TryGetValue("internalNxtFrzrCamCode", ref internalNxtFrzrCamCode); + DFsettingsNode.TryGetValue("internalPrvFrzrCamCode", ref internalPrvFrzrCamCode); Utilities.Log_Debug("DFSettings load complete"); } } @@ -162,6 +165,7 @@ internal void Save(ConfigNode node) settingsNode.AddValue("comatoseTime", comatoseTime); settingsNode.AddValue("UseAppLauncher", UseAppLauncher); settingsNode.AddValue("debugging", debugging); + settingsNode.AddValue("ToolTips", ToolTips); settingsNode.AddValue("AutoRecoverFznKerbals", AutoRecoverFznKerbals); settingsNode.AddValue("KSCcostToThawKerbal", KSCcostToThawKerbal); settingsNode.AddValue("ECReqdToFreezeThaw", ECReqdToFreezeThaw); diff --git a/Source/DeepFreeze.cs b/Source/DeepFreeze.cs index 63834c5..5d211e6 100644 --- a/Source/DeepFreeze.cs +++ b/Source/DeepFreeze.cs @@ -116,7 +116,12 @@ public override void OnLoad(ConfigNode gameNode) } Utilities.debuggingOn = DFsettings.debugging; APIReady = true; - Debug.Log("Scenario: " + HighLogic.LoadedScene + " OnLoad: \n " + gameNode + "\n" + globalNode); + if (Utilities.debuggingOn) + Debug.Log("Scenario: " + HighLogic.LoadedScene + " OnLoad: \n " + gameNode + "\n" + globalNode); + else + { + Debug.Log("DeepFreeze Scenario Onload Completed."); + } } public override void OnSave(ConfigNode gameNode) @@ -130,7 +135,12 @@ public override void OnSave(ConfigNode gameNode) } DFsettings.Save(globalNode); globalNode.Save(globalConfigFilename); - Debug.Log("Scenario: " + HighLogic.LoadedScene + " OnSave: \n" + gameNode + "\n" + globalNode); + if (Utilities.debuggingOn) + Debug.Log("Scenario: " + HighLogic.LoadedScene + " OnSave: \n" + gameNode + "\n" + globalNode); + else + { + Debug.Log("DeepFreeze Scenario OnSave completed."); + } } protected void OnGameSceneLoadRequested(GameScenes gameScene) @@ -173,7 +183,7 @@ protected void DeepFreezeEventRem() Utilities.Log("DeepFreezeEvents DeepFreezeEventRem ended"); } - protected void onVesselRecovered(ProtoVessel vessel) + protected void onVesselRecovered(ProtoVessel vessel, bool notSureWhatFor) { Utilities.Log("DeepFreezeEvents onVesselRecovered " + vessel.vesselID); List frznKerbalkeys = new List(DFgameSettings.KnownFrozenKerbals.Keys); @@ -200,7 +210,7 @@ protected void onVesselRecovered(ProtoVessel vessel) realkerbal.type = ProtoCrewMember.KerbalType.Unowned; realkerbal.rosterStatus = ProtoCrewMember.RosterStatus.Dead; Utilities.Log_Debug("Kerbal " + realkerbal.name + " " + realkerbal.type + " " + realkerbal.rosterStatus); - ScreenMessages.PostScreenMessage(key + " was stored frozen at KSC", 5.0f, ScreenMessageStyle.UPPER_RIGHT); + ScreenMessages.PostScreenMessage(key + " was stored frozen at KSC", 5.0f, ScreenMessageStyle.UPPER_LEFT); } } } @@ -301,7 +311,7 @@ internal void ThawFrozenCrew(String FrozenCrew, Guid vesselID) else { Utilities.Log("Not enough funds to thaw kerbal"); - ScreenMessages.PostScreenMessage("Insufficient funds to thaw " + kerbal.name + " at this time", 5.0f, ScreenMessageStyle.UPPER_RIGHT); + ScreenMessages.PostScreenMessage("Insufficient funds to thaw " + kerbal.name + " at this time", 5.0f, ScreenMessageStyle.UPPER_LEFT); return; } } @@ -313,7 +323,7 @@ internal void ThawFrozenCrew(String FrozenCrew, Guid vesselID) Utilities.Log_Debug("Kerbal " + kerbal.name + " " + kerbal.type + " " + kerbal.rosterStatus); if (!fundstaken) { - ScreenMessages.PostScreenMessage(kerbal.name + " was found and thawed out", 5.0f, ScreenMessageStyle.UPPER_RIGHT); + ScreenMessages.PostScreenMessage(kerbal.name + " was found and thawed out", 5.0f, ScreenMessageStyle.UPPER_LEFT); } else { diff --git a/Source/DeepFreeze.csproj b/Source/DeepFreeze.csproj index 7d3bada..216706f 100644 --- a/Source/DeepFreeze.csproj +++ b/Source/DeepFreeze.csproj @@ -34,7 +34,20 @@ False - ..\..\Assembly-CSharp.dll + ..\..\KSPDLLs\Assembly-CSharp.dll + + + False + ..\..\KSPDLLs\Assembly-CSharp-firstpass.dll + + + ..\..\KSPDLLs\Assembly-UnityScript.dll + + + ..\..\KSPDLLs\Assembly-UnityScript-firstpass.dll + + + ..\..\KSPDLLs\KSPUtil.dll @@ -44,13 +57,18 @@ False - ..\..\UnityEngine.dll + ..\..\KSPDLLs\UnityEngine.dll + + + False + ..\..\KSPDLLs\UnityEngine.UI.dll RSTutilities.cs + @@ -65,6 +83,7 @@ + @@ -129,6 +148,7 @@ + diff --git a/Source/DeepFreezeGUI.cs b/Source/DeepFreezeGUI.cs index e02e0e4..804f1e7 100644 --- a/Source/DeepFreezeGUI.cs +++ b/Source/DeepFreezeGUI.cs @@ -22,6 +22,7 @@ using RSTUtils; using UnityEngine; using Random = System.Random; +using KSP.UI.Screens; namespace DF { @@ -47,8 +48,8 @@ internal class DeepFreezeGUI : MonoBehaviour, Savable private static int KACwindowID = 2000001; private static int VSwindowID = 2000002; private static int VSFwindowID = 2000003; - private GUIStyle statusStyle, frozenStyle, comaStyle, sectionTitleStyle, resizeStyle, StatusOKStyle, StatusWarnStyle, StatusRedStyle, StatusGrayStyle, ButtonStyle; - private Vector2 GUIscrollViewVector, GUIscrollViewVector2, GUIscrollViewVectorKAC, GUIscrollViewVectorKACKerbals = Vector2.zero; + private Vector2 GUIscrollViewVector, GUIscrollViewVector2, GUIscrollViewVectorSettings, + GUIscrollViewVectorKAC, GUIscrollViewVectorKACKerbals = Vector2.zero; private bool mouseDownDF; private bool mouseDownKAC; private float DFtxtWdthName; @@ -83,6 +84,7 @@ internal class DeepFreezeGUI : MonoBehaviour, Savable private bool InputVautoRecover; private bool InputVdebug; + private bool InputVToolTips; private bool InputVECReqd; private bool InputAppL = true; private string InputScostThawKerbal = ""; @@ -110,6 +112,7 @@ internal class DeepFreezeGUI : MonoBehaviour, Savable private bool ECreqdForFreezer; private bool debugging; + private bool ToolTips; private bool AutoRecoverFznKerbals; private float KSCcostToThawKerbal; private int ECReqdToFreezeThaw; @@ -144,14 +147,6 @@ public Boolean GuiVisible set { _Visible = value; //Set the private variable - if (_Visible) - { - RenderingManager.AddToPostDrawQueue(3, onDraw); - } - else - { - RenderingManager.RemoveFromPostDrawQueue(3, onDraw); - } } } @@ -186,7 +181,8 @@ private void DummyVoid() private void onAppLaunchToggle() { GuiVisible = !GuiVisible; - stockToolbarButton.SetTexture(GameDatabase.Instance.GetTexture(GuiVisible ? "REPOSoftTech/DeepFreeze/Icons/DeepFreezeOn" : "REPOSoftTech/DeepFreeze/Icons/DeepFreezeOff", false)); + if (stockToolbarButton != null) + stockToolbarButton.SetTexture(GameDatabase.Instance.GetTexture(GuiVisible ? "REPOSoftTech/DeepFreeze/Icons/DeepFreezeOn" : "REPOSoftTech/DeepFreeze/Icons/DeepFreezeOff", false)); } #endregion AppLauncher @@ -195,7 +191,8 @@ internal void OnDestroy() { if (ToolbarManager.ToolbarAvailable && Useapplauncher == false) { - button1.Destroy(); + if (button1 != null) + button1.Destroy(); } else { @@ -301,8 +298,13 @@ private void FixedUpdate() #region GUI - private void onDraw() + private void OnGUI() { + if (!GuiVisible) return; + + if (!Textures.StylesSet) + Textures.SetupStyles(); + if (showSwitchVessel) { if (!Utilities.WindowVisibile(DFVSwindowPos)) @@ -343,6 +345,7 @@ private void onDraw() InputAppL = Useapplauncher; InputVECReqd = ECreqdForFreezer; InputVdebug = debugging; + InputVToolTips = ToolTips; InputVautoRecover = AutoRecoverFznKerbals; InputScostThawKerbal = KSCcostToThawKerbal.ToString(); InputSecReqdToFreezeThaw = ECReqdToFreezeThaw.ToString(); @@ -362,7 +365,7 @@ private void onDraw() if (!Utilities.WindowVisibile(CFwindowPos)) Utilities.MakeWindowVisible(CFwindowPos); CFwindowPos = GUILayout.Window(CFwindowID, CFwindowPos, windowCF, "DeepFreeze Settings", GUILayout.ExpandWidth(false), - GUILayout.ExpandHeight(true), GUILayout.Width(320), GUILayout.MinHeight(100)); + GUILayout.ExpandHeight(true), GUILayout.Width(550), GUILayout.Height(500)); } if (showKACGUI) { @@ -372,59 +375,16 @@ private void onDraw() GUILayout.ExpandHeight(true), GUILayout.MinWidth(360), GUILayout.MinHeight(150)); } } + + if (DeepFreeze.Instance.DFsettings.ToolTips) + Utilities.DrawToolTip(); } private void windowDF(int id) { - //Init styles - sectionTitleStyle = new GUIStyle(GUI.skin.label); - sectionTitleStyle.alignment = TextAnchor.MiddleLeft; - sectionTitleStyle.stretchWidth = true; - sectionTitleStyle.normal.textColor = Color.blue; - sectionTitleStyle.fontStyle = FontStyle.Bold; - - statusStyle = new GUIStyle(GUI.skin.label); - statusStyle.alignment = TextAnchor.MiddleLeft; - statusStyle.stretchWidth = true; - statusStyle.normal.textColor = Color.white; - - frozenStyle = new GUIStyle(GUI.skin.label); - frozenStyle.alignment = TextAnchor.MiddleLeft; - frozenStyle.stretchWidth = true; - frozenStyle.normal.textColor = Color.cyan; - - comaStyle = new GUIStyle(GUI.skin.label); - comaStyle.alignment = TextAnchor.MiddleLeft; - comaStyle.stretchWidth = true; - comaStyle.normal.textColor = Color.gray; - - StatusOKStyle = new GUIStyle(GUI.skin.label); - StatusOKStyle.alignment = TextAnchor.MiddleLeft; - StatusOKStyle.stretchWidth = true; - StatusOKStyle.normal.textColor = Color.green; - - StatusWarnStyle = new GUIStyle(GUI.skin.label); - StatusWarnStyle.alignment = TextAnchor.MiddleLeft; - StatusWarnStyle.stretchWidth = true; - StatusWarnStyle.normal.textColor = Color.yellow; - - StatusRedStyle = new GUIStyle(GUI.skin.label); - StatusRedStyle.alignment = TextAnchor.MiddleLeft; - StatusRedStyle.stretchWidth = true; - StatusRedStyle.normal.textColor = Color.red; - - StatusGrayStyle = new GUIStyle(GUI.skin.label); - StatusGrayStyle.alignment = TextAnchor.MiddleLeft; - StatusGrayStyle.stretchWidth = true; - StatusGrayStyle.normal.textColor = Color.gray; - - resizeStyle = new GUIStyle(GUI.skin.button); - resizeStyle.alignment = TextAnchor.MiddleCenter; - resizeStyle.padding = new RectOffset(1, 1, 1, 1); - - GUIContent closeContent = new GUIContent("X", "Close Window"); - Rect closeRect = new Rect(DFwindowPos.width - 17, 4, 16, 16); - if (GUI.Button(closeRect, closeContent)) + GUIContent closeContent = new GUIContent(Textures.BtnRedCross, "Close Window"); + Rect closeRect = new Rect(DFwindowPos.width - 21, 4, 16, 16); + if (GUI.Button(closeRect, closeContent, Textures.ClosebtnStyle)) { onAppLaunchToggle(); return; @@ -433,28 +393,28 @@ private void windowDF(int id) GUIscrollViewVector2 = GUILayout.BeginScrollView(GUIscrollViewVector2, false, false, GUILayout.MaxHeight(140f)); GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); - GUILayout.Label("Vessel", sectionTitleStyle, GUILayout.Width(DFvslWdthName)); - GUILayout.Label("Part", sectionTitleStyle, GUILayout.Width(DFvslPrtName)); - GUILayout.Label("Tmp", sectionTitleStyle, GUILayout.Width(DFvslPrtTmp)); - GUILayout.Label("EC", sectionTitleStyle, GUILayout.Width(DFvslPrtElec)); + GUILayout.Label(new GUIContent("Vessel","Vessel Name"), Textures.sectionTitleLeftStyle, GUILayout.Width(DFvslWdthName)); + GUILayout.Label(new GUIContent("Part", "Part Name"), Textures.sectionTitleLeftStyle, GUILayout.Width(DFvslPrtName)); + GUILayout.Label(new GUIContent("Tmp", "Part Temperature Status"), Textures.sectionTitleLeftStyle, GUILayout.Width(DFvslPrtTmp)); + GUILayout.Label(new GUIContent("EC", "Electric Charge Status"), Textures.sectionTitleLeftStyle, GUILayout.Width(DFvslPrtElec)); if (DFInstalledMods.IsRTInstalled) - GUILayout.Label("R.T", sectionTitleStyle, GUILayout.Width(DFvslRT)); - GUILayout.Label("Alarms", sectionTitleStyle, GUILayout.Width(DFvslAlarms)); - GUILayout.Label("LastUpd", sectionTitleStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(new GUIContent("R.T", "Remote Tech Status"), Textures.sectionTitleLeftStyle, GUILayout.Width(DFvslRT)); + GUILayout.Label(new GUIContent("Alarms", "Press the button for Kerbal Alarm Clock Alarms assigned to this part"), Textures.sectionTitleLeftStyle, GUILayout.Width(DFvslAlarms)); + GUILayout.Label(new GUIContent("LastUpd", "The Time the part was last updated"), Textures.sectionTitleLeftStyle, GUILayout.Width(DFvslLstUpd)); if (DeepFreeze.Instance.DFsettings.ECreqdForFreezer) - GUILayout.Label("TimeRem", sectionTitleStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(new GUIContent("TimeRem", "Approx. time remaining before Electric Charge will run out"), Textures.sectionTitleLeftStyle, GUILayout.Width(DFvslLstUpd)); GUILayout.EndHorizontal(); foreach (KeyValuePair frzr in DeepFreeze.Instance.DFgameSettings.knownFreezerParts) { GUILayout.BeginHorizontal(); VesselInfo vsl = DeepFreeze.Instance.DFgameSettings.knownVessels[frzr.Value.vesselID]; - GUILayout.Label(vsl.vesselName, statusStyle, GUILayout.Width(DFvslWdthName)); + GUILayout.Label(vsl.vesselName, Textures.statusStyle, GUILayout.Width(DFvslWdthName)); string partname = string.Empty; if (frzr.Value.PartName.Substring(8, 1) == "R") partname = frzr.Value.PartName.Substring(0, 9); else partname = frzr.Value.PartName.Substring(0, 8); - GUILayout.Label(partname, statusStyle, GUILayout.Width(DFvslPrtName)); + GUILayout.Label(partname, Textures.statusStyle, GUILayout.Width(DFvslPrtName)); string TempVar; if (DeepFreeze.Instance.DFsettings.TempinKelvin) { @@ -471,17 +431,17 @@ private void windowDF(int id) { case FrzrTmpStatus.OK: { - GUILayout.Label(TempVar, StatusOKStyle, GUILayout.Width(DFvslPrtTmp)); + GUILayout.Label(TempVar, Textures.StatusOKStyle, GUILayout.Width(DFvslPrtTmp)); break; } case FrzrTmpStatus.WARN: { - GUILayout.Label(TempVar, StatusWarnStyle, GUILayout.Width(DFvslPrtTmp)); + GUILayout.Label(TempVar, Textures.StatusWarnStyle, GUILayout.Width(DFvslPrtTmp)); break; } case FrzrTmpStatus.RED: { - GUILayout.Label(TempVar, StatusRedStyle, GUILayout.Width(DFvslPrtTmp)); + GUILayout.Label(TempVar, Textures.StatusRedStyle, GUILayout.Width(DFvslPrtTmp)); switchVessel = FlightGlobals.Vessels.Find(a => a.id == frzr.Value.vesselID); showSwitchVesselStr = "Vessel " + switchVessel.vesselName + " is Over-Heating."; if (HighLogic.LoadedSceneIsFlight) @@ -497,20 +457,20 @@ private void windowDF(int id) } else { - GUILayout.Label("OFF", StatusGrayStyle, GUILayout.Width(DFvslPrtTmp)); + GUILayout.Label("OFF", Textures.StatusGrayStyle, GUILayout.Width(DFvslPrtTmp)); } if (DeepFreeze.Instance.DFsettings.ECreqdForFreezer && !chgECHeatsettings) { if (frzr.Value.numFrznCrew == 0) { - GUILayout.Label("S/BY", StatusOKStyle, GUILayout.Width(DFvslPrtElec)); + GUILayout.Label("S/BY", Textures.StatusOKStyle, GUILayout.Width(DFvslPrtElec)); } else { if (frzr.Value.outofEC) { - GUILayout.Label("OUT", StatusRedStyle, GUILayout.Width(DFvslPrtElec)); + GUILayout.Label("OUT", Textures.StatusRedStyle, GUILayout.Width(DFvslPrtElec)); switchVessel = FlightGlobals.Vessels.Find(a => a.id == frzr.Value.vesselID); showSwitchVesselStr = "Vessel " + switchVessel.vesselName + " is out of ElectricCharge.\n Situation Critical."; if (HighLogic.LoadedSceneIsFlight) @@ -525,7 +485,7 @@ private void windowDF(int id) { if (vsl.predictedECOut < DeepFreeze.Instance.DFsettings.EClowCriticalTime) { - GUILayout.Label("ALRT", StatusRedStyle, GUILayout.Width(DFvslPrtElec)); + GUILayout.Label("ALRT", Textures.StatusRedStyle, GUILayout.Width(DFvslPrtElec)); switchVessel = FlightGlobals.Vessels.Find(a => a.id == frzr.Value.vesselID); showSwitchVesselStr = "Vessel " + switchVessel.vesselName + " is almost out of ElectricCharge."; if (HighLogic.LoadedSceneIsFlight) @@ -541,11 +501,11 @@ private void windowDF(int id) if (vsl.predictedECOut < DeepFreeze.Instance.DFsettings.ECLowWarningTime) // ONE HOUR OF EC WARNING { // Utilities.Log_Debug("Remaining EC time " + vsl.predictedECOut); - GUILayout.Label("LOW", StatusWarnStyle, GUILayout.Width(DFvslPrtElec)); + GUILayout.Label("LOW", Textures.StatusWarnStyle, GUILayout.Width(DFvslPrtElec)); } else { - GUILayout.Label("OK", StatusOKStyle, GUILayout.Width(DFvslPrtElec)); + GUILayout.Label("OK", Textures.StatusOKStyle, GUILayout.Width(DFvslPrtElec)); } } } @@ -553,18 +513,18 @@ private void windowDF(int id) } else { - GUILayout.Label("OFF", StatusGrayStyle, GUILayout.Width(DFvslPrtElec)); + GUILayout.Label("OFF", Textures.StatusGrayStyle, GUILayout.Width(DFvslPrtElec)); } if (DFInstalledMods.IsRTInstalled) { if (DFInstalledMods.RTVesselConnected(frzr.Value.vesselID)) { - GUILayout.Label("OK", StatusOKStyle, GUILayout.Width(DFvslRT)); + GUILayout.Label("OK", Textures.StatusOKStyle, GUILayout.Width(DFvslRT)); } else { - GUILayout.Label("NC", StatusRedStyle, GUILayout.Width(DFvslRT)); + GUILayout.Label("NC", Textures.StatusRedStyle, GUILayout.Width(DFvslRT)); } } @@ -580,14 +540,14 @@ private void windowDF(int id) } else { - GUILayout.Label(" ", StatusGrayStyle, GUILayout.Width(DFvslAlarms)); + GUILayout.Label(" ", Textures.StatusGrayStyle, GUILayout.Width(DFvslAlarms)); } if (HighLogic.LoadedSceneIsFlight) { if (frzr.Value.vesselID == FlightGlobals.ActiveVessel.id) { - GUILayout.Label(" ", StatusOKStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(" ", Textures.StatusOKStyle, GUILayout.Width(DFvslLstUpd)); } else { @@ -595,23 +555,23 @@ private void windowDF(int id) { if (vsl.predictedECOut < DeepFreeze.Instance.DFsettings.EClowCriticalTime) { - GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), StatusRedStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), Textures.StatusRedStyle, GUILayout.Width(DFvslLstUpd)); } else { if (vsl.predictedECOut < DeepFreeze.Instance.DFsettings.ECLowWarningTime) { - GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), StatusWarnStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), Textures.StatusWarnStyle, GUILayout.Width(DFvslLstUpd)); } else { - GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), StatusOKStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), Textures.StatusOKStyle, GUILayout.Width(DFvslLstUpd)); } } } else { - GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), StatusGrayStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), Textures.StatusGrayStyle, GUILayout.Width(DFvslLstUpd)); } } } @@ -621,23 +581,23 @@ private void windowDF(int id) { if (vsl.predictedECOut < DeepFreeze.Instance.DFsettings.EClowCriticalTime) { - GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), StatusRedStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), Textures.StatusRedStyle, GUILayout.Width(DFvslLstUpd)); } else { if (vsl.predictedECOut < DeepFreeze.Instance.DFsettings.ECLowWarningTime) { - GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), StatusWarnStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), Textures.StatusWarnStyle, GUILayout.Width(DFvslLstUpd)); } else { - GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), StatusOKStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), Textures.StatusOKStyle, GUILayout.Width(DFvslLstUpd)); } } } else { - GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), StatusGrayStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(Utilities.FormatDateString(Planetarium.GetUniversalTime() - frzr.Value.timeLastElectricity), Textures.StatusGrayStyle, GUILayout.Width(DFvslLstUpd)); } } @@ -645,17 +605,17 @@ private void windowDF(int id) { if (vsl.predictedECOut < DeepFreeze.Instance.DFsettings.EClowCriticalTime) { - GUILayout.Label(Utilities.FormatDateString(vsl.predictedECOut), StatusRedStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(Utilities.FormatDateString(vsl.predictedECOut), Textures.StatusRedStyle, GUILayout.Width(DFvslLstUpd)); } else { if (vsl.predictedECOut < DeepFreeze.Instance.DFsettings.ECLowWarningTime) { - GUILayout.Label(Utilities.FormatDateString(vsl.predictedECOut), StatusWarnStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(Utilities.FormatDateString(vsl.predictedECOut), Textures.StatusWarnStyle, GUILayout.Width(DFvslLstUpd)); } else { - GUILayout.Label(Utilities.FormatDateString(vsl.predictedECOut), StatusOKStyle, GUILayout.Width(DFvslLstUpd)); + GUILayout.Label(Utilities.FormatDateString(vsl.predictedECOut), Textures.StatusOKStyle, GUILayout.Width(DFvslLstUpd)); } } } @@ -672,22 +632,22 @@ private void windowDF(int id) if (DeepFreeze.Instance.DFgameSettings.KnownFrozenKerbals.Count == 0) { GUILayout.BeginHorizontal(); - GUILayout.Label("There are currently no Frozen Kerbals", frozenStyle); + GUILayout.Label("There are currently no Frozen Kerbals", Textures.frozenStyle); GUILayout.EndHorizontal(); } else { Headers = true; GUILayout.BeginHorizontal(); - GUILayout.Label("Kerbal Name", sectionTitleStyle, GUILayout.Width(DFtxtWdthName)); - GUILayout.Label("Profession", sectionTitleStyle, GUILayout.Width(DFtxtWdthProf)); - GUILayout.Label("Vessel Name", sectionTitleStyle, GUILayout.Width(DFtxtWdthVslN)); + GUILayout.Label("Kerbal Name", Textures.sectionTitleLeftStyle, GUILayout.Width(DFtxtWdthName)); + GUILayout.Label("Profession", Textures.sectionTitleLeftStyle, GUILayout.Width(DFtxtWdthProf)); + GUILayout.Label("Vessel Name", Textures.sectionTitleLeftStyle, GUILayout.Width(DFtxtWdthVslN)); GUILayout.EndHorizontal(); List> ThawKeysToDelete = new List>(); foreach (KeyValuePair kerbal in DeepFreeze.Instance.DFgameSettings.KnownFrozenKerbals) { GUILayout.BeginHorizontal(); - GUIStyle dispstyle = kerbal.Value.type != ProtoCrewMember.KerbalType.Tourist ? frozenStyle : comaStyle; + GUIStyle dispstyle = kerbal.Value.type != ProtoCrewMember.KerbalType.Tourist ? Textures.frozenStyle : Textures.comaStyle; GUILayout.Label(kerbal.Key, dispstyle, GUILayout.Width(DFtxtWdthName)); GUILayout.Label(kerbal.Value.experienceTraitName, dispstyle, GUILayout.Width(DFtxtWdthProf)); GUILayout.Label(kerbal.Value.vesselName, dispstyle, GUILayout.Width(DFtxtWdthVslN)); @@ -747,9 +707,9 @@ private void windowDF(int id) if (!Headers) { GUILayout.BeginHorizontal(); - GUILayout.Label("Kerbal Name", sectionTitleStyle, GUILayout.Width(DFtxtWdthName)); - GUILayout.Label("Profession", sectionTitleStyle, GUILayout.Width(DFtxtWdthProf)); - GUILayout.Label("Vessel Name", sectionTitleStyle, GUILayout.Width(DFtxtWdthVslN)); + GUILayout.Label("Kerbal Name", Textures.sectionTitleLeftStyle, GUILayout.Width(DFtxtWdthName)); + GUILayout.Label("Profession", Textures.sectionTitleLeftStyle, GUILayout.Width(DFtxtWdthProf)); + GUILayout.Label("Vessel Name", Textures.sectionTitleLeftStyle, GUILayout.Width(DFtxtWdthVslN)); GUILayout.EndHorizontal(); Headers = true; } @@ -758,9 +718,9 @@ private void windowDF(int id) foreach (ProtoCrewMember crewMember in frzr.part.protoModuleCrew.FindAll(a => a.type == ProtoCrewMember.KerbalType.Crew)) { GUILayout.BeginHorizontal(); - GUILayout.Label(crewMember.name, statusStyle, GUILayout.Width(DFtxtWdthName)); - GUILayout.Label(crewMember.experienceTrait.Title, statusStyle, GUILayout.Width(DFtxtWdthProf)); - GUILayout.Label(frzr.part.vessel.vesselName, statusStyle, GUILayout.Width(DFtxtWdthVslN)); + GUILayout.Label(crewMember.name, Textures.statusStyle, GUILayout.Width(DFtxtWdthName)); + GUILayout.Label(crewMember.experienceTrait.Title, Textures.statusStyle, GUILayout.Width(DFtxtWdthProf)); + GUILayout.Label(frzr.part.vessel.vesselName, Textures.statusStyle, GUILayout.Width(DFtxtWdthVslN)); if (crewMember.type != ProtoCrewMember.KerbalType.Tourist) { if (frzr.DFIcrewXferFROMActive || frzr.DFIcrewXferTOActive || (DFInstalledMods.IsSMInstalled && frzr.IsSMXferRunning()) @@ -781,11 +741,11 @@ private void windowDF(int id) GUILayout.EndScrollView(); GUILayout.EndVertical(); - GUILayout.Space(14); + GUILayout.Space(24); if (KACWrapper.AssemblyExists && KACWrapper.InstanceExists && KACWrapper.APIReady) { GUIContent AlarmsContent = new GUIContent("Alarms", "KAC Alarms"); - Rect AlarmsRect = new Rect(DFwindowPos.width - 90, DFwindowPos.height - 17, 70, 16); + Rect AlarmsRect = new Rect(DFwindowPos.width - 95, DFwindowPos.height - 22, 70, 20); if (GUI.Button(AlarmsRect, AlarmsContent)) { showKACGUI = !showKACGUI; @@ -795,37 +755,30 @@ private void windowDF(int id) if (HighLogic.LoadedScene == GameScenes.SPACECENTER) { GUIContent settingsContent = new GUIContent("Settings", "Config Settings"); - Rect settingsRect = new Rect(DFwindowPos.width - 165, DFwindowPos.height - 17, 70, 16); + Rect settingsRect = new Rect(DFwindowPos.width - 170, DFwindowPos.height - 22, 70, 20); if (GUI.Button(settingsRect, settingsContent)) { showConfigGUI = !showConfigGUI; } } + + GUIContent resizeContent = new GUIContent(Textures.BtnResize, "Resize Window"); + Rect resizeRect = new Rect(DFwindowPos.width - 21, DFwindowPos.height - 22, 16, 16); + GUI.Label(resizeRect, resizeContent, Textures.ResizeStyle); - GUIContent resizeContent = new GUIContent("R", "Resize Window"); - Rect resizeRect = new Rect(DFwindowPos.width - 17, DFwindowPos.height - 17, 16, 16); - GUI.Label(resizeRect, resizeContent, resizeStyle); HandleResizeEventsDF(resizeRect); + if (DeepFreeze.Instance.DFsettings.ToolTips) + Utilities.SetTooltipText(); + GUI.DragWindow(); } private void windowCF(int id) { - //Init styles - sectionTitleStyle = new GUIStyle(GUI.skin.label); - sectionTitleStyle.alignment = TextAnchor.MiddleCenter; - sectionTitleStyle.stretchWidth = true; - sectionTitleStyle.fontStyle = FontStyle.Bold; - - statusStyle = new GUIStyle(GUI.skin.label); - statusStyle.alignment = TextAnchor.MiddleLeft; - statusStyle.stretchWidth = true; - statusStyle.normal.textColor = Color.white; - - GUIContent closeContent = new GUIContent("X", "Close Window"); - Rect closeRect = new Rect(CFwindowPos.width - 17, 4, 16, 16); - if (GUI.Button(closeRect, closeContent)) + GUIContent closeContent = new GUIContent(Textures.BtnRedCross, "Close Window"); + Rect closeRect = new Rect(CFwindowPos.width - 21, 4, 16, 16); + if (GUI.Button(closeRect, closeContent, Textures.ClosebtnStyle)) { showConfigGUI = false; LoadConfig = true; @@ -834,21 +787,23 @@ private void windowCF(int id) GUILayout.BeginVertical(); + GUIscrollViewVectorSettings = GUILayout.BeginScrollView(GUIscrollViewVectorSettings, false, false, GUILayout.Height(450)); + GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("ElectricCharge Required to run Freezers", "If on, EC is required to run freezers"), statusStyle, GUILayout.Width(280)); + GUILayout.Box(new GUIContent("ElectricCharge Required to run Freezers", "If on, EC is required to run freezers"), Textures.statusStyle, GUILayout.Width(280)); InputVECReqd = GUILayout.Toggle(InputVECReqd, "", GUILayout.MinWidth(30.0F)); //you can play with the width of the text box GUILayout.EndHorizontal(); if (!InputVECReqd) GUI.enabled = false; GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Fatal EC/Heat Option", "If on Kerbals will die if EC runs out or it gets too hot"), statusStyle, GUILayout.Width(280)); + GUILayout.Box(new GUIContent("Fatal EC/Heat Option", "If on Kerbals will die if EC runs out or it gets too hot"), Textures.statusStyle, GUILayout.Width(280)); InputfatalOption = GUILayout.Toggle(InputfatalOption, "", GUILayout.MinWidth(30.0F)); //you can play with the width of the text box GUILayout.EndHorizontal(); GUI.enabled = true; if (InputfatalOption) GUI.enabled = false; GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Non Fatal Kerbal Comatose Time(in secs)", "The time in seconds a kerbal is comatose if fatal EC/Heat option is off"), statusStyle, GUILayout.Width(250)); + GUILayout.Box(new GUIContent("Non Fatal Kerbal Comatose Time(in secs)", "The time in seconds a kerbal is comatose if fatal EC/Heat option is off"), Textures.statusStyle, GUILayout.Width(250)); InputScomatoseTime = Regex.Replace(GUILayout.TextField(InputScomatoseTime, 5, GUILayout.MinWidth(30.0F)), "[^.0-9]", ""); //you can play with the width of the text box GUILayout.EndHorizontal(); GUI.enabled = true; @@ -859,12 +814,12 @@ private void windowCF(int id) } GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("AutoRecover Frozen Kerbals at KSC", "If on, will AutoRecover Frozen Kerbals at the KSC and deduct the Cost from your funds"), statusStyle, GUILayout.Width(280)); + GUILayout.Box(new GUIContent("AutoRecover Frozen Kerbals at KSC", "If on, will AutoRecover Frozen Kerbals at the KSC and deduct the Cost from your funds"), Textures.statusStyle, GUILayout.Width(280)); InputVautoRecover = GUILayout.Toggle(InputVautoRecover, "", GUILayout.MinWidth(30.0F)); //you can play with the width of the text box GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Cost to Thaw a Kerbal at KSC", "Amt of currency Reqd to Freeze a Kerbal from the KSC"), statusStyle, GUILayout.Width(250)); + GUILayout.Box(new GUIContent("Cost to Thaw a Kerbal at KSC", "Amt of currency Reqd to Freeze a Kerbal from the KSC"), Textures.statusStyle, GUILayout.Width(250)); InputScostThawKerbal = Regex.Replace(GUILayout.TextField(InputScostThawKerbal, 5, GUILayout.MinWidth(30.0F)), "[^.0-9]", ""); //you can play with the width of the text box GUILayout.EndHorizontal(); @@ -874,7 +829,7 @@ private void windowCF(int id) } GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("ElecCharge Reqd to Freeze/Thaw a Kerbal", "Amt of ElecCharge Reqd to Freeze/Thaw a Kerbal"), statusStyle, GUILayout.Width(250)); + GUILayout.Box(new GUIContent("ElecCharge Reqd to Freeze/Thaw a Kerbal", "Amt of ElecCharge Reqd to Freeze/Thaw a Kerbal"), Textures.statusStyle, GUILayout.Width(250)); InputSecReqdToFreezeThaw = Regex.Replace(GUILayout.TextField(InputSecReqdToFreezeThaw, 5, GUILayout.MinWidth(30.0F)), "[^.0-9]", ""); //you can play with the width of the text box GUILayout.EndHorizontal(); @@ -884,7 +839,7 @@ private void windowCF(int id) } GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Glykerol Reqd to Freeze a Kerbal", "Amt of Glykerol used to Freeze a Kerbal, Overrides Part values"), statusStyle, GUILayout.Width(250)); + GUILayout.Box(new GUIContent("Glykerol Reqd to Freeze a Kerbal", "Amt of Glykerol used to Freeze a Kerbal, Overrides Part values"), Textures.statusStyle, GUILayout.Width(250)); InputSglykerolReqdToFreeze = Regex.Replace(GUILayout.TextField(InputSglykerolReqdToFreeze, 5, GUILayout.MinWidth(30.0F)), "[^.0-9]", ""); //you can play with the width of the text box GUILayout.EndHorizontal(); @@ -893,17 +848,17 @@ private void windowCF(int id) InputVglykerolReqdToFreeze = GlykerolReqdToFreeze; } GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Temps are in (K)elvin. (K) = (C)elcius + 273.15. (K) = ((F)arenheit + 459.67) × 5/9", "Get your calculator out"), statusStyle, GUILayout.Width(280)); + GUILayout.Box(new GUIContent("Temps are in (K)elvin. (K) = (C)elcius + 273.15. (K) = ((F)arenheit + 459.67) × 5/9", "Get your calculator out"), Textures.statusStyle, GUILayout.Width(280)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Regulated Temperatures Required", "If on, Regulated Temps apply to freeze and keep Kerbals Frozen"), statusStyle, GUILayout.Width(280)); + GUILayout.Box(new GUIContent("Regulated Temperatures Required", "If on, Regulated Temps apply to freeze and keep Kerbals Frozen"), Textures.statusStyle, GUILayout.Width(280)); InputVRegTempReqd = GUILayout.Toggle(InputVRegTempReqd, "", GUILayout.MinWidth(30.0F)); //you can play with the width of the text box GUILayout.EndHorizontal(); if (!InputVRegTempReqd) GUI.enabled = false; GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Minimum Part Temp. for Freezer to Freeze (K)", "Minimum part temperature for Freezer to be able to Freeze"), statusStyle, GUILayout.Width(250)); + GUILayout.Box(new GUIContent("Minimum Part Temp. for Freezer to Freeze (K)", "Minimum part temperature for Freezer to be able to Freeze"), Textures.statusStyle, GUILayout.Width(250)); InputSRegTempFreeze = Regex.Replace(GUILayout.TextField(InputSRegTempFreeze, 3, GUILayout.MinWidth(30.0F)), "[^.0-9]", ""); //you can play with the width of the text box GUILayout.EndHorizontal(); if (!double.TryParse(InputSRegTempFreeze, out InputVRegTempFreeze)) @@ -912,7 +867,7 @@ private void windowCF(int id) } GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("maximum Part Temp. to Keep Kerbals Frozen (K)", "Maximum part temperature for Freezer to keep Kerbals frozen"), statusStyle, GUILayout.Width(250)); + GUILayout.Box(new GUIContent("maximum Part Temp. to Keep Kerbals Frozen (K)", "Maximum part temperature for Freezer to keep Kerbals frozen"), Textures.statusStyle, GUILayout.Width(250)); InputSRegTempMonitor = Regex.Replace(GUILayout.TextField(InputSRegTempMonitor, 3, GUILayout.MinWidth(30.0F)), "[^.0-9]", ""); //you can play with the width of the text box GUILayout.EndHorizontal(); if (!double.TryParse(InputSRegTempMonitor, out InputVRegTempMonitor)) @@ -921,7 +876,7 @@ private void windowCF(int id) } GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Heat generated in thaw/freeze process (kW)", "Amount of thermal heat (kW) generated with each thaw/freeze process"), statusStyle, GUILayout.Width(250)); + GUILayout.Box(new GUIContent("Heat generated in thaw/freeze process (kW)", "Amount of thermal heat (kW) generated with each thaw/freeze process"), Textures.statusStyle, GUILayout.Width(250)); InputSheatamtThawFreezeKerbal = Regex.Replace(GUILayout.TextField(InputSheatamtThawFreezeKerbal, 3, GUILayout.MinWidth(30.0F)), "[^.0-9]", ""); //you can play with the width of the text box GUILayout.EndHorizontal(); if (!double.TryParse(InputSheatamtThawFreezeKerbal, out InputVheatamtThawFreezeKerbal)) @@ -930,7 +885,7 @@ private void windowCF(int id) } GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Equip. heat generated per frozen kerbal (kW) per minute", "Amount of thermal heat (kW) generated by equip. for each frozen kerbal"), statusStyle, GUILayout.Width(250)); + GUILayout.Box(new GUIContent("Equip. heat generated per frozen kerbal (kW) per minute", "Amount of thermal heat (kW) generated by equip. for each frozen kerbal"), Textures.statusStyle, GUILayout.Width(250)); InputSheatamtMonitoringFrznKerbals = Regex.Replace(GUILayout.TextField(InputSheatamtMonitoringFrznKerbals, 3, GUILayout.MinWidth(30.0F)), "[^.0-9]", ""); //you can play with the width of the text box GUILayout.EndHorizontal(); if (!double.TryParse(InputSheatamtMonitoringFrznKerbals, out InputVheatamtMonitoringFrznKerbals)) @@ -941,27 +896,34 @@ private void windowCF(int id) GUI.enabled = true; GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Show Part Temperature in Kelvin", "If on Part right click will show temp in Kelvin, if Off will show in Celcius"), statusStyle, GUILayout.Width(280)); + GUILayout.Box(new GUIContent("Show Part Temperature in Kelvin", "If on Part right click will show temp in Kelvin, if Off will show in Celcius"), Textures.statusStyle, GUILayout.Width(280)); InputVTempinKelvin = GUILayout.Toggle(InputVTempinKelvin, "", GUILayout.MinWidth(30.0F)); //you can play with the width of the text box GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Use Stock Launcher Icon (restart required)", "If on uses AppLauncher, If Off Uses Toolbar"), statusStyle, GUILayout.Width(280)); + GUILayout.Box(new GUIContent("Use Stock Launcher Icon (restart required)", "If on uses AppLauncher, If Off Uses Toolbar"), Textures.statusStyle, GUILayout.Width(280)); InputAppL = GUILayout.Toggle(InputAppL, "", GUILayout.MinWidth(30.0F)); //you can play with the width of the text box GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Freezer Strip Lights On", "Turn off if you do not want the internal freezer strip lights to function"), statusStyle, GUILayout.Width(280)); + GUILayout.Box(new GUIContent("Freezer Strip Lights On", "Turn off if you do not want the internal freezer strip lights to function"), Textures.statusStyle, GUILayout.Width(280)); InputStripLightsOn = GUILayout.Toggle(InputStripLightsOn, "", GUILayout.MinWidth(30.0F)); //you can play with the width of the text box GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); - GUILayout.Box("Debug Mode", statusStyle, GUILayout.Width(280)); + GUILayout.Box(new GUIContent("Debug Mode", "Turns Log Debuggin on and off to assist with problems at the expense of heavy performance overhead"), Textures.statusStyle, GUILayout.Width(280)); InputVdebug = GUILayout.Toggle(InputVdebug, "", GUILayout.MinWidth(30.0F)); //you can play with the width of the text box GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); - if (GUILayout.Button(new GUIContent("Save & Exit Settings", "Save & Exit Settings"), GUILayout.Width(155f))) + GUILayout.Box(new GUIContent("ToolTips", "Turn the Tooltips on and off"), Textures.statusStyle, GUILayout.Width(280)); + InputVToolTips = GUILayout.Toggle(InputVToolTips, "", GUILayout.MinWidth(30.0F)); //you can play with the width of the text box + GUILayout.EndHorizontal(); + + GUILayout.EndScrollView(); + + GUILayout.BeginHorizontal(); + if (GUILayout.Button(new GUIContent("Save & Exit Settings", "Exit this menu and Save Settings"), GUILayout.Width(155f))) { Useapplauncher = InputAppL; if (ECreqdForFreezer != InputVECReqd) @@ -972,6 +934,7 @@ private void windowCF(int id) ECreqdForFreezer = InputVECReqd; debugging = InputVdebug; + ToolTips = InputVToolTips; AutoRecoverFznKerbals = InputVautoRecover; KSCcostToThawKerbal = InputVcostThawKerbal; @@ -995,62 +958,22 @@ private void windowCF(int id) ConfigNode tmpNode = new ConfigNode(); Save(tmpNode); } - if (GUILayout.Button(new GUIContent("Reset Settings", "Reset Settings"), GUILayout.Width(155f))) + if (GUILayout.Button(new GUIContent("Reset Settings", "Reload last saved settings and reset screen"), GUILayout.Width(155f))) { LoadConfig = true; } GUILayout.EndHorizontal(); GUILayout.EndVertical(); + if (DeepFreeze.Instance.DFsettings.ToolTips) + Utilities.SetTooltipText(); GUI.DragWindow(); } private void windowKAC(int id) { - //Init styles - sectionTitleStyle = new GUIStyle(GUI.skin.label); - sectionTitleStyle.alignment = TextAnchor.MiddleLeft; - sectionTitleStyle.stretchWidth = true; - sectionTitleStyle.normal.textColor = Color.blue; - sectionTitleStyle.fontStyle = FontStyle.Bold; - - statusStyle = new GUIStyle(GUI.skin.label); - statusStyle.alignment = TextAnchor.MiddleLeft; - statusStyle.stretchWidth = true; - statusStyle.normal.textColor = Color.white; - - frozenStyle = new GUIStyle(GUI.skin.label); - frozenStyle.alignment = TextAnchor.MiddleLeft; - frozenStyle.stretchWidth = true; - frozenStyle.normal.textColor = Color.cyan; - - StatusOKStyle = new GUIStyle(GUI.skin.label); - StatusOKStyle.alignment = TextAnchor.MiddleLeft; - StatusOKStyle.stretchWidth = true; - StatusOKStyle.normal.textColor = Color.green; - - StatusWarnStyle = new GUIStyle(GUI.skin.label); - StatusWarnStyle.alignment = TextAnchor.MiddleLeft; - StatusWarnStyle.stretchWidth = true; - StatusWarnStyle.normal.textColor = Color.yellow; - - StatusRedStyle = new GUIStyle(GUI.skin.label); - StatusRedStyle.alignment = TextAnchor.MiddleLeft; - StatusRedStyle.stretchWidth = true; - StatusRedStyle.normal.textColor = Color.red; - - resizeStyle = new GUIStyle(GUI.skin.button); - resizeStyle.alignment = TextAnchor.MiddleCenter; - resizeStyle.padding = new RectOffset(1, 1, 1, 1); - - ButtonStyle = new GUIStyle(GUI.skin.toggle); - ButtonStyle.margin.top = 0; - ButtonStyle.margin.bottom = 0; - ButtonStyle.padding.top = 0; - ButtonStyle.padding.bottom = 0; - - GUIContent closeContent = new GUIContent("X", "Close Window"); - Rect closeRect = new Rect(DFKACwindowPos.width - 17, 4, 16, 16); - if (GUI.Button(closeRect, closeContent)) + GUIContent closeContent = new GUIContent(Textures.BtnRedCross, "Close Window"); + Rect closeRect = new Rect(DFKACwindowPos.width - 21, 4, 16, 16); + if (GUI.Button(closeRect, closeContent, Textures.ClosebtnStyle)) { showKACGUI = false; return; @@ -1062,14 +985,14 @@ private void windowKAC(int id) GUIscrollViewVectorKAC = GUILayout.BeginScrollView(GUIscrollViewVectorKAC, false, false); GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); - GUILayout.Label("Name", sectionTitleStyle, GUILayout.Width(KACtxtWdthName)); - GUILayout.Label("Alarm Type", sectionTitleStyle, GUILayout.Width(KACtxtWdthAtyp)); - GUILayout.Label("Time Remain.", sectionTitleStyle, GUILayout.Width(KACtxtWdthATme)); + GUILayout.Label(new GUIContent("Name", "Alarm Name"), Textures.sectionTitleLeftStyle, GUILayout.Width(KACtxtWdthName)); + GUILayout.Label(new GUIContent("Alarm Type", "KAC Alarm Type"), Textures.sectionTitleLeftStyle, GUILayout.Width(KACtxtWdthAtyp)); + GUILayout.Label(new GUIContent("Time Remain.", "Time remaining before Alarm is triggered"), Textures.sectionTitleLeftStyle, GUILayout.Width(KACtxtWdthATme)); GUILayout.EndHorizontal(); if (KACWrapper.KAC.Alarms.Count == 0) { GUILayout.BeginHorizontal(); - GUILayout.Label("There are currently no KAC alarms associated to a DeepFreeze vessel", frozenStyle); + GUILayout.Label("There are currently no KAC alarms associated to a DeepFreeze vessel", Textures.frozenStyle); GUILayout.EndHorizontal(); } else @@ -1077,6 +1000,10 @@ private void windowKAC(int id) foreach (KACWrapper.KACAPI.KACAlarm alarm in KACWrapper.KAC.Alarms) { //Only show KAC alarms that are in the DeepFreeze known vessels list. (IE: vessels that have a freezer) + if (alarm.VesselID == "") + { + continue; + } Guid tmpid = new Guid(alarm.VesselID); if (DeepFreeze.Instance.DFgameSettings.knownVessels.ContainsKey(tmpid)) { @@ -1085,15 +1012,15 @@ private void windowKAC(int id) if (TmeRemaining <= 5) { - GUILayout.Label(alarm.Name, StatusWarnStyle, GUILayout.Width(KACtxtWdthName)); - GUILayout.Label(alarm.AlarmType.ToString(), StatusWarnStyle, GUILayout.Width(KACtxtWdthAtyp)); - GUILayout.Label(Utilities.FormatDateString(TmeRemaining), StatusWarnStyle, GUILayout.Width(KACtxtWdthATme)); + GUILayout.Label(alarm.Name, Textures.StatusWarnStyle, GUILayout.Width(KACtxtWdthName)); + GUILayout.Label(alarm.AlarmType.ToString(), Textures.StatusWarnStyle, GUILayout.Width(KACtxtWdthAtyp)); + GUILayout.Label(Utilities.FormatDateString(TmeRemaining), Textures.StatusWarnStyle, GUILayout.Width(KACtxtWdthATme)); } else { - GUILayout.Label(alarm.Name, statusStyle, GUILayout.Width(KACtxtWdthName)); - GUILayout.Label(alarm.AlarmType.ToString(), statusStyle, GUILayout.Width(KACtxtWdthAtyp)); - GUILayout.Label(Utilities.FormatDateString(TmeRemaining), statusStyle, GUILayout.Width(KACtxtWdthATme)); + GUILayout.Label(alarm.Name, Textures.statusStyle, GUILayout.Width(KACtxtWdthName)); + GUILayout.Label(alarm.AlarmType.ToString(), Textures.statusStyle, GUILayout.Width(KACtxtWdthAtyp)); + GUILayout.Label(Utilities.FormatDateString(TmeRemaining), Textures.statusStyle, GUILayout.Width(KACtxtWdthATme)); } // Utilities.Log_Debug("Show alarm from KAC " + alarm.ID + " " + alarm.Name + " " + alarm.VesselID); @@ -1102,14 +1029,14 @@ private void windowKAC(int id) { //If a modify is in progress we turn off the delete button GUI.enabled = false; - GUILayout.Button("Delete", GUILayout.Width(50)); + GUILayout.Button(new GUIContent("Delete", "Delete this KAC alarm completely"), GUILayout.Width(50)); GUI.enabled = true; // Utilities.Log_Debug("Delete button disabled"); } else { if (TmeRemaining <= 0) GUI.enabled = false; - if (GUILayout.Button("Delete", GUILayout.Width(50))) + if (GUILayout.Button(new GUIContent("Delete", "Delete this KAC alarm completely"), GUILayout.Width(50))) { KACWrapper.KAC.DeleteAlarm(alarm.ID); } @@ -1122,14 +1049,14 @@ private void windowKAC(int id) if (KACalarmMod.ID != alarm.ID) //If it isn't this alarm we disable the button { GUI.enabled = false; - GUILayout.Button("Modify", GUILayout.Width(50)); + GUILayout.Button(new GUIContent("Modify", "Modify this Alarm"), GUILayout.Width(50)); GUI.enabled = true; // Utilities.Log_Debug("Modify button disabled"); } else //We are modifying an alarm and it's this one. So we draw a SAVE and Cancel button to save/cancel changes. { // Utilities.Log_Debug("mod in progress and it's this one, change to Save/Cancel"); - if (GUILayout.Button("Save", GUILayout.Width(50))) + if (GUILayout.Button(new GUIContent("Save", "Save Alarm Changes"), GUILayout.Width(50))) { if (DFInstalledMods.IsRTInstalled && !DFInstalledMods.RTVesselConnected(tmpid)) { @@ -1151,7 +1078,7 @@ private void windowKAC(int id) } ModKACAlarm = false; } - if (GUILayout.Button("Cancel", GUILayout.Width(50))) + if (GUILayout.Button(new GUIContent("Cancel", "Cancel any changes"), GUILayout.Width(50))) { // Utilities.Log_Debug("User cancelled mod"); ModKACAlarm = false; @@ -1160,10 +1087,10 @@ private void windowKAC(int id) GUIscrollViewVectorKACKerbals = GUILayout.BeginScrollView(GUIscrollViewVectorKACKerbals, false, false, GUILayout.MaxHeight(100f)); GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); - GUILayout.Label("Name", sectionTitleStyle, GUILayout.Width(KACtxtWdthKName)); - GUILayout.Label("Trait", sectionTitleStyle, GUILayout.Width(KACtxtWdthKTyp)); - GUILayout.Label("Thaw", sectionTitleStyle, GUILayout.Width(KACtxtWdthKTg1)); - GUILayout.Label("Freeze", sectionTitleStyle, GUILayout.Width(KACtxtWdthKTg2)); + GUILayout.Label(new GUIContent("Name", "The Kerbals Name"), Textures.sectionTitleLeftStyle, GUILayout.Width(KACtxtWdthKName)); + GUILayout.Label(new GUIContent("Trait", "The Kerbals Profession"), Textures.sectionTitleLeftStyle, GUILayout.Width(KACtxtWdthKTyp)); + GUILayout.Label(new GUIContent("Thaw", "Thaw this kerbal on alarm activation"), Textures.sectionTitleLeftStyle, GUILayout.Width(KACtxtWdthKTg1)); + GUILayout.Label(new GUIContent("Freeze", "Freeze this kerbal on alarm activation"), Textures.sectionTitleLeftStyle, GUILayout.Width(KACtxtWdthKTg2)); GUILayout.EndHorizontal(); //Build the Crew list for the alarm and allow modifications List> frzrs = DeepFreeze.Instance.DFgameSettings.knownFreezerParts.Where(a => a.Value.vesselID == tmpid).ToList(); @@ -1176,10 +1103,10 @@ private void windowKAC(int id) GUILayout.BeginHorizontal(); bool ThawCrew = KACAlarm_ThwKbls.Contains(frzr.Value.crewMembers[i]); bool FrzCrew = KACAlarm_FrzKbls.Contains(frzr.Value.crewMembers[i]); - GUILayout.Label(frzr.Value.crewMembers[i], statusStyle, GUILayout.Width(KACtxtWdthKName)); - GUILayout.Label(frzr.Value.crewMemberTraits[i], statusStyle, GUILayout.Width(KACtxtWdthKTyp)); + GUILayout.Label(frzr.Value.crewMembers[i], Textures.statusStyle, GUILayout.Width(KACtxtWdthKName)); + GUILayout.Label(frzr.Value.crewMemberTraits[i], Textures.statusStyle, GUILayout.Width(KACtxtWdthKTyp)); if (FrzCrew) GUI.enabled = false; - ThawCrew = GUILayout.Toggle(ThawCrew, "", ButtonStyle, GUILayout.Width(KACtxtWdthKTg1)); + ThawCrew = GUILayout.Toggle(ThawCrew, "", Textures.ButtonStyle, GUILayout.Width(KACtxtWdthKTg1)); GUI.enabled = true; if (ThawCrew) { @@ -1196,7 +1123,7 @@ private void windowKAC(int id) } } if (ThawCrew) GUI.enabled = false; - FrzCrew = GUILayout.Toggle(FrzCrew, "", ButtonStyle, GUILayout.Width(KACtxtWdthKTg2)); + FrzCrew = GUILayout.Toggle(FrzCrew, "", Textures.ButtonStyle, GUILayout.Width(KACtxtWdthKTg2)); GUI.enabled = true; if (FrzCrew) @@ -1223,10 +1150,10 @@ private void windowKAC(int id) GUILayout.BeginHorizontal(); bool ThawCrew = KACAlarm_ThwKbls.Contains(crew.Key); bool FrzCrew = KACAlarm_FrzKbls.Contains(crew.Key); - GUILayout.Label(crew.Key, frozenStyle, GUILayout.Width(KACtxtWdthKName)); - GUILayout.Label(crew.Value.experienceTraitName, frozenStyle, GUILayout.Width(KACtxtWdthKTyp)); + GUILayout.Label(crew.Key, Textures.frozenStyle, GUILayout.Width(KACtxtWdthKName)); + GUILayout.Label(crew.Value.experienceTraitName, Textures.frozenStyle, GUILayout.Width(KACtxtWdthKTyp)); if (FrzCrew) GUI.enabled = false; - ThawCrew = GUILayout.Toggle(ThawCrew, "", ButtonStyle, GUILayout.Width(KACtxtWdthKTg1)); + ThawCrew = GUILayout.Toggle(ThawCrew, "", Textures.ButtonStyle, GUILayout.Width(KACtxtWdthKTg1)); GUI.enabled = true; if (ThawCrew) { @@ -1243,7 +1170,7 @@ private void windowKAC(int id) } } if (ThawCrew) GUI.enabled = false; - FrzCrew = GUILayout.Toggle(FrzCrew, "", ButtonStyle, GUILayout.Width(KACtxtWdthKTg2)); + FrzCrew = GUILayout.Toggle(FrzCrew, "", Textures.ButtonStyle, GUILayout.Width(KACtxtWdthKTg2)); GUI.enabled = true; if (FrzCrew) { @@ -1271,7 +1198,7 @@ private void windowKAC(int id) { // Utilities.Log_Debug("no modify in progress so just show modify buttons on KAC alarm"); if (TmeRemaining <= 0) GUI.enabled = false; - if (GUILayout.Button("Modify", GUILayout.Width(50))) + if (GUILayout.Button(new GUIContent("Modify", "Modify this Alarms settings"), GUILayout.Width(50))) { KACalarmMod = alarm; KACAlarm_FrzKbls.Clear(); @@ -1289,26 +1216,19 @@ private void windowKAC(int id) GUILayout.EndScrollView(); GUILayout.EndVertical(); GUILayout.Space(14); - GUIContent resizeContent = new GUIContent("R", "Resize Window"); + + GUIContent resizeContent = new GUIContent(Textures.BtnResize, "Resize Window"); Rect resizeRect = new Rect(DFKACwindowPos.width - 17, DFKACwindowPos.height - 17, 16, 16); - GUI.Label(resizeRect, resizeContent, resizeStyle); + GUI.Label(resizeRect, resizeContent, Textures.ResizeStyle); + HandleResizeEventsKAC(resizeRect); + if (DeepFreeze.Instance.DFsettings.ToolTips) + Utilities.SetTooltipText(); GUI.DragWindow(); } private void windowVS(int id) { - //Init styles - sectionTitleStyle = new GUIStyle(GUI.skin.label); - sectionTitleStyle.alignment = TextAnchor.MiddleCenter; - sectionTitleStyle.stretchWidth = true; - sectionTitleStyle.fontStyle = FontStyle.Bold; - - statusStyle = new GUIStyle(GUI.skin.label); - statusStyle.alignment = TextAnchor.MiddleCenter; - statusStyle.stretchWidth = true; - statusStyle.normal.textColor = Color.white; - //Pause the game TimeWarp.SetRate(0, true); if (HighLogic.LoadedSceneIsFlight && FlightGlobals.ready && !FlightDriver.Pause) @@ -1317,7 +1237,7 @@ private void windowVS(int id) GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); //GUILayout.Box(new GUIContent("ElectricCharge is running out on vessel, you must switch to the vessel now.", "Switch to DeepFreeze vessel required"), statusStyle, GUILayout.Width(280)); - GUILayout.Box(new GUIContent(showSwitchVesselStr, showSwitchVesselStr), statusStyle, GUILayout.Width(320)); + GUILayout.Box(new GUIContent(showSwitchVesselStr, showSwitchVesselStr), Textures.statusStyle, GUILayout.Width(320)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); @@ -1357,29 +1277,20 @@ private void windowVS(int id) } GUILayout.EndHorizontal(); GUILayout.EndVertical(); + if (DeepFreeze.Instance.DFsettings.ToolTips) + Utilities.SetTooltipText(); GUI.DragWindow(); } private void windowVSF(int id) { - //Init styles - sectionTitleStyle = new GUIStyle(GUI.skin.label); - sectionTitleStyle.alignment = TextAnchor.MiddleCenter; - sectionTitleStyle.stretchWidth = true; - sectionTitleStyle.fontStyle = FontStyle.Bold; - - statusStyle = new GUIStyle(GUI.skin.label); - statusStyle.alignment = TextAnchor.MiddleCenter; - statusStyle.stretchWidth = true; - statusStyle.normal.textColor = Color.white; - TimeWarp.SetRate(0, true); if (HighLogic.LoadedSceneIsFlight && FlightGlobals.ready) FlightDriver.SetPause(true); GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); - GUILayout.Box(new GUIContent("Automatic Switch to vessel failed.\nPlease switch manually to vessel Immediately", "Switch to DeepFreeze vessel required"), statusStyle, GUILayout.Width(280)); + GUILayout.Box(new GUIContent("Automatic Switch to vessel failed.\nPlease switch manually to vessel Immediately", "Switch to DeepFreeze vessel required"), Textures.statusStyle, GUILayout.Width(280)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); @@ -1394,6 +1305,8 @@ private void windowVSF(int id) } GUILayout.EndHorizontal(); GUILayout.EndVertical(); + if (DeepFreeze.Instance.DFsettings.ToolTips) + Utilities.SetTooltipText(); GUI.DragWindow(); } @@ -1497,6 +1410,7 @@ public void Load(ConfigNode globalNode) Useapplauncher = DeepFreeze.Instance.DFsettings.UseAppLauncher; AutoRecoverFznKerbals = DeepFreeze.Instance.DFsettings.AutoRecoverFznKerbals; debugging = DeepFreeze.Instance.DFsettings.debugging; + ToolTips = DeepFreeze.Instance.DFsettings.ToolTips; ECreqdForFreezer = DeepFreeze.Instance.DFsettings.ECreqdForFreezer; fatalOption = DeepFreeze.Instance.DFsettings.fatalOption; comatoseTime = DeepFreeze.Instance.DFsettings.comatoseTime; @@ -1525,6 +1439,7 @@ public void Save(ConfigNode globalNode) DeepFreeze.Instance.DFsettings.UseAppLauncher = Useapplauncher; DeepFreeze.Instance.DFsettings.AutoRecoverFznKerbals = AutoRecoverFznKerbals; DeepFreeze.Instance.DFsettings.debugging = debugging; + DeepFreeze.Instance.DFsettings.ToolTips = ToolTips; DeepFreeze.Instance.DFsettings.ECreqdForFreezer = ECreqdForFreezer; DeepFreeze.Instance.DFsettings.fatalOption = fatalOption; DeepFreeze.Instance.DFsettings.comatoseTime = comatoseTime; diff --git a/Source/DeepFreezerPart.cs b/Source/DeepFreezerPart.cs index 16ac746..7ac8678 100644 --- a/Source/DeepFreezerPart.cs +++ b/Source/DeepFreezerPart.cs @@ -19,6 +19,8 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using DeepFreeze; +using KSP.UI.Screens.Flight; using RSTUtils; using UnityEngine; using Object = System.Object; @@ -82,9 +84,10 @@ public class DeepFreezer : PartModule, IResourceConsumer private bool crewXferSMActive; // set to true if CrewXfer is active and SM is installed and managing the xfer. private bool crewXferSMStock; // set to true if a Stock CrewXfer is active and SM is installed and managing the xfer. private bool xferbackwhenFull; // set to true when a CrewXfer triggers and the part is already full. - private int IvaUpdateFrameDelay = 5; // Frame delay for Iva portrait updates - private bool IvaUpdateActive; // True when an Iva update framedelay is active - private int IvaPortraitDelay; // Counter for IVA portrait delay + private bool crewTransferInputLock = false; //This is turned on if a stock Xfer is started and Off when it finishes. + //private int IvaUpdateFrameDelay = 2; // Frame delay for Iva portrait updates + //private bool IvaUpdateActive; // True when an Iva update framedelay is active + //private int IvaPortraitDelay; // Counter for IVA portrait delay private double timecrewXferTOfired; // The Time.time that last crewXferTOFired so we can timeout if it takes too long. private double timecrewXferFROMfired; // The Time.time that last crewXferFROMFired so we can timeout if it takes too long. private double crewXferSMTimeDelay; // crewXfer time delay used by Ship Manifest. @@ -144,6 +147,11 @@ public bool DFIPartFull } } + public bool DFIECReqd + { + get { return DeepFreeze.Instance.DFsettings.ECreqdForFreezer; } + } + [KSPField(isPersistant = false, guiName = "R/T Connection", guiActive = false)] public bool isRTConnected; @@ -271,7 +279,14 @@ public bool DFIIsThawActive [KSPField] public string animationName = string.Empty; //Set by part.cfg. name of external animation name for doors if equipped. + [KSPField] + public bool PartHasDoor = false; //Set by part.cfg. true if part has external door (CRY-0300). + private Animation externalDoorAnim; + private Animation externalDoorAnimOccluder; + + [KSPField(isPersistant = true)] + public bool ExternalDoorActive; //Set internal to partmodule. True if PartHasDoor and RPM/JSI TransparentPods is installed. Otherwise it is false. Used to determine if the door is activated/enabled or not. //we persist the external door state in strings because KSP can't handle ENUMs [KSPField(isPersistant = true)] @@ -286,8 +301,7 @@ public bool DFIIsThawActive internal string _prevRPMTransparentpodSetting = string.Empty; - [KSPField(isPersistant = true)] - public bool hasExternalDoor; + [KSPField] public string transparentTransforms = string.Empty; //Set by part.cfg. contains list of transforms that should be transparent | separated. @@ -301,11 +315,10 @@ public void eventOpenDoors() Utilities.Log_Debug("eventOpenDoors triggered - open the bay doors Hal"); try { - Animation anim; Animation[] animators = part.internalModel.FindModelAnimators("DOORHandle"); if (animators.Length > 0) { - anim = animators[0]; + var anim = animators[0]; anim["DOORHandle"].speed = float.MaxValue; anim["DOORHandle"].normalizedTime = 0; anim.Play("DOORHandle"); @@ -333,11 +346,10 @@ public void eventCloseDoors() Utilities.Log_Debug("eventOpenDoors triggered - close the bay doors Hal"); try { - Animation anim; Animation[] animators = part.internalModel.FindModelAnimators("DOORHandle"); if (animators.Length > 0) { - anim = animators[0]; + var anim = animators[0]; anim["DOORHandle"].speed = float.MinValue; anim["DOORHandle"].normalizedTime = 1; anim.Play("DOORHandle"); @@ -378,6 +390,7 @@ public void DeActivateAction(KSPActionParam param) private Animation _windowAnimation; private Shader TransparentSpecularShader; private Shader KSPSpecularShader; + private object JSITransparentPodModule; private FrznCrewList _StoredCrewList = new FrznCrewList(); // This is the frozen StoredCrewList for the part @@ -450,8 +463,20 @@ public void Update() onceoffSetup(); } + //For some reason when we go on EVA or switch vessels the InternalModel is destroyed. + //Which causes a problem when we re-board the part as the re-boarding kerbal ends up in a frozen kerbals seat. + //So we check for the internalmodel existing while the vessel this part is attached to is loaded and if it isn't we re-instansiate it. + if (HighLogic.LoadedSceneIsFlight && FlightGlobals.ready && vessel.loaded && partHasInternals && part.internalModel == null) + { + Utilities.Log("Part " + part.name + "(" + part.flightID + ") is loaded and internalModel has disappeared, so re-instantiate it"); + //part.SpawnIVA(); + Utilities.spawnInternal(part); + resetFrozenKerbals(); + resetCryopods(true); + } + // If we have an external door (CRY-0300) or external pod (CRY-0300R) check RPM transparency setting and change the door settings as appropriate - if ((hasExternalDoor || isPodExternal) && DFInstalledMods.IsRPMInstalled && !IsFreezeActive && !IsThawActive) + if ((PartHasDoor || isPodExternal) && DFInstalledMods.IsJSITransparentPodsInstalled && !IsFreezeActive && !IsThawActive) { try { @@ -464,47 +489,72 @@ public void Update() } } + //We have to process the occluders for the CRY-0300 and CRY-0300R for KSP 1.1 + if (PartHasDoor || isPodExternal) + { + if (DFInstalledMods.IsJSITransparentPodsInstalled) + { + RPMPodOccluderProcessing(); + } + else + { + noRPMPodOccluderProcessing(); + } + } + if (!HighLogic.LoadedSceneIsFlight) // If scene is not flight we are done with onUpdate return; //This is necessary to override stock crew xfer behaviour. When the user cancels the xfer the Stock highlighting system - // makes the transparent pod opaque. There is no way (that I can find) to know when this occurs. + // makes the transparent pod opaque. The only way I can find to know if this occurs is to continually check if the crewTransfer + // Lock occurs and when it turns off we do this (still could be the transfer actually worked, but means we do it a LOT LOT Less times. // So we look through the parts pod states for any part that is not animated (IE: CRY-0300R) any that are OPEN we - // set their window to transparent..... Maybe we should check it first. - if (FlightGlobals.ready && vessel.loaded && isPodExternal && !IsFreezeActive && !IsThawActive && DFInstalledMods.IsRPMInstalled) + // set their window to transparent..... + //If the lock is ON set the bool to true and wait until the lock is off. + if (InputLockManager.IsLocked(ControlTypes.ALLBUTCAMERAS) && + InputLockManager.lockStack.ContainsKey("crewTransfer")) + { + crewTransferInputLock = true; + } + else //So the lock is off was the lock previously set? If it as we process, otherwise we do nothing. { - if (_prevRPMTransparentpodSetting == "ON") + if (crewTransferInputLock) { - for (int i = 0; i < cryopodstateclosed.Length; i++) + crewTransferInputLock = false; //Reset the bool and then process. + if (FlightGlobals.ready && vessel.loaded && isPodExternal && !IsFreezeActive && !IsThawActive && DFInstalledMods.IsJSITransparentPodsInstalled) { - if (!cryopodstateclosed[i]) + if (_prevRPMTransparentpodSetting == "ON") { - string windowname = "Cryopod-" + (i + 1) + "-Window"; - Renderer extwindowrenderer = part.FindModelComponent(windowname); - if (extwindowrenderer != null) + for (int i = 0; i < cryopodstateclosed.Length; i++) { - if (extwindowrenderer.material.shader != TransparentSpecularShader) - setCryopodWindowTransparent(i); + if (!cryopodstateclosed[i]) //If there isn't a frozen kerbal inside + { + string windowname = "Cryopod-" + (i + 1) + "-Window"; + Renderer extwindowrenderer = part.FindModelComponent(windowname); + if (extwindowrenderer != null) + { + if (extwindowrenderer.material.shader != TransparentSpecularShader) + { + setCryopodWindowTransparent(i); + Utilities.SetInternalDepthMask(part, false, "External_Window_Occluder"); + } + } + } } } } } - } + } - //For some reason when we go on EVA or switch vessels the InternalModel is destroyed. - //Which causes a problem when we re-board the part as the re-boarding kerbal ends up in a frozen kerbals seat. - //So we check for the internmodel existing while the vessel this part is attached to is loaded and if it isn't we re-instansiate it. - if (FlightGlobals.ready && vessel.loaded && partHasInternals && part.internalModel == null) + if (PartHasDoor && Utilities.IsInIVA) //So if we are in IVA mode (inside this loop) and in a CRY-0300 (have External door) Open the Kerbals EYES WIDER! { - Utilities.Log("Part " + part.name + "(" + part.flightID + ") is loaded and internalModel has disappeared, so re-instansiate it"); - part.SpawnCrew(); - resetFrozenKerbals(); - resetCryopods(true); - // If part does not have JSITransparentPod module we check the portrait cams. Otherwise JSITransparenPod will do it for us. - if (!hasJSITransparentPod) - { - Utilities.CheckPortraitCams(vessel); - } + //Kerbal currentKerbal = CameraManager.Instance.IVACameraActiveKerbal; + CameraManager.Instance.IVACameraActiveKerbal.kerbalCam.nearClipPlane = 0.01f; + CameraManager.Instance.IVACameraActiveKerbal.kerbalCam.fieldOfView = 95f; + //CameraManager.Instance.ivaFOV = 95f; + //Turn OFF the Door occluders so we can see outside. + if (_externaldoorstate != DoorState.CLOSED) + Utilities.SetInternalDepthMask(part, false, "CRY_0300_Doors_Occluder"); } if (Time.time - lastUpdate > updatetnterval && Time.time - lastRemove > updatetnterval) // We only update every updattnterval time interval. @@ -550,7 +600,7 @@ public void Update() } // If we have an external door (CRY-0300) check if the door state has changed and then set the helmet state - if (hasExternalDoor) + if (ExternalDoorActive) { // if the current and previous door states are different we need to do checks, otherwise we do nothing. if (_externaldoorstate != _prevexterndoorstate) @@ -567,9 +617,10 @@ public void Update() _prevexterndoorstate = _externaldoorstate; } } - + // This is now handled by a coroutine callback. //If a kerbal entered the part from EVA into a frozen kerbals seat then we moved them // and now we wait IvaUpdateFrameDelay frames to refresh the portraits + /* if (IvaUpdateActive) { Utilities.Log_Debug("IvaUpdateActive delay counter=" + IvaPortraitDelay); @@ -579,54 +630,66 @@ public void Update() IvaPortraitDelay = 0; vessel.SpawnCrew(); resetFrozenKerbals(); + onvslchgInternal = true; + GameEvents.onVesselChange.Fire(vessel); } else { IvaPortraitDelay += 1; } } - + */ //Refresh IVA mode Messages and Bools - ScreenMessages.RemoveMessage(IVAKerbalName); - ScreenMessages.RemoveMessage(IVAkerbalPart); - ScreenMessages.RemoveMessage(IVAkerbalPod); + if (IVAKerbalName != null) ScreenMessages.RemoveMessage(IVAKerbalName); + if (IVAkerbalPart != null) ScreenMessages.RemoveMessage(IVAkerbalPart); + if (IVAkerbalPod != null) ScreenMessages.RemoveMessage(IVAkerbalPod); if (Utilities.VesselIsInIVA(part.vessel)) { // Utilities.Log_Debug("Vessel is in IVA mode"); vesselisinIVA = true; vesselisinInternal = false; - Kerbal actkerbal = part.FindCurrentKerbal(); - if (actkerbal != null) + //Kerbal actkerbal = CameraManager.Instance.IVACameraActiveKerbal; + if (CameraManager.Instance.IVACameraActiveKerbal != null) { - ProtoCrewMember crew = part.protoModuleCrew.FirstOrDefault(a => a.name == actkerbal.name); - int SeatIndx = -1; - if (crew != null) - { - SeatIndx = crew.seatIdx; - } - // Utilities.Log_Debug("ActiveKerbalFound, seatidx=" + SeatIndx); - if (SeatIndx != -1) + if (Utilities.ActiveKerbalIsLocal(part)) { - SeatIndx++; - IVAkerbalPod = ScreenMessages.PostScreenMessage("Pod:" + SeatIndx); - } - IVAkerbalPart = ScreenMessages.PostScreenMessage(part.name.Substring(0, 8)); - IVAKerbalName = ScreenMessages.PostScreenMessage(actkerbal.name); - //monitoring beep - if (TotalFrozen > 0 && !mon_beep.isPlaying) - { - mon_beep.Play(); + ProtoCrewMember crew = part.protoModuleCrew.FirstOrDefault(a => a.name == CameraManager.Instance.IVACameraActiveKerbal.name); + int SeatIndx = -1; + if (crew != null) + { + SeatIndx = crew.seatIdx; + } + // Utilities.Log_Debug("ActiveKerbalFound, seatidx=" + SeatIndx); + if (SeatIndx != -1) + { + SeatIndx++; + IVAkerbalPod = new ScreenMessage("Pod:" + SeatIndx, 1, ScreenMessageStyle.UPPER_LEFT); + IVAkerbalPod.color = Color.white; + ScreenMessages.PostScreenMessage(IVAkerbalPod); + } + IVAkerbalPart = new ScreenMessage(part.name.Substring(0, 8), 1, ScreenMessageStyle.UPPER_LEFT); + IVAkerbalPart.color = Color.white; + ScreenMessages.PostScreenMessage(IVAkerbalPart); + + IVAKerbalName = new ScreenMessage(CameraManager.Instance.IVACameraActiveKerbal.crewMemberName, 1, ScreenMessageStyle.UPPER_LEFT); + IVAKerbalName.color = Color.white; + ScreenMessages.PostScreenMessage(IVAKerbalName); } } + //monitoring beep + if (TotalFrozen > 0 && !mon_beep.isPlaying) + { + mon_beep.Play(); + } } else { - ScreenMessages.RemoveMessage(IVAKerbalName); - ScreenMessages.RemoveMessage(IVAkerbalPart); - ScreenMessages.RemoveMessage(IVAkerbalPod); + if (IVAKerbalName != null) ScreenMessages.RemoveMessage(IVAKerbalName); + if (IVAkerbalPart != null) ScreenMessages.RemoveMessage(IVAkerbalPart); + if (IVAkerbalPod != null) ScreenMessages.RemoveMessage(IVAkerbalPod); vesselisinIVA = false; // Utilities.Log_Debug("Vessel is NOT in IVA mode"); - if (Utilities.IsInInternal()) + if (Utilities.IsActiveVessel(vessel) && Utilities.IsInInternal) { vesselisinInternal = true; if (TotalFrozen > 0 && !mon_beep.isPlaying) @@ -662,133 +725,309 @@ private void checkRPMPodTransparencySetting() { try { - string transparentPodSetting = string.Empty; - object JSITransparentPodModule = part.Modules["JSITransparentPod"]; + //Get the TransparentPodPartModule and only proceed if we find one. + JSITransparentPodModule = part.Modules["JSIAdvTransparentPod"]; if (JSITransparentPodModule != null) { + //Get the transparentPodSetting (ON/OFF/AUTO) and only proceed if we got it. object outputField = Utilities.GetObjectField(JSITransparentPodModule, "transparentPodSetting"); if (outputField != null) { - transparentPodSetting = outputField.ToString(); + string transparentPodSetting = outputField.ToString(); + //We only need to do this processing if the Pod Setting has CHANGED since last time we checked. if (transparentPodSetting != _prevRPMTransparentpodSetting) { - switch (transparentPodSetting) + if (PartHasDoor) //CRY-0300 + { + processRPMPodSettingsPartHasDoor(transparentPodSetting); + } + else + { + if (isPodExternal) //CRY-0300R + { + processRPMPodSettingsPodisExternal(transparentPodSetting); + } + } + _prevRPMTransparentpodSetting = transparentPodSetting; + } + + + } + } + } + catch (Exception) + { + Utilities.Log("DeepFreezer Error checking RPM TransparentPod Setting"); + //Utilities.Log("DeepFreezer ", ex.Message); + } + } + + private void processRPMPodSettingsPartHasDoor(string transparentPodSetting) + { + switch (transparentPodSetting) + { + case "ON": + // If the doors are closed or closing set open doors event active + if (_externaldoorstate != DoorState.CLOSED && + _externaldoorstate != DoorState.CLOSING) + { + Events["eventOpenDoors"].active = false; + Events["eventCloseDoors"].active = true; + } + else + { + //If the doors are open or opening set close doors event active + if (_externaldoorstate != DoorState.OPEN && + _externaldoorstate != DoorState.OPENING) + { + Events["eventOpenDoors"].active = true; + Events["eventCloseDoors"].active = false; + } + } + break; + + default: + Utilities.Log_Debug("RPM set to OFF or AUTO for transparent pod"); + + // We must close the doors if they are not or we see an empty internal. + DoorState actualDoorState = getdoorState(); + if (actualDoorState != DoorState.CLOSED) + { + try + { + //Animate the RPM Door Handle Prop + Animation anim; + Animation[] animators = + part.internalModel.FindModelAnimators("DOORHandle"); + if (animators.Length > 0) + { + anim = animators[0]; + anim["DOORHandle"].speed = float.MinValue; + anim["DOORHandle"].normalizedTime = 1; + anim.Play("DOORHandle"); + } + ext_door.Play(); + } + catch (Exception ex) + { + Debug.Log("Exception trying to run the Doorhandle animation"); + Debug.Log("Err: " + ex); + } + + //Run the Close Door Animation. + if (animationName != null) + { + if (externalDoorAnimOccluder != null) { - case "ON": - if (hasExternalDoor) //CRY-0300 + externalDoorAnimOccluder[animationName].normalizedTime = 1; + externalDoorAnimOccluder[animationName].speed = float.MinValue; + externalDoorAnimOccluder.Play(animationName); + } + externalDoorAnim[animationName].normalizedTime = 1; + externalDoorAnim[animationName].speed = float.MinValue; + externalDoorAnim.Play(animationName); + } + _prevexterndoorstate = _externaldoorstate; + _externaldoorstate = DoorState.CLOSED; + } + Events["eventOpenDoors"].active = false; + Events["eventCloseDoors"].active = false; + + break; + } + } + + private void processRPMPodSettingsPodisExternal(string transparentPodSetting) + { + switch (transparentPodSetting) + { + case "ON": + + for (int i = 0; i < FreezerSize; i++) + { + string windowname = "Cryopod-" + (i + 1) + "-Window"; + Renderer extwindowrenderer = part.FindModelComponent(windowname); + if (extwindowrenderer != null) + { + if (HighLogic.LoadedSceneIsFlight) + //If in flight, we check the pod state + { + if (!cryopodstateclosed[i]) //No frozen kerbal inside + { + if (extwindowrenderer.material.shader != TransparentSpecularShader) { - // If the doors are closed or closing set open doors event active - if (_externaldoorstate != DoorState.CLOSED && _externaldoorstate != DoorState.CLOSING) + setCryopodWindowTransparent(i); + } + } + else //Frozen kerbal inside + { + if (extwindowrenderer.material.shader != KSPSpecularShader) + { + setCryopodWindowSpecular(i); + } + } + } + else //If in editor, always transparent + { + if (extwindowrenderer.material.shader != TransparentSpecularShader) + { + setCryopodWindowTransparent(i); + } + } + } + } + break; + + default: + Utilities.Log_Debug("RPM set to OFF or AUTO for transparent pod"); + + for (int i = 0; i < FreezerSize; i++) + { + string windowname = "Cryopod-" + (i + 1) + "-Window"; + Renderer extwindowrenderer = part.FindModelComponent(windowname); + + if (extwindowrenderer != null) + { + if (extwindowrenderer.material.shader != KSPSpecularShader) + { + setCryopodWindowSpecular(i); + } + } + } + break; + } + } + + private void RPMPodOccluderProcessing() + { + try + { + //We have to process the occluders for the CRY-0300 and CRY-0300R for KSP 1.1 + if (HighLogic.LoadedSceneIsFlight && !Utilities.IsInIVA) + { + //Get the TransparentPodPartModule and only proceed if we find one. + JSITransparentPodModule = part.Modules["JSIAdvTransparentPod"]; + if (JSITransparentPodModule != null) + { + //Get the transparentPodSetting (ON/OFF/AUTO) and only proceed if we got it. + object outputField = Utilities.GetObjectField(JSITransparentPodModule, "transparentPodSetting"); + if (outputField != null) + { + string transparentPodSetting = outputField.ToString(); + if (PartHasDoor) //If CRY-0300, set the door occluder ON so we see the closed/closing doors + { + if (transparentPodSetting == "ON") + { + if (_externaldoorstate == DoorState.CLOSED || + _externaldoorstate == DoorState.CLOSING || + _externaldoorstate == DoorState.OPENING) + //If the Door is Closed, closing or opening + { + //If Stock Overlay is on we turn the Occluder OFF so we can see inside. + //Otherwise is it ON and we see the closed/closing/opening doors. + if (Utilities.StockOverlayCamIsOn) { - Events["eventOpenDoors"].active = false; - Events["eventCloseDoors"].active = true; + Utilities.SetInternalDepthMask(part, false, "CRY_0300_Doors_Occluder"); } else { - //If the doors are open or opening set close doors event active - if (_externaldoorstate != DoorState.OPEN && _externaldoorstate != DoorState.OPENING) - { - Events["eventOpenDoors"].active = true; - Events["eventCloseDoors"].active = false; - } + Utilities.SetInternalDepthMask(part, true, "CRY_0300_Doors_Occluder"); } } - else //CRY-0300R + else + //Door is Open we turn the Occluder OFF so we can see inside RPM style or Stock style, doesn't matter. { - for (int i = 0; i < FreezerSize; i++) - { - string windowname = "Cryopod-" + (i + 1) + "-Window"; - Renderer extwindowrenderer = part.FindModelComponent(windowname); - if (extwindowrenderer != null) - { - if (HighLogic.LoadedSceneIsFlight) //If in flight, we check the pod state - { - if (!cryopodstateclosed[i]) //Pod is open - { - if (extwindowrenderer.material.shader != TransparentSpecularShader) - setCryopodWindowTransparent(i); - } - else //Pod is closed - { - if (extwindowrenderer.material.shader != KSPSpecularShader) - setCryopodWindowSpecular(i); - } - } - else //If in editor, always transparent - { - if (extwindowrenderer.material.shader != TransparentSpecularShader) - setCryopodWindowTransparent(i); - } - } - } + Utilities.SetInternalDepthMask(part, false, "CRY_0300_Doors_Occluder"); } - - break; - - default: - Utilities.Log_Debug("RPM set to OFF or AUTO for transparent pod"); - if (hasExternalDoor) //CRY-0300 + } + else //Podsetting is OFF or AUTO + { + //If pod is OFF or AUTO the Doors are CLOSED so if Stock Overlay is on we turn the overlay OFF so we can see inside + //This will be ok and the Internal should be there because when Stock Overlay is on TransparentPods turns itself OFF + if (Utilities.StockOverlayCamIsOn) { - //hasExternalDoor = false; - // We must close the doors if they are not or we see an empty internal. - - DoorState actualDoorState = getdoorState(); - if (actualDoorState != DoorState.CLOSED) - { - try - { - Animation anim; - Animation[] animators = part.internalModel.FindModelAnimators("DOORHandle"); - if (animators.Length > 0) - { - anim = animators[0]; - anim["DOORHandle"].speed = float.MinValue; - anim["DOORHandle"].normalizedTime = 1; - anim.Play("DOORHandle"); - } - ext_door.Play(); - } - catch (Exception ex) - { - Debug.Log("Exception trying to run the Doorhandle animation"); - Debug.Log("Err: " + ex); - } - if (animationName != null) - { - externalDoorAnim[animationName].normalizedTime = 1; - externalDoorAnim[animationName].speed = float.MinValue; - externalDoorAnim.Play("Open"); - } - _prevexterndoorstate = _externaldoorstate; - _externaldoorstate = DoorState.CLOSED; - } - Events["eventOpenDoors"].active = false; - Events["eventCloseDoors"].active = false; + Utilities.SetInternalDepthMask(part, false, "External_Window_Occluder"); } - else //CRY-0300R + else + //So Stock Overlay is off we want to see the CLOSED Doors so overlay is ON so we see the doors. { - for (int i = 0; i < FreezerSize; i++) - { - string windowname = "Cryopod-" + (i + 1) + "-Window"; - Renderer extwindowrenderer = part.FindModelComponent(windowname); - - if (extwindowrenderer != null) - { - if (extwindowrenderer.material.shader != KSPSpecularShader) - setCryopodWindowSpecular(i); - } - } + Utilities.SetInternalDepthMask(part, true, "External_Window_Occluder"); } - break; + } + + } + else //CRY-0300R + { + //The CRY-0300R is a bit backwards. Occluders when ON will SHOW the external part. + //So in the case of the CRY-0300R we want to SHOW the external PART when there is a frozen Kerbal only. + //But don't cycle the Occluder if a freeze or thaw is running otherwise we interrupt the nice freeze/thaw + //effect on the window glass. + if (IsThawActive || IsFreezeActive) + return; + if (!cryopodstateclosed[0] && transparentPodSetting == "ON") //No frozen kerbal inside + { + Utilities.SetInternalDepthMask(part, false, "External_Window_Occluder"); + + } + else //Frozen kerbal inside or OFF or AUTO model. + { + Utilities.SetInternalDepthMask(part, true, "External_Window_Occluder"); + } } - _prevRPMTransparentpodSetting = transparentPodSetting; } } } } catch (Exception) { - Utilities.Log("DeepFreezer Error checking RPM TransparentPod Setting"); + Utilities.Log("DeepFreezer Error setting RPM Occluders"); + //Utilities.Log("DeepFreezer ", ex.Message); + } + } + + private void noRPMPodOccluderProcessing() + { + try + { + //If RPM is not installed we need to set the depthshader occluders for the stock overlay processing. + //We have to process the occluders for the CRY-0300 and CRY-0300R for KSP 1.1 + if (HighLogic.LoadedSceneIsFlight && !Utilities.IsInIVA) + { + if (PartHasDoor) //If CRY-0300, set the door occluder ON so we see the closed/closing doors + { + //If Stock Overlay is on we turn the Occluder OFF so we can see inside. + //Otherwise is it ON. + if (Utilities.StockOverlayCamIsOn) + { + Utilities.SetInternalDepthMask(part, false, "CRY_0300_Doors_Occluder"); + } + else + { + Utilities.SetInternalDepthMask(part, true, "CRY_0300_Doors_Occluder"); + } + } + else //CRY-0300R + { + //The CRY-0300R is a bit backwards. Occluders when ON will SHOW the external part. + //So in the case of the CRY-0300R we want to SHOW the external PART when there is a frozen Kerbal only. + //But don't cycle the Occluder if a freeze or thaw is running otherwise we interrupt the nice freeze/thaw + //effect on the window glass. + + if (!cryopodstateclosed[0] && (!IsThawActive || !IsFreezeActive)) //No frozen kerbal inside + { + Utilities.SetInternalDepthMask(part, false, "External_Window_Occluder"); + + } + else //Frozen kerbal inside or freeze/thaw occuring. Can't see inside. + { + Utilities.SetInternalDepthMask(part, true, "External_Window_Occluder"); + } + } + } + } + catch (Exception) + { + Utilities.Log("DeepFreezer Error setting no RPM Occluders"); //Utilities.Log("DeepFreezer ", ex.Message); } } @@ -852,7 +1091,7 @@ private void onceoffSetup() resetCryopods(true); } - if (part.Modules.Contains("JSITransparentPod")) + if (part.Modules.Contains("JSIAdvTransparentPod")) { hasJSITransparentPod = true; } @@ -867,7 +1106,7 @@ private void onceoffSetup() } //If we have an external door (CRY-0300) enabled set the current door state and the helmet states - if (hasExternalDoor) + if (ExternalDoorActive) { setHelmetstoDoorState(); } @@ -1015,7 +1254,7 @@ private void FixedUpdate() { resetCryopods(true); } - if (hasExternalDoor) + if (ExternalDoorActive) { setHelmetstoDoorState(); setDoorHandletoDoorState(); @@ -1055,7 +1294,7 @@ private void ChkOngoingEC(PartInfo partInfo) Utilities.Log_Debug("DeepFreezer Running the freezer parms currenttime = {0} timeperiod = {1} ecreqd = {2}" , currenttime.ToString(), timeperiod.ToString(), ECreqd.ToString()); if (requireResource(vessel, EC, ECreqd, false, out ResAvail)) { - ScreenMessages.RemoveMessage(OnGoingECMsg); + if (OnGoingECMsg != null) ScreenMessages.RemoveMessage(OnGoingECMsg); //Have resource requireResource(vessel, EC, ECreqd, true, out ResAvail); FrznChargeUsage = (float)ResAvail; @@ -1085,7 +1324,7 @@ private void ChkOngoingEC(PartInfo partInfo) partInfo.ECWarning = true; deathCounter = currenttime; } - ScreenMessages.RemoveMessage(OnGoingECMsg); + if (OnGoingECMsg != null) ScreenMessages.RemoveMessage(OnGoingECMsg); OnGoingECMsg = ScreenMessages.PostScreenMessage(" Freezer Out of EC : Systems critical in " + (deathRoll - (currenttime - deathCounter)).ToString("######0") + " secs"); _FreezerOutofEC = true; FrznChargeUsage = 0f; @@ -1153,7 +1392,7 @@ private void ChkOngoingTemp(PartInfo partInfo) if (part.temperature < DeepFreeze.Instance.DFsettings.RegTempMonitor) { Utilities.Log_Debug("DeepFreezer Temperature check is good parttemp=" + part.temperature + ",MaxTemp=" + DeepFreeze.Instance.DFsettings.RegTempMonitor); - ScreenMessages.RemoveMessage(TempChkMsg); + if (TempChkMsg != null) ScreenMessages.RemoveMessage(TempChkMsg); _FrzrTmp = FrzrTmpStatus.OK; tmpdeathCounter = currenttime; // do warning if within 40 and 20 kelvin @@ -1186,7 +1425,7 @@ private void ChkOngoingTemp(PartInfo partInfo) } _FrzrTmp = FrzrTmpStatus.RED; Utilities.Log_Debug("DeepFreezer tmpdeathCounter = {0}" , tmpdeathCounter.ToString()); - ScreenMessages.RemoveMessage(TempChkMsg); + if (TempChkMsg != null) ScreenMessages.RemoveMessage(TempChkMsg); TempChkMsg = ScreenMessages.PostScreenMessage(" Freezer Over Temp : Systems critical in " + (tmpdeathRoll - (currenttime - tmpdeathCounter)).ToString("######0") + " secs"); if (currenttime - tmpdeathCounter > tmpdeathRoll) { @@ -1251,13 +1490,14 @@ public override void OnStart(StartState state) GameEvents.onCrewBoardVessel.Add(OnCrewBoardVessel); GameEvents.onCrewOnEva.Add(onCrewOnEva); GameEvents.onVesselDestroy.Add(onVesselDestroy); + GameEvents.OnCameraChange.Add(OnCameraChange); } //Set Shaders for changing the Crypod Windows HashSet shaders = new HashSet(); Resources.FindObjectsOfTypeAll().ToList().ForEach(sh => shaders.Add(sh)); List listshaders = new List(shaders); - TransparentSpecularShader = listshaders.Find(a => a.name == "Transparent/Specular"); + TransparentSpecularShader = listshaders.Find(a => a.name == "Legacy Shaders/Transparent/Specular"); KSPSpecularShader = listshaders.Find(b => b.name == "KSP/Specular"); // Setup the sounds @@ -1266,43 +1506,49 @@ public override void OnStart(StartState state) mon_beep = gameObject.AddComponent(); mon_beep.clip = GameDatabase.Instance.GetAudioClip("REPOSoftTech/DeepFreeze/Sounds/mon_beep"); mon_beep.volume = .2F; - mon_beep.panLevel = 0; + mon_beep.panStereo = 0; + mon_beep.spatialBlend = 0; mon_beep.rolloffMode = AudioRolloffMode.Logarithmic; - mon_beep.audio.maxDistance = 10f; - mon_beep.audio.minDistance = 8f; - mon_beep.audio.dopplerLevel = 0f; - mon_beep.audio.panLevel = 0f; - mon_beep.audio.playOnAwake = false; - mon_beep.audio.priority = 255; + mon_beep.maxDistance = 10f; + mon_beep.minDistance = 8f; + mon_beep.dopplerLevel = 0f; + //mon_beep.panLevel = 0f; + mon_beep.playOnAwake = false; + mon_beep.priority = 255; mon_beep.Stop(); flatline = gameObject.AddComponent(); flatline.clip = GameDatabase.Instance.GetAudioClip("REPOSoftTech/DeepFreeze/Sounds/flatline"); flatline.volume = 1; - flatline.panLevel = 0; + flatline.panStereo = 0; + mon_beep.spatialBlend = 0; flatline.rolloffMode = AudioRolloffMode.Linear; flatline.Stop(); hatch_lock = gameObject.AddComponent(); hatch_lock.clip = GameDatabase.Instance.GetAudioClip("REPOSoftTech/DeepFreeze/Sounds/hatch_lock"); hatch_lock.volume = .5F; - hatch_lock.panLevel = 0; + hatch_lock.panStereo = 0; + mon_beep.spatialBlend = 0; hatch_lock.rolloffMode = AudioRolloffMode.Linear; hatch_lock.Stop(); ice_freeze = gameObject.AddComponent(); ice_freeze.clip = GameDatabase.Instance.GetAudioClip("REPOSoftTech/DeepFreeze/Sounds/ice_freeze"); ice_freeze.volume = 1; - ice_freeze.panLevel = 0; + ice_freeze.panStereo = 0; + mon_beep.spatialBlend = 0; ice_freeze.rolloffMode = AudioRolloffMode.Linear; ice_freeze.Stop(); machine_hum = gameObject.AddComponent(); machine_hum.clip = GameDatabase.Instance.GetAudioClip("REPOSoftTech/DeepFreeze/Sounds/machine_hum"); machine_hum.volume = .2F; - machine_hum.panLevel = 0; + machine_hum.panStereo = 0; + mon_beep.spatialBlend = 0; machine_hum.rolloffMode = AudioRolloffMode.Linear; machine_hum.Stop(); ding_ding = gameObject.AddComponent(); ding_ding.clip = GameDatabase.Instance.GetAudioClip("REPOSoftTech/DeepFreeze/Sounds/ding_ding"); ding_ding.volume = .4F; - ding_ding.panLevel = 0; + ding_ding.panStereo = 0; + mon_beep.spatialBlend = 0; ding_ding.rolloffMode = AudioRolloffMode.Linear; ding_ding.Stop(); List databaseAudioFiles = new List(); @@ -1310,24 +1556,26 @@ public override void OnStart(StartState state) ext_door = gameObject.AddComponent(); ext_door.clip = GameDatabase.Instance.GetAudioClip("REPOSoftTech/DeepFreeze/Sounds/externaldoorswitch"); ext_door.volume = .7F; - ext_door.panLevel = 0; + ext_door.panStereo = 0; + mon_beep.spatialBlend = 0; ext_door.rolloffMode = AudioRolloffMode.Linear; ext_door.Stop(); charge_up = gameObject.AddComponent(); charge_up.clip = GameDatabase.Instance.GetAudioClip("REPOSoftTech/DeepFreeze/Sounds/charge_up"); charge_up.volume = 1; - charge_up.panLevel = 0; + charge_up.panStereo = 0; + mon_beep.spatialBlend = 0; charge_up.rolloffMode = AudioRolloffMode.Linear; charge_up.Stop(); } //If we have an external door (CRY-0300) check if RPM is installed, if not disable the door, otherwise set it's current state (open/closed). - if (animationName != string.Empty) + if (animationName != string.Empty && PartHasDoor) { externalDoorAnim = part.FindModelAnimators(animationName).FirstOrDefault(); if (externalDoorAnim == null) { Utilities.Log_Debug("Part has external animation defined but cannot find the animation on the part"); - hasExternalDoor = false; + ExternalDoorActive = false; Events["eventOpenDoors"].active = false; Events["eventCloseDoors"].active = false; if (transparentTransforms != string.Empty) @@ -1335,11 +1583,20 @@ public override void OnStart(StartState state) } else { - Utilities.Log_Debug("Part has external animation, check if RPM is installed and process"); - if (DFInstalledMods.IsRPMInstalled) + if (part.internalModel != null) { - Utilities.Log_Debug("RPM installed, set doorstate"); - hasExternalDoor = true; + externalDoorAnimOccluder = part.internalModel.FindModelAnimators(animationName).FirstOrDefault(); + } + else + { + externalDoorAnimOccluder = null; + Utilities.Log_Debug("No InternalModel found to check for external door occluder animation"); + } + Utilities.Log_Debug("Part has external animation, check if JSITransparentPods is installed and process"); + if (DFInstalledMods.IsJSITransparentPodsInstalled) + { + Utilities.Log_Debug("JSITransparentPods installed, set doorstate"); + ExternalDoorActive = true; if (_externaldoorstate == DoorState.OPEN) { StartCoroutine(openDoors(float.MaxValue)); @@ -1351,8 +1608,8 @@ public override void OnStart(StartState state) } else //RPM is not installed, disable the doors. { - Utilities.Log_Debug("RPM NOT installed, set transparent transforms"); - hasExternalDoor = false; + Utilities.Log_Debug("JSITransparentPods NOT installed, set transparent transforms"); + ExternalDoorActive = false; Events["eventOpenDoors"].active = false; Events["eventCloseDoors"].active = false; Utilities.Log_Debug("door actions/events off"); @@ -1393,6 +1650,7 @@ private void OnDestroy() GameEvents.onCrewBoardVessel.Remove(OnCrewBoardVessel); GameEvents.onCrewOnEva.Remove(onCrewOnEva); GameEvents.onVesselDestroy.Remove(onVesselDestroy); + GameEvents.OnCameraChange.Remove(OnCameraChange); Debug.Log("DeepFreezer END OnDestroy"); } @@ -1586,7 +1844,7 @@ private void ProcessFreezeKerbal() { requireResource(vessel, EC, ChargeRate, true, out ResAvail); StoredCharge = StoredCharge + ChargeRate; - ScreenMessages.RemoveMessage(FreezeMsg); + if (FreezeMsg != null) ScreenMessages.RemoveMessage(FreezeMsg); FreezeMsg = ScreenMessages.PostScreenMessage(" Cryopod - Charging: " + StoredCharge.ToString("######0")); if (DeepFreeze.Instance.DFsettings.RegTempReqd) { @@ -1595,7 +1853,7 @@ private void ProcessFreezeKerbal() Utilities.Log_Debug("DeepFreezer Drawing Charge StoredCharge =" + StoredCharge.ToString("0000.00") + " ChargeRequired =" + ChargeRequired); if (StoredCharge >= ChargeRequired) { - ScreenMessages.RemoveMessage(FreezeMsg); + if (FreezeMsg != null) ScreenMessages.RemoveMessage(FreezeMsg); if (requireResource(vessel, Glykerol, GlykerolRequired, true, out ResAvail)) { charge_up.Stop(); // stop the sound effects @@ -1613,6 +1871,7 @@ private void ProcessFreezeKerbal() case 2: //close the Pod door Hal Utilities.Log_Debug("Freeze Step 2"); + if (partHasInternals && isPodExternal) // Part has no animated cryopods but has internals. skip to step 3. { @@ -1841,7 +2100,7 @@ private void FreezeKerbalAbort(ProtoCrewMember CrewMember) { Utilities.Log_Debug("FreezeKerbalAbort " + CrewMember.name + " seat " + ToFrzeKerbalSeat); ScreenMessages.PostScreenMessage("Freezing Aborted", 5.0f, ScreenMessageStyle.UPPER_CENTER); - Utilities.setFrznKerbalLayer(CrewMember, true, false); + Utilities.setFrznKerbalLayer(part, CrewMember, true); if (partHasInternals) { if (vesselisinIVA || vesselisinInternal) @@ -1850,8 +2109,12 @@ private void FreezeKerbalAbort(ProtoCrewMember CrewMember) } if (isPartAnimated) openCryopod(ToFrzeKerbalSeat, float.MaxValue); - if (isPartAnimated || (isPodExternal && DFInstalledMods.IsRPMInstalled && _prevRPMTransparentpodSetting == "ON")) + if (isPartAnimated || (isPodExternal && DFInstalledMods.IsJSITransparentPodsInstalled && _prevRPMTransparentpodSetting == "ON")) thawCryopodWindow(ToFrzeKerbalSeat, float.MaxValue); + if (isPodExternal && !DFInstalledMods.IsJSITransparentPodsInstalled) + { + + } cryopodstateclosed[ToFrzeKerbalSeat] = false; savecryopodstatepersistent(); if (partHasStripLights && DeepFreeze.Instance.DFsettings.StripLightsActive) @@ -1864,7 +2127,6 @@ private void FreezeKerbalAbort(ProtoCrewMember CrewMember) { Debug.Log("FreezeKerbalAbort Procedure FAILED! Critical error"); } - IsFreezeActive = false; // Turn the Freezer actively freezing mode off FreezeStepInProgress = 0; ClosePodAnimPlaying = false; @@ -1874,15 +2136,10 @@ private void FreezeKerbalAbort(ProtoCrewMember CrewMember) charge_up.Stop(); StoredCharge = 0; // Discharge all EC stored UpdateCounts(); // Update the Crew counts - onvslchgInternal = true; - GameEvents.onVesselChange.Fire(vessel); - ScreenMessages.RemoveMessage(FreezeMsg); - //Add them from the GUIManager Portrait cams. - if (!KerbalGUIManager.ActiveCrew.Contains(CrewMember.KerbalRef)) - { - KerbalGUIManager.AddActiveCrew(CrewMember.KerbalRef); - KerbalGUIManager.PrintActiveCrew(); - } + //Add them to the portrait cams. + //Portraits.RestorePortrait(part, CrewMember.KerbalRef); + base.StartCoroutine(CallbackUtil.DelayedCallback(1, new Callback(this.fireOnVesselChange))); + if (FreezeMsg != null) ScreenMessages.RemoveMessage(FreezeMsg); } catch (Exception ex) { @@ -1902,7 +2159,7 @@ private void FreezeKerbalConfirm(ProtoCrewMember CrewMember) //Make them invisible if (partHasInternals) { - Utilities.setFrznKerbalLayer(CrewMember, false, false); + Utilities.setFrznKerbalLayer(part, CrewMember, false); } //Remove them if (!RemoveKerbal(CrewMember, ToFrzeKerbalSeat)) @@ -1942,6 +2199,19 @@ private void FreezeKerbalConfirm(ProtoCrewMember CrewMember) Utilities.Log("DeepFreeze Err: " + ex); } } + if (DFInstalledMods.IskerbalismInstalled) // IF Kerbalism Installed, remove tracking. + { + Utilities.Log_Debug("kerbalism installed untrack kerbal=" + CrewMember.name); + try + { + KBDisableKerbal(CrewMember.name, true); + } + catch (Exception ex) + { + Utilities.Log("DeepFreeze Exception attempting to untrack a kerbal in Kerbalism. Report this error on the Forum Thread."); + Utilities.Log("DeepFreeze Err: " + ex); + } + } ScreenMessages.PostScreenMessage(CrewMember.name + " frozen", 5.0f, ScreenMessageStyle.UPPER_CENTER); onvslchgInternal = true; @@ -1970,6 +2240,19 @@ private void USIUntrackKerbal(string crewmember) } } + private void KBDisableKerbal(string crewmember, bool disable) + //This will remove tracking of a frozen kerbal from USI Life Support MOD, so that they don't consume resources when they are thawed. + { + if (KBWrapper.APIReady) + { + KBWrapper.KBActualAPI.DisableKerbal(crewmember, disable); + } + else + { + Debug.Log("DeepFreeze has been unable to connect to Kerbalism mod. API is not ready. Report this error on the Forum Thread."); + } + } + private void USIUntrackVessel(string vesselId) //This will remove tracking of a frozen kerbal from USI Life Support MOD, so that they don't consume resources when they are thawed. { @@ -2032,7 +2315,7 @@ private void ProcessThawKerbal() { requireResource(vessel, EC, ChargeRate, true, out ResAvail); StoredCharge = StoredCharge + ChargeRate; - ScreenMessages.RemoveMessage(ThawMsg); + if (ThawMsg != null) ScreenMessages.RemoveMessage(ThawMsg); ThawMsg = ScreenMessages.PostScreenMessage(" Cryopod - Charging: " + StoredCharge.ToString("######0")); if (DeepFreeze.Instance.DFsettings.RegTempReqd) @@ -2042,7 +2325,7 @@ private void ProcessThawKerbal() if (StoredCharge >= ChargeRequired) { Utilities.Log_Debug("Stored charge requirement met. Have EC"); - ScreenMessages.RemoveMessage(ThawMsg); + if (ThawMsg != null) ScreenMessages.RemoveMessage(ThawMsg); charge_up.Stop(); ThawStepInProgress = 2; } @@ -2059,7 +2342,7 @@ private void ProcessThawKerbal() Utilities.Log_Debug("Thawing the cryopod window"); ice_freeze.Play(); ThawWindowAnimPlaying = true; - if (isPartAnimated || (isPodExternal && DFInstalledMods.IsRPMInstalled && _prevRPMTransparentpodSetting == "ON")) + if (isPartAnimated || (isPodExternal && DFInstalledMods.IsJSITransparentPodsInstalled && _prevRPMTransparentpodSetting == "ON")) thawCryopodWindow(ToThawKerbalSeat, 1f); if (partHasStripLights && DeepFreeze.Instance.DFsettings.StripLightsActive) { @@ -2250,10 +2533,16 @@ private void ThawKerbalStep0(string frozenkerbal) { Utilities.subdueIVAKerbalAnimations(kerbal.KerbalRef); } - Utilities.setFrznKerbalLayer(kerbal, true, false); //Set the Kerbal renderer layers on so they are visible again. + Utilities.setFrznKerbalLayer(part, kerbal, true); //Set the Kerbal renderer layers on so they are visible again. kerbal.KerbalRef.InPart = part; //Put their kerbalref back in the part. kerbal.KerbalRef.rosterStatus = ProtoCrewMember.RosterStatus.Assigned; codestep = 2; + //Add them to the portrait cams. + Portraits.RestorePortrait(part, kerbal.KerbalRef); + base.StartCoroutine(CallbackUtil.DelayedCallback(1, new Callback(this.fireOnVesselChange))); + base.StartCoroutine(CallbackUtil.DelayedCallback(5, new Callback(this.checkPortraitRegistered), kerbal.KerbalRef)); + Utilities.Log_Debug("Expected condition met, kerbal already in their seat."); + codestep = 3; try { if (DFInstalledMods.IsTexReplacerInstalled) @@ -2266,19 +2555,12 @@ private void ThawKerbalStep0(string frozenkerbal) Debug.Log("Exception attempting to restore Kerbals Texture Replacer mod customisations. Report this error on the Forum Thread."); Debug.Log("Err: " + ex); } - - codestep = 3; - KerbalGUIManager.AddActiveCrew(kerbal.KerbalRef); //Add them to the portrait cams. - Utilities.Log_Debug("Just thawing crew and added to GUIManager"); - KerbalGUIManager.PrintActiveCrew(); - //Utilities.setFrznKerbalLayer(kerbal, false, true); - Utilities.Log_Debug("Expected condition met, kerbal already in their seat."); + codestep = 4; // If in IVA mode set the camera to watch the process. if (vesselisinIVA || vesselisinInternal) setIVAFrzrCam(tmpcrew.SeatIdx); - - codestep = 4; - if (hasExternalDoor) + codestep = 5; + if (ExternalDoorActive) { //now set the helmet state depending on the external door state. if (_externaldoorstate == DoorState.CLOSED) @@ -2291,7 +2573,6 @@ private void ThawKerbalStep0(string frozenkerbal) } } Utilities.Log_Debug("Finishing ThawKerbalStep0"); - // Utilities.Log_Debug("Reference part after add=" + this.vessel.GetReferenceTransformPart().name + ",flightid=" + this.vessel.GetReferenceTransformPart().flightID); } catch (Exception ex) { @@ -2302,7 +2583,7 @@ private void ThawKerbalStep0(string frozenkerbal) ThawKerbalAbort(frozenkerbal); } } - else //Seat is taken, but not by our frozen KErbal, we can't continue. + else //Seat is taken, but not by our frozen Kerbal, we can't continue. { Utilities.Log_Debug("Seat taken by someone else, Abort"); Debug.Log("Could not start kerbal Thaw process as seat is taken by another kerbal. Very Very Bad. Report this to Mod thread"); @@ -2320,23 +2601,29 @@ private void ThawKerbalStep0(string frozenkerbal) try { part.internalModel.SitKerbalAt(kerbal, part.internalModel.seats[tmpcrew.SeatIdx]); - if (hasExternalDoor) + if (ExternalDoorActive) { //set the seat to allow helmet, this will cause the helmet to appear kerbal.seat.allowCrewHelmet = true; } codestep = 1; kerbal.seat.SpawnCrew(); - setseatstaticoverlay(part.internalModel.seats[tmpcrew.SeatIdx]); // Think this will get rid of the static that appears on the portrait camera + setseatstaticoverlay(part.internalModel.seats[tmpcrew.SeatIdx]); if (kerbal.KerbalRef != null) { Utilities.subdueIVAKerbalAnimations(kerbal.KerbalRef); } - Utilities.setFrznKerbalLayer(kerbal, true, false); //Set the Kerbal renderer layers on so they are visible again. + Utilities.setFrznKerbalLayer(part, kerbal, true); //Set the Kerbal renderer layers on so they are visible again. kerbal.KerbalRef.InPart = part; //Put their kerbalref back in the part. kerbal.KerbalRef.rosterStatus = ProtoCrewMember.RosterStatus.Assigned; codestep = 2; + //Add them to the portrait cams. + Portraits.RestorePortrait(part, kerbal.KerbalRef); + base.StartCoroutine(CallbackUtil.DelayedCallback(1, new Callback(this.fireOnVesselChange))); + base.StartCoroutine(CallbackUtil.DelayedCallback(5, new Callback(this.checkPortraitRegistered), kerbal.KerbalRef)); + Utilities.Log_Debug("Just thawing crew and added to GUIManager"); + codestep = 3; try { if (DFInstalledMods.IsTexReplacerInstalled) @@ -2349,16 +2636,11 @@ private void ThawKerbalStep0(string frozenkerbal) Debug.Log("Exception attempting to restore Kerbals Texture Replacer mod customisations. Report this error on the Forum Thread."); Debug.Log("Err: " + ex); } - - codestep = 3; - KerbalGUIManager.AddActiveCrew(kerbal.KerbalRef); //Add them to the portrait cams. - Utilities.Log_Debug("Just thawing crew and added to GUIManager"); - KerbalGUIManager.PrintActiveCrew(); codestep = 4; if (vesselisinIVA || vesselisinInternal) setIVAFrzrCam(tmpcrew.SeatIdx); codestep = 5; - if (hasExternalDoor) + if (ExternalDoorActive) { //now set the helmet state depending on the external door state. if (_externaldoorstate == DoorState.CLOSED) @@ -2467,9 +2749,9 @@ private void ThawKerbalAbort(String ThawKerbal) { if (isPartAnimated) closeCryopod(ToThawKerbalSeat, float.MaxValue); - Utilities.Log_Debug("Time freezewindow started " + Planetarium.GetUniversalTime()); + // Utilities.Log_Debug("Time freezewindow started " + Planetarium.GetUniversalTime()); freezeCryopodWindow(ToThawKerbalSeat, float.MaxValue); - Utilities.Log_Debug("Time freezewindow finished make them invisible " + Planetarium.GetUniversalTime()); + // Utilities.Log_Debug("Time freezewindow finished make them invisible " + Planetarium.GetUniversalTime()); cryopodstateclosed[ToThawKerbalSeat] = true; savecryopodstatepersistent(); if (partHasStripLights && DeepFreeze.Instance.DFsettings.StripLightsActive) @@ -2478,8 +2760,8 @@ private void ThawKerbalAbort(String ThawKerbal) } } //Make them invisible again - Utilities.setFrznKerbalLayer(kerbal, false, false); - ScreenMessages.RemoveMessage(ThawMsg); + Utilities.setFrznKerbalLayer(part, kerbal, false); + if (ThawMsg != null) ScreenMessages.RemoveMessage(ThawMsg); Utilities.Log_Debug("ThawkerbalAbort End"); } @@ -2559,6 +2841,19 @@ private void ThawKerbalStep4(String frozenkerbal) ding_ding.Play(); OpenPodAnimPlaying = false; onvslchgInternal = true; + if (DFInstalledMods.IskerbalismInstalled) // IF Kerbalism Installed, add tracking. + { + Utilities.Log_Debug("kerbalism installed track kerbal=" + frozenkerbal); + try + { + KBDisableKerbal(frozenkerbal, false); + } + catch (Exception ex) + { + Utilities.Log("DeepFreeze Exception attempting to track a kerbal in Kerbalism. Report this error on the Forum Thread."); + Utilities.Log("DeepFreeze Err: " + ex); + } + } GameEvents.onVesselChange.Fire(vessel); GameEvents.onVesselWasModified.Fire(vessel); Utilities.Log_Debug("ThawKerbalConfirm End"); @@ -2618,7 +2913,7 @@ private bool RemoveKerbal(ProtoCrewMember kerbal, int SeatIndx) ScreenMessages.PostScreenMessage("DeepFreezer mechanical failure", 5.0f, ScreenMessageStyle.UPPER_CENTER); return false; } - if (partHasInternals && hasExternalDoor) + if (partHasInternals && ExternalDoorActive) Utilities.setHelmetshaders(kerbal.KerbalRef, true); // remove the CrewMember from the part crewlist and unregister their traits, because they are frozen, and this is the only way to trick the game. kerbal.UnregisterExperienceTraits(part); @@ -2633,19 +2928,14 @@ private bool RemoveKerbal(ProtoCrewMember kerbal, int SeatIndx) part.internalModel.seats[SeatIndx].taken = true; // Set their seat to Taken, because they are really still there. :) seatTakenbyFrznKerbal[SeatIndx] = true; } - // Set our newly frozen Popsicle, er Kerbal, to Unowned type (usually a Crew) and Dead status. - kerbal.type = ProtoCrewMember.KerbalType.Unowned; - kerbal.rosterStatus = ProtoCrewMember.RosterStatus.Dead; if (kerbal.KerbalRef != null) { - kerbal.KerbalRef.InPart = null; //Remove them from the GUIManager Portrait cams. - if (KerbalGUIManager.ActiveCrew.Contains(kerbal.KerbalRef)) - { - KerbalGUIManager.RemoveActiveCrew(kerbal.KerbalRef); - KerbalGUIManager.PrintActiveCrew(); - } + Portraits.DestroyPortrait(kerbal.KerbalRef); } + // Set our newly frozen Popsicle, er Kerbal, to Unowned type (usually a Crew) and Dead status. + kerbal.type = ProtoCrewMember.KerbalType.Unowned; + kerbal.rosterStatus = ProtoCrewMember.RosterStatus.Dead; return true; } catch (Exception ex) @@ -2662,7 +2952,6 @@ private bool AddKerbal(ProtoCrewMember kerbal, int SeatIndx) Utilities.Log_Debug("Start AddKerbal " + kerbal.name); try { - //FrznCrewMbr tmpcrew = new FrznCrewMbr(kerbal.name, SeatIndx, this.vessel.id, this.vessel.name); try { FrznCrewMbr tmpcrew = _StoredCrewList.Find(a => a.CrewName == kerbal.name); // Find the thawed kerbal in the frozen kerbal list. @@ -2697,7 +2986,7 @@ private bool AddKerbal(ProtoCrewMember kerbal, int SeatIndx) ScreenMessages.PostScreenMessage("DeepFreezer mechanical failure", 5.0f, ScreenMessageStyle.UPPER_CENTER); return false; } - if (partHasInternals && hasExternalDoor) + if (partHasInternals && ExternalDoorActive) Utilities.setHelmetshaders(kerbal.KerbalRef, true); // add the CrewMember to the part crewlist and register their traits. kerbal.RegisterExperienceTraits(part); @@ -2730,19 +3019,15 @@ private bool AddKerbal(ProtoCrewMember kerbal, int SeatIndx) } seatTakenbyFrznKerbal[SeatIndx] = false; } - if (kerbal.KerbalRef != null) + /*if (kerbal.KerbalRef != null) { if (kerbal.KerbalRef.InPart == null) { kerbal.KerbalRef.InPart = part; } //Add themto the GUIManager Portrait cams. - if (!KerbalGUIManager.ActiveCrew.Contains(kerbal.KerbalRef)) - { - KerbalGUIManager.AddActiveCrew(kerbal.KerbalRef); - KerbalGUIManager.PrintActiveCrew(); - } - } + Portraits.RestorePortrait(kerbal.KerbalRef); + }*/ Utilities.Log_Debug("End AddKerbal"); return true; } @@ -2754,6 +3039,16 @@ private bool AddKerbal(ProtoCrewMember kerbal, int SeatIndx) } } + internal void checkPortraitRegistered(Kerbal kerbal) + { + List portraits = KerbalPortraitGallery.Instance.gameObject.GetComponentsInChildren().Where(a => a.crewMemberName == kerbal.crewMemberName).ToList(); + if (!portraits.Any()) + { + vessel.DespawnCrew(); + base.StartCoroutine(CallbackUtil.DelayedCallback(3, new Callback(this.delayedSpawCrew))); + } + } + #region CrewXfers //This region contains the methods for handling Crew Transfers correctly @@ -2847,21 +3142,9 @@ private void OnCrewTransferred(GameEvents.HostedFromToAction(); - if (messages != null) - { - var messagesToRemove = - messages.activeMessages.Where( - x => - x.startTime == message.startTime && - x.style == ScreenMessageStyle.LOWER_CENTER).ToList(); - foreach (var m in messagesToRemove) - ScreenMessages.RemoveMessage(m); - } xferisfromEVA = false; xferfromPart = fromToAction.from; xferfromSeat = fromToAction.host.seat; @@ -2881,7 +3164,7 @@ private void OnCrewTransferred(GameEvents.HostedFromToAction().Any(x => x is KerbalEVA)) // Kerbal is going EVA { @@ -2943,7 +3226,7 @@ private void OnCrewTransferred(GameEvents.HostedFromToAction().Any(x => x is KerbalEVA)) // Kerbal is entering from EVA @@ -2973,16 +3256,8 @@ private void OnCrewTransferred(GameEvents.HostedFromToAction(); - if (messages != null) - { - var messagesToRemove = messages.activeMessages.Where(x => x.startTime == message.startTime && x.style == ScreenMessageStyle.LOWER_CENTER).ToList(); - foreach (var m in messagesToRemove) - ScreenMessages.RemoveMessage(m); - } xferbackwhenFull = true; } timecrewXferTOfired = Time.time; @@ -2997,7 +3272,7 @@ private void completeCrewTransferProcessing() { Debug.Log("Crew XferTO Active, but freezer is full, revert Xfer"); xferBackifPartisFull(); - FlightEVA.fetch.EnableInterface(); + CrewHatchController.fetch.EnableInterface(); return; } @@ -3015,7 +3290,7 @@ private void completeCrewTransferProcessing() _crewXferFROMActive = false; crewXferSMActive = false; crewXferSMStock = false; - FlightEVA.fetch.EnableInterface(); + CrewHatchController.fetch.EnableInterface(); return; } @@ -3031,7 +3306,7 @@ private void completeCrewTransferProcessing() _crewXferTOActive = false; crewXferSMActive = false; crewXferSMStock = false; - FlightEVA.fetch.EnableInterface(); + CrewHatchController.fetch.EnableInterface(); return; } @@ -3054,7 +3329,7 @@ private void completeCrewTransferProcessing() _crewXferFROMActive = false; crewXferSMActive = false; crewXferSMStock = false; - FlightEVA.fetch.EnableInterface(); + CrewHatchController.fetch.EnableInterface(); Utilities.Log_Debug("DeepFreezer CrewXferFROM SMXfer Completed"); return; } @@ -3069,7 +3344,7 @@ private void completeCrewTransferProcessing() _crewXferFROMActive = false; crewXferSMActive = false; crewXferSMStock = false; - FlightEVA.fetch.EnableInterface(); + CrewHatchController.fetch.EnableInterface(); Utilities.Log_Debug("DeepFreezer CrewXferFROM Stock Completed"); return; } @@ -3112,7 +3387,7 @@ private void completeCrewTransferProcessing() _crewXferTOActive = false; crewXferSMActive = false; crewXferSMStock = false; - FlightEVA.fetch.EnableInterface(); + CrewHatchController.fetch.EnableInterface(); Utilities.Log_Debug("DeepFreezer CrewXferTO SMXfer Completed"); } } @@ -3137,15 +3412,15 @@ private void completeCrewTransferProcessing() foundseat = true; part.RemoveCrewmember(xfercrew); part.AddCrewmemberAt(xfercrew, i); - IvaUpdateActive = true; - IvaPortraitDelay = 0; + //IvaUpdateActive = true; + //IvaPortraitDelay = 0; break; } } if (!foundseat) //If we didn't find a seat Transfer them back. { xferBackifPartisFull(); - FlightEVA.fetch.EnableInterface(); + CrewHatchController.fetch.EnableInterface(); return; } } @@ -3155,7 +3430,7 @@ private void completeCrewTransferProcessing() resetFrozenKerbals(); if (xferisfromEVA) { - if (hasExternalDoor) + if (ExternalDoorActive) { setHelmetstoDoorState(); setDoorHandletoDoorState(); @@ -3180,7 +3455,7 @@ private void completeCrewTransferProcessing() _crewXferTOActive = false; crewXferSMActive = false; crewXferSMStock = false; - FlightEVA.fetch.EnableInterface(); + CrewHatchController.fetch.EnableInterface(); Utilities.Log_Debug("DeepFreezer CrewXferTO Stock Completed"); } else @@ -3199,7 +3474,7 @@ private void xferBackifPartisFull() if (xferisfromEVA) // if it was from EVA send them back outside. { Utilities.Log_Debug("DeepFreezer CrewXfer xferisfromEVA = true kick them out to EVA"); - if (hasExternalDoor) + if (ExternalDoorActive) { setHelmetstoDoorState(); setDoorHandletoDoorState(); @@ -3209,8 +3484,8 @@ private void xferBackifPartisFull() { resetCryopods(true); } - xferbackwhenFull = false; - FlightEVA.fetch.EnableInterface(); + xferbackwhenFull = false;; + CrewHatchController.fetch.EnableInterface(); xferisfromEVA = false; _crewXferTOActive = false; crewXferSMActive = false; @@ -3221,30 +3496,61 @@ private void xferBackifPartisFull() else // it wasn't from EVA so send them back to the part they came from. { Utilities.Log_Debug("DeepFreezer CrewXfer xferisfromEVA = false kick them out to from part"); - part.RemoveCrewmember(xfercrew); - xferfromPart.AddCrewmember(xfercrew); + xfercrew.UnregisterExperienceTraits(part); + part.protoModuleCrew.Remove(xfercrew); + if (part.internalModel != null) + { + part.internalModel.UnseatKerbal(xfercrew); + } + xferfromPart.protoModuleCrew.Add(xfercrew); + xfercrew.RegisterExperienceTraits(xferfromPart); + if (xferfromPart.internalModel != null) + { + InternalSeat seat = xferfromPart.internalModel.GetNextAvailableSeat(); + xferfromPart.internalModel.SitKerbalAt(xfercrew, seat); + } + else + { + xfercrew.seatIdx = -1; + xfercrew.seat = null; + } setseatstaticoverlay(xfercrew.seat); resetFrozenKerbals(); if (partHasInternals) { resetCryopods(true); } - IvaUpdateActive = true; - IvaPortraitDelay = 0; + base.StartCoroutine(CallbackUtil.DelayedCallback(3, new Callback(this.delayedSpawCrew))); } onvslchgInternal = true; xferbackwhenFull = false; - FlightEVA.fetch.EnableInterface(); + CrewHatchController.fetch.EnableInterface(); GameEvents.onVesselChange.Fire(vessel); ScreenMessages.PostScreenMessage("Freezer is Full, cannot enter at this time", 5.0f, ScreenMessageStyle.UPPER_CENTER); xferisfromEVA = false; _crewXferTOActive = false; crewXferSMActive = false; crewXferSMStock = false; - FlightEVA.fetch.EnableInterface(); + CrewHatchController.fetch.EnableInterface(); Utilities.Log_Debug("Transfer back if Part is FULL ended"); } + //Delayed corountine to fire an internal onvesselchange, this forces the portraits system to refresh + internal void fireOnVesselChange() + { + onvslchgInternal = true; + GameEvents.onVesselChange.Fire(vessel); + } + + //For crew Xfer borked by a full freezer and we transfer them back we have to spawn the vessel crew then fire the onvesselchange to get the + // portraits system to refresh + internal void delayedSpawCrew() + { + vessel.SpawnCrew(); + resetFrozenKerbals(); + fireOnVesselChange(); + } + // this is called when a vessel change event fires. // Triggered when switching to a different vessel, loading a vessel, or launching private void OnVesselChange(Vessel vessel) @@ -3276,10 +3582,7 @@ private void OnVesselChange(Vessel vessel) loadcryopodstatepersistent(); loadexternaldoorstatepersistent(); resetFrozenKerbals(); - if (!hasJSITransparentPod) - { - Utilities.CheckPortraitCams(vessel); - } + resetCryopods(true); } else { @@ -3292,6 +3595,12 @@ private void OnVesselChange(Vessel vessel) } } + // when the camera mode changes reset the frozen kerbal portrait cams. + private void OnCameraChange(CameraManager.CameraMode cammode) + { + resetFrozenPortraits(); + } + // this is called when vessel is destroyed. // Triggered when a vessel instance is destroyed; any time a vessel is unloaded, // ie scene changes, exiting loading distance @@ -3312,17 +3621,40 @@ private void onVesselDestroy(Vessel vessel) FreezeKerbalAbort(ActiveFrzKerbal); } } + + /// + /// This Method will get a list of all frozen kerbals in this part and remove their Portrait Cameras from the PortraitGallery if there is one. + /// It is called when GameEvent OnCameraChange is fired. + /// + internal void resetFrozenPortraits() + { + // create a list of kerbal that are in this part in this vessel & they are not comatose/tourist + List> FrznKerbalsinPart = + DeepFreeze.Instance.DFgameSettings.KnownFrozenKerbals.Where( + e => + e.Value.partID == CrntPartID && e.Value.vesselID == CrntVslID && + e.Value.type != ProtoCrewMember.KerbalType.Tourist).ToList(); + for (int i = 0; i < FrznKerbalsinPart.Count; i++) + { + ProtoCrewMember crewmember = HighLogic.CurrentGame.CrewRoster.Unowned.FirstOrDefault(a => a.name == FrznKerbalsinPart[i].Key); + if (crewmember != null) + { + Portraits.DestroyPortrait(crewmember.KerbalRef); + } + } + } internal void resetFrozenKerbals() { try { - // Create a list of kerbals that are in InvSeats (SeatIndx == -1 where kerbal is in this part in this vessel & they are not comatose/tourist + // Create a list of kerbals that are in Invalid Seats (SeatIndx == -1 where kerbal is in this part in this vessel & they are not comatose/tourist List> kerbalsInvSeats = DeepFreeze.Instance.DFgameSettings.KnownFrozenKerbals.Where(e => e.Value.partID == CrntPartID && e.Value.vesselID == CrntVslID && e.Value.type != ProtoCrewMember.KerbalType.Tourist && e.Value.seatIdx == -1).ToList(); // create a list of kerbal that are in this part in this vessel & they are not comatose/tourist List> FrznKerbalsinPart = DeepFreeze.Instance.DFgameSettings.KnownFrozenKerbals.Where(e => e.Value.partID == CrntPartID && e.Value.vesselID == CrntVslID && e.Value.type != ProtoCrewMember.KerbalType.Tourist).ToList(); - - if (kerbalsInvSeats.Any()) //If we found any Invalid Seat assignments we need to find them empty seats + + //If we found any Invalid Seat assignments we need to find them empty seats + if (kerbalsInvSeats.Any()) { bool[] seatIndxs = new bool[FreezerSize]; //Create a bool array to store whether seats are taken or not //go through all the frozen kerbals in the part that don't have invalid seats and set bool array seat index to true (taken) for each @@ -3352,6 +3684,7 @@ internal void resetFrozenKerbals() } } } + // Iterate through the dictionary of all known frozen kerbals where kerbal is in this part in this vessel & they are not comatose/tourist foreach (KeyValuePair kerbal in FrznKerbalsinPart) { @@ -3365,45 +3698,50 @@ internal void resetFrozenKerbals() _StoredCrewList.Add(fzncrew); } - //check if they are in part spawned, if not do so. + //check if they are in the part and spawned, if not do so. ProtoCrewMember crewmember = HighLogic.CurrentGame.CrewRoster.Unowned.FirstOrDefault(a => a.name == kerbal.Key); - if (partHasInternals) + if (crewmember != null) { - crewmember.seatIdx = kerbal.Value.seatIdx; - if (crewmember.seatIdx != -1 && crewmember.seatIdx < FreezerSize) - crewmember.seat = part.internalModel.seats[crewmember.seatIdx]; - if (crewmember.KerbalRef == null) - { - crewmember.Spawn(); - } - crewmember.KerbalRef.transform.parent = part.internalModel.seats[crewmember.seatIdx].seatTransform; - crewmember.KerbalRef.transform.localPosition = Vector3.zero; - crewmember.KerbalRef.transform.localRotation = Quaternion.identity; - crewmember.KerbalRef.InPart = null; - if (hasExternalDoor) - { - //set the seat to allow helmet, this will cause the helmet to appear - crewmember.KerbalRef.showHelmet = true; - } - else + if (partHasInternals) { - crewmember.KerbalRef.showHelmet = false; - crewmember.KerbalRef.ShowHelmet(false); + crewmember.seatIdx = kerbal.Value.seatIdx; + if (crewmember.seatIdx != -1 && crewmember.seatIdx < FreezerSize) + crewmember.seat = part.internalModel.seats[crewmember.seatIdx]; + if (crewmember.KerbalRef == null) + { + crewmember.Spawn(); + } + crewmember.KerbalRef.transform.parent = + part.internalModel.seats[crewmember.seatIdx].seatTransform; + crewmember.KerbalRef.transform.localPosition = Vector3.zero; + crewmember.KerbalRef.transform.localRotation = Quaternion.identity; + crewmember.KerbalRef.InPart = null; + if (ExternalDoorActive) + { + //set the seat to allow helmet, this will cause the helmet to appear + crewmember.KerbalRef.showHelmet = true; + } + else + { + crewmember.KerbalRef.showHelmet = false; + crewmember.KerbalRef.ShowHelmet(false); + } + seatTakenbyFrznKerbal[crewmember.seatIdx] = true; + //setup seat and part settings for frozen kerbal. + Utilities.setFrznKerbalLayer(part, crewmember, false); + part.internalModel.seats[crewmember.seatIdx].taken = true; + part.internalModel.seats[crewmember.seatIdx].kerbalRef = crewmember.KerbalRef; + part.internalModel.seats[crewmember.seatIdx].crew = crewmember; + setseatstaticoverlay(part.internalModel.seats[crewmember.seatIdx]); } - seatTakenbyFrznKerbal[crewmember.seatIdx] = true; - //setup seat and part settings for frozen kerbal. - Utilities.setFrznKerbalLayer(crewmember, false, false); - part.internalModel.seats[crewmember.seatIdx].taken = true; - part.internalModel.seats[crewmember.seatIdx].kerbalRef = crewmember.KerbalRef; - part.internalModel.seats[crewmember.seatIdx].crew = crewmember; - setseatstaticoverlay(part.internalModel.seats[crewmember.seatIdx]); + //Unregister their traits/abilities and remove them from the Portrait Cameras if they are there. + crewmember.UnregisterExperienceTraits(part); + part.protoModuleCrew.Remove(crewmember); + Portraits.DestroyPortrait(crewmember.KerbalRef); } - //Unregister their traits/abilities and remove them from the Portrait Cameras if they are there. - crewmember.UnregisterExperienceTraits(part); - part.protoModuleCrew.Remove(crewmember); - if (KerbalGUIManager.ActiveCrew.Contains(crewmember.KerbalRef)) + else { - KerbalGUIManager.RemoveActiveCrew(crewmember.KerbalRef); + Utilities.Log("DeepFreezer Error attempting to resetFrozenKerbal {0}, cannot find them in the Roster", kerbal.Key); } } } @@ -3445,14 +3783,15 @@ private void UpdateCounts() // reset seats to TAKEN for all frozen kerbals in the part, check KerbalRef is still in place or re-instantiate it and check frozen kerbals // are not appearing in the Portrait Cameras, if they are remove them. //Utilities.Log_Debug("DeepFreezer StoredCrewList"); - foreach (FrznCrewMbr lst in _StoredCrewList) + for (int i = 0; i < _StoredCrewList.Count; i++) + //{ + // foreach (FrznCrewMbr lst in _StoredCrewList) { + FrznCrewMbr lst = _StoredCrewList[i]; part.internalModel.seats[lst.SeatIdx].taken = true; - seatTakenbyFrznKerbal[lst.SeatIdx] = true; - if (partHasInternals) - { - setCryopodWindowSpecular(lst.SeatIdx); - } + seatTakenbyFrznKerbal[lst.SeatIdx] = true; + setCryopodWindowSpecular(lst.SeatIdx); + ProtoCrewMember kerbal = HighLogic.CurrentGame.CrewRoster.Unowned.FirstOrDefault(a => a.name == lst.CrewName); if (kerbal == null) { @@ -3463,24 +3802,17 @@ private void UpdateCounts() if (kerbal.KerbalRef == null) // Check if the KerbalRef is null, as this causes issues with CrewXfers, if it is, respawn it. { Utilities.Log_Debug("Kerbalref = null"); - kerbal.rosterStatus = ProtoCrewMember.RosterStatus.Dead; - kerbal.type = ProtoCrewMember.KerbalType.Unowned; part.internalModel.seats[lst.SeatIdx].crew = kerbal; part.internalModel.seats[lst.SeatIdx].SpawnCrew(); // This spawns the Kerbal and sets the seat.kerbalref setseatstaticoverlay(part.internalModel.seats[lst.SeatIdx]); - //Remove them from the GUIManager Portrait cams. - if (KerbalGUIManager.ActiveCrew.Contains(kerbal.KerbalRef)) - { - KerbalGUIManager.RemoveActiveCrew(kerbal.KerbalRef); - KerbalGUIManager.PrintActiveCrew(); - } + kerbal.KerbalRef.InPart = null; + kerbal.rosterStatus = ProtoCrewMember.RosterStatus.Dead; + kerbal.type = ProtoCrewMember.KerbalType.Unowned; } - Utilities.setFrznKerbalLayer(kerbal, false, false); // Double check kerbal is invisible. + //Remove them from the GUIManager Portrait cams. + Portraits.DestroyPortrait(kerbal.KerbalRef); + Utilities.setFrznKerbalLayer(part, kerbal, false); // Double check kerbal is invisible. } - string kerblrefstring; - if (part.internalModel.seats[lst.SeatIdx].kerbalRef == null) kerblrefstring = "kerbalref not found"; - else kerblrefstring = part.internalModel.seats[lst.SeatIdx].kerbalRef.crewMemberName; - //Utilities.Log_Debug("DeepFreezer Frozen Crew SeatIdx= " + lst.SeatIdx + ",Seattaken=" + this.part.internalModel.seats[lst.SeatIdx].taken + ",KerbalRef=" + kerblrefstring); } } //Utilities.Log_Debug("DeepFreezer UpdateCounts end"); @@ -3556,7 +3888,7 @@ private void loadcryopodstatepersistent() cryopodstateclosed[i] = bool.Parse(cryopodstatestring[i]); } } - Debug.Log("Load cryopodstatepersistent value " + cryopodstateclosedstring); + //Debug.Log("Load cryopodstatepersistent value " + cryopodstateclosedstring); } catch (Exception ex) { @@ -3574,7 +3906,7 @@ private void savecryopodstatepersistent() { cryopodstateclosedstring = string.Empty; cryopodstateclosedstring = string.Join(", ", cryopodstateclosed.Select(b => b.ToString()).ToArray()); - Debug.Log("Save cryopodstatepersistent value " + cryopodstateclosedstring); + //Debug.Log("Save cryopodstatepersistent value " + cryopodstateclosedstring); } catch (Exception ex) { @@ -3589,7 +3921,7 @@ public void resetCryopods(bool resetall) try { // If resetall is true we check the last time a resetall was done, if it is within cryopodREsettimeDelay seconds - // we skil this resetcryopods call (so we don't see flickering). + // we skip this resetcryopods call (so we don't see flickering). //Otherwise we set all cryopodstatclosed to true which will force processing further down to open pods that // may already be open , regardless. if (resetall) @@ -3628,9 +3960,7 @@ public void resetCryopods(bool resetall) if (isPartAnimated) closeCryopod(i, float.MaxValue); cryopodstateclosed[i] = true; - // Utilities.Log_Debug("Time freezewindow started " + Planetarium.GetUniversalTime()); freezeCryopodWindow(i, float.MaxValue); - // Utilities.Log_Debug("Time freezewindow finished make them invisible " + Planetarium.GetUniversalTime()); } else { @@ -3647,13 +3977,15 @@ public void resetCryopods(bool resetall) { openCryopod(i, float.MaxValue); } - thawCryopodWindow(i, float.MaxValue); + if (isPartAnimated || (isPodExternal && DFInstalledMods.IsJSITransparentPodsInstalled && _prevRPMTransparentpodSetting == "ON")) + thawCryopodWindow(i, float.MaxValue); cryopodstateclosed[i] = false; } else { - Utilities.Log_Debug("pod is already open"); - thawCryopodWindow(i, float.MaxValue); + Utilities.Log_Debug("pod is already open"); + if (isPartAnimated || (isPodExternal && DFInstalledMods.IsJSITransparentPodsInstalled && _prevRPMTransparentpodSetting == "ON")) + thawCryopodWindow(i, float.MaxValue); } } setseatstaticoverlay(part.internalModel.seats[i]); @@ -3670,7 +4002,6 @@ public void resetCryopods(bool resetall) private void openCryopod(int seatIndx, float speed) //only called for animated internal parts { string podname = "Animated-Cryopod-" + (seatIndx + 1); - string windowname = "Animated-Cryopod-" + (seatIndx + 1) + "-Window"; try { _animation = part.internalModel.FindModelComponent(podname); @@ -3708,6 +4039,7 @@ private void thawCryopodWindow(int seatIndx, float speed) if (isPodExternal) { _extwindowAnimation = part.FindModelComponent(windowname); + Utilities.SetInternalDepthMask(part, false, "External_Window_Occluder"); //Set window occluder off } if (_windowAnimation == null) @@ -3718,11 +4050,11 @@ private void thawCryopodWindow(int seatIndx, float speed) { _windowAnimation["CryopodWindowOpen"].speed = speed; _windowAnimation.Play("CryopodWindowOpen"); - if (isPodExternal && _extwindowAnimation != null) - { - _extwindowAnimation["CryopodWindowOpen"].speed = speed; - _extwindowAnimation.Play("CryopodWindowOpen"); - } + } + if (isPodExternal && _extwindowAnimation != null) + { + _extwindowAnimation["CryopodWindowOpen"].speed = speed; + _extwindowAnimation.Play("CryopodWindowOpen"); } } @@ -3736,6 +4068,7 @@ private void setCryopodWindowOpaque(int seatIndx) windowname = "Animated-Cryopod-" + (seatIndx + 1) + "-Window"; else windowname = "Cryopod-" + (seatIndx + 1) + "-Window"; + Renderer windowrenderer = part.internalModel.FindModelComponent(windowname); if (windowrenderer != null) { @@ -3772,15 +4105,18 @@ private void setCryopodWindowSpecular(int seatIndx) if (isPartAnimated) windowname = "Animated-Cryopod-" + (seatIndx + 1) + "-Window"; else - windowname = "Cryopod-" + (seatIndx + 1) + "-Window"; + windowname = "Cryopod-" + (seatIndx + 1) + "-Window"; Renderer windowrenderer = part.internalModel.FindModelComponent(windowname); Renderer extwindowrenderer = null; if (isPodExternal) extwindowrenderer = part.FindModelComponent(windowname); - if (windowrenderer != null && windowrenderer.material.shader != KSPSpecularShader) - windowrenderer.material.shader = KSPSpecularShader; + if (windowrenderer != null) + { + if (windowrenderer.material.shader != KSPSpecularShader) + windowrenderer.material.shader = KSPSpecularShader; + } if (isPodExternal && extwindowrenderer != null) { @@ -3852,7 +4188,7 @@ private void startStripLightFlash(int seatIndx) private void freezeCryopodWindow(int seatIndx, float speed) { - if (isPartAnimated || (isPodExternal && DFInstalledMods.IsRPMInstalled && _prevRPMTransparentpodSetting == "ON")) + if (isPartAnimated || (isPodExternal && DFInstalledMods.IsJSITransparentPodsInstalled && _prevRPMTransparentpodSetting == "ON")) setCryopodWindowTransparent(seatIndx); else speed = float.MaxValue; @@ -3867,6 +4203,7 @@ private void freezeCryopodWindow(int seatIndx, float speed) if (isPodExternal) { _extwindowAnimation = part.FindModelComponent(windowname); + Utilities.SetInternalDepthMask(part, true, "External_Window_Occluder"); //Set window occluder visible (block internals) } if (_windowAnimation == null) @@ -3877,11 +4214,11 @@ private void freezeCryopodWindow(int seatIndx, float speed) { _windowAnimation["CryopodWindowClose"].speed = speed; _windowAnimation.Play("CryopodWindowClose"); - if (isPodExternal && _extwindowAnimation != null) - { - _extwindowAnimation["CryopodWindowClose"].speed = speed; - _extwindowAnimation.Play("CryopodWindowClose"); - } + } + if (isPodExternal && _extwindowAnimation != null) + { + _extwindowAnimation["CryopodWindowClose"].speed = speed; + _extwindowAnimation.Play("CryopodWindowClose"); } } @@ -3895,11 +4232,14 @@ private void setCryopodWindowTransparent(int seatIndx) windowname = "Animated-Cryopod-" + (seatIndx + 1) + "-Window"; else windowname = "Cryopod-" + (seatIndx + 1) + "-Window"; - Renderer windowrenderer = part.internalModel.FindModelComponent(windowname); + Renderer windowrenderer = part.internalModel.FindModelComponent(windowname); + if (windowrenderer != null) + { windowrenderer.material.shader = TransparentSpecularShader; Color savedwindowcolor = windowrenderer.material.color; savedwindowcolor.a = 0.3f; windowrenderer.material.color = savedwindowcolor; + } if (isPodExternal) { @@ -3999,8 +4339,14 @@ private IEnumerator openDoors(float speed) { externalDoorAnim[animationName].normalizedTime = 0; externalDoorAnim[animationName].speed = speed; - externalDoorAnim.Play("Open"); - IEnumerator wait = Utilities.WaitForAnimation(externalDoorAnim, "Open"); + if (externalDoorAnimOccluder != null) + { + externalDoorAnimOccluder[animationName].normalizedTime = 0; + externalDoorAnimOccluder[animationName].speed = speed; + externalDoorAnimOccluder.Play(animationName); + } + externalDoorAnim.Play(animationName); + IEnumerator wait = Utilities.WaitForAnimation(externalDoorAnim, animationName); while (wait.MoveNext()) yield return null; } Events["eventCloseDoors"].active = true; @@ -4018,8 +4364,14 @@ private IEnumerator closeDoors(float speed) { externalDoorAnim[animationName].normalizedTime = 1; externalDoorAnim[animationName].speed = speed; - externalDoorAnim.Play("Open"); - IEnumerator wait = Utilities.WaitForAnimation(externalDoorAnim, "Open"); + if (externalDoorAnimOccluder != null) + { + externalDoorAnimOccluder[animationName].normalizedTime = 1; + externalDoorAnimOccluder[animationName].speed = speed; + externalDoorAnimOccluder.Play(animationName); + } + externalDoorAnim.Play(animationName); + IEnumerator wait = Utilities.WaitForAnimation(externalDoorAnim, animationName); while (wait.MoveNext()) yield return null; } Events["eventOpenDoors"].active = true; @@ -4045,11 +4397,10 @@ private void setDoorHandletoDoorState() { try { - Animation anim; Animation[] animators = part.internalModel.FindModelAnimators("DOORHandle"); if (animators.Length > 0) { - anim = animators[0]; + var anim = animators[0]; anim["DOORHandle"].speed = float.MaxValue; anim["DOORHandle"].normalizedTime = 0; anim.Play("DOORHandle"); @@ -4104,7 +4455,7 @@ private void saveexternaldoorstatepersistent() strexternaldoorstate = "CLOSED"; } if (_prevexterndoorstate == DoorState.OPEN || _externaldoorstate == DoorState.OPENING) - { + { strprevexterndoorstate = "OPEN"; } else @@ -4207,7 +4558,7 @@ public static void FixedBackgroundUpdate(Vessel v, uint partFlightID, Func= (float)Ecreqd * 0.99) { - ScreenMessages.RemoveMessage(OnGoingECMsg); + if (OnGoingECMsg != null) ScreenMessages.RemoveMessage(OnGoingECMsg); partInfo.timeLastElectricity = (float)currenttime; partInfo.deathCounter = currenttime; partInfo.outofEC = false; @@ -4223,7 +4574,7 @@ public static void FixedBackgroundUpdate(Vessel v, uint partFlightID, Func + + + + + + + + + + squadcore + + \ No newline at end of file diff --git a/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/KSPedia/deepfreeze_kspedia.xml b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/KSPedia/deepfreeze_kspedia.xml new file mode 100644 index 0000000..8afade4 --- /dev/null +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/KSPedia/deepfreeze_kspedia.xml @@ -0,0 +1,68 @@ + + + + + DeepFreeze + DeepFreezeMain + + + + DeepFreeze Parts + DeepFreezeParts + + + + + + + + + deepfreeze + Assets/KSPedia/DeepFreezeParts.prefab + + <Background /> + <Text> + <Text Name="headingText"> + <Text>DeepFreeze</Text> + </Text> + <Text Name="TextDesc1"> + <Text>The CRY-0300 has animated doors and the CRY-0300R is transparent (with RasterPropMonitor installed). Both can hold One Kerbal and are equipped with one Cryopod. The CRY-0300R can be radially attached.</Text> + </Text> + <Text Name="TextDesc2"> + <Text>All DeepFreeze Freezers come with a built-in Glykerol storage tank of various capacities. But the Radial Glykerol Tank allows you to bring along extra Glykerol if required.</Text> + </Text> + <Text Name="TextDesc3"> + <Text>The CRY-1300 is a 2.5M Freezer with three Cryopod (kerbal) capacity.</Text> + </Text> + <Text Name="TextDesc4"> + <Text>The CRY-2300 is a 2.5M Freeze with ten Cryopod (kerbal) capacity.</Text> + </Text> + <Text Name="TextDesc5"> + <Text>The CRY-5000 (4 Cryopod) and the X200 Glykerol Container are actually distributed as part of the KPBS Mod but are DeepFreeze parts (and dependant) made to fit-in and be part of KPBS mod. </Text> + </Text> + </Text> + <Tooltips /> + </Screen> + <Screen Name="DeepFreezeMain"> + <BundleName>deepfreeze</BundleName> + <AssetPath>Assets/KSPedia/DeepFreezeMain.prefab</AssetPath> + <Title /> + <Background /> + <Text> + <Text Name="headingText"> + <Text>DeepFreeze</Text> + </Text> + <Text Name="TextDescription"> + <Text>DeepFreeze is a Mod that allows you to Freeze Kerbals using the magic of Glykerol and Electricity. Whilst frozen Kerbals will not consume any resources (from Life Support Mods).</Text> + </Text> + <Text Name="TextParts"> + <Text>DeepFreeze Freezer Parts come in a variety of sizes. From the CRY-0300 and CRY-0300R Single Kerbal Freezers right up to the 10 kerbal capacity CRY-2300.</Text> + </Text> + <Text Name="TextGUI"> + <Text>The GUI Window allows easy access to monitor all your vessels equiped with DeepFreezer parts and buttons to freeze and thaw your Kerbals.</Text> + </Text> + </Text> + <Tooltips /> + </Screen> + </Screens> +</KSPedia> \ No newline at end of file diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/MMDeepFreezeCLS.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/MMDeepFreezeCLS.cfg similarity index 81% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/MMDeepFreezeCLS.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/MMDeepFreezeCLS.cfg index 2ba7dea..d15783e 100644 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/MMDeepFreezeCLS.cfg +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/MMDeepFreezeCLS.cfg @@ -1,12 +1,3 @@ -@PART[cryofreezer]:HAS[!MODULE[ModuleConnectedLivingSpace]]:NEEDS[ConnectedLivingSpace] -{ - MODULE - { - name = ModuleConnectedLivingSpace - passable = true - } -} - @PART[CRY-2300Freezer]:HAS[!MODULE[ModuleConnectedLivingSpace]]:NEEDS[ConnectedLivingSpace] { MODULE diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/MMDeepFreezeCTT.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/MMDeepFreezeCTT.cfg similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/MMDeepFreezeCTT.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/MMDeepFreezeCTT.cfg diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC Licence.txt b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC Licence.txt similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC Licence.txt rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC Licence.txt diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC.dll b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC.dll similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC.dll rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC.dll diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC.xml b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC.xml similarity index 87% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC.xml rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC.xml index a16c6eb..b98b8b2 100644 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC.xml +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/MiniAVC.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <AddonSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <AllowCheck>true</AllowCheck> - <FirstRun>true</FirstRun> + <FirstRun>false</FirstRun> </AddonSettings> \ No newline at end of file diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300Freezer.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300Freezer.cfg similarity index 91% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300Freezer.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300Freezer.cfg index 5de0f5b..f6dbcb6 100644 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300Freezer.cfg +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300Freezer.cfg @@ -9,7 +9,7 @@ PART { model = REPOSoftTech/DeepFreeze/Assets/CRY-0300Freezer texture = CRY0300_color, REPOSoftTech/DeepFreeze/Assets/CRY0300_color - texture = CRY0300_bump_NRM, REPOSoftTech/DeepFreeze/Assets/CRY0300_bump_NRM + texture = CRY0300_bump, REPOSoftTech/DeepFreeze/Assets/CRY0300_bump texture = CryopodCushionColor, REPOSoftTech/DeepFreeze/Assets/CryopodCushionColor } @@ -37,6 +37,7 @@ there is a risk of frozen Kerbals dying. vesselType = Ship CrewCapacity = 1 bulkheadProfiles = size1 + tags = deepfreeze cryogenic freezer INTERNAL { name = Cry-0300Internals @@ -56,7 +57,8 @@ there is a risk of frozen Kerbals dying. ChargeRate = 30 FrznChargeRequired = 10 isPartAnimated = True - animationName = Open + PartHasDoor = True + animationName = OpenDoors cryopodstateclosedstring = True } } diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RFreezer.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RFreezer.cfg similarity index 78% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RFreezer.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RFreezer.cfg index 3245806..3b95118 100644 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RFreezer.cfg +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RFreezer.cfg @@ -12,10 +12,23 @@ PART texture = CryopodTexture, REPOSoftTech/DeepFreeze/Assets/CryopodTexture texture = RadialCryopodTexture, REPOSoftTech/DeepFreeze/Assets/RadialCryopodTexture } - - //node_attach = 0.0, 0.0, 0.312, 0.0, 0.0, -1.0 - node_attach = 0.0, 0.0, 0.352, 0.0, 0.0, -1.0 - node_stack_top = 0.0, 0.667, 0.0, 0.0, 1.0, 0.0, 0 + NODE + { + name = TopNode + transform = TopNode + size = 1 + method = FIXED_JOINT + } + //NODE + //{ + // name = BackNode + // transform = BackNode + // size = 1 + // method = FIXED_JOINT + //} + node_attach = 0.0, 0.0, 0.312, 0.0, 0.0, -1.0 + //node_attach = 0.0, 0.0, 0.452, 0.0, 0.0, -1.0 + //node_stack_top = 0.0, 0.667, 0.0, 0.0, 1.0, 0.0, 0 TechRequired = spaceExploration entryCost = 8000 cost = 4000 @@ -38,6 +51,8 @@ there is a risk of frozen Kerbals dying. vesselType = Ship CrewCapacity = 1 bulkheadProfiles = size1 + tags = deepfreeze cryogenic freezer + INTERNAL { name = Cry-0300RInternals @@ -57,7 +72,8 @@ there is a risk of frozen Kerbals dying. ChargeRate = 30 FrznChargeRequired = 10 isPartAnimated = False - isPodExternal = True + isPodExternal = True + PartHasDoor = False cryopodstateclosedstring = True } } diff --git a/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RPMInternalsMM.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RPMInternalsMM.cfg new file mode 100644 index 0000000..e6daba9 --- /dev/null +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RPMInternalsMM.cfg @@ -0,0 +1,7 @@ +@PART[CRY-0300Freezer]:FOR[DeepFreeze]:NEEDS[JSIAdvTransparentPods] +{ + MODULE + { + name = JSIAdvTransparentPod + } +} \ No newline at end of file diff --git a/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RRPMInternalsMM.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RRPMInternalsMM.cfg new file mode 100644 index 0000000..ce26b1e --- /dev/null +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY0300RRPMInternalsMM.cfg @@ -0,0 +1,7 @@ +@PART[CRY-0300RFreezer]:FOR[DeepFreeze]:NEEDS[JSIAdvTransparentPods] +{ + MODULE + { + name = JSIAdvTransparentPod + } +} \ No newline at end of file diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY1300Freezer.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY1300Freezer.cfg similarity index 97% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY1300Freezer.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY1300Freezer.cfg index d4d02b5..d95085e 100644 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY1300Freezer.cfg +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY1300Freezer.cfg @@ -36,6 +36,8 @@ there is a risk of frozen Kerbals dying. maxTemp = 2000 // = 2900 vesselType = Ship bulkheadProfiles = size2 + tags = deepfreeze cryogenic freezer + INTERNAL { name = Cry-1300Internals diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY2300Freezer.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY2300Freezer.cfg similarity index 97% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY2300Freezer.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY2300Freezer.cfg index c7399ad..f488e3d 100644 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY2300Freezer.cfg +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/CRY2300Freezer.cfg @@ -40,6 +40,8 @@ there is a risk of frozen Kerbals dying. vesselType = Ship bulkheadProfiles = size2 + tags = deepfreeze cryogenic freezer + INTERNAL { name = Cry-2300Internals diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/GlykerolRadialTank.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/GlykerolRadialTank.cfg similarity index 94% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/GlykerolRadialTank.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/GlykerolRadialTank.cfg index 1701371..bc03fda 100644 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/GlykerolRadialTank.cfg +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Parts/GlykerolRadialTank.cfg @@ -27,6 +27,7 @@ PART crashTolerance = 12 maxTemp = 2000 // = 2900 bulkheadProfiles = srf + tags = deepfreeze cryogenic freezer glykerol tank RESOURCE { name = Glykerol diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/Config.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/Config.cfg similarity index 67% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/Config.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/Config.cfg index f77417e..5f19013 100644 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/Config.cfg +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/Config.cfg @@ -1,14 +1,17 @@ DFSettings { DFwindowPosX = 40 - DFwindowPosY = 50 - CFwindowPosX = 500 - CFwindowPosY = 140 + DFwindowPosY = 440 + CFwindowPosX = 450 + CFwindowPosY = 440 + DFKACwindowPosX = 600 + DFKACwindowPosY = 440 ECreqdForFreezer = False fatalOption = True comatoseTime = 300 UseAppLauncher = True debugging = False + ToolTips = True AutoRecoverFznKerbals = True KSCcostToThawKerbal = 10000 ECReqdToFreezeThaw = 3000 @@ -20,14 +23,14 @@ DFSettings heatamtThawFreezeKerbal = 1000 TempinKelvin = True defaultTimeoutforCrewXfer = 10 - cryopodResettimeDelay = 3 - DFWindowWidth = 560 - CFWindowWidth = 340 - KACWindowWidth = 485 - ECLowWarningTime = 3600 - EClowCriticalTime = 900 + cryopodResettimeDelay = 2 + DFWindowWidth = 560 + CFWindowWidth = 340 + KACWindowWidth = 485 + ECLowWarningTime = 3600 + EClowCriticalTime = 900 StripLightsActive = True internalFrzrCamCode = 100 internalNxtFrzrCamCode = 47 internalPrvFrzrCamCode = 98 -} \ No newline at end of file +} diff --git a/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/DeepFreeze.dll b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/DeepFreeze.dll new file mode 100644 index 0000000..ad0154a Binary files /dev/null and b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Plugins/DeepFreeze.dll differ diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/DoorHandle.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/DoorHandle.cfg similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Props/DoorHandle.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/DoorHandle.cfg diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/DoorHandle.mu b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/DoorHandle.mu similarity index 52% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Props/DoorHandle.mu rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/DoorHandle.mu index e87a50c..6de2e3f 100644 Binary files a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/DoorHandle.mu and b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/DoorHandle.mu differ diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/ElectricGaugeBar.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/ElectricGaugeBar.cfg similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Props/ElectricGaugeBar.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/ElectricGaugeBar.cfg diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/GykerolGaugeBar.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/GykerolGaugeBar.cfg similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Props/GykerolGaugeBar.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/GykerolGaugeBar.cfg diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/LightSwitch.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/LightSwitch.cfg similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Props/LightSwitch.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/LightSwitch.cfg diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/LightSwitch.mu b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/LightSwitch.mu similarity index 64% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Props/LightSwitch.mu rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/LightSwitch.mu index f5de24c..a846708 100644 Binary files a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/LightSwitch.mu and b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/LightSwitch.mu differ diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/flatBarGauge.mu b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/flatBarGauge.mu similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Props/flatBarGauge.mu rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/flatBarGauge.mu diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propBase_DIF.dds b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propBase_DIF.dds similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propBase_DIF.dds rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propBase_DIF.dds diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propBase_EMI.dds b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propBase_EMI.dds similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propBase_EMI.dds rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propBase_EMI.dds diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propLabels_DIF.dds b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propLabels_DIF.dds similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propLabels_DIF.dds rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propLabels_DIF.dds diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propLabels_EMI.dds b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propLabels_EMI.dds similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propLabels_EMI.dds rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Props/propLabels_EMI.dds diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Resources/DF-Resources.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Resources/DF-Resources.cfg similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Resources/DF-Resources.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Resources/DF-Resources.cfg diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/beep.wav b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/beep.wav similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/beep.wav rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/beep.wav diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/charge_up.wav b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/charge_up.wav similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/charge_up.wav rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/charge_up.wav diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/ding_ding.wav b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/ding_ding.wav similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/ding_ding.wav rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/ding_ding.wav diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/externaldoorswitch.wav b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/externaldoorswitch.wav similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/externaldoorswitch.wav rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/externaldoorswitch.wav diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/flatline.wav b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/flatline.wav similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/flatline.wav rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/flatline.wav diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/hatch_lock.wav b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/hatch_lock.wav similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/hatch_lock.wav rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/hatch_lock.wav diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/ice_freeze.wav b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/ice_freeze.wav similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/ice_freeze.wav rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/ice_freeze.wav diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/machine_hum.wav b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/machine_hum.wav similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/machine_hum.wav rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/machine_hum.wav diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/mon_beep.wav b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/mon_beep.wav similarity index 100% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/mon_beep.wav rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Sounds/mon_beep.wav diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-0300Rinternal.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-0300Rinternal.cfg similarity index 96% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-0300Rinternal.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-0300Rinternal.cfg index c42d0c2..427d0c3 100644 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-0300Rinternal.cfg +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-0300Rinternal.cfg @@ -6,13 +6,13 @@ INTERNAL model = REPOSoftTech/DeepFreeze/Assets/Cry-0300RInternals texture = CryopodTexture, REPOSoftTech/DeepFreeze/Assets/CryopodTexture texture = RadialCryopodTexture, REPOSoftTech/DeepFreeze/Assets/RadialCryopodTexture - } + } MODULE { name = InternalSeat seatTransformName = Seat1 portraitCameraName = Cam1 - allowCrewHelmet = true + allowCrewHelmet = false } PROP { diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-0300internal.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-0300internal.cfg similarity index 89% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-0300internal.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-0300internal.cfg index d90c8c7..9a6f0c1 100644 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-0300internal.cfg +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-0300internal.cfg @@ -8,9 +8,9 @@ INTERNAL texture = CryopodTexture, REPOSoftTech/DeepFreeze/Assets/CryopodTexture texture = hitchhikerIVAcolor, REPOSoftTech/DeepFreeze/Assets/hitchhikerIVAcolor texture = tubesColor, REPOSoftTech/DeepFreeze/Assets/tubesColor - texture = TubesBump_NRM, REPOSoftTech/DeepFreeze/Assets/TubesBump_NRM + texture = TubesBump, REPOSoftTech/DeepFreeze/Assets/TubesBump texture = CRY0300_color, REPOSoftTech/DeepFreeze/Assets/CRY0300_color - texture = CRY0300_bump_NRM, REPOSoftTech/DeepFreeze/Assets/CRY0300_bump_NRM + texture = CRY0300_bump, REPOSoftTech/DeepFreeze/Assets/CRY0300_bump } MODULE { diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-1300internal.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-1300internal.cfg similarity index 85% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-1300internal.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-1300internal.cfg index 79cf118..fa9cd8f 100644 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-1300internal.cfg +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-1300internal.cfg @@ -7,12 +7,13 @@ INTERNAL texture = CryopodTexture, REPOSoftTech/DeepFreeze/Assets/CryopodTexture texture = hitchhikerIVAcolor, REPOSoftTech/DeepFreeze/Assets/hitchhikerIVAcolor texture = tubesColor, REPOSoftTech/DeepFreeze/Assets/tubesColor - texture = TubesBump_NRM, REPOSoftTech/DeepFreeze/Assets/TubesBump_NRM + texture = TubesBump, REPOSoftTech/DeepFreeze/Assets/TubesBump texture = CRY2300IVA_color, REPOSoftTech/DeepFreeze/Assets/CRY2300IVA_color + texture = CRY2300IVA_bump, REPOSoftTech/DeepFreeze/Assets/CRY2300IVA_bump texture = wallTextureColor, REPOSoftTech/DeepFreeze/Assets/wallTextureColor - texture = wallTextureBump_NRM, REPOSoftTech/DeepFreeze/Assets/wallTextureBump_NRM + texture = wallTextureBump, REPOSoftTech/DeepFreeze/Assets/wallTextureBump texture = cornerColor, REPOSoftTech/DeepFreeze/Assets/cornerColor - texture = cornerBump_NRM, REPOSoftTech/DeepFreeze/Assets/cornerBump_NRM + texture = cornerBump, REPOSoftTech/DeepFreeze/Assets/cornerBump } MODULE { diff --git a/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-2300internal.cfg b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-2300internal.cfg similarity index 92% rename from Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-2300internal.cfg rename to Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-2300internal.cfg index a774d26..322ec8e 100644 --- a/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-2300internal.cfg +++ b/Source/Distribution/GameData/REPOSoftTech/DeepFreeze/Spaces/Cry-2300internal.cfg @@ -6,12 +6,12 @@ INTERNAL model = REPOSoftTech/DeepFreeze/Assets/Cry-2300Internals texture = CryopodTexture, REPOSoftTech/DeepFreeze/Assets/CryopodTexture texture = tubesColor, REPOSoftTech/DeepFreeze/Assets/tubesColor - texture = TubesBump_NRM, REPOSoftTech/DeepFreeze/Assets/TubesBump_NRM - texture = CRY2300IVA_color, REPOSoftTech/DeepFreeze/Assets/CRY2300IVA_color + texture = TubesBump, REPOSoftTech/DeepFreeze/Assets/TubesBump + texture = CRY2300IVA_color, REPOSoftTech/DeepFreeze/Assets/CRY2300IVA_color texture = wallTextureColor, REPOSoftTech/DeepFreeze/Assets/wallTextureColor - texture = wallTextureBump_NRM, REPOSoftTech/DeepFreeze/Assets/wallTextureBump_NRM + texture = wallTextureBump, REPOSoftTech/DeepFreeze/Assets/wallTextureBump texture = cornerColor, REPOSoftTech/DeepFreeze/Assets/cornerColor - texture = cornerBump_NRM, REPOSoftTech/DeepFreeze/Assets/cornerBump_NRM + texture = cornerBump, REPOSoftTech/DeepFreeze/Assets/cornerBump } MODULE { diff --git a/Source/InstallChecker.cs b/Source/InstallChecker.cs index 858b68b..e50fa89 100644 --- a/Source/InstallChecker.cs +++ b/Source/InstallChecker.cs @@ -44,10 +44,11 @@ protected void Start() var badPaths = loadedAssemblies.Select(a => a.path).Select(p => Uri.UnescapeDataString(new Uri(Path.GetFullPath(KSPUtil.ApplicationRootPath)).MakeRelativeUri(new Uri(p)).ToString().Replace('/', Path.DirectorySeparatorChar))); string badPathsString = String.Join("\n", badPaths.ToArray()); Utilities.Log(modName + " - Incorrectly installed, bad paths:\n" + badPathsString); - PopupDialog.SpawnPopupDialog("Incorrect " + modName + " Installation", + PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "Incorrect " + modName + " Installation", modName + " has been installed incorrectly and will not function properly. All files should be located in KSP/GameData/" + expectedPath + ". Do not move any files from inside that folder.\n\nPlease Remove all old installations and invalid files, as follows.\n\nIncorrect path(s):\n" + badPathsString, - "OK", false, HighLogic.Skin); + "OK", false, HighLogic.UISkin); + } // Check for Raster Prop Monitor, If installed must also have Module Manager Installed @@ -56,9 +57,9 @@ protected void Start() if (!AssemblyLoader.loadedAssemblies.Any(a => a.assembly.GetName().Name.StartsWith("ModuleManager") && a.url == "")) { Utilities.Log(modName + " - Missing or incorrectly installed RPM & ModuleManager."); - PopupDialog.SpawnPopupDialog("Missing Module Manager", + PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "Missing Module Manager", modName + " requires the Module Manager mod in order to function properly with Raster Prop Monitor mod Installed.\n\nPlease download from http://forum.kerbalspaceprogram.com/threads/55219 and copy to the KSP/GameData/ directory.", - "OK", false, HighLogic.Skin); + "OK", false, HighLogic.UISkin); } } @@ -89,13 +90,13 @@ protected void Start() catch (Exception ex) { Utilities.Log("DeepFreeze - Caught an exception:\n" + ex.Message + "\n" + ex.StackTrace); - PopupDialog.SpawnPopupDialog("Incorrect " + modName + " Installation", + PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "Incorrect " + modName + " Installation", "A very serious error has occurred while checking the installation of " + modName + ".\n\n" + "You need to\n" + " (1) shut down KSP,\n" + " (2) send a complete copy of the entire log file to the mod developer\n" + " (3) completely delete and re-install " + modName, - "OK", false, HighLogic.Skin); + "OK", false, HighLogic.UISkin); } } diff --git a/Source/KerbalPortraits.cs b/Source/KerbalPortraits.cs new file mode 100644 index 0000000..5ff67c3 --- /dev/null +++ b/Source/KerbalPortraits.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using KSP.UI.Screens.Flight; +using UnityEngine; + + +namespace DeepFreeze +{ + //This Class does not work very well. It was meant to attach to the Portrait PreFab to build our own list of Portraits. + //But for some reason it is resulting in duplicated portraits and I have spent hours and hours on this trying to figure it out. + //So I am doing a brute force approach to get the Portrait GameObjects. I am pretty sure this is breaking the EULA of KSP but pretty sure it is not + //as I am still ONLY accessing the PUBLIC Portraits Class and fields. + // I hope Squad open the list up to public as per my request in the next release: http://bugs.kerbalspaceprogram.com/issues/8993 + + [KSPAddon(KSPAddon.Startup.Flight, false)] + class Portraits : MonoBehaviour + { + public static readonly List<KerbalPortrait> PortraitList = new List<KerbalPortrait>(); + + class PortraitTracker : MonoBehaviour + { + private KerbalPortrait _portrait; + + private void Start() // Awake might be too early + { + if (transform.GetComponentCached(ref _portrait) == null) + Destroy(this); + else AddPortrait(_portrait); + } + + private void OnDestroy() + { + if (_portrait == null) return; + + RemovePortrait(_portrait); + } + } + + + private void Awake() + { + //var kpg = KerbalPortraitGallery.Instance; + + //AddTracker(kpg.portraitPrefab); + + // uncertain whether KSPAddons created before KerbalPortraits initialized + // pretty sure they are but too lazy to check + //kpg.gameObject.GetComponentsInChildren<KerbalPortrait>() + // .ToList() + // .ForEach(AddTracker); + + //Destroy(gameObject); + } + + // Might only need to edit the prefab once. This will make sure we don't add duplicates + private static void AddTracker(KerbalPortrait portrait) + { + if (portrait.gameObject.GetComponent<PortraitTracker>() != null) return; + + portrait.gameObject.AddComponent<PortraitTracker>(); + } + + + private static void AddPortrait(KerbalPortrait portrait) + { + if (portrait == null) return; + + PortraitList.AddUnique(portrait); + //PortraitList.Add(portrait); + } + + private static void RemovePortrait(KerbalPortrait portrait) + { + if (PortraitList.Contains(portrait)) PortraitList.RemoveAll(a => a.crewMember == portrait.crewMember); + } + + /// <summary> + /// Destroy Portraits for a kerbal and Unregisters them from the KerbalPortraitGallery + /// </summary> + /// <param name="kerbal">the Kerbal we want to delete portraits for</param> + internal static void DestroyPortrait(Kerbal kerbal) + { + //set the kerbal InPart to null - this should stop their portrait from re-spawning. + kerbal.InPart = null; + KerbalPortraitGallery.Instance.gameObject.GetComponentsInChildren<KerbalPortrait>().Where(a => a.crewMemberName == kerbal.crewMemberName).ToList().ForEach(x => DestroyObject(x)); + + KerbalPortraitGallery.Instance.UnregisterActiveCrew(kerbal); + } + + /// <summary> + /// Restore the Portrait for a kerbal. If Using Texture Replacer mod you must Re-initialise the Textures after this is called. + /// Otherwise the kerbal will revert back to stock textures. + /// The Kerbal's RosterStatus must NOT be DEAD if DeepFreeze Frozen otherwise the Portrait will come up as DEAD. + /// This method will also call: Kerbal.SetVisibleInPortrait(true) which seems to reset the kerbal's portrait camera update routine. + /// </summary> + /// <param name="part">The Part the kerbal is inside</param> + /// <param name="kerbal">The Kerbal we want to register</param> + internal static void RestorePortrait(Part part, Kerbal kerbal) + { + // Select all KerbalPortrait in our PortraitList where the crewMember name is the kerbal we are interested in. + // We should NOT get any. If we do, Call DestroyPortrait first then come back. + //KerbalPortrait portrait = PortraitList.FirstOrDefault(a => a.crewMember == kerbal); + List<KerbalPortrait> portraits = KerbalPortraitGallery.Instance.gameObject.GetComponentsInChildren<KerbalPortrait>().Where(a => a.crewMemberName == kerbal.crewMemberName).ToList(); + if (portraits.Any()) + { + //This will destroy ALL Portraits and un-register them as many times as we have an entry for them. + DestroyPortrait(kerbal); + } + //set the kerbal InPart to the Part passed in. + kerbal.InPart = part; + //Set them visible in portrait to true + kerbal.SetVisibleInPortrait(true); + //This should reset the kerbal portrait back up for us. + kerbal.state = Kerbal.States.ALIVE; + kerbal.randomizeOnStartup = false; + kerbal.Start(); + } + } +} diff --git a/Source/LocalDev/ksp_dir.txt b/Source/LocalDev/ksp_dir.txt index 15d50e3..d8e4629 100644 --- a/Source/LocalDev/ksp_dir.txt +++ b/Source/LocalDev/ksp_dir.txt @@ -1 +1 @@ -C:\KSP_win 1.0.5 Test Setup +C:\KSP 1.1\Kerbal Space Program - Test diff --git a/Source/PartInfo.cs b/Source/PartInfo.cs index f38c8c7..6b60f3a 100644 --- a/Source/PartInfo.cs +++ b/Source/PartInfo.cs @@ -85,9 +85,12 @@ internal PartInfo(Guid vesselid, string PartName, double currentTime) internal static PartInfo Load(ConfigNode node) { - string PartName = Utilities.GetNodeValue(node, "PartName", "Unknown"); - double lastUpdate = Utilities.GetNodeValue(node, "lastUpdate", 0.0); - string tmpvesselID = Utilities.GetNodeValue(node, "vesselID", ""); + string PartName = "Unknown"; + node.TryGetValue("PartName", ref PartName); + double lastUpdate = 0.0; + node.TryGetValue("lastUpdate", ref lastUpdate); + string tmpvesselID = ""; + node.TryGetValue("vesselID", ref tmpvesselID); Guid vesselID = Guid.Empty; try { @@ -99,9 +102,12 @@ internal static PartInfo Load(ConfigNode node) Debug.Log("DFInterface - Load of GUID VesselID for known part failed Err: " + ex); } PartInfo info = new PartInfo(vesselID, PartName, lastUpdate); - info.numSeats = Utilities.GetNodeValue(node, "numSeats", 0); - info.numCrew = Utilities.GetNodeValue(node, "numCrew", 0); - string CrewString = Utilities.GetNodeValue(node, "crewMembers", string.Empty); + node.TryGetValue("numSeats", ref info.numSeats); + node.TryGetValue("numCrew", ref info.numCrew); + + string CrewString = ""; + node.TryGetValue("crewMembers", ref CrewString); + string[] CrewStrings = CrewString.Split(','); if (CrewStrings.Length > 0) { @@ -110,7 +116,8 @@ internal static PartInfo Load(ConfigNode node) info.crewMembers.Add(CrewStrings[i]); } } - string CrewTraitString = Utilities.GetNodeValue(node, "crewMemberTraits", string.Empty); + string CrewTraitString = ""; + node.TryGetValue("crewMemberTraits", ref CrewTraitString); string[] CrewTStrings = CrewTraitString.Split(','); if (CrewTStrings.Length > 0) { @@ -119,21 +126,21 @@ internal static PartInfo Load(ConfigNode node) info.crewMemberTraits.Add(CrewTStrings[i]); } } - info.numFrznCrew = Utilities.GetNodeValue(node, "numFrznCrew", 0); - info.hibernating = Utilities.GetNodeValue(node, "hibernating", false); - info.hasextDoor = Utilities.GetNodeValue(node, "hasextDoor", false); - info.hasextPod = Utilities.GetNodeValue(node, "hasextPod", false); - info.timeLastElectricity = Utilities.GetNodeValue(node, "timeLastElectricity", lastUpdate); - info.frznChargeRequired = Utilities.GetNodeValue(node, "frznChargeRequired", 0d); - info.timeLastTempCheck = Utilities.GetNodeValue(node, "timeLastTempCheck", lastUpdate); - info.deathCounter = Utilities.GetNodeValue(node, "deathCounter", 0d); - info.tmpdeathCounter = Utilities.GetNodeValue(node, "tmpdeathCounter", 0d); - info.outofEC = Utilities.GetNodeValue(node, "outofEC", false); + node.TryGetValue("numFrznCrew", ref info.numFrznCrew); + node.TryGetValue("hibernating", ref info.hibernating); + node.TryGetValue("hasextDoor", ref info.hasextDoor); + node.TryGetValue("hasextPod", ref info.hasextPod); + node.TryGetValue("timeLastElectricity", ref info.timeLastElectricity); + node.TryGetValue("frznChargeRequired", ref info.frznChargeRequired); + node.TryGetValue("timeLastTempCheck", ref info.timeLastTempCheck); + node.TryGetValue("deathCounter", ref info.deathCounter); + node.TryGetValue("tmpdeathCounter", ref info.tmpdeathCounter); + node.TryGetValue("outofEC", ref info.outofEC); info.TmpStatus = Utilities.GetNodeValue(node, "TmpStatus", FrzrTmpStatus.OK); - info.cabinTemp = Utilities.GetNodeValue(node, "cabinTemp", 0f); - info.ECWarning = Utilities.GetNodeValue(node, "ECWarning", false); - info.TempWarning = Utilities.GetNodeValue(node, "TempWarning", false); - + node.TryGetValue("cabinTemp", ref info.cabinTemp); + node.TryGetValue("ECWarning", ref info.ECWarning); + node.TryGetValue("TempWarning", ref info.TempWarning); + return info; } diff --git a/Source/Properties/AssemblyInfo.cs b/Source/Properties/AssemblyInfo.cs index e71c346..ba40611 100644 --- a/Source/Properties/AssemblyInfo.cs +++ b/Source/Properties/AssemblyInfo.cs @@ -9,7 +9,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("DeepFreeze")] -[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyCopyright("Copyright © 2015-16")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -31,6 +31,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.20.4.0")] -[assembly: AssemblyFileVersion("0.20.4.0")] -[assembly: KSPAssembly("DeepFreeze", 0, 20)] \ No newline at end of file +[assembly: AssemblyVersion("0.22.0.0")] +[assembly: AssemblyFileVersion("0.22.0.0")] +[assembly: KSPAssembly("DeepFreeze", 0, 22)] \ No newline at end of file diff --git a/Source/REPOSoftTechKSPUtils/RSTutilities.cs b/Source/REPOSoftTechKSPUtils/RSTutilities.cs index 45df600..b75a5ad 100644 --- a/Source/REPOSoftTechKSPUtils/RSTutilities.cs +++ b/Source/REPOSoftTechKSPUtils/RSTutilities.cs @@ -18,902 +18,1282 @@ using System.Reflection; using System.Text; using UnityEngine; +using Object = UnityEngine.Object; using Random = System.Random; namespace RSTUtils { - public enum GameState - { - FLIGHT = 0, - EDITOR = 1, - EVA = 2 - } - - internal static class Utilities - { - public static int randomSeed = new Random().Next(); - private static int _nextrandomInt = randomSeed; - - public static int getnextrandomInt() - { - _nextrandomInt ++; - return _nextrandomInt; - } + public enum GameState + { + FLIGHT = 0, + EDITOR = 1, + EVA = 2, + SPACECENTER = 3 + } + + internal static class Utilities + { + public static int randomSeed = new Random().Next(); + private static int _nextrandomInt = randomSeed; + + public static int getnextrandomInt() + { + _nextrandomInt ++; + return _nextrandomInt; + } //Set the Game State mode indicator, 0 = inflight, 1 = editor, 2 on EVA or F2 - public static bool GameModeisFlight; - public static bool GameModeisEditor; - public static bool GameModeisEVA; + public static bool GameModeisFlight + { + get + { + GameState state = SetModeFlag(); + if (state == GameState.FLIGHT) return true; + return false; + } + } - public static GameState SetModeFlag() - { - //Set the mode flag, 0 = inflight, 1 = editor, 2 on EVA or F2 - if (FlightGlobals.fetch != null && FlightGlobals.ActiveVessel != null) // Check if in flight - { - if (FlightGlobals.ActiveVessel.isEVA) // EVA kerbal, do nothing - { - GameModeisEVA = true; - GameModeisFlight = GameModeisEditor = false; - return GameState.EVA; - } - GameModeisFlight = true; - GameModeisEVA = GameModeisEditor = false; - return GameState.FLIGHT; - } - if (EditorLogic.fetch != null) // Check if in editor - { - GameModeisEditor = true; - GameModeisFlight = GameModeisEVA = false; - return GameState.EDITOR; - } - GameModeisEVA = true; - GameModeisFlight = GameModeisEditor = false; - return GameState.EVA; - } + public static bool GameModeisEditor + { + get + { + GameState state = SetModeFlag(); + if (state == GameState.EDITOR) return true; + return false; + } + } + + public static bool GameModeisEVA + { + get + { + GameState state = SetModeFlag(); + if (state == GameState.EVA) return true; + return false; + } + } - //Geometry and space + public static bool GameModeisSpaceCenter + { + get + { + GameState state = SetModeFlag(); + if (state == GameState.SPACECENTER) return true; + return false; + } + } - public static double DistanceFromHomeWorld(Vessel vessel) - { - Vector3d vslPos = vessel.GetWorldPos3D(); - CelestialBody HmePlanet = Planetarium.fetch.Home; - Log_Debug("Home = " + HmePlanet.name + " Pos = " + HmePlanet.position); - Log_Debug("Vessel Pos = " + vslPos); - Vector3d hmeplntPos = HmePlanet.position; - double DstFrmHome = Math.Sqrt(Math.Pow(vslPos.x - hmeplntPos.x, 2) + Math.Pow(vslPos.y - hmeplntPos.y, 2) + Math.Pow(vslPos.z - hmeplntPos.z, 2)); - Log_Debug("Distance from Home Planet = " + DstFrmHome); - return DstFrmHome; - } - + public static GameState GameMode + { + get + { + return SetModeFlag(); + } + } + + public static GameState SetModeFlag() + { + //Set the mode flag, 0 = inflight, 1 = editor, 2 on EVA or F2 + if (HighLogic.LoadedScene == GameScenes.SPACECENTER) + { + return GameState.SPACECENTER; + } + if (FlightGlobals.fetch != null && FlightGlobals.ActiveVessel != null) // Check if in flight + { + if (FlightGlobals.ActiveVessel.isEVA) // EVA kerbal, do nothing + { + return GameState.EVA; + } + return GameState.FLIGHT; + } + if (EditorLogic.fetch != null) // Check if in editor + { + return GameState.EDITOR; + } + return GameState.EVA; + } + + #region GeometryandSpace + //Geometry and space + + public static double DistanceFromHomeWorld(Vessel vessel) + { + Vector3d vslPos = vessel.GetWorldPos3D(); + CelestialBody HmePlanet = Planetarium.fetch.Home; + Log_Debug("Home = " + HmePlanet.name + " Pos = " + HmePlanet.position); + Log_Debug("Vessel Pos = " + vslPos); + Vector3d hmeplntPos = HmePlanet.position; + double DstFrmHome = Math.Sqrt(Math.Pow(vslPos.x - hmeplntPos.x, 2) + Math.Pow(vslPos.y - hmeplntPos.y, 2) + Math.Pow(vslPos.z - hmeplntPos.z, 2)); + Log_Debug("Distance from Home Planet = " + DstFrmHome); + return DstFrmHome; + } + + #endregion GeometryandSpace + + #region ObjectsandTransforms public static void PrintTransform(Transform t, string title = "") - { - Log_Debug("------" + title + "------"); - Log_Debug("Position: " + t.localPosition); - Log_Debug("Rotation: " + t.localRotation); - Log_Debug("Scale: " + t.localScale); - Log_Debug("------------------"); - } + { + Log_Debug("------" + title + "------"); + Log_Debug("Position: " + t.localPosition); + Log_Debug("Rotation: " + t.localRotation); + Log_Debug("Scale: " + t.localScale); + Log_Debug("------------------"); + } - public static void DumpObjectProperties(object o, string title = "---------") - { - // Iterate through all of the properties - Log_Debug("--------- " + title + " ------------"); - foreach (PropertyInfo property in o.GetType().GetProperties()) - { - if (property.CanRead) - Log_Debug(property.Name + " = " + property.GetValue(o, null)); - } - Log_Debug("--------------------------------------"); - } + public static void DumpObjectProperties(object o, string title = "---------") + { + // Iterate through all of the properties + Log_Debug("--------- " + title + " ------------"); + foreach (PropertyInfo property in o.GetType().GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public)) + { + if (property.CanRead) + Log_Debug(property.Name + " = " + property.GetValue(o, null)); + } + Log_Debug("--------------------------------------"); + } // Dump an object by reflection - internal static void DumpObjectFields(object o, string title = "---------") - { - // Dump (by reflection) - Debug.Log("---------" + title + "------------"); - foreach (FieldInfo field in o.GetType().GetFields()) - { - if (!field.IsStatic) - { - Debug.Log(field.Name + " = " + field.GetValue(o)); - } - } - Debug.Log("--------------------------------------"); - } + internal static void DumpObjectFields(object o, string title = "---------") + { + // Dump (by reflection) + Debug.Log("---------" + title + "------------"); + foreach (FieldInfo field in o.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public)) + { + if (!field.IsStatic) + { + Debug.Log(field.Name + " = " + field.GetValue(o)); + } + } + Debug.Log("--------------------------------------"); + } - // Use Reflection to get a field from an object - internal static object GetObjectField(object o, string fieldName) - { - object outputObj = new object(); - bool foundObj = false; - foreach (FieldInfo field in o.GetType().GetFields()) - { - if (!field.IsStatic) - { - if (field.Name == fieldName) - { - foundObj = true; - outputObj = field.GetValue(o); - break; - } - } - } - if (foundObj) - { - return outputObj; - } - return null; - } + // Use Reflection to get a field from an object + internal static object GetObjectField(object o, string fieldName) + { + object outputObj = new object(); + bool foundObj = false; + foreach (FieldInfo field in o.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public)) + { + if (!field.IsStatic) + { + if (field.Name == fieldName) + { + foundObj = true; + outputObj = field.GetValue(o); + break; + } + } + } + if (foundObj) + { + return outputObj; + } + return null; + } - // Dump all Unity Cameras - internal static void DumpCameras() - { - // Dump (by reflection) - Debug.Log("--------- Dump Unity Cameras ------------"); - foreach (Camera c in Camera.allCameras) - { - Debug.Log("Camera " + c.name + " cullingmask " + c.cullingMask + " depth " + c.depth + " farClipPlane " + c.farClipPlane + " nearClipPlane " + c.nearClipPlane); - } - Debug.Log("--------------------------------------"); - } + /** + * Recursively searches for a named transform in the Transform heirarchy. The requirement of + * such a function is sad. This should really be in the Unity3D API. Transform.Find() only + * searches in the immediate children. + * + * @param transform Transform in which is search for named child + * @param name Name of child to find + * + * @return Desired transform or null if it could not be found + */ + + internal static Transform FindInChildren(Transform transform, string name) + { + // Is this null? + if (transform == null) + { + return null; + } - public static Camera findCameraByName(string camera) + // Are the names equivalent + if (transform.name == name) + { + return transform; + } + + // If we did not find a transform, search through the children + return (from Transform child in transform select FindInChildren(child, name)).FirstOrDefault(t => t != null); + + // Return the transform (will be null if it was not found) + } + + public static Transform FindChildRecursive(Transform parent, string name) { - return Camera.allCameras.FirstOrDefault(cam => cam.name == camera); + return parent.gameObject.GetComponentsInChildren<Transform>().FirstOrDefault(t => t.name == name); } - /** - * Recursively searches for a named transform in the Transform heirarchy. The requirement of - * such a function is sad. This should really be in the Unity3D API. Transform.Find() only - * searches in the immediate children. - * - * @param transform Transform in which is search for named child - * @param name Name of child to find - * - * @return Desired transform or null if it could not be found - */ + public static Animation FindAnimChildRecursive(Transform parent, string name) + { + return parent.gameObject.GetComponentsInChildren<Animation>().FirstOrDefault(t => t.name == name); + } - internal static Transform FindInChildren(Transform transform, string name) - { - // Is this null? - if (transform == null) - { - return null; - } + internal static void dmpKerbalRefs(Kerbal kerbal, Kerbal seatkerbalref, Kerbal protocrewkerbalref) + { + if (kerbal != null) + { + Log_Debug("kerbal " + kerbal.name + " " + kerbal.GetInstanceID()); + Log_Debug(kerbal.GetComponent("TRIvaModule") != null + ? "kerbal has TRIvaModule attached" + : "kerbal DOES NOT have TRIvaModule attached"); + } - // Are the names equivalent - if (transform.name == name) - { - return transform; - } + if (seatkerbalref != null) + { + Log_Debug("seatkerbalref " + seatkerbalref.name + " " + seatkerbalref.GetInstanceID()); + Log_Debug(seatkerbalref.GetComponent("TRIvaModule") != null + ? "seatkerbalref has TRIvaModule attached" + : "seatkerbalref DOES NOT have TRIvaModule attached"); + } + if (protocrewkerbalref != null) + { + Log_Debug("protocrewkerbalref " + protocrewkerbalref.name + " " + protocrewkerbalref.GetInstanceID()); + Log_Debug(protocrewkerbalref.GetComponent("TRIvaModule") != null + ? "protocrewkerbalref has TRIvaModule attached" + : "protocrewkerbalref DOES NOT have TRIvaModule attached"); + } + } + + internal static void dmpAllKerbals() + { + foreach (Kerbal kerbal in Resources.FindObjectsOfTypeAll<Kerbal>()) + { + Log_Debug("Kerbal " + kerbal.name + " " + kerbal.crewMemberName + " instance " + kerbal.GetInstanceID() + " rosterstatus " + kerbal.rosterStatus); + Log_Debug(kerbal.protoCrewMember == null ? "ProtoCrewmember is null " : "ProtoCrewmember exists " + kerbal.protoCrewMember.name); + } + } - // If we did not find a transform, search through the children - return (from Transform child in transform select FindInChildren(child, name)).FirstOrDefault(t => t != null); + internal static void dmpAnimationNames(Animation anim) + { + List<AnimationState> states = new List<AnimationState>(anim.Cast<AnimationState>()); + Log_Debug("Animation " + anim.name); + foreach (AnimationState state in states) + { + Log_Debug("Animation clip " + state.name); + } + } - // Return the transform (will be null if it was not found) - } + // The following method is modified from RasterPropMonitor as-is. Which is covered by GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + internal static void setTransparentTransforms(this Part thisPart, string transparentTransforms) + { + string transparentShaderName = "Transparent/Specular"; + var transparentShader = Shader.Find(transparentShaderName); + foreach (string transformName in transparentTransforms.Split('|')) + { + Log_Debug("setTransparentTransforms " + transformName); + try + { + Transform tr = thisPart.FindModelTransform(transformName.Trim()); + if (tr != null) + { + // We both change the shader and backup the original shader so we can undo it later. + Shader backupShader = tr.GetComponent<Renderer>().material.shader; + tr.GetComponent<Renderer>().material.shader = transparentShader; + } + } + catch (Exception e) + { + Debug.Log("Unable to set transparent shader transform " + transformName); + Debug.LogException(e); + } + } + } - public static Transform FindChildRecursive(Transform parent, string name) - { - return parent.gameObject.GetComponentsInChildren<Transform>().FirstOrDefault(t => t.name == name); - } + #endregion ObjectsandTransforms - internal static Camera FindCamera(string name) - { - return Camera.allCameras.FirstOrDefault(c => c.name == name); - } + #region Cameras - internal static void dmpKerbalRefs(Kerbal kerbal, Kerbal seatkerbalref, Kerbal protocrewkerbalref) - { - if (kerbal != null) - { - Log_Debug("kerbal " + kerbal.name + " " + kerbal.GetInstanceID()); - Log_Debug(kerbal.GetComponent("TRIvaModule") != null - ? "kerbal has TRIvaModule attached" - : "kerbal DOES NOT have TRIvaModule attached"); - } + internal static Camera FindCamera(string name) + { + return Camera.allCameras.FirstOrDefault(c => c.name == name); + } - if (seatkerbalref != null) - { - Log_Debug("seatkerbalref " + seatkerbalref.name + " " + seatkerbalref.GetInstanceID()); - Log_Debug(seatkerbalref.GetComponent("TRIvaModule") != null - ? "seatkerbalref has TRIvaModule attached" - : "seatkerbalref DOES NOT have TRIvaModule attached"); - } - if (protocrewkerbalref != null) - { - Log_Debug("protocrewkerbalref " + protocrewkerbalref.name + " " + protocrewkerbalref.GetInstanceID()); - Log_Debug(protocrewkerbalref.GetComponent("TRIvaModule") != null - ? "protocrewkerbalref has TRIvaModule attached" - : "protocrewkerbalref DOES NOT have TRIvaModule attached"); - } - } + // Dump all Unity Cameras + internal static void DumpCameras() + { + // Dump (by reflection) + Debug.Log("--------- Dump Unity Cameras ------------"); + foreach (Camera c in Camera.allCameras) + { + Debug.Log("Camera " + c.name + " cullingmask " + c.cullingMask + " depth " + c.depth + " farClipPlane " + c.farClipPlane + " nearClipPlane " + c.nearClipPlane); + } - internal static void dmpAnimationNames(Animation anim) - { - List<AnimationState> states = new List<AnimationState>(anim.Cast<AnimationState>()); - Log_Debug("Animation " + anim.name); - foreach (AnimationState state in states) - { - Log_Debug("Animation clip " + state.name); - } - } - - public static IEnumerator WaitForAnimation(Animation animation, string name) - { - do - { - yield return null; - } while (animation.IsPlaying(name)); - } + Debug.Log("--------------------------------------"); + } - internal static void dmpAllKerbals() + public static Camera findCameraByName(string camera) + { + return Camera.allCameras.FirstOrDefault(cam => cam.name == camera); + } + /// <summary> + /// Returns True if the Stock Overlay Camera Mode is on, otherwise will return false. + /// </summary> + public static bool StockOverlayCamIsOn { - foreach (Kerbal kerbal in Resources.FindObjectsOfTypeAll<Kerbal>()) + get { - Log_Debug("Kerbal " + kerbal.name + " " + kerbal.crewMemberName + " instance " + kerbal.GetInstanceID() + " rosterstatus " + kerbal.rosterStatus); - Log_Debug(kerbal.protoCrewMember == null ? "ProtoCrewmember is null " : "ProtoCrewmember exists " + kerbal.protoCrewMember.name); + Camera StockOverlayCamera = findCameraByName("InternalSpaceOverlay Host"); + if (StockOverlayCamera != null) return true; + return false; } } - // The following method is modified from RasterPropMonitor as-is. Which is covered by GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - internal static void setTransparentTransforms(this Part thisPart, string transparentTransforms) + private static Shader DepthMaskShader; + private static string DepthMaskShaderName = "DepthMask"; + /// <summary> + /// Will search for and change the Mesh (and all it's children) supplied in MeshName Field on the part supplied to Enabled or NotEnabled based on the SetVisible parm. + /// </summary> + /// <param name="part">The part to look for the mesh on</param> + /// <param name="SetVisible">True will Enable the mesh, False will disable the mesh</param> + /// <param name="MeshName">String containing the Mesh name to look for on the part</param> + internal static void SetInternalDepthMask(Part part, bool SetVisible, string MeshName = "") { - string transparentShaderName = "Transparent/Specular"; - var transparentShader = Shader.Find(transparentShaderName); - foreach (string transformName in transparentTransforms.Split('|')) + if (DepthMaskShader == null) DepthMaskShader = Shader.Find(DepthMaskShaderName); + if (part.internalModel != null) { - Log_Debug("setTransparentTransforms " + transformName); - try + if (MeshName != "") { - Transform tr = thisPart.FindModelTransform(transformName.Trim()); - if (tr != null) + Transform parentTransform = FindInChildren(part.internalModel.transform, MeshName); + if (parentTransform != null) { - // We both change the shader and backup the original shader so we can undo it later. - Shader backupShader = tr.renderer.material.shader; - tr.renderer.material.shader = transparentShader; + parentTransform.gameObject.SetActive(SetVisible); } } - catch (Exception e) - { - Debug.Log("Unable to set transparent shader transform " + transformName); - Debug.LogException(e); - } } } - // The following method is derived from TextureReplacer mod. Which is licensed as: - //Copyright © 2013-2015 Davorin Učakar, Ryan Bray - //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - private static double atmSuitPressure = 50.0; + #endregion Cameras - internal static bool isAtmBreathable() - { - bool value = !HighLogic.LoadedSceneIsFlight - || (FlightGlobals.getStaticPressure() >= atmSuitPressure); - Log_Debug("isATMBreathable Inflight? " + value + " InFlight " + HighLogic.LoadedSceneIsFlight + " StaticPressure " + FlightGlobals.getStaticPressure()); - return value; - } + #region Animations + public static IEnumerator WaitForAnimation(Animation animation, string name) + { + do + { + yield return null; + } while (animation.IsPlaying(name)); + } - // The following method is derived from TextureReplacer mod. Which is licensed as: - //Copyright © 2013-2015 Davorin Učakar, Ryan Bray - //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - private static Mesh[] helmetMesh = { null, null }; + public static IEnumerator WaitForAnimationNoClip(Animation animation) + { + do + { + yield return null; + } while (animation.isPlaying); + } - private static Mesh[] visorMesh = { null, null }; - private static bool helmetMeshstored; + #endregion Animations - internal static void storeHelmetMesh() - { - Log_Debug("StoreHelmetMesh"); - foreach (Kerbal kerbal in Resources.FindObjectsOfTypeAll<Kerbal>()) - { - int gender = kerbal.transform.name == "kerbalFemale" ? 1 : 0; - // Save pointer to helmet & visor meshes so helmet removal can restore them. - foreach (SkinnedMeshRenderer smr in kerbal.GetComponentsInChildren<SkinnedMeshRenderer>(true)) - { - if (smr.name.EndsWith("helmet", StringComparison.Ordinal)) - helmetMesh[gender] = smr.sharedMesh; - else if (smr.name.EndsWith("visor", StringComparison.Ordinal)) - visorMesh[gender] = smr.sharedMesh; - } - } - helmetMeshstored = true; - } + #region Kerbals - // The following method is derived from TextureReplacer mod.Which is licensed as: - //Copyright © 2013-2015 Davorin Učakar, Ryan Bray - //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - internal static void setHelmetshaders(Kerbal thatKerbal, bool helmetOn) - { - if (!helmetMeshstored) - storeHelmetMesh(); + // The following method is derived from TextureReplacer mod. Which is licensed as: + //Copyright © 2013-2015 Davorin Učakar, Ryan Bray + //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + private static double atmSuitPressure = 50.0; - //This will check if Atmospher is breathable then we always remove our hetmets regardless. - if (helmetOn && isAtmBreathable()) - { - helmetOn = false; - Log_Debug("setHelmetShaders to put on helmet but in breathable atmosphere"); - } + internal static bool isAtmBreathable() + { + bool value = !HighLogic.LoadedSceneIsFlight + || (FlightGlobals.getStaticPressure() >= atmSuitPressure); + Log_Debug("isATMBreathable Inflight? " + value + " InFlight " + HighLogic.LoadedSceneIsFlight + " StaticPressure " + FlightGlobals.getStaticPressure()); + return value; + } - try - { - foreach (SkinnedMeshRenderer smr in thatKerbal.helmetTransform.GetComponentsInChildren<SkinnedMeshRenderer>()) - { - if (smr.name.EndsWith("helmet", StringComparison.Ordinal)) - smr.sharedMesh = helmetOn ? helmetMesh[(int)thatKerbal.protoCrewMember.gender] : null; - else if (smr.name.EndsWith("visor", StringComparison.Ordinal)) - smr.sharedMesh = helmetOn ? visorMesh[(int)thatKerbal.protoCrewMember.gender] : null; - } - } - catch (Exception ex) - { - Log("Error attempting to setHelmetshaders for " + thatKerbal.name + " to " + helmetOn); - Log(ex.Message); - } - } + // The following method is derived from TextureReplacer mod. Which is licensed as: + //Copyright © 2013-2015 Davorin Učakar, Ryan Bray + //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + private static Mesh[] helmetMesh = { null, null }; - // The following method is derived from TextureReplacer mod. Which is licensed as: - //Copyright © 2013-2015 Davorin Učakar, Ryan Bray - //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - internal static void setHelmets(this Part thisPart, bool helmetOn) - { - if (thisPart.internalModel == null) - { - Log_Debug("setHelmets but no internalModel"); - return; - } + private static Mesh[] visorMesh = { null, null }; + private static bool helmetMeshstored; - if (!helmetMeshstored) - storeHelmetMesh(); + internal static void storeHelmetMesh() + { + Log_Debug("StoreHelmetMesh"); + foreach (Kerbal kerbal in Resources.FindObjectsOfTypeAll<Kerbal>()) + { + int gender = kerbal.transform.name == "kerbalFemale" ? 1 : 0; + // Save pointer to helmet & visor meshes so helmet removal can restore them. + foreach (SkinnedMeshRenderer smr in kerbal.GetComponentsInChildren<SkinnedMeshRenderer>(true)) + { + if (smr.name.EndsWith("helmet", StringComparison.Ordinal)) + helmetMesh[gender] = smr.sharedMesh; + else if (smr.name.EndsWith("visor", StringComparison.Ordinal)) + visorMesh[gender] = smr.sharedMesh; + } + } + helmetMeshstored = true; + } - Log_Debug("setHelmets helmetOn=" + helmetOn); - //Kerbal thatKerbal = null; - foreach (InternalSeat thatSeat in thisPart.internalModel.seats) - { - if (thatSeat.crew != null) - { - Kerbal thatKerbal = thatSeat.kerbalRef; - if (thatKerbal != null) - { - thatSeat.allowCrewHelmet = helmetOn; - Log_Debug("Setting helmet=" + helmetOn + " for kerbal " + thatSeat.crew.name); - // `Kerbal.ShowHelmet(false)` irreversibly removes a helmet while - // `Kerbal.ShowHelmet(true)` has no effect at all. We need the following workaround. - // I think this can be done using a coroutine to despawn and spawn the internalseat crewmember kerbalref. - // But I found this workaround in TextureReplacer so easier to use that. - //if (thatKerbal.showHelmet) - //{ - setHelmetshaders(thatKerbal, helmetOn); - //} - //else - // Log_Debug("Showhelmet is OFF so the helmettransform does not exist"); - } - else - Log_Debug("kerbalref = null?"); - } - } - } + // The following method is derived from TextureReplacer mod.Which is licensed as: + //Copyright © 2013-2015 Davorin Učakar, Ryan Bray + //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + internal static void setHelmetshaders(Kerbal thatKerbal, bool helmetOn) + { + if (!helmetMeshstored) + storeHelmetMesh(); - // Sets the kerbal layers to make them visible (Thawed) or not (Frozen), setVisible = true sets layers to visible, false turns them off. - // If bodyOnly is true only the "body01" mesh is changed (to be replaced by placeholder mesh lying down as kerbals in IVA are always in sitting position). - internal static void setFrznKerbalLayer(ProtoCrewMember kerbal, bool setVisible, bool bodyOnly) - { - //Log_Debug("setFrznKerbalLayer " + kerbal.name + " visible " + setVisible); - int layer = 16; - if (!setVisible) - { - layer = 21; - } + //This will check if Atmospher is breathable then we always remove our hetmets regardless. + if (helmetOn && isAtmBreathable()) + { + helmetOn = false; + Log_Debug("setHelmetShaders to put on helmet but in breathable atmosphere"); + } - foreach (Renderer renderer in kerbal.KerbalRef.GetComponentsInChildren<Renderer>(true)) - { - if ((bodyOnly && renderer.name == "body01") || !bodyOnly) - { - if (renderer.gameObject.layer == layer) - { - //Log_Debug("Layers already set"); - break; - } - //Log_Debug("Renderer: " + renderer.name + " set to layer " + layer); - renderer.gameObject.layer = layer; - if (setVisible) renderer.enabled = true; - else renderer.enabled = false; - } - } - } + try + { + foreach (SkinnedMeshRenderer smr in thatKerbal.helmetTransform.GetComponentsInChildren<SkinnedMeshRenderer>()) + { + if (smr.name.EndsWith("helmet", StringComparison.Ordinal)) + smr.sharedMesh = helmetOn ? helmetMesh[(int)thatKerbal.protoCrewMember.gender] : null; + else if (smr.name.EndsWith("visor", StringComparison.Ordinal)) + smr.sharedMesh = helmetOn ? visorMesh[(int)thatKerbal.protoCrewMember.gender] : null; + } + } + catch (Exception ex) + { + Log("Error attempting to setHelmetshaders for " + thatKerbal.name + " to " + helmetOn); + Log(ex.Message); + } + } - internal static void CheckPortraitCams(Vessel vessel) - { - // Only the pods in the active vessel should be doing it since the list refers to them. - //Log_Debug("DeepFreeze CheckPortraitCams vessel " + vessel.name + "(" + vessel.id + ") activevessel " + FlightGlobals.ActiveVessel.name + "(" + FlightGlobals.ActiveVessel.id + ")"); + // The following method is derived from TextureReplacer mod. Which is licensed as: + //Copyright © 2013-2015 Davorin Učakar, Ryan Bray + //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + internal static void setHelmets(this Part thisPart, bool helmetOn) + { + if (thisPart.internalModel == null) + { + Log_Debug("setHelmets but no internalModel"); + return; + } - // First, We check through the list of portaits and remove everyone who is from some other vessel, or NO vessel. - var stowaways = new List<Kerbal>(); - foreach (Kerbal thatKerbal in KerbalGUIManager.ActiveCrew) - { - if (thatKerbal.InPart == null) - { - Log_Debug("kerbal " + thatKerbal.name + " Invessel = null add stowaway"); - stowaways.Add(thatKerbal); - } - else - { - Log_Debug("kerbal " + thatKerbal.name + " Invessel = " + thatKerbal.InVessel + " InvesselID = " + thatKerbal.InVessel.id); - if (thatKerbal.InVessel.id != FlightGlobals.ActiveVessel.id) - { - Log_Debug("Adding stowaway"); - stowaways.Add(thatKerbal); - } - } - } - foreach (Kerbal thatKerbal in stowaways) - { - KerbalGUIManager.RemoveActiveCrew(thatKerbal); - } + if (!helmetMeshstored) + storeHelmetMesh(); - if (FlightGlobals.ActiveVessel.id == vessel.id) - { - // Then, Check the list of seats in every crewable part in the vessel and see if anyone is missing who should be present. - List<Part> crewparts = (from p in vessel.parts where p.CrewCapacity > 0 && p.internalModel != null select p).ToList(); - foreach (Part part in crewparts) - { - Log_Debug("Check Portraits for part " + part.name); - foreach (InternalSeat seat in part.internalModel.seats) - { - Log_Debug("checking Seat " + seat.seatTransformName); - if (seat.kerbalRef != null) Log_Debug("kerbalref=" + seat.kerbalRef.crewMemberName); - else Log_Debug("Seat kerbalref is null"); - if (seat.kerbalRef != null && !KerbalGUIManager.ActiveCrew.Contains(seat.kerbalRef)) - { - Log_Debug("Checking crewstatus " + seat.kerbalRef.protoCrewMember.rosterStatus + " " + seat.kerbalRef.protoCrewMember.type); - if (seat.kerbalRef.protoCrewMember.rosterStatus != ProtoCrewMember.RosterStatus.Dead || seat.kerbalRef.protoCrewMember.type != ProtoCrewMember.KerbalType.Unowned) - { - Log_Debug("Adding missing Portrait for " + seat.kerbalRef.crewMemberName); - KerbalGUIManager.AddActiveCrew(seat.kerbalRef); - } - } - } - } - } - else Log_Debug("Vessel is not active vessel"); + Log_Debug("setHelmets helmetOn=" + helmetOn); + //Kerbal thatKerbal = null; + foreach (InternalSeat thatSeat in thisPart.internalModel.seats) + { + if (thatSeat.crew != null) + { + Kerbal thatKerbal = thatSeat.kerbalRef; + if (thatKerbal != null) + { + thatSeat.allowCrewHelmet = helmetOn; + Log_Debug("Setting helmet=" + helmetOn + " for kerbal " + thatSeat.crew.name); + // `Kerbal.ShowHelmet(false)` irreversibly removes a helmet while + // `Kerbal.ShowHelmet(true)` has no effect at all. We need the following workaround. + // I think this can be done using a coroutine to despawn and spawn the internalseat crewmember kerbalref. + // But I found this workaround in TextureReplacer so easier to use that. + //if (thatKerbal.showHelmet) + //{ + setHelmetshaders(thatKerbal, helmetOn); + //} + //else + // Log_Debug("Showhelmet is OFF so the helmettransform does not exist"); + } + else + Log_Debug("kerbalref = null?"); + } + } + } + + // Sets the kerbal layers to make them visible (Thawed) or not (Frozen), setVisible = true sets layers to visible, false turns them off. + internal static void setFrznKerbalLayer(Part part, ProtoCrewMember kerbal, bool setVisible) + { + if (!setVisible) + { + kerbal.KerbalRef.SetVisibleInPortrait(setVisible); + kerbal.KerbalRef.InPart = null; + } + + kerbal.KerbalRef.gameObject.SetActive(setVisible); + if (setVisible) + { + kerbal.KerbalRef.SetVisibleInPortrait(setVisible); + kerbal.KerbalRef.InPart = part; + } + } - // The following method is taken from RasterPropMonitor as-is. Which is covered by GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - internal static Kerbal FindCurrentKerbal(this Part thisPart) - { - if (thisPart.internalModel == null || !VesselIsInIVA(thisPart.vessel)) - return null; - // InternalCamera instance does not contain a reference to the kerbal it's looking from. - // So we have to search through all of them... - Kerbal thatKerbal = null; - foreach (InternalSeat thatSeat in thisPart.internalModel.seats) - { - if (thatSeat.kerbalRef != null) - { - if (thatSeat.kerbalRef.eyeTransform == InternalCamera.Instance.transform.parent) - { - thatKerbal = thatSeat.kerbalRef; - break; - } - } - } - return thatKerbal; - } + internal static RuntimeAnimatorController kerbalIVAController; + + internal static void subdueIVAKerbalAnimations(Kerbal kerbal) + { + try + { + foreach (Animator anim in kerbal.gameObject.GetComponentsInChildren<Animator>()) + { + if (anim.name == kerbal.name) + { + kerbalIVAController = anim.runtimeAnimatorController; + RuntimeAnimatorController myController = anim.runtimeAnimatorController; + AnimatorOverrideController myOverrideController = new AnimatorOverrideController(); + myOverrideController.runtimeAnimatorController = myController; + myOverrideController["idle_animA_upWord"] = myOverrideController["idle_animH_notDoingAnything"]; + myOverrideController["idle_animB"] = myOverrideController["idle_animH_notDoingAnything"]; + myOverrideController["idle_animC"] = myOverrideController["idle_animH_notDoingAnything"]; + myOverrideController["idle_animD_dance"] = myOverrideController["idle_animH_notDoingAnything"]; + myOverrideController["idle_animE_drummingHelmet"] = myOverrideController["idle_animH_notDoingAnything"]; + myOverrideController["idle_animI_drummingControls"] = myOverrideController["idle_animH_notDoingAnything"]; + myOverrideController["idle_animJ_yo"] = myOverrideController["idle_animH_notDoingAnything"]; + myOverrideController["idle_animJ_IdleLoopShort"] = myOverrideController["idle_animH_notDoingAnything"]; + myOverrideController["idle_animK_footStretch"] = myOverrideController["idle_animH_notDoingAnything"]; + myOverrideController["head_rotation_staringUp"] = myOverrideController["idle_animH_notDoingAnything"]; + myOverrideController["head_rotation_longLookUp"] = myOverrideController["idle_animH_notDoingAnything"]; + myOverrideController["head_faceExp_fun_ohAh"] = myOverrideController["idle_animH_notDoingAnything"]; + // Put this line at the end because when you assign a controller on an Animator, unity rebinds all the animated properties + anim.runtimeAnimatorController = myOverrideController; + Log_Debug("Animator " + anim.name + " for " + kerbal.name + " subdued"); + } + } + } + catch (Exception ex) + { + Log(" failed to subdue IVA animations for " + kerbal.name); + Debug.LogException(ex); + } + } + + internal static void reinvigerateIVAKerbalAnimations(Kerbal kerbal) + { + foreach (Animator anim in kerbal.gameObject.GetComponentsInChildren<Animator>()) + { + if (anim.name == kerbal.name) + { + RuntimeAnimatorController myController = kerbalIVAController; + AnimatorOverrideController myOverrideController = new AnimatorOverrideController(); + myOverrideController.runtimeAnimatorController = myController; + // Put this line at the end because when you assign a controller on an Animator, unity rebinds all the animated properties + anim.runtimeAnimatorController = myOverrideController; + Log_Debug("Animator " + anim.name + " for " + kerbal.name + " reinvigerated"); + } + } + } + + #endregion Kerbals + #region Vessels // The following method is taken from RasterPropMonitor as-is. Which is covered by GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + /// <summary> + /// Returns True if thatVessel is the activevessel and the camera is in IVA mode, otherwise returns false. + /// </summary> + /// <param name="thatVessel"></param> + /// <returns></returns> internal static bool VesselIsInIVA(Vessel thatVessel) - { - // Inactive IVAs are renderer.enabled = false, this can and should be used... - // ... but now it can't because we're doing transparent pods, so we need a more complicated way to find which pod the player is in. - return HighLogic.LoadedSceneIsFlight && IsActiveVessel(thatVessel) && IsInIVA(); - } + { + // Inactive IVAs are renderer.enabled = false, this can and should be used... + // ... but now it can't because we're doing transparent pods, so we need a more complicated way to find which pod the player is in. + return HighLogic.LoadedSceneIsFlight && IsActiveVessel(thatVessel) && IsInIVA; + } // The following method is taken from RasterPropMonitor as-is. Which is covered by GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + /// <summary> + /// Returns True if thatVessel is the ActiveVessel, otherwise returns false. + /// </summary> + /// <param name="thatVessel"></param> + /// <returns></returns> internal static bool IsActiveVessel(Vessel thatVessel) - { - return HighLogic.LoadedSceneIsFlight && thatVessel != null && thatVessel.isActiveVessel; - } - + { + return HighLogic.LoadedSceneIsFlight && thatVessel != null && thatVessel.isActiveVessel; + } + // The following method is taken from RasterPropMonitor as-is. Which is covered by GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - internal static bool IsInIVA() + public static bool UserIsInPod(Part thisPart) { - return CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.IVA; - } - internal static bool IsInInternal() - { - return CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.Internal; - } - - internal static RuntimeAnimatorController kerbalIVAController; + // Just in case, check for whether we're not in flight. + if (!HighLogic.LoadedSceneIsFlight) + return false; - internal static void subdueIVAKerbalAnimations(Kerbal kerbal) - { - try - { - foreach (Animator anim in kerbal.gameObject.GetComponentsInChildren<Animator>()) - { - if (anim.name == kerbal.name) - { - kerbalIVAController = anim.runtimeAnimatorController; - RuntimeAnimatorController myController = anim.runtimeAnimatorController; - AnimatorOverrideController myOverrideController = new AnimatorOverrideController(); - myOverrideController.runtimeAnimatorController = myController; - myOverrideController["idle_animA_upWord"] = myOverrideController["idle_animH_notDoingAnything"]; - myOverrideController["idle_animB"] = myOverrideController["idle_animH_notDoingAnything"]; - myOverrideController["idle_animC"] = myOverrideController["idle_animH_notDoingAnything"]; - myOverrideController["idle_animD_dance"] = myOverrideController["idle_animH_notDoingAnything"]; - myOverrideController["idle_animE_drummingHelmet"] = myOverrideController["idle_animH_notDoingAnything"]; - myOverrideController["idle_animI_drummingControls"] = myOverrideController["idle_animH_notDoingAnything"]; - myOverrideController["idle_animJ_yo"] = myOverrideController["idle_animH_notDoingAnything"]; - myOverrideController["idle_animJ_IdleLoopShort"] = myOverrideController["idle_animH_notDoingAnything"]; - myOverrideController["idle_animK_footStretch"] = myOverrideController["idle_animH_notDoingAnything"]; - myOverrideController["head_rotation_staringUp"] = myOverrideController["idle_animH_notDoingAnything"]; - myOverrideController["head_rotation_longLookUp"] = myOverrideController["idle_animH_notDoingAnything"]; - myOverrideController["head_faceExp_fun_ohAh"] = myOverrideController["idle_animH_notDoingAnything"]; - // Put this line at the end because when you assign a controller on an Animator, unity rebinds all the animated properties - anim.runtimeAnimatorController = myOverrideController; - Log_Debug("Animator " + anim.name + " for " + kerbal.name + " subdued"); - } - } - } - catch (Exception ex) + // If we're not in IVA, or the part does not have an instantiated IVA, the user can't be in it. + if (!VesselIsInIVA(thisPart.vessel) || thisPart.internalModel == null) + return false; + + // Now that we got that out of the way, we know that the user is in SOME pod on our ship. We just don't know which. + // Let's see if he's controlling a kerbal in our pod. + if (ActiveKerbalIsLocal(thisPart)) + return true; + + // There still remains an option of InternalCamera which we will now sort out. + if (CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.Internal) { - Log(" failed to subdue IVA animations for " + kerbal.name); - Debug.LogException(ex); + // So we're watching through an InternalCamera. Which doesn't record which pod we're in anywhere, like with kerbals. + // But we know that if the camera's transform parent is somewhere in our pod, it's us. + // InternalCamera.Instance.transform.parent is the transform the camera is attached to that is on either a prop or the internal itself. + // The problem is figuring out if it's in our pod, or in an identical other pod. + // Unfortunately I don't have anything smarter right now than get a list of all transforms in the internal and cycle through it. + // This is a more annoying computation than looking through every kerbal in a pod (there's only a few of those, + // but potentially hundreds of transforms) and might not even be working as I expect. It needs testing. + return thisPart.internalModel.GetComponentsInChildren<Transform>().Any(thisTransform => thisTransform == InternalCamera.Instance.transform.parent); } + + return false; } - internal static void reinvigerateIVAKerbalAnimations(Kerbal kerbal) + // The following method is taken from RasterPropMonitor as-is. Which is covered by GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + public static bool ActiveKerbalIsLocal(this Part thisPart) { - foreach (Animator anim in kerbal.gameObject.GetComponentsInChildren<Animator>()) - { - if (anim.name == kerbal.name) - { - RuntimeAnimatorController myController = kerbalIVAController; - AnimatorOverrideController myOverrideController = new AnimatorOverrideController(); - myOverrideController.runtimeAnimatorController = myController; - // Put this line at the end because when you assign a controller on an Animator, unity rebinds all the animated properties - anim.runtimeAnimatorController = myOverrideController; - Log_Debug("Animator " + anim.name + " for " + kerbal.name + " reinvigerated"); - } - } + return FindCurrentKerbal(thisPart) != null; } - - // The following method is taken from Kerbal Alarm Clock as-is. Which is covered by MIT license. - internal static int getVesselIdx(Vessel vtarget) + // The following method is taken from RasterPropMonitor as-is. Which is covered by GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + public static Kerbal FindCurrentKerbal(this Part thisPart) { - for (int i = 0; i < FlightGlobals.Vessels.Count; i++) - { - if (FlightGlobals.Vessels[i].id == vtarget.id) - { - Log_Debug("Found Target idx=" + i + " (" + vtarget.id + ")"); - return i; - } - } - return -1; + if (thisPart.internalModel == null || !VesselIsInIVA(thisPart.vessel)) + return null; + // InternalCamera instance does not contain a reference to the kerbal it's looking from. + // So we have to search through all of them... + return (from thatSeat in thisPart.internalModel.seats + where thatSeat.kerbalRef != null + where thatSeat.kerbalRef.eyeTransform == InternalCamera.Instance.transform.parent + select thatSeat.kerbalRef).FirstOrDefault(); } + // The following method is taken from RasterPropMonitor as-is. Which is covered by GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + /// <summary> + /// True if Camera is in IVA mode, otherwise false. + /// </summary> + internal static bool IsInIVA + { + get { return CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.IVA; } + } + /// <summary> + /// True if Camera is in Internal mode, otherwise false. + /// </summary> + internal static bool IsInInternal + { + get { return CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.Internal; } + } + + internal static bool ValidVslType(Vessel v) + { + switch (v.vesselType) + { + case VesselType.Base: + case VesselType.Lander: + case VesselType.Probe: + case VesselType.Rover: + case VesselType.Ship: + case VesselType.Station: + return true; + + default: + return false; + } + } + + // The following method is taken from Kerbal Alarm Clock as-is. Which is covered by MIT license. + internal static int getVesselIdx(Vessel vtarget) + { + for (int i = 0; i < FlightGlobals.Vessels.Count; i++) + { + if (FlightGlobals.Vessels[i].id == vtarget.id) + { + Log_Debug("Found Target idx=" + i + " (" + vtarget.id + ")"); + return i; + } + } + return -1; + } + + /// <summary> + /// Will Spawn the Internal Model for a part, we do this for DeepFreeze Mod because it doesn't work if the crew capacity is zero, which may be + /// the case sometimes for DeepFreeze parts. + /// </summary> + /// <param name="part">The Part to spawn the internal model for</param> + /// <returns>True if successful or False if not</returns> + internal static bool spawnInternal(Part part) + { + try + { + if (part.internalModel != null) return true; + part.CreateInternalModel(); + if (part.internalModel != null) + { + part.internalModel.Initialize(part); + part.internalModel.SpawnCrew(); + } + else + { + return false; + } + + return true; + } + catch (Exception) + { + return false; + } + } + + #endregion Vessels + + #region Temperature //Temperature internal static float KelvintoCelsius(float kelvin) - { - return kelvin - 273.15f; - } + { + return kelvin - 273.15f; + } + + internal static float CelsiustoKelvin(float celsius) + { + return celsius + 273.15f; + } + + #endregion Temperature + + #region Resources - internal static float CelsiustoKelvin(float celsius) - { - return celsius + 273.15f; - } - //Resources public static double GetAvailableResource(Part part, String resourceName) - { - var resources = new List<PartResource>(); - part.GetConnectedResources(PartResourceLibrary.Instance.GetDefinition(resourceName).id, ResourceFlowMode.ALL_VESSEL, resources); - double total = 0; - foreach (PartResource pr in resources) - { - total += pr.amount; - } - return total; - } + { + var resources = new List<PartResource>(); + part.GetConnectedResources(PartResourceLibrary.Instance.GetDefinition(resourceName).id, ResourceFlowMode.ALL_VESSEL, resources); + return resources.Sum(pr => pr.amount); + } + public const int MAX_TRANSFER_ATTEMPTS = 4; - // GUI & Window Methods + public static double RequestResource(Part cvp, String name, double amount) + { + if (amount <= 0.0) + return 0.0; + double totalReceived = 0.0; + double requestAmount = amount; + for (int attempts = 0; (attempts < MAX_TRANSFER_ATTEMPTS) && (amount > 0.000000000001); attempts++) + { + double received = cvp.RequestResource(name, requestAmount, ResourceFlowMode.ALL_VESSEL); + Log_Debug("requestResource attempt " + attempts); + Log_Debug("requested power = " + requestAmount.ToString("0.0000000000000000000000")); + Log_Debug("received power = " + received.ToString("0.0000000000000000000000")); + totalReceived += received; + amount -= received; + Log_Debug("amount = " + amount.ToString("0.0000000000000000000000")); + if (received <= 0.0) + requestAmount = amount * 0.5; + else + requestAmount = amount; + } + return totalReceived; + } - public static int scaledScreenHeight = 1; - public static int scaledScreenWidth = 1; - private static bool scaledScreenset; + #endregion Resources - internal static void setScaledScreen() - { - scaledScreenHeight = Mathf.RoundToInt(Screen.height / 1); - scaledScreenWidth = Mathf.RoundToInt(Screen.width / 1); - scaledScreenset = true; - } + #region GUI&Window + // GUI & Window Methods - internal static bool WindowVisibile(Rect winpos) - { - if (!scaledScreenset) setScaledScreen(); - float minmargin = 20.0f; // 20 bytes margin for the window - float xMin = minmargin - winpos.width; - float xMax = scaledScreenWidth - minmargin; - float yMin = minmargin - winpos.height; - float yMax = scaledScreenHeight - minmargin; - bool xRnge = (winpos.x > xMin) && (winpos.x < xMax); - bool yRnge = (winpos.y > yMin) && (winpos.y < yMax); - return xRnge && yRnge; - } + public static int scaledScreenHeight = 1; + public static int scaledScreenWidth = 1; + private static bool scaledScreenset; - internal static Rect MakeWindowVisible(Rect winpos) - { - if (!scaledScreenset) setScaledScreen(); - float minmargin = 20.0f; // 20 bytes margin for the window - float xMin = minmargin - winpos.width; - float xMax = scaledScreenWidth - minmargin; - float yMin = minmargin - winpos.height; - float yMax = scaledScreenHeight - minmargin; + internal static void setScaledScreen() + { + scaledScreenHeight = Mathf.RoundToInt(Screen.height / 1); + scaledScreenWidth = Mathf.RoundToInt(Screen.width / 1); + scaledScreenset = true; + } - winpos.x = Mathf.Clamp(winpos.x, xMin, xMax); - winpos.y = Mathf.Clamp(winpos.y, yMin, yMax); + internal static bool WindowVisibile(Rect winpos) + { + if (!scaledScreenset) setScaledScreen(); + float minmargin = 20.0f; // 20 bytes margin for the window + float xMin = minmargin - winpos.width; + float xMax = scaledScreenWidth - minmargin; + float yMin = minmargin - winpos.height; + float yMax = scaledScreenHeight - minmargin; + bool xRnge = (winpos.x > xMin) && (winpos.x < xMax); + bool yRnge = (winpos.y > yMin) && (winpos.y < yMax); + return xRnge && yRnge; + } - return winpos; - } + internal static Rect MakeWindowVisible(Rect winpos) + { + if (!scaledScreenset) setScaledScreen(); + float minmargin = 20.0f; // 20 bytes margin for the window + float xMin = minmargin - winpos.width; + float xMax = scaledScreenWidth - minmargin; + float yMin = minmargin - winpos.height; + float yMax = scaledScreenHeight - minmargin; - // The following method is taken from RasterPropMonitor as-is. Which is covered by GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - public static string WordWrap(string text, int maxLineLength) - { - var sb = new StringBuilder(); - char[] prc = { ' ', ',', '.', '?', '!', ':', ';', '-' }; - char[] ws = { ' ' }; + winpos.x = Mathf.Clamp(winpos.x, xMin, xMax); + winpos.y = Mathf.Clamp(winpos.y, yMin, yMax); - foreach (string line in text.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)) - { - int currentIndex; - int lastWrap = 0; - do - { - currentIndex = lastWrap + maxLineLength > line.Length ? line.Length : line.LastIndexOfAny(prc, Math.Min(line.Length - 1, lastWrap + maxLineLength)) + 1; - if (currentIndex <= lastWrap) - currentIndex = Math.Min(lastWrap + maxLineLength, line.Length); - sb.AppendLine(line.Substring(lastWrap, currentIndex - lastWrap).Trim(ws)); - lastWrap = currentIndex; - } while (currentIndex < line.Length); - } - return sb.ToString(); - } + return winpos; + } - // Get Config Node Values out of a config node Methods + internal static RectOffset SetRectOffset(RectOffset tmpRectOffset, int intValue) + { + return SetRectOffset(tmpRectOffset, intValue, intValue, intValue, intValue); + } - internal static bool GetNodeValue(ConfigNode confignode, string fieldname, bool defaultValue) - { - bool newValue; - if (confignode.HasValue(fieldname) && bool.TryParse(confignode.GetValue(fieldname), out newValue)) - { - return newValue; - } - return defaultValue; - } + internal static RectOffset SetRectOffset(RectOffset tmpRectOffset, int Left, int Right, int Top, int Bottom) + { + tmpRectOffset.left = Left; + tmpRectOffset.top = Top; + tmpRectOffset.right = Right; + tmpRectOffset.bottom = Bottom; + return tmpRectOffset; + } - internal static int GetNodeValue(ConfigNode confignode, string fieldname, int defaultValue) - { - int newValue; - if (confignode.HasValue(fieldname) && int.TryParse(confignode.GetValue(fieldname), out newValue)) - { - return newValue; - } - return defaultValue; - } + //Tooltip variables + //Store the tooltip text from throughout the code + internal static String strToolTipText = ""; + internal static String strLastTooltipText = ""; + //is it displayed and where + internal static Boolean blnToolTipDisplayed; + internal static Rect rectToolTipPosition; + internal static Int32 intTooltipVertOffset = 12; + internal static Int32 intTooltipMaxWidth = 250; + //timer so it only displays for a preriod of time + internal static float fltTooltipTime; + internal static float fltMaxToolTipTime = 15f; + internal static GUIStyle _TooltipStyle; + + // The following two methods are derived from Kerbal Alarm Clock mod. Which is licensed under: + //The MIT License(MIT) Copyright(c) 2014, David Tregoning + // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal + // in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + // copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + // THE SOFTWARE. + internal static void DrawToolTip() + { + if (strToolTipText != "" && (fltTooltipTime < fltMaxToolTipTime)) + { + GUIContent contTooltip = new GUIContent(strToolTipText); + if (!blnToolTipDisplayed || (strToolTipText != strLastTooltipText)) + { + //reset display time if text changed + fltTooltipTime = 0f; + //Calc the size of the Tooltip + rectToolTipPosition = new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y + intTooltipVertOffset, 0, 0); + float minwidth, maxwidth; + if (_TooltipStyle == null) + { + Log("Missing _TooltipStyle definition, cannot draw tooltips"); + return; + } + _TooltipStyle.CalcMinMaxWidth(contTooltip, out minwidth, out maxwidth); // figure out how wide one line would be + rectToolTipPosition.width = Math.Min(intTooltipMaxWidth - _TooltipStyle.padding.horizontal, maxwidth); //then work out the height with a max width + rectToolTipPosition.height = _TooltipStyle.CalcHeight(contTooltip, rectToolTipPosition.width); // heers the result + //Make sure its not off the right of the screen + if (rectToolTipPosition.x + rectToolTipPosition.width > Screen.width) rectToolTipPosition.x = Screen.width - rectToolTipPosition.width; + } + //Draw the Tooltip + GUI.Label(rectToolTipPosition, contTooltip, _TooltipStyle); + //On top of everything + GUI.depth = 0; + + //update how long the tip has been on the screen and reset the flags + fltTooltipTime += Time.deltaTime; + blnToolTipDisplayed = true; + } + else + { + //clear the flags + blnToolTipDisplayed = false; + } + if (strToolTipText != strLastTooltipText) fltTooltipTime = 0f; + strLastTooltipText = strToolTipText; + } - internal static float GetNodeValue(ConfigNode confignode, string fieldname, float defaultValue) - { - float newValue; - if (confignode.HasValue(fieldname) && float.TryParse(confignode.GetValue(fieldname), out newValue)) - { - return newValue; - } - return defaultValue; - } + internal static void SetTooltipText() + { + if (Event.current.type == EventType.Repaint) + { + strToolTipText = GUI.tooltip; + } + } + + // The following method is taken from RasterPropMonitor as-is. Which is covered by GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + public static string WordWrap(string text, int maxLineLength) + { + var sb = new StringBuilder(); + char[] prc = { ' ', ',', '.', '?', '!', ':', ';', '-' }; + char[] ws = { ' ' }; - internal static double GetNodeValue(ConfigNode confignode, string fieldname, double defaultValue) - { - double newValue; - if (confignode.HasValue(fieldname) && double.TryParse(confignode.GetValue(fieldname), out newValue)) - { - return newValue; - } - return defaultValue; - } + foreach (string line in text.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)) + { + int currentIndex; + int lastWrap = 0; + do + { + currentIndex = lastWrap + maxLineLength > line.Length ? line.Length : line.LastIndexOfAny(prc, Math.Min(line.Length - 1, lastWrap + maxLineLength)) + 1; + if (currentIndex <= lastWrap) + currentIndex = Math.Min(lastWrap + maxLineLength, line.Length); + sb.AppendLine(line.Substring(lastWrap, currentIndex - lastWrap).Trim(ws)); + lastWrap = currentIndex; + } while (currentIndex < line.Length); + } + return sb.ToString(); + } - internal static string GetNodeValue(ConfigNode confignode, string fieldname, string defaultValue) - { - if (confignode.HasValue(fieldname)) - { - return confignode.GetValue(fieldname); - } - return defaultValue; - } + /// <summary> + /// Displays a horizontal list of toggles and returns the index of the selected item. + /// all you have to do is check items[selected] to see what is selected. + /// </summary> + public static int ToggleList(int selected, GUIContent[] items, GUIStyle[] styles, float width) + { + // Keep the selected index within the bounds of the items array + selected = selected < 0 ? 0 : selected >= items.Length ? items.Length - 1 : selected; - internal static Guid GetNodeValue(ConfigNode confignode, string fieldname) - { - if (confignode.HasValue(fieldname)) - { - try - { - Guid id = new Guid(confignode.GetValue(fieldname)); - return id; - } - catch (Exception ex) - { - Debug.Log("Unable to getNodeValue " + fieldname + " from " + confignode); - Debug.Log("Err: " + ex); - return Guid.Empty; - } - } - return Guid.Empty; - } + GUILayout.BeginHorizontal(); + for (int i = 0; i < items.Length; i++) + { + // Display toggle. Get if toggle changed. + bool change = GUILayout.Toggle(selected == i, items[i], styles[i], GUILayout.Width(width)); + // If changed, set selected to current index. + if (change) + selected = i; + } + GUILayout.EndHorizontal(); - internal static T GetNodeValue<T>(ConfigNode confignode, string fieldname, T defaultValue) where T : IComparable, IFormattable, IConvertible - { - if (confignode.HasValue(fieldname)) - { - string stringValue = confignode.GetValue(fieldname); - if (Enum.IsDefined(typeof(T), stringValue)) - { - return (T)Enum.Parse(typeof(T), stringValue); - } - } - return defaultValue; - } - + // Return the currently selected item's index + return selected; + } + + //Returns True if the PauseMenu is open. Because the GameEvent callbacks don't work on the mainmenu. + internal static bool isPauseMenuOpen + { + get + { + try + { + + return PauseMenu.isOpen; + } + catch(Exception) + { + return false; + } + } + } + /// <summary> + ///Will delete Screen Messages. If you pass in messagetext it will only delete messages that contain that text string. + ///If you pass in a messagearea it will only delete messages in that area. Values are: UC,UL,UR,LC,ALL + /// </summary> + /// <param name="messagetext">Specify a string that is part of a message that you want to remove, or pass in empty string to delete all messages</param> + /// <param name="messagearea">Specify a string representing the message area of the screen that you want messages removed from, + /// or pass in "ALL" string to delete from all message areas. + /// messagearea accepts the values of "UC" - UpperCenter, "UL" - UpperLeft, "UR" - UpperRight, "LC" - LowerCenter, "ALL" - All Message Areas</param> + internal static void DeleteScreenMessages(string messagetext, string messagearea) + { + //Get the ScreenMessages Instance + var messages = ScreenMessages.Instance; + List<ScreenMessagesText> messagetexts = new List<ScreenMessagesText>(); + //Get the message Area messages based on the value of messagearea parameter. + switch (messagearea) + { + case "UC": + messagetexts = messages.upperCenter.gameObject.GetComponentsInChildren<ScreenMessagesText>().ToList(); + break; + case "UL": + messagetexts = messages.upperLeft.gameObject.GetComponentsInChildren<ScreenMessagesText>().ToList(); + break; + case "UR": + messagetexts = messages.upperRight.gameObject.GetComponentsInChildren<ScreenMessagesText>().ToList(); + break; + case "LC": + messagetexts = messages.lowerCenter.gameObject.GetComponentsInChildren<ScreenMessagesText>().ToList(); + break; + case "ALL": + messagetexts = messages.gameObject.GetComponentsInChildren<ScreenMessagesText>().ToList(); + break; + } + //Loop through all the mesages we found. + foreach (var msgtext in messagetexts) + { + //If the user specified text to search for only delete messages that contain that text. + if (messagetext != "") + { + if (msgtext != null && msgtext.text.text.Contains(messagetext)) + { + Object.Destroy(msgtext.gameObject); + } + } + else //If the user did not specific a message text to search for we DELETE ALL messages!! + { + Object.Destroy(msgtext.gameObject); + } + } + } + + #endregion GUI&Window + + #region ConfigNodes + // Get Config Node Values out of a config node Methods + + internal static Guid GetNodeValue(ConfigNode confignode, string fieldname) + { + if (confignode.HasValue(fieldname)) + { + try + { + Guid id = new Guid(confignode.GetValue(fieldname)); + return id; + } + catch (Exception ex) + { + Debug.Log("Unable to getNodeValue " + fieldname + " from " + confignode); + Debug.Log("Err: " + ex); + return Guid.Empty; + } + } + return Guid.Empty; + } + + internal static T GetNodeValue<T>(ConfigNode confignode, string fieldname, T defaultValue) where T : IComparable, IFormattable, IConvertible + { + if (confignode.HasValue(fieldname)) + { + string stringValue = confignode.GetValue(fieldname); + if (Enum.IsDefined(typeof(T), stringValue)) + { + return (T)Enum.Parse(typeof(T), stringValue); + } + } + return defaultValue; + } + #endregion ConfigNodes + + #region Time //Formatting time functions - + //Format a Time double variable into format "xxxx:year xxxx:days xxxx:hours xxxx:mins x:xx:secs" - //Future expansion required to format to different formats. - public static String formatTime(double seconds) - { - int y = (int)(seconds / (6.0 * 60.0 * 60.0 * 426.08)); - seconds = seconds % (6.0 * 60.0 * 60.0 * 426.08); - int d = (int)(seconds / (6.0 * 60.0 * 60.0)); - seconds = seconds % (6.0 * 60.0 * 60.0); - int h = (int)(seconds / (60.0 * 60.0)); - seconds = seconds % (60.0 * 60.0); - int m = (int)(seconds / 60.0); - seconds = seconds % 60.0; - - List<String> parts = new List<String>(); - - if (y > 0) - { - parts.Add(String.Format("{0}:year ", y)); - } + //Future expansion required to format to different formats. + public static String formatTime(double seconds) + { + int y = (int)(seconds / (6.0 * 60.0 * 60.0 * 426.08)); + seconds = seconds % (6.0 * 60.0 * 60.0 * 426.08); + int d = (int)(seconds / (6.0 * 60.0 * 60.0)); + seconds = seconds % (6.0 * 60.0 * 60.0); + int h = (int)(seconds / (60.0 * 60.0)); + seconds = seconds % (60.0 * 60.0); + int m = (int)(seconds / 60.0); + seconds = seconds % 60.0; + + List<string> parts = new List<string>(); + + if (y > 0) + { + parts.Add(String.Format("{0}:year ", y)); + } - if (d > 0) - { - parts.Add(String.Format("{0}:days ", d)); - } + if (d > 0) + { + parts.Add(String.Format("{0}:days ", d)); + } - if (h > 0) - { - parts.Add(String.Format("{0}:hours ", h)); - } + if (h > 0) + { + parts.Add(String.Format("{0}:hours ", h)); + } - if (m > 0) - { - parts.Add(String.Format("{0}:mins ", m)); - } + if (m > 0) + { + parts.Add(String.Format("{0}:mins ", m)); + } - if (seconds > 0) - { - parts.Add(String.Format("{0:00}:secs ", seconds)); - } + if (seconds > 0) + { + parts.Add(String.Format("{0:00}:secs ", seconds)); + } - if (parts.Count > 0) - { - return String.Join(" ", parts.ToArray()); - } - return "0s"; - } + if (parts.Count > 0) + { + return String.Join(" ", parts.ToArray()); + } + return "0s"; + } - //Format a Time double variable into format "YxxxxDxxxhh:mm:ss" - //Future expansion required to format to different formats. - internal static string FormatDateString(double time) - { - string outputstring = string.Empty; - int[] datestructure = new int[5]; - if (GameSettings.KERBIN_TIME) - { - datestructure[0] = (int)time / 60 / 60 / 6 / 426; // Years - datestructure[1] = (int)time / 60 / 60 / 6 % 426; // Days - datestructure[2] = (int)time / 60 / 60 % 6; // Hours - datestructure[3] = (int)time / 60 % 60; // Minutes - datestructure[4] = (int)time % 60; //seconds - } - else - { - datestructure[0] = (int)time / 60 / 60 / 24 / 365; // Years - datestructure[1] = (int)time / 60 / 60 / 24 % 365; // Days - datestructure[2] = (int)time / 60 / 60 % 24; // Hours - datestructure[3] = (int)time / 60 % 60; // Minutes - datestructure[4] = (int)time % 60; //seconds - } - if (datestructure[0] > 0) - outputstring += "Y" + datestructure[0].ToString("####") + ":"; - if (datestructure[1] > 0) - outputstring += "D" + datestructure[1].ToString("###") + ":"; - outputstring += datestructure[2].ToString("00:"); - outputstring += datestructure[3].ToString("00:"); - outputstring += datestructure[4].ToString("00"); - return outputstring; - } + //Format a Time double variable into format "YxxxxDxxxhh:mm:ss" + //Future expansion required to format to different formats. + internal static string FormatDateString(double time) + { + string outputstring = String.Empty; + int[] datestructure = new int[5]; + if (GameSettings.KERBIN_TIME) + { + datestructure[0] = (int)time / 60 / 60 / 6 / 426; // Years + datestructure[1] = (int)time / 60 / 60 / 6 % 426; // Days + datestructure[2] = (int)time / 60 / 60 % 6; // Hours + datestructure[3] = (int)time / 60 % 60; // Minutes + datestructure[4] = (int)time % 60; //seconds + } + else + { + datestructure[0] = (int)time / 60 / 60 / 24 / 365; // Years + datestructure[1] = (int)time / 60 / 60 / 24 % 365; // Days + datestructure[2] = (int)time / 60 / 60 % 24; // Hours + datestructure[3] = (int)time / 60 % 60; // Minutes + datestructure[4] = (int)time % 60; //seconds + } + if (datestructure[0] > 0) + outputstring += "Y" + datestructure[0].ToString("####") + ":"; + if (datestructure[1] > 0) + outputstring += "D" + datestructure[1].ToString("###") + ":"; + outputstring += datestructure[2].ToString("00:"); + outputstring += datestructure[3].ToString("00:"); + outputstring += datestructure[4].ToString("00"); + return outputstring; + } - //Returns True if the PauseMenu is open. Because the GameEvent callbacks don't work on the mainmenu. - internal static bool isPauseMenuOpen - { - get - { - try - { - return PauseMenu.isOpen; - } - catch - { - return false; - } - } - } + // Electricity and temperature functions are only valid if timewarp factor is < 5. + internal static bool timewarpIsValid(int max) + { + return TimeWarp.CurrentRateIndex < max; + } - // Electricity and temperature functions are only valid if timewarp factor is < 5. - internal static bool timewarpIsValid(int max) - { - return TimeWarp.CurrentRateIndex < max; - } + internal static void stopWarp() + { + TimeWarp.SetRate(0, false); + } - internal static void stopWarp() - { - TimeWarp.SetRate(0, false); - } + #endregion Time + + #region Strings + /// <summary> + /// Removes a String A from String B. + /// </summary> + internal static string RemoveSubStr(string B, string A) + { + StringBuilder b = new StringBuilder(B); + b.Replace(A, String.Empty); + return b.ToString(); + } + + public enum ISRUStatus + { + Inactive, + Active, + MissingResource, + OutputFull + } + + /// <summary> + /// Returns a Status Indicating the Status of a ISRU ModuleResourceConverter, given that it's actual status can be active, but not actually doing anything. + /// </summary> + internal static ISRUStatus GetModResConverterStatus(ModuleResourceConverter tmpRegRc) + { + ISRUStatus returnStatus = ISRUStatus.Inactive; + if (!tmpRegRc.IsActivated) return ISRUStatus.Inactive; //If it's not Activated, it must be inactive. + // Otherwise it's Activated, but is it really working and using EC? Get it's real status. + if (tmpRegRc.status.ToLower().Contains("inactive")) returnStatus = ISRUStatus.Inactive; //Status is inactive, it's inactive.. Not sure how but sometimes this remains on load even when it's inactive? Hence the test above. + if (tmpRegRc.status.ToLower().Contains("missing")) returnStatus = ISRUStatus.MissingResource; //Missing an Input resource makes this appear in the status. + if (tmpRegRc.status.ToLower().Contains("full")) returnStatus = ISRUStatus.OutputFull; //If the vessel has nowhere to store the output, full appears in the status. + if (tmpRegRc.status.ToLower().Contains("load")) returnStatus = ISRUStatus.Active; //a Percentage Load indicates it is active and actually processing... except when it gets stuck on this. + return returnStatus; + } + + #endregion Strings + + #region ModsInstalled + + private static Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); - // Logging Functions - // Name of the Assembly that is running this MonoBehaviour - internal static String _AssemblyName - { get { return Assembly.GetExecutingAssembly().GetName().Name; } } + internal static bool IsRTInstalled + { + get + { + return IsModInstalled("RemoteTech"); + } + } + + internal static bool IsKopInstalled + { + get + { + return IsModInstalled("Kopernicus"); + } + } + + internal static bool IsRSSInstalled + { + get + { + return IsModInstalled("RealSolarSystem"); + } + } + + internal static bool IsResearchBodiesInstalled + { + get + { + return IsModInstalled("ResearchBodies"); + } + } + + internal static bool IsOPMInstalled + { + get + { + CelestialBody sarnus = FlightGlobals.Bodies.FirstOrDefault(a => a.name == "Sarnus"); + if (sarnus != null) + { + return true; + } + return false; + } + } + + internal static bool IsModInstalled(string assemblyName) + { + Assembly assembly = (from a in assemblies + where a.FullName.Contains(assemblyName) + select a).FirstOrDefault(); + return assembly != null; + } + + #endregion ModsInstalled + + #region Logging + // Logging Functions + // Name of the Assembly that is running this MonoBehaviour + internal static String _AssemblyName + { get { return Assembly.GetExecutingAssembly().GetName().Name; } } internal static bool debuggingOn = false; /// <summary> - /// Logging to the debug file - /// </summary> - /// <param name="Message">Text to be printed - can be formatted as per String.format</param> - /// <param name="strParams">Objects to feed into a String.format</param> + /// Logging to the debug file + /// </summary> + /// <param name="Message">Text to be printed - can be formatted as per String.format</param> + /// <param name="strParams">Objects to feed into a String.format</param> internal static void Log_Debug(String Message, params object[] strParams) - { - if (debuggingOn) + { + if (debuggingOn) { Log("DEBUG: " + Message, strParams); } - } + } /// <summary> - /// Logging to the log file - /// </summary> - /// <param name="Message">Text to be printed - can be formatted as per String.format</param> - /// <param name="strParams">Objects to feed into a String.format</param> - + /// Logging to the log file + /// </summary> + /// <param name="Message">Text to be printed - can be formatted as per String.format</param> + /// <param name="strParams">Objects to feed into a String.format</param> + internal static void Log(String Message, params object[] strParams) - { - Message = String.Format(Message, strParams); // This fills the params into the message - String strMessageLine = String.Format("{0},{2},{1}", - DateTime.Now, Message, - _AssemblyName); // This adds our standardised wrapper to each line - Debug.Log(strMessageLine); // And this puts it in the log - } - } + { + Message = String.Format(Message, strParams); // This fills the params into the message + String strMessageLine = String.Format("{0},{2},{1}", + DateTime.Now, Message, + _AssemblyName); // This adds our standardised wrapper to each line + Debug.Log(strMessageLine); // And this puts it in the log + } + #endregion Logging + } } \ No newline at end of file diff --git a/Source/Textures.cs b/Source/Textures.cs new file mode 100644 index 0000000..c2ab1bb --- /dev/null +++ b/Source/Textures.cs @@ -0,0 +1,215 @@ +// The following Class is derived from Kerbal Alarm Clock mod. Which is licensed under: +// The MIT License(MIT) Copyright(c) 2014, David Tregoning +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using UnityEngine; +using RSTUtils; + +namespace DF +{ + [KSPAddon(KSPAddon.Startup.MainMenu, false)] + public class LoadGlobals : MonoBehaviour + { + public static LoadGlobals Instance; + //Awake Event - when the DLL is loaded + public void Awake() + { + if (Instance != null) + return; + Instance = this; + Textures.LoadIconAssets(); + DontDestroyOnLoad(this); + Utilities.Log("DeepFreeze LoadGlobals Awake Complete"); + } + + public void Start() + { + //GameEvents.onGameSceneSwitchRequested.Add(onGameSceneSwitchRequested); + } + + public void OnDestroy() + { + //GameEvents.onGameSceneSwitchRequested.Remove(onGameSceneSwitchRequested); + } + } + + internal static class Textures + { + + internal static Texture2D TooltipBox = new Texture2D(10, 10, TextureFormat.ARGB32, false); + internal static Texture2D BtnRedCross = new Texture2D(16, 16, TextureFormat.ARGB32, false); + internal static Texture2D BtnResize = new Texture2D(16, 16, TextureFormat.ARGB32, false); + + internal static String PathIconsPath = System.IO.Path.Combine(DeepFreeze._AssemblyFolder.Substring(0, DeepFreeze._AssemblyFolder.IndexOf("\\DeepFreeze\\") + 11), "Icons").Replace("\\", "/"); + internal static String PathToolbarIconsPath = PathIconsPath.Substring(PathIconsPath.ToLower().IndexOf("/gamedata/") + 10); + + + internal static void LoadIconAssets() + { + try + { + LoadImageFromFile(ref TooltipBox, "DFToolTipBox.png", PathIconsPath); + LoadImageFromFile(ref BtnRedCross, "DFbtnRedCross.png", PathIconsPath); + LoadImageFromFile(ref BtnResize, "DFbtnResize.png", PathIconsPath); + } + catch (Exception) + { + RSTUtils.Utilities.Log("DeepFreeze Failed to Load Textures - are you missing a file?"); + } + } + + public static Boolean LoadImageFromFile(ref Texture2D tex, String fileName, String folderPath = "") + { + Boolean blnReturn = false; + try + { + if (folderPath == "") folderPath = PathIconsPath; + + //File Exists check + if (System.IO.File.Exists(String.Format("{0}/{1}", folderPath, fileName))) + { + try + { + tex.LoadImage(System.IO.File.ReadAllBytes(String.Format("{0}/{1}", folderPath, fileName))); + blnReturn = true; + } + catch (Exception ex) + { + RSTUtils.Utilities.Log("TST Failed to load the texture:" + folderPath + "(" + fileName + ")"); + RSTUtils.Utilities.Log(ex.Message); + } + } + else + { + RSTUtils.Utilities.Log("TST Cannot find texture to load:" + folderPath + "(" + fileName + ")"); + } + + + } + catch (Exception ex) + { + RSTUtils.Utilities.Log("TST Failed to load (are you missing a file):" + folderPath + "(" + fileName + ")"); + RSTUtils.Utilities.Log(ex.Message); + } + return blnReturn; + } + + internal static GUIStyle ResizeStyle, ClosebtnStyle; + internal static GUIStyle statusStyle, frozenStyle, comaStyle, sectionTitleLeftStyle, sectionTitleCenterStyle, resizeStyle, StatusOKStyle, + StatusWarnStyle, StatusRedStyle, StatusGrayStyle, ButtonStyle; + + + internal static bool StylesSet = false; + + internal static void SetupStyles() + { + GUI.skin = HighLogic.Skin; + + //Init styles + + Utilities._TooltipStyle = new GUIStyle(GUI.skin.label) + { + fontSize = 12, + fontStyle = FontStyle.Normal, + stretchHeight = true, + wordWrap = true, + border = new RectOffset(3, 3, 3, 3), + padding = new RectOffset(4, 4, 6, 4), + alignment = TextAnchor.MiddleCenter + }; + Utilities._TooltipStyle.normal.background = Textures.TooltipBox; + Utilities._TooltipStyle.normal.textColor = new Color32(207, 207, 207, 255); + Utilities._TooltipStyle.hover.textColor = Color.blue; + + ClosebtnStyle = new GUIStyle(GUI.skin.button) + { + alignment = TextAnchor.MiddleCenter, + fixedWidth = 20, + fixedHeight = 20, + fontSize = 14, + fontStyle = FontStyle.Normal + }; + ClosebtnStyle.active.background = GUI.skin.toggle.onNormal.background; + ClosebtnStyle.onActive.background = ClosebtnStyle.active.background; + ClosebtnStyle.padding = Utilities.SetRectOffset(ClosebtnStyle.padding, 3); + + ResizeStyle = new GUIStyle(GUI.skin.button) + { + alignment = TextAnchor.MiddleCenter, + fixedWidth = 20, + fixedHeight = 20, + fontSize = 14, + fontStyle = FontStyle.Normal + }; + ResizeStyle.onActive.background = ClosebtnStyle.active.background; + ResizeStyle.padding = Utilities.SetRectOffset(ClosebtnStyle.padding, 3); + + //Init styles + sectionTitleLeftStyle = new GUIStyle(GUI.skin.label); + sectionTitleLeftStyle.alignment = TextAnchor.MiddleLeft; + sectionTitleLeftStyle.stretchWidth = true; + sectionTitleLeftStyle.normal.textColor = Color.blue; + sectionTitleLeftStyle.fontStyle = FontStyle.Bold; + + sectionTitleCenterStyle = new GUIStyle(GUI.skin.label); + sectionTitleCenterStyle.alignment = TextAnchor.MiddleCenter; + sectionTitleCenterStyle.stretchWidth = true; + sectionTitleCenterStyle.fontStyle = FontStyle.Bold; + + statusStyle = new GUIStyle(GUI.skin.label); + statusStyle.alignment = TextAnchor.MiddleLeft; + statusStyle.stretchWidth = true; + statusStyle.normal.textColor = Color.white; + + frozenStyle = new GUIStyle(GUI.skin.label); + frozenStyle.alignment = TextAnchor.MiddleLeft; + frozenStyle.stretchWidth = true; + frozenStyle.normal.textColor = Color.cyan; + + comaStyle = new GUIStyle(GUI.skin.label); + comaStyle.alignment = TextAnchor.MiddleLeft; + comaStyle.stretchWidth = true; + comaStyle.normal.textColor = Color.gray; + + StatusOKStyle = new GUIStyle(GUI.skin.label); + StatusOKStyle.alignment = TextAnchor.MiddleLeft; + StatusOKStyle.stretchWidth = true; + StatusOKStyle.normal.textColor = Color.green; + + StatusWarnStyle = new GUIStyle(GUI.skin.label); + StatusWarnStyle.alignment = TextAnchor.MiddleLeft; + StatusWarnStyle.stretchWidth = true; + StatusWarnStyle.normal.textColor = Color.yellow; + + StatusRedStyle = new GUIStyle(GUI.skin.label); + StatusRedStyle.alignment = TextAnchor.MiddleLeft; + StatusRedStyle.stretchWidth = true; + StatusRedStyle.normal.textColor = Color.red; + + StatusGrayStyle = new GUIStyle(GUI.skin.label); + StatusGrayStyle.alignment = TextAnchor.MiddleLeft; + StatusGrayStyle.stretchWidth = true; + StatusGrayStyle.normal.textColor = Color.gray; + + resizeStyle = new GUIStyle(GUI.skin.button); + resizeStyle.alignment = TextAnchor.MiddleCenter; + resizeStyle.padding = new RectOffset(1, 1, 1, 1); + + ButtonStyle = new GUIStyle(GUI.skin.toggle); + ButtonStyle.margin.top = 0; + ButtonStyle.margin.bottom = 0; + ButtonStyle.padding.top = 0; + ButtonStyle.padding.bottom = 0; + + StylesSet = true; + } + } +} \ No newline at end of file diff --git a/Source/VesselInfo.cs b/Source/VesselInfo.cs index 4fa8662..3eb9b9a 100644 --- a/Source/VesselInfo.cs +++ b/Source/VesselInfo.cs @@ -54,26 +54,32 @@ internal VesselInfo(string vesselName, double currentTime) hibernating = false; hasextDoor = false; hasextDoor = false; + hasextPod = false; lastUpdate = currentTime; } internal static VesselInfo Load(ConfigNode node) { - string vesselName = Utilities.GetNodeValue(node, "vesselName", "Unknown"); - double lastUpdate = Utilities.GetNodeValue(node, "lastUpdate", 0.0); + string vesselName = "Unknown"; + node.TryGetValue("vesselName", ref vesselName); + double lastUpdate = 0f; + node.TryGetValue("lastUpdate", ref lastUpdate); + //string vesselName = Utilities.GetNodeValue(node, "vesselName", "Unknown"); + //double lastUpdate = Utilities.GetNodeValue(node, "lastUpdate", 0.0); VesselInfo info = new VesselInfo(vesselName, lastUpdate); - info.numSeats = Utilities.GetNodeValue(node, "numSeats", 0); - info.vesselType = Utilities.GetNodeValue(node, "vesselType", VesselType.Unknown); - info.numCrew = Utilities.GetNodeValue(node, "numCrew", 0); - info.numOccupiedParts = Utilities.GetNodeValue(node, "numOccupiedParts", 0); - info.numFrznCrew = Utilities.GetNodeValue(node, "numFrznCrew", 0); - info.hibernating = Utilities.GetNodeValue(node, "hibernating", false); - info.hasextDoor = Utilities.GetNodeValue(node, "hasextDoor", false); - info.hasextPod = Utilities.GetNodeValue(node, "hasextPod", false); - info.storedEC = Utilities.GetNodeValue(node, "storedEC", 0d); - info.predictedECOut = Utilities.GetNodeValue(node, "predictedECOut", 0d); + node.TryGetValue("numSeats", ref info.numSeats); + node.TryGetValue("numCrew", ref info.numCrew); + node.TryGetValue("numOccupiedParts", ref info.numOccupiedParts); + node.TryGetValue("numFrznCrew", ref info.numFrznCrew); + node.TryGetValue("hibernating", ref info.hibernating); + node.TryGetValue("hasextDoor", ref info.hasextDoor); + node.TryGetValue("hasextPod", ref info.hasextPod); + node.TryGetValue("storedEC", ref info.storedEC); + node.TryGetValue("predictedECOut", ref info.predictedECOut); + info.vesselType = Utilities.GetNodeValue(node, "vesselType", VesselType.Unknown); + return info; }