Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using I2.Loc;
- using KSP.Game;
- using KSP.Game.Science;
- using KSP.Iteration.UI.Binding;
- using KSP.Sim.impl;
- using KSP.Sim.ResourceSystem;
- using KSP.UI.Flight;
- using Newtonsoft.Json;
- using RTG;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- using UnityEngine;
- namespace KSRe {
- internal class ReUtil {
- internal static string GetColorForRange(double min, double max, double value) {
- if (value <= min) return "<color=#b4d455>";
- else if (value >= max) return "<color=#d45455>";
- string[] colorKeys = new string[11] { "b4d4", "c4d4", "d4d4", "d4c4", "d4b4", "d4a4", "d494", "d484", "d474", "d464", "d454" };
- return $"<color=#{colorKeys[(int)Math.Round((value - min) / (max - min) * 10)]}55>";
- }
- internal static string GetUllageStr(double gForce) {
- if (gForce == 0) return $"<color=#d45455>{LocalizationManager.GetTermTranslation($"PartModules/DamageEngine/Low")}</color>";
- else if (gForce > 0.035) return $"<color=#b4d455>{LocalizationManager.GetTermTranslation($"PartModules/DamageEngine/Nominal")}</color>";
- string[] colorKeys = new string[11] { "b4d4", "c4d4", "d4d4", "d4c4", "d4b4", "d4a4", "d494", "d484", "d474", "d464", "d454" };
- string nameKey = "Low";
- if (gForce > 0.0125) nameKey = "Marginal";
- if (gForce > 0.025) nameKey = "Nominal";
- return $"<color=#{colorKeys[(int)Math.Floor((0.035 - gForce) * 300)]}55>{LocalizationManager.GetTermTranslation($"PartModules/DamageEngine/{nameKey}")}</color>";
- }
- internal static string GetDamageStr(double damage) {
- if (damage <= 0) return $"<color=#b4d455>{LocalizationManager.GetTermTranslation($"PartModules/Damage/None")}</color>";
- string[] colorKeys = new string[11] { "b4d4", "c4d4", "d4d4", "d4c4", "d4b4", "d4a4", "d494", "d484", "d474", "d464", "d454" };
- string nameKey = "None";
- if (damage > 85) nameKey = "Heavy";
- else if (damage > 35) nameKey = "Medium";
- else if (damage > 10) nameKey = "Light";
- return $"<color=#{colorKeys[(int)Math.Floor(Math.Min(damage * 0.1, 10))]}55>{LocalizationManager.GetTermTranslation($"PartModules/Damage/{nameKey}")}</color>";
- }
- internal static string GetMachRegStr(double velocity) {
- string key = "Hyper";
- if (velocity < 273) key = "Sub";
- else if (velocity < 409) key = "Trans";
- else if (velocity < 1702) key = "Super";
- return LocalizationManager.GetTranslation($"Diagnostic/{key}sonic");
- }
- internal static string GetGradeStr(float pct) {
- string[] grades = new string[13] { "F", "D-", "D", "D+", "C-", "C", "C+", "B-", "B", "B+", "A-", "A", "A+" };
- return pct < 0.2f ? grades[0] : grades[Mathf.Clamp((int)Math.Round((pct - 0.2f) * 15), 1, 12)];
- }
- internal static bool IsGameSandbox() => GameManager.Instance.Game.SessionManager.ActiveGameMode == "SandboxMode";
- internal static bool IsPALActive(VesselComponent vessel = null, int level = 1, bool bypassVessel = false) {
- GameInstance Game = GameManager.Instance.Game;
- if (!bypassVessel) {
- VesselComponent vsl = vessel ?? GameManager.Instance.Game.ViewController?.GetActiveVehicle()?.GetSimVessel();
- if (vsl == null) return false;
- // if (vsl.IsKerbalEVA) return Game.ScienceManager?.IsNodeUnlocked($"tNode_pal5000_13") ?? false;
- bool hasProbe = vsl.SimulationObject?.PartOwner?.Parts?.Any(p => p.PartData.family == "0010-Probe") ?? false;
- if (!hasProbe) return false;
- }
- bool partTypeCheck = true;
- if (level == 4) partTypeCheck = RePlugin.UIPart.PartName.EndsWith("reactionwheel");
- else if (level == 6) partTypeCheck = "0100-Methalox|0101-DeepThrottle|0102-Cryogenic|0103-DeepSpace".Contains(RePlugin.UIPart.PartData.family) &&
- !"engine_0v_monoprop_puff|engine_0v_xenon_dawn".Contains(RePlugin.UIPart.PartName);
- else if (level == 5 || level == 10) partTypeCheck = RePlugin.UIPart.PartData.category == PartCategories.FuelTank && RePlugin.UIPart.PartData.family != "0070-Xenon";
- if (!partTypeCheck) return false;
- return Game.SessionManager.ActiveGameMode == "SandboxMode" || (Game.ScienceManager?.IsNodeUnlocked($"tNode_pal5000_{(level < 10 ? "0" : "")}{level}") ?? true);
- }
- internal static Dictionary<string, string[]> careerSpecTechs;
- internal static Dictionary<string, float> dmgSciRates;
- internal static Dictionary<string, string[]> mfParts;
- internal static Dictionary<string, string[]> crewAgencies;
- internal static Dictionary<int, float> sciLvls;
- internal static Dictionary<string, string[]> partKerbStats;
- internal static Dictionary<string, Texture2D> agencyFlags;
- internal static string GetPartMfrKey(string partName) => mfParts.FirstOrDefault(m => m.Value.Contains(partName)).Key ?? "";
- internal static ReAgency PlayerReAgency() => RePlugin.saveData.agencies?.FirstOrDefault(a => a.Name == PlayerAgencyName());
- internal static KerbalInfo GetKerbalForAgency(ReAgency agency) {
- KerbalInfo kerbal;
- GameManager.Instance.Game.SessionManager.KerbalRosterManager.TryGetKerbalByName(RePlugin.saveData.kerbals.FirstOrDefault(k => k?.agencyName == agency.Name).Name, out kerbal);
- return kerbal;
- }
- internal static List<KerbalDamage> GetKerbalsForAgency(ReAgency agency) => RePlugin.saveData?.kerbals?.Where(k => k?.agencyName == agency.Name)?.ToList() ?? new List<KerbalDamage>();
- internal static bool IsPlayerAgency(ReAgency agency) => agency?.Name == PlayerAgencyName();
- internal static string RandomTrait() {
- List<string> traits = careerSpecTechs.Keys.Where(s => !s.Contains("_")).ToList();
- List<string> traitsInUse = RePlugin.saveData.kerbals?.Select(k => k?.Trait)?.ToList() ?? new List<string>();
- if (traitsInUse.Count < traits.Count)
- traits.RemoveAll(t => traitsInUse.Contains(t));
- return traits[UnityEngine.Random.Range(0, traits.Count)];
- }
- internal static string PlayerTrait() => RePlugin.saveData.kerbals.FirstOrDefault(k => k?.agencyName == PlayerAgencyName())?.Trait;
- internal static string PlayerAgencyName() => GameManager.Instance.Game.AgencyManager.FindAgencyEntryFirst().AgencyName;
- internal static void TryAddDamage(PartComponent part, double damage, string dmgType) {
- if (part.TryGetModule(out PartComponentModule_DamageEngine moduleDmgEng) && moduleDmgEng != null)
- moduleDmgEng.AddDamage(damage, dmgType);
- else if (part.TryGetModule(out PartComponentModule_Damage moduleDmg) && moduleDmg != null)
- moduleDmg.AddDamage(damage, dmgType);
- }
- internal static double TryGetDamage(PartComponent part, bool mod = true) {
- if (part.TryGetModule(out PartComponentModule_DamageEngine moduleDmgEng) && moduleDmgEng != null)
- return moduleDmgEng.GetDamage(mod);
- else if (part.TryGetModule(out PartComponentModule_Damage moduleDmg) && moduleDmg != null)
- return moduleDmg.GetDamage(mod);
- return 0;
- }
- internal static int GetTotalScience() => !GameManager.Instance.Game.CampaignPlayerManager.TryGetMyCampaignPlayerEntry(out CampaignPlayerEntry player) ? 0 :
- player.AllocatedSciencePoints + player.AvailableSciencePoints;
- internal static void AddScience(int amount, bool pushNotify = true) {
- GameManager.Instance.Game.SessionManager.UpdateMyAgencyAdditionalSciencePoints(GameManager.Instance.Game.SessionManager.GetMyAgencyAdditionalSciencePoints() + amount);
- if (!pushNotify) return;
- NotificationData notify = new NotificationData { Tier = NotificationTier.Alert, Importance = NotificationImportance.Low };
- notify.AlertTitle.LocKey = "Missions/TriumphWindow/AcceptScienceReward";
- notify.FirstLine.LocKey = "+" + amount;
- GameManager.Instance.Game.Notifications.ProcessNotification(notify);
- }
- internal static int GetSciLevel(string sciType) {
- //bool useSub = sciType.Contains("_");
- //List<int> subLvls = new List<int>();
- //if (useSub) {
- // subLvls = sciLvlBonuses.Keys.Take(sciLvlBonuses.Count - 2).ToList();
- // List<int> halfLvls = subLvls.Skip(1).Select(i => i / 2).ToList();
- // subLvls.AddRange(halfLvls);
- // subLvls = subLvls.Distinct().ToList();
- // subLvls.Sort();
- //}
- // (!useSub ? sciLvlBonuses.Keys.ToList() : subLvls)
- int sci = PlayerReAgency().rocketScience.Where(s => s.Key.StartsWith(sciType)).Select(s => s.Value).Sum();
- return Mathf.Clamp(sciLvls.Keys.ToList().TakeWhile(l => l <= sci).Count() - 1 +
- (PlayerTrait() == sciType ? 2 : 0), 0, sciLvls.Keys.ToList().Count - 1);
- }
- internal static float GetSciBonus(string sciType) => sciLvls.ElementAt(GetSciLevel(sciType.Contains("_") ? sciType.Split('_')[0] : sciType)).Value;
- internal static string GetSciLocKey(string sciType) {
- bool isSub = sciType.Contains("_");
- string[] keys = isSub ? sciType.Split('_') : new string[2] { sciType, "Title" };
- string locKey = sciType.StartsWith("Science") && isSub ? $"Science/Experiments/{keys[1]}/{keys[0].Replace("Science", "")}/ReportName" : $"Career/{keys[0]}/{keys[1]}";
- if (sciType.Contains("CrewObservation")) locKey = "Science/Experiments/CrewObservation/Data/ReportName";
- else if (sciType == "Aeronautics_Sample" || sciType == "Aeronautics_Data") locKey = $"Science/Experiments/AtmosphereSurvey/{sciType.Split('_')[1]}/ReportName";
- return locKey;
- }
- internal static void PushNotify(string name, string descKey, NotificationImportance color, bool rand = true, string obj = null) {
- UnityEngine.Random.InitState((name + descKey).GetHashCode() + DateTime.Now.Millisecond);
- NotificationData notify = new NotificationData { Tier = NotificationTier.Alert, TimeStamp = GameManager.Instance.Game.UniverseModel.UniverseTime, Importance = color };
- notify.AlertTitle.LocKey = name;
- notify.FirstLine.LocKey = $"{(rand || descKey.StartsWith("Wings") || descKey.StartsWith("Recovery") ? "KerbalLife" : "Career")}/Notifications/{descKey}{(rand ? UnityEngine.Random.Range(0, 3) + "" : "")}";
- if (obj != null) notify.FirstLine.ObjectParams = new object[1] { obj };
- GameManager.Instance.Game.Notifications.ProcessNotification(notify);
- }
- internal static string GetRandomKerbalName(int i) {
- string[] prefix = new string[] {
- "Ad", "Al", "Ald", "An", "Bar", "Bart", "Bil", "Billy-Bob", "Bob", "Bur", "Cal", "Cam", "Chad", "Cor", "Dan", "Der", "Des", "Dil", "Do", "Don", "Dood", "Dud", "Dun",
- "Ed", "El", "En", "Er", "Fer", "Fred", "Gene", "Geof", "Ger", "Gil", "Greg", "Gus", "Had", "Hal", "Han", "Har", "Hen", "Her", "Hud", "Jed", "Jen", "Jer", "Joe", "John",
- "Jon", "Jor", "Kel", "Ken", "Ker", "Kir", "Lan", "Lem", "Len", "Lo", "Lod", "Lu", "Lud", "Mac", "Mal", "Mat", "Mel", "Mer", "Mil", "Mit", "Mun", "Ned", "Neil", "Nel",
- "New", "Ob", "Or", "Pat", "Phil", "Ray", "Rib", "Rich", "Ro", "Rod", "Ron", "Sam", "Sean", "See", "Shel", "Shep", "Sher", "Sid", "Sig", "Son", "Thom", "Thomp", "Tom",
- "Wehr", "Wil"
- };
- string[] suffix = new string[] {
- "ald", "bal", "bald", "bart", "bas", "berry", "bert", "bin", "ble", "bles", "bo", "bree", "brett", "bro", "bur", "burry", "bus", "by", "cal", "can", "cas", "cott",
- "dan", "das", "den", "din", "do", "don", "dorf", "dos", "dous", "dred", "drin", "dun", "ely", "emone", "emy", "eny", "fal", "fel", "fen", "field", "ford", "fred",
- "frey", "frey", "frid", "frod", "fry", "furt", "gan", "gard", "gas", "gee", "gel", "ger", "gun", "hat", "ing", "ke", "kin", "lan", "las", "ler", "ley", "lie", "lin",
- "lin", "lo", "lock", "long", "lorf", "ly", "mal", "man", "min", "ming", "mon", "more", "mund", "my", "nand", "nard", "ner", "ney", "nie", "ny", "oly", "ory", "rey",
- "rick", "rie", "righ", "rim", "rod", "ry", "sby", "sel", "sen", "sey", "ski", "son", "sted", "ster", "sy", "ton", "top", "trey", "van", "vey", "vin", "vis", "well",
- "wig", "win", "wise", "zer", "zon", "zor"
- };
- UnityEngine.Random.InitState(i);
- return prefix[UnityEngine.Random.Range(0, prefix.Length)] + suffix[UnityEngine.Random.Range(0, suffix.Length)];
- }
- internal static string GetGameObjPath(GameObject obj) {
- string path = "/" + obj.name;
- while (obj.transform.parent != null) {
- obj = obj.transform.parent.gameObject;
- path = "/" + obj.name + path;
- }
- return path;
- }
- }
- internal class ReUtilKerb {
- internal static int GetDamageInt(double value) {
- if (value < -50) return 0;
- else if (value < 0) return 1;
- else if (value > 90) return 11;
- return (int)Math.Floor(value / 10) + 2;
- }
- internal static string GetPsychologyStr(float pct) {
- string color = ReUtil.GetColorForRange(0, 1, 1 - pct);
- if (pct <= 0.2) return $"{color}--</color>";
- else if (pct >= 0.8) return $"{color}++</color>";
- return new string[3] { $"{color}-</color>", $"{color}±</color>", $"{color}+</color>" }[(int)Math.Floor((pct - 0.2) * 5)];
- }
- }
- public class KerbalDamage {
- // public IGGuid Id { get; private set; }
- public string Name { get; private set; }
- public string Trait { get; private set; }
- public string agencyName;
- public string status;
- public string celName;
- public Dictionary<string, double> damage;
- // public Dictionary<string, double> records;
- public KerbalDamage(string name, string trait, string agency) {
- Name = name;
- Trait = trait;
- agencyName = agency;
- damage = new Dictionary<string, double>();
- // records = new Dictionary<string, double>();
- }
- }
- public class ReAgency {
- public string Name { get; private set; }
- // public string leaderName;
- // public string leaderTrait;
- public Dictionary<string, int> rocketScience;
- public Dictionary<string, double> partRecords;
- public ReAgency(string name) {
- Name = name;
- rocketScience = new Dictionary<string, int>();
- partRecords = new Dictionary<string, double>();
- }
- }
- public class Repairer {
- public string Name { get; private set; }
- public string Guid { get; private set; }
- public string TargetGuid { get; private set; }
- // public float Estimate { get; private set; }
- public Repairer(string name, string guid, string targetGuid) {
- Name = name;
- Guid = guid;
- TargetGuid = targetGuid;
- // Estimate = estimate;
- }
- }
- }
- // ---
- using BepInEx;
- using BepInEx.Logging;
- using HarmonyLib;
- using I2.Loc;
- using KSP;
- using KSP.Api.CoreTypes;
- using KSP.Game;
- using KSP.Game.Science;
- using KSP.Iteration.UI.Binding;
- using KSP.Messages;
- using KSP.Modules;
- using KSP.Networking.MP.GameClient;
- using KSP.OAB;
- using KSP.Rendering.Planets;
- using KSP.Sim;
- using KSP.Sim.Definitions;
- using KSP.Sim.DeltaV;
- using KSP.Sim.impl;
- using KSP.Sim.ResourceSystem;
- using KSP.UI;
- using KSP.UI.Binding.Widget;
- using KSP.UI.Flight;
- using Newtonsoft.Json;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Text;
- using System.Threading.Tasks;
- using TMPro;
- using UnityEngine;
- using UnityEngine.UI;
- using static KSP.Api.UIDataPropertyStrings.View;
- namespace KSRe {
- [HarmonyPatch]
- public class ReHarmony {
- [HarmonyPatch(typeof(Curtain), "Awake")]
- [HarmonyPrefix]
- public static void FixLoadingScreen(Curtain __instance) =>
- typeof(Curtain).GetField("_appStartLoadingScreenSprite1", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(__instance, null);
- [HarmonyPatch(typeof(PopulationComponent), nameof(PopulationComponent.OnStart))]
- [HarmonyPrefix]
- public static void AddKerbalSpawnDelay(PopulationComponent __instance) =>
- typeof(PopulationComponent).GetField("_refillDelay", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(__instance, 0.8);
- [HarmonyPatch(typeof(PopulationComponent), "UpdateCurrentKerbalCount")]
- [HarmonyPostfix]
- public static void FixKerbalSpawnCap(PopulationComponent __instance) {
- typeof(PopulationComponent).GetField("_refillKerbalLimit", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(__instance, ReUtil.IsGameSandbox() ? 10 : GameManager.Instance.Game.UniverseModel.UniverseTime < 10 ? 6 : 0);
- typeof(PopulationComponent).GetField("_refillKerbalEmptySubIdOnly", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(__instance, ReUtil.IsGameSandbox());
- }
- [HarmonyPatch(typeof(PartInfoOverlay), "PopulateCoreInfoFromPart")]
- [HarmonyPostfix]
- public static void FixPartStats(IObjectAssemblyAvailablePart IOBAPart, ref List<KeyValuePair<string, string>> __result) {
- __result[0] = new KeyValuePair<string, string>(__result[0].Key, $"{IOBAPart.Mass:F3} {Units.SymbolTonne}");
- if (IOBAPart.CrewCapacity > 0) {
- __result.Add(new KeyValuePair<string, string>(OABLocalization.GetTranslation("VAB/Tooltip/Crew Capacity"), IOBAPart.CrewCapacity + ""));
- if (ReUtil.partKerbStats.Any(p => p.Value.Contains(IOBAPart.Name)))
- __result.Add(new KeyValuePair<string, string>(OABLocalization.GetTranslation("KerbalLife/Title"), ReUtil.partKerbStats.FirstOrDefault(p => p.Value.Contains(IOBAPart.Name)).Key));
- }
- }
- [HarmonyPatch(typeof(PartInfoOverlay), "PopulateResourceInfoFromPart")]
- [HarmonyPostfix]
- public static void FixFuelContainerTotal(List<KeyValuePair<string, string>> dict, IObjectAssemblyResource[] resourceArray) {
- if (!resourceArray.Any(r => r.Name == "FuelContainer")) return;
- dict[dict.Count - 1] = new KeyValuePair<string, string>(dict.Last().Key, $"~{resourceArray.First(r => r.Name == "FuelContainer").Capacity} {Units.SymbolTonne}");
- }
- [HarmonyPatch(typeof(PartInfoOverlay), "PopulateEngineThrustAndISP")]
- [HarmonyPostfix]
- public static void ReEngineStats(List<KeyValuePair<string, string>> dictToPopulate, IObjectAssemblyAvailablePart IOABPart) {
- if (!(IOABPart is OABPartData) || IOABPart.Category != PartCategories.Engine) return;
- if (!IOABPart.PartData.serializedPartModules.Any(m => m.BehaviourType == typeof(Module_Engine))) return;
- Data_Engine engine = (Data_Engine)IOABPart.PartData.serializedPartModules.First(m => m.BehaviourType == typeof(Module_Engine)).ModuleData.First(d =>
- d.DataObject.DataType == typeof(Data_Engine)).DataObject;
- Data_Engine.EngineMode mode = engine.engineModes.First();
- dictToPopulate.RemoveAt(dictToPopulate.Count - 4);
- dictToPopulate[dictToPopulate.Count - 3] = new KeyValuePair<string, string>(
- OABLocalization.GetTranslation($"VAB/Tooltip/Thrust ({(mode.engineType != EngineType.Turbine ? "Vacuum" : "Atmo")})"),
- dictToPopulate[dictToPopulate.Count - 3].Value);
- string ispStr = $"{dictToPopulate[dictToPopulate.Count - 1].Value}";
- if (mode.engineType != EngineType.Turbine) ispStr = $"{ispStr} - {dictToPopulate[dictToPopulate.Count - 2].Value}";
- dictToPopulate[dictToPopulate.Count - 2] = new KeyValuePair<string, string>(
- $"{OABLocalization.GetTranslation($"VAB/Tooltip/ISP{(mode.engineType == EngineType.Turbine ? " (Atmo)" : "")}")}" +
- (mode.engineType != EngineType.Turbine ? $" (0 - 1 < {mode.atmosphereCurve.Curve?.keys?.Last().time:N0} {OABLocalization.GetTranslation("Unit/Symbol/Atmosphere")})" : ""), ispStr);
- dictToPopulate.RemoveAt(dictToPopulate.Count - 1);
- dictToPopulate.Insert(dictToPopulate.Count - 1, new KeyValuePair<string, string>(OABLocalization.GetTranslation("VAB/StagingStack/TWR"),
- $"{mode.maxThrust / ((mode.engineType != EngineType.SolidBooster ? IOABPart.Mass : IOABPart.TotalMass) * GameManager.Instance.Game.UniverseModel.HomeWorld.gravityASL * 10):N2}"));
- if (mode.engineType != EngineType.SolidBooster) {
- string throttleStr = Math.Abs(mode.maxThrust - mode.minThrust) > 0.1 ? $"{mode.minThrust / mode.maxThrust * 100:N0}-{1:P0}" : "-";
- dictToPopulate.Add(new KeyValuePair<string, string>(OABLocalization.GetTranslation("PartModules/Engine/EngineThrottle"), throttleStr));
- }
- string fuelStr = "";
- if (mode.propellant.mixtureName == "Methalox")
- fuelStr = $"{OABLocalization.GetTranslation("Resource/Abbreviation/Ox")} : {OABLocalization.GetTranslation("Resource/Abbreviation/LF")} " +
- ((RePlugin.fuelRatiosByVol?.Value ?? false) ? "(2:1)" : "(5:2)");
- else if (mode.propellant.mixtureName == "Hydrolox")
- fuelStr = $"{OABLocalization.GetTranslation("Resource/Abbreviation/H")} : {OABLocalization.GetTranslation("Resource/Abbreviation/Ox")} " +
- ((RePlugin.fuelRatiosByVol?.Value ?? false) ? "(5:2)" : "(5:32)");
- else if (mode.propellant.mixtureName == "Hypergolic")
- fuelStr = $"{OABLocalization.GetTranslation("Resource/Abbreviation/MP")} : {OABLocalization.GetTranslation("Resource/Abbreviation/LF")} " +
- ((RePlugin.fuelRatiosByVol?.Value ?? false) ? "(5:1)" : "(15:2)");
- else if (mode.propellant.mixtureName == "XenonEC")
- fuelStr = $"{OABLocalization.GetTranslation("Resource/Abbreviation/Xe")} + {OABLocalization.GetTranslation("Resource/Abbreviation/EC")}";
- else if ("MonoPropellant|Hydrogen|Methane Air".Contains(mode.propellant.mixtureName))
- fuelStr = OABLocalization.GetTranslation("Resource/DisplayName/" + mode.propellant.mixtureName);
- if (fuelStr.Length > 0) dictToPopulate.Add(new KeyValuePair<string, string>(OABLocalization.GetTranslation("PartModules/Generic/Tooltip/Propellants"), fuelStr));
- }
- //[HarmonyPatch(typeof(StagePartDataContext), "GetFuelTotalAmount")]
- //[HarmonyPostfix]
- //public static void ReFuelTotal(int fuelIngredientIndex, ref float __result, StagePartDataContext __instance) {
- // if (__result == 0.0f) return;
- // if (!"Methalox|Hydrolox|Hypergolic".Contains(__instance.associatedEngineData.engineModes[0].propellant.mixtureName)) return; // 0 -> 1 for rapier
- // GameInstance game = GameManager.Instance.Game;
- // VesselDeltaVComponent deltaComp = game.GlobalGameState.GetGameState().GameState == GameState.VehicleAssemblyBuilder ?
- // game.OAB.Current.Stats.MainAssembly.VesselDeltaV : game.ViewController.GetActiveVehicle().GetSimVessel().VesselDeltaV;
- // // deltaComp.GetStage(__instance.associatedPart.InStageIndex).Parts.
- // if (__instance.associatedEngineData != null && __instance.associatedEngineData.PropellantStates != null) {
- // ResourceFlowRequestHandle reqHandle = __instance.associatedEngineData.PropellantStates[__instance.associatedEngineData.currentEngineModeIndex].requestHandle;
- // ResourceFlowRequestManager.ManagedRequestWrapper reqWrap = null;
- // bool reqValid = false;
- // if (__instance.associatedPartComponent != null)
- // reqValid = __instance.associatedPartComponent.PartResourceFlowRequestBroker.TryGetCurrentRequest(reqHandle, out reqWrap);
- // else if (__instance.associatedPart != null && __instance.associatedPart.ResourceFlowRequestBroker != null)
- // reqValid = __instance.associatedPart.ResourceFlowRequestBroker.TryGetCurrentRequest(reqHandle, out reqWrap);
- // if (reqValid && reqWrap.instructions.Count > fuelIngredientIndex) {
- // FlowInstructionConfig flowConfig = reqWrap.instructions[fuelIngredientIndex];
- // if (flowConfig.ResourceContainerGroup != null) {
- // double resTotal = flowConfig.ResourceContainerGroup.GetResourceCapacityUnits(flowConfig.FlowResource);
- // RePlugin.Logger.LogInfo("flowResTotal: " + resTotal);
- // foreach (ContainedResourceData resData in flowConfig.ResourceContainerGroup.GetAllResourcesContainedData()) {
- // RePlugin.Logger.LogInfo("this stored: " + resData.StoredUnits);
- // RePlugin.Logger.LogInfo("this total: " + resData.CapacityUnits);
- // }
- // // __result = (float)resTotal;
- // }
- // }
- // }
- //}
- [HarmonyPatch(typeof(PartsManagerCore), nameof(PartsManagerCore.Initialize))]
- [HarmonyPostfix]
- public static void AddPartMgrMinBtn(PartsManagerCore __instance) {
- GameObject xBtn = __instance.transform.FindChildRecursive("BTN-Close")?.gameObject;
- if (xBtn == null) return;
- GameObject minBtn = UnityEngine.Object.Instantiate(xBtn, xBtn.transform.parent);
- minBtn.transform.SetSiblingIndex(minBtn.transform.parent.childCount - 2);
- Image imageComp = minBtn.GetChild("Icon")?.GetComponent<Image>();
- if (imageComp != null) {
- imageComp.sprite = null;
- // GameManager.Instance.Assets.Load<Sprite>("WB-ICO-Minimize", s => { imageComp.sprite = s; });
- }
- UIAction_Void_Button actionComp = minBtn.GetComponent<UIAction_Void_Button>();
- if (actionComp != null) {
- actionComp.enabled = false;
- ButtonExtended btnComp = minBtn.GetComponent<ButtonExtended>();
- if (btnComp != null) {
- btnComp.onClick.AddListener(delegate {
- RectTransform tformComp = __instance.GetComponent<RectTransform>();
- if (tformComp == null) return;
- float botEdgePad = 18;
- float minSizeY = 100;
- float maxSizeY = Math.Min((Screen.height / 2) + minSizeY - botEdgePad + tformComp.localPosition.y, 900);
- tformComp.localPosition = new Vector2(tformComp.localPosition.x,
- tformComp.localPosition.y + (tformComp.sizeDelta.y == minSizeY ? -(maxSizeY - minSizeY) : tformComp.sizeDelta.y - minSizeY));
- tformComp.sizeDelta = new Vector2 (tformComp.sizeDelta.x,
- tformComp.sizeDelta.y == minSizeY ? maxSizeY : minSizeY);
- });
- }
- }
- }
- [HarmonyPatch(typeof(PartBehavior), nameof(PartBehavior.OnCollisionEnter))]
- [HarmonyPostfix]
- public static void AddImpactDamage(PartBehavior __instance, Collision c) {
- if (c == null || (__instance?.IsSimObjectDestroyed() ?? true) || __instance == null) return;
- if (c.relativeVelocity.magnitude > __instance.Model.CrashTolerance || c.relativeVelocity.magnitude < 0.1) return;
- if (__instance.SimObjectComponent.Guid == RePlugin.UIPart?.Guid) {
- RePlugin.UIPartImpacts = Tuple.Create(c.relativeVelocity.magnitude < RePlugin.UIPartImpacts.Item1 || RePlugin.UIPartImpacts.Item1 == 0 ? c.relativeVelocity.magnitude : RePlugin.UIPartImpacts.Item1,
- c.relativeVelocity.magnitude > RePlugin.UIPartImpacts.Item2 ? c.relativeVelocity.magnitude : RePlugin.UIPartImpacts.Item2);
- }
- // if (c.relativeVelocity.magnitude < __instance.Model.CrashTolerance * 0.667) return;
- // ((c.relativeVelocity.magnitude - __instance.Model.CrashTolerance * 0.667) / __instance.Model.CrashTolerance) * 200.0;
- double dmg = Math.Pow(1.047, (c.relativeVelocity.magnitude / __instance.Model.CrashTolerance) * 100) - 1;
- if (__instance.SimObjectComponent.PartName == "eva_kerbal") {
- RePlugin.AddKerbalDamage(__instance.partOwner.SimObjectComponent.DisplayName, "Medicine_Impacts", dmg);
- if (c.relativeVelocity.magnitude > 3) ReUtil.PushNotify(__instance.partOwner.SimObjectComponent.DisplayName, "Hurt", NotificationImportance.Medium);
- } else ReUtil.TryAddDamage(__instance.SimObjectComponent, dmg, "Flight_Impacts");
- }
- [HarmonyPatch(typeof(RDCenterUIController), "InitializeTechTreeEnviroment")]
- [HarmonyPrefix]
- public static void AddTechTiers(RDCenterUIController __instance) {
- typeof(RDCenterUIController).GetField("_tiers", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(__instance, 8);
- //FieldInfo sizeField = typeof(RDCenterUIController).GetField("_treeContainerHorizontalSize", BindingFlags.Instance | BindingFlags.NonPublic);
- //if (sizeField != null) sizeField.SetValue(__instance, (float)sizeField.GetValue(__instance) * 0.5);
- }
- [HarmonyPatch(typeof(RDCenterUIController), "UpdateFocusedTechNode")]
- [HarmonyPostfix]
- public static void ReTechPanel(RDCenterUIController __instance) {
- TechNodeView tNode = (TechNodeView)typeof(RDCenterUIController).GetField("_focusedNode", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance);
- FieldInfo textField = typeof(RDCenterUIController).GetField("_techNodeRequiredTechnologiesProperty", BindingFlags.Instance | BindingFlags.NonPublic);
- ScienceManager sciMgr = GameManager.Instance.Game.ScienceManager;
- Property<string> txtProp = (Property<string>)textField?.GetValue(__instance);
- // string path = "GameManager/Default Game Instance(Clone)/UI Manager(Clone)/Main Canvas/RDCenterUI(Clone)/Container/TechNodeInfo/Content/";
- // TextMeshProUGUI txtComp = GameObject.Find(path + "Footer/RequiredTechList")?.GetComponent<TextMeshProUGUI>();
- // if (txtComp == null) return;
- List<string> prqs = tNode?.AssociatedTechNode?.RequiredTechNodeIDs?.ToList();
- if (prqs?.All(t => sciMgr.IsNodeUnlocked(t)) ?? true) {
- if (tNode.CurrentNodeState == TechNodeView.NodeState.Visible) {
- string cost = tNode.AssociatedTechNode.RequiredSciencePoints.ToString();
- bool isSubTier = cost.StartsWith("2") || cost.StartsWith("3") || cost.StartsWith("6") || cost.StartsWith("8");
- int lvl = tNode.AssociatedTechNode.TierToUnlock * 2 - (isSubTier ? 0 : 1);
- List<string> sciReqs = ReUtil.careerSpecTechs.Where(p => p.Value.Any(t => tNode.AssociatedTechNode.ID.Contains(t))).Select(p => p.Key).Where(s =>
- lvl > ReUtil.GetSciLevel(s)).ToList();
- if (sciReqs?.Count > 0)
- txtProp?.SetValue($"<color=#5FBFE4>{LocalizationManager.GetTranslation("Career/Level")} {lvl} " +
- $"{LocalizationManager.GetTranslation(ReUtil.GetSciLocKey(sciReqs.First()))}{(sciReqs.Count == 1 ? "" : $" (+{sciReqs.Count - 1})")}</color>");
- textField?.SetValue(__instance, txtProp);
- }
- return;
- } else if (prqs.Count == 1) return;
- prqs.RemoveAll(t => sciMgr.IsNodeUnlocked(t));
- // txtComp.text = LocalizationManager.GetTranslation(sciMgr.TechNodeDataStore.AvailableData[prqs.First()].NameLocKey) + (prqs.Count == 1 ? "" : $" (+{prqs.Count - 1})");
- txtProp?.SetValue(LocalizationManager.GetTranslation(sciMgr.TechNodeDataStore.AvailableData[prqs.First()].NameLocKey) + (prqs.Count == 1 ? "" : $" (+{prqs.Count - 1})"));
- textField?.SetValue(__instance, txtProp);
- }
- [HarmonyPatch(typeof(RDCenterUIController), "GetNodeState")]
- [HarmonyPostfix]
- public static void ReTechNodeState(RDCenterUIController __instance, TechNodeView node, ref TechNodeView.NodeState __result) {
- if (__result != TechNodeView.NodeState.Unlockable) return;
- string cost = node.AssociatedTechNode.RequiredSciencePoints.ToString();
- bool isSubTier = cost.StartsWith("2") || cost.StartsWith("3") || cost.StartsWith("6") || cost.StartsWith("8");
- List<string> sciReqs = ReUtil.careerSpecTechs.Where(p => p.Value.Any(t => node.AssociatedTechNode.ID.Contains(t))).Select(p => p.Key).Where(s =>
- (node.AssociatedTechNode.TierToUnlock * 2 - (isSubTier ? 0 : 1)) > ReUtil.GetSciLevel(s)).ToList();
- if (sciReqs?.Count > 0)
- __result = TechNodeView.NodeState.Visible;
- }
- [HarmonyPatch(typeof(RDCenterUIController), "OnUnlockTechNode")]
- [HarmonyPostfix]
- public static void UnlockTechEvents(RDCenterUIController __instance) {
- TechNodeView tNode = (TechNodeView)typeof(RDCenterUIController).GetField("_focusedNode", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance);
- if (tNode == null) return;
- List<TechNodeData> tree = GameManager.Instance.Game.ScienceManager.TechNodeDataStore.AvailableData.Select(p => p.Value).ToList();
- int total = tree.Count(t => t.TierToUnlock == tNode.AssociatedTechNode.TierToUnlock);
- int unlocked = tree.Count(t => t.TierToUnlock == tNode.AssociatedTechNode.TierToUnlock && GameManager.Instance.Game.ScienceManager.IsNodeUnlocked(t.ID));
- if (unlocked == 1 || total == unlocked)
- for (int i = 0; i < tNode.AssociatedTechNode.TierToUnlock; i++)
- GameManager.Instance.Game.SessionManager.KerbalRosterManager.CreateKerbalByName(ReUtil.GetRandomKerbalName(i + DateTime.Now.Second + DateTime.Now.Millisecond));
- foreach (string partID in tNode.AssociatedTechNode.UnlockedPartsIDs.Where(p => ReUtil.GetPartMfrKey(p)?.Length > 0 && RePlugin.TryGetPartRecord(p) == 0))
- RePlugin.AddPartRecord(partID, 0);
- bool addAgency = false;
- foreach (TechNodeData tech in tree.Where(t => t.RequiredTechNodeIDs.Contains(tNode.AssociatedTechNode.ID)))
- foreach (string partID in tech.UnlockedPartsIDs) {
- string mfKey = ReUtil.GetPartMfrKey(partID);
- if (mfKey?.Length > 0 && RePlugin.saveData.agencies.All(a => a.Name != mfKey)) {
- addAgency = true;
- RePlugin.saveData.agencies.Add(new ReAgency(mfKey));
- __instance.StartCoroutine(CallbackUtil.DelayedCallback(2.0f, delegate {
- ReUtil.PushNotify($"Missions/MissionGranter/Name/{mfKey}", "NewAgency", NotificationImportance.Low, false);
- }));
- }
- }
- if (addAgency) return;
- if (tNode.AssociatedTechNode.TierToUnlock > ReUtil.crewAgencies.Keys.Count(ca => RePlugin.saveData.agencies.Any(sa => sa.Name == ca)) - 3) {
- UnityEngine.Random.InitState((GameManager.Instance.Game.SessionGuidString + tNode.AssociatedTechNode.TierToUnlock).GetHashCode());
- addAgency = unlocked > UnityEngine.Random.Range(0, total);
- // addAgOrCrew = Math.Pow(1.047, (unlocked / total) * 100) - 1 > UnityEngine.Random.value * 100;
- }
- if (!addAgency) return;
- int rand = UnityEngine.Random.Range(0, ReUtil.crewAgencies.Keys.Count(ca => RePlugin.saveData.agencies.All(sa => ca != sa.Name)));
- string agency = ReUtil.crewAgencies.Keys.Where(ca => RePlugin.saveData.agencies.All(sa => ca != sa.Name)).ToList()[rand];
- RePlugin.saveData.agencies.Add(new ReAgency(agency));
- __instance.StartCoroutine(CallbackUtil.DelayedCallback(2.0f, delegate {
- ReUtil.PushNotify($"Missions/MissionGranter/Name/{agency}", "NewAgency", NotificationImportance.Low, false);
- foreach (string kerb in ReUtil.crewAgencies[agency])
- GameManager.Instance.Game.SessionManager.KerbalRosterManager.CreateKerbalByName(kerb.Split(' ')[0]);
- }));
- }
- [HarmonyPatch(typeof(UIWidget_viewport_ivaportrait), nameof(UIWidget_viewport_ivaportrait.SetEmpty))]
- [HarmonyPostfix]
- public static void AddPALPortraitName(UIWidget_viewport_ivaportrait __instance) {
- ButtonExtended btn = (ButtonExtended)typeof(UIWidget_viewport_ivaportrait).GetField("buttonEVA", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance);
- if (!btn?.interactable ?? false) __instance.SetKerbalName(LocalizationManager.GetTranslation("Diagnostic/PAL5000"));
- }
- [HarmonyPatch(typeof(IndicatorHeatWarning), "Awake")]
- [HarmonyPostfix]
- public static void HideHeatIndicator(IndicatorHeatWarning __instance) {
- typeof(IndicatorHeatWarning).GetField("_startThreshold", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(__instance, 0.999f);
- typeof(IndicatorHeatWarning).GetField("_criticalThreshold", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(__instance, 0.9999f);
- }
- [HarmonyPatch(typeof(IndicatorHeatWarning), nameof(IndicatorHeatWarning.OnUpdate))]
- [HarmonyPostfix]
- public static void TogglePALMini(IndicatorHeatWarning __instance) {
- if (!RePlugin.PALMiniUpdate) return;
- PartHeatIndicatorTracker partTracker = (PartHeatIndicatorTracker)typeof(IndicatorHeatWarning).GetField("_partTracker", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance);
- bool isKerbal = partTracker.PartBehavior.SimObjectComponent.PartData.partName == "eva_kerbal";
- typeof(IndicatorHeatWarning).GetField("_startThreshold", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(__instance, RePlugin.PALMiniActive && !isKerbal ? 0.0f : 0.999f);
- //if (!RePlugin.PALMiniActive) return;
- //__instance.StartCoroutine(CallbackUtil.DelayedCallback(1, delegate {
- // PartHeatIndicatorTracker partTracker = (PartHeatIndicatorTracker)typeof(IndicatorHeatWarning).GetField("_partTracker", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance);
- // FieldInfo progress = typeof(IndicatorHeatWarning).GetField("_progress", BindingFlags.Instance | BindingFlags.NonPublic);
- // Image image = (Image)progress?.GetValue(__instance);
- // if (partTracker != null && image != null) {
- // float dmgPct = (float)ReUtil.TryGetDamage(partTracker.PartBehavior.SimObjectComponent) / 100f;
- // image.rectTransform.sizeDelta = new Vector2(image.rectTransform.sizeDelta.x, dmgPct > 0 ? __instance.GetComponent<RectTransform>().sizeDelta.y * dmgPct : 0);
- // progress.SetValue(__instance, image);
- // }
- //}));
- }
- [HarmonyPatch(typeof(PartHeatIndicatorTracker), "CalculateTemperatureRatio")]
- [HarmonyPostfix]
- public static void SetPalMiniDamage(PartHeatIndicatorTracker __instance) {
- if (!RePlugin.PALMiniActive) return;
- typeof(PartHeatIndicatorTracker).GetProperty("PartTemperatureRatio")?.SetMethod.Invoke(__instance,
- new object[] { (float)Math.Max(ReUtil.TryGetDamage(__instance.PartBehavior.SimObjectComponent) / 100, double.Epsilon) });
- }
- [HarmonyPatch(typeof(VesselComponent), nameof(VesselComponent.SetModelPhysicsMode))]
- [HarmonyPrefix]
- public static void PersistRotationCheck(VesselComponent __instance, ref PhysicsMode physics) {
- if (physics == __instance.Physics) return;
- if (GameManager.Instance.Game.ViewController?.GetActiveVehicle()?.GetSimVessel().Guid != __instance.Guid) return;
- if (GameManager.Instance.Game.UniverseModel.TimeScale <= 1 || physics != PhysicsMode.Orbital) return;
- if (__instance.AngularVelocity.relativeAngularVelocity.magnitude < 0.015 &&
- (__instance.SimulationObject?.PartOwner?.Parts?.Any(p => p.PartData.family == "0530-Stabilizer") ?? true))
- return;
- physics = PhysicsMode.RigidBody;
- }
- }
- }
- // ---
- using I2.Loc;
- using KSP.Game;
- using KSP;
- using KSP.Modules;
- using KSP.Sim;
- using KSP.Sim.Definitions;
- using KSP.Sim.impl;
- using KSP.Sim.ResourceSystem;
- using Newtonsoft.Json;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using UnityEngine;
- using System.Data;
- namespace KSRe {
- [Serializable]
- public class Data_Damage : ModuleData {
- [KSPState]
- public double damage;
- [KSPState]
- public Dictionary<string, double> records;
- public override Type ModuleType => typeof(Module_Damage);
- }
- [DisallowMultipleComponent]
- public class Module_Damage : PartBehaviourModule {
- [SerializeField]
- protected Data_Damage dataDamage;
- protected Module_RCS moduleRCS;
- protected Data_Parachute dataChute;
- protected Data_CompoundPart dataCompound;
- // protected Data_ControlSurface dataCtrlSrf;
- private double initRepairDmg;
- private double lastSlowUpdateUT;
- private float updateDeltaT;
- internal double lastSlowUpdateDmg;
- private List<double> fixedGees;
- public override Type PartComponentModuleType => typeof(PartComponentModule_Damage);
- public virtual Data_Damage DataDmg => dataDamage;
- public virtual PartComponentModule_Damage CompModuleDmg => ComponentModule as PartComponentModule_Damage;
- protected override void AddDataModules() => DataModules.TryAddUnique(dataDamage, out dataDamage);
- protected override void OnInitialize() {
- fixedGees = new List<double>() { 0, 0 };
- if (PartBackingMode != PartBackingModes.Flight) return;
- lastSlowUpdateUT = Game.UniverseModel.UniverseTime;
- updateDeltaT = (float)CompModuleDmg?.Modifier;
- }
- protected override void OnStart() {
- fixedGees = new List<double>() { 0, 0 };
- TryGetComponent(out moduleRCS);
- if (TryGetComponent(out Module_Parachute moduleChute))
- moduleChute.DataModules.TryGetByType(out dataChute);
- //if (TryGetComponent(out Module_FuelLine moduleFuelLine))
- // moduleFuelLine.DataModules.TryGetByType(out dataCompound);
- // moduleRCS.DataModules.TryGetByType(out dataRCS);
- }
- protected override void OnModuleUpdate(float deltaTime) {
- updateDeltaT += deltaTime;
- if (updateDeltaT > 1) {
- OnModuleSlowUpdate(Game.UniverseModel.UniverseTime - lastSlowUpdateUT);
- lastSlowUpdateUT = Game.UniverseModel.UniverseTime;
- updateDeltaT = 0;
- }
- }
- protected override void OnModuleFixedUpdate(float fixedDeltaTime) {
- if (part?.IsSimObjectDestroyed() ?? true) return;
- double heatDmgThreshold = part.SimObjectComponent.PartData.maxTemp * 0.6;
- if (part.SimObjectComponent.ThermalData.Temperature > heatDmgThreshold) {
- bool ablate = false;
- if (part.SimObjectComponent.PartData.family == "0450-Heat Shield")
- if (part.SimObjectComponent.PartData.partName == "heatshield_2v_inflatable") ablate = true;
- else if (part.SimObjectComponent.PartOwner.ContainerGroup.GetStoredResourcesTotalMass() > 0) ablate = true;
- // double tempDiff = part.SimObjectComponent.ThermalData.Temperature - part.SimObjectComponent.PartData.maxTemp * 0.6;
- // CompModuleDmg.AddDamage(fixedDeltaTime * tempDiff * 0.015);
- double dmg = fixedDeltaTime * (Math.Pow(1.047, ((part.SimObjectComponent.ThermalData.Temperature - heatDmgThreshold) / (part.SimObjectComponent.PartData.maxTemp - heatDmgThreshold)) * 75) - 1);
- if (ablate) CompModuleDmg.AddRecords(dmg, "Flight_Heat");
- else CompModuleDmg.AddDamage(dmg, "Flight_Heat");
- }
- if (this is Module_DamageEngine) return;
- if (moduleRCS?.isOperational ?? false)
- CompModuleDmg.AddDamage(fixedDeltaTime * 0.1, "Propulsion_RCS");
- if (part.SimObjectComponent.PartData.family == "0430-Landing Gear" || part.SimObjectComponent.PartData.family == "0440-Wheel")
- if (vessel.SimObjectComponent.SurfaceVelocity.magnitude > 0.1 && part.vessel.SimObjectComponent.VesselScienceRegionSituation.ResearchLocation?.ScienceSituation == KSP.Game.Science.ScienceSitutation.Landed) {
- double dmg = fixedDeltaTime * (Math.Pow(1.047, (vessel.SimObjectComponent.SurfaceVelocity.magnitude / (part.SimObjectComponent.PartData.crashTolerance * 2)) * 25) - 1);
- CompModuleDmg.AddDamage(dmg, part.SimObjectComponent.PartData.family == "0440-Wheel" ? "Electrical_Wheel" : "Aeronautics_LandingGear");
- }
- if (dataChute != null) {
- Data_Parachute.DeploymentStates state = dataChute.deployState.GetValue();
- if (state == Data_Parachute.DeploymentStates.SEMIDEPLOYED || state == Data_Parachute.DeploymentStates.DEPLOYED)
- CompModuleDmg.AddDamage(fixedDeltaTime * (state == Data_Parachute.DeploymentStates.DEPLOYED ? 0.4 : 0.2), "Aeronautics_Parachute");
- }
- //RePlugin.Logger.LogInfo(vessel.SimObjectComponent.geeForce + "" + part.SimObjectComponent.PartData.partName + " " + part.SimObjectComponent.Guid);
- //fixedGees.Add(Math.Round(vessel.SimObjectComponent.geeForce, vessel.SimObjectComponent.geeForce < 100 ? 2 : 1));
- //if (fixedGees[1] > part.SimObjectComponent.PartData.crashTolerance)
- // if (fixedGees.Count == fixedGees.Distinct().Count())
- // CompModuleDmg.AddDamage(fixedDeltaTime * (Math.Pow(1.047, (fixedGees[1] / (part.SimObjectComponent.PartData.crashTolerance * 2)) * 50) - 1), "Flight_GeeForces");
- // CompModuleDmg.AddDamage(fixedDeltaTime * Math.Min(vessel.SimObjectComponent.geeForce - part.SimObjectComponent.PartData.crashTolerance, 400.0) * 0.5);
- //fixedGees.RemoveAt(0);
- if (vessel.SimObjectComponent.geeForce < part.SimObjectComponent.PartData.crashTolerance) return;
- if (vessel.SimObjectComponent.Physics == PhysicsMode.RigidBody && vessel.flightCtrlState.mainThrottle == 0) return;
- CompModuleDmg.AddDamage(fixedDeltaTime * (Math.Pow(1.047, ((part.SimObjectComponent.PartData.crashTolerance - vessel.SimObjectComponent.geeForce) / (part.SimObjectComponent.PartData.crashTolerance * 2)) * 50) - 1), "Flight_GeeForces");
- // if (dataCtrlSrf?.IsCtrlSurfaceActive ?? false)
- // CompModuleDmg.AddDamage(fixedDeltaTime * 0.075, "Aeronautics_ControlSurface");
- }
- protected virtual void OnModuleSlowUpdate(double fixedDeltaT) {
- if (lastSlowUpdateDmg != 0 && lastSlowUpdateDmg < CompModuleDmg.FailPoint && CompModuleDmg.GetDamage() > CompModuleDmg.FailPoint)
- CompModuleDmg.ApplyFault();
- if (ReUtil.IsPALActive(vessel.SimObjectComponent)) {
- if (ReUtil.IsPALActive(level: 7, bypassVessel: true) && CompModuleDmg.GetDamage(false) > 85 && lastSlowUpdateDmg <= 85)
- CompModuleDmg.PushNotify("/Heavy");
- else if (ReUtil.IsPALActive(level: 8, bypassVessel: true) && CompModuleDmg.GetDamage(false) > 35 && lastSlowUpdateDmg <= 35)
- CompModuleDmg.PushNotify("/Medium");
- }
- lastSlowUpdateDmg = CompModuleDmg.GetDamage(false);
- if (RePlugin.UIPart?.Guid == part.SimObjectComponent.Guid) {
- if (RePlugin.inspectTicks == -1)
- RePlugin.inspectTicks = 7; // (int)Math.Round(part.SimObjectComponent.PartData.PartSizeDiameter * 1.5)
- RePlugin.UIPartDmg = CompModuleDmg.GetDamage();
- }
- if (RePlugin.repairers.Count == 0) return;
- if (!RePlugin.repairers.Any(r => r.TargetGuid == part.SimObjectComponent.Guid)) return;
- double repairMax = 15.01 + 5 * (vessel.SimObjectComponent.TimeSinceLaunch / 7884000d);
- if (initRepairDmg == 0) {
- if (CompModuleDmg.GetDamage() < repairMax) {
- RePlugin.repairers.RemoveAll(r => r.TargetGuid == part.SimObjectComponent.Guid);
- return;
- }
- initRepairDmg = CompModuleDmg.GetDamage();
- }
- CompModuleDmg.AddDamage(-0.02 * fixedDeltaT * RePlugin.repairers.Count(r => r.TargetGuid == part.SimObjectComponent.Guid));
- if (CompModuleDmg.GetDamage() < repairMax) {
- CompModuleDmg.SetDamage(repairMax);
- CompModuleDmg.isLeaking = false;
- //if (RePlugin.repairers.Any(r => r.Guid == RePlugin.activeVessel.Guid))
- // RePlugin.lockUI = false;
- RePlugin.repairers.RemoveAll(r => r.TargetGuid == part.SimObjectComponent.Guid);
- CompModuleDmg.PushNotify("/Repaired");
- if (ReUtil.IsGameSandbox()) return;
- float diffScale;
- if (!Game.SessionManager.TryGetDifficultyOptionState("ScienceRewards", out diffScale)) diffScale = 1f;
- int sciGain = Math.Max(1, (int)Math.Round(initRepairDmg * 0.025 * (ReUtil.GetSciBonus("Engineering") + 1) * diffScale));
- ReUtil.AddScience(sciGain);
- RePlugin.AddRocketScience("Engineering_Repairs", sciGain);
- initRepairDmg = 0;
- } else {
- if (vessel.SimObjectComponent.SimulationObject.Telemetry.CommNetConnectionStatus != ConnectionNodeStatus.Connected)
- RePlugin.repairers.RemoveAll(r => r.Guid == vessel.SimObjectComponent.Guid);
- foreach (VesselComponent vessel in Game?.ViewController?.VesselsInRange.Where(v => RePlugin.repairers.Any(r => r.Guid == v.Guid)))
- if (Position.Distance(vessel.transform.Position, part.SimObjectComponent.transform.Position) > part.SimObjectComponent.PartData.PartSizeDiameter + 1.5)
- RePlugin.repairers.RemoveAll(r => r.Guid == vessel.Guid);
- }
- }
- }
- public class PartComponentModule_Damage : PartComponentModule {
- private Data_Damage dataDamage;
- private double lastDailyUpdateUT;
- // private double lastSlowUpdateUT;
- internal double Modifier { get; private set; }
- internal double FailPoint { get; private set; }
- internal bool isLeaking;
- public override Type PartBehaviourModuleType => typeof(Module_Damage);
- public virtual Data_Damage DataDmg => dataDamage;
- public override void OnStart(double universalTime) {
- DataModules.TryGetByType(out dataDamage);
- UnityEngine.Random.InitState(Part.Guid.GetHashCode());
- Modifier = UnityEngine.Random.value;
- lastDailyUpdateUT = universalTime - 21600 * Modifier;
- // lastSlowUpdateUT = universalTime - Modifier * 2;
- FailPoint = ReUtil.mfParts.Values.Any(p => p.Contains(Part.PartData.partName)) && !ReUtil.IsGameSandbox() ?
- (RePlugin.TryGetPartRecord(Part.PartData.partName, true) - 0.2 + Modifier) * 100 : Modifier * 125;
- if (DataDmg.records == null)
- DataDmg.records = new Dictionary<string, double> { ["Engineering_Age"] = 0 };
- CheckFailPoint();
- }
- public override void OnUpdate(double universalTime, double deltaUniversalTime) {
- if (Part?.IsDestroyedOrBeingDestroyed ?? true) return;
- if (GetDamage() > 100) {
- // if (RePlugin.destroyableParts?.Value ?? false) {
- if ((Part.ParentPart?.TryGetModule(out PartComponentModule_DamageEngine moduleDmgEng) ?? false) && moduleDmgEng != null)
- moduleDmgEng.AddDamage(Part.ExplosionPotential * UnityEngine.Random.Range(15, 35), "Flight_Collateral");
- else if ((Part.ParentPart?.TryGetModule(out PartComponentModule_Damage moduleDmg) ?? false) && moduleDmg != null)
- moduleDmg.AddDamage(Part.ExplosionPotential * UnityEngine.Random.Range(15, 35), "Flight_Collateral");
- Part.DestroyPart(ExplosionType.Default);
- // } else SetDamage(85.01);
- return;
- } else if (GetDamage() < 85 && universalTime > (lastDailyUpdateUT + 21600)) {
- OnDailyUpdate(universalTime - lastDailyUpdateUT);
- lastDailyUpdateUT = universalTime;
- }
- //if (universalTime > (lastDailyUpdateUT + 2)) {
- // OnSlowUpdate(universalTime - lastSlowUpdateUT);
- // lastSlowUpdateUT = universalTime;
- //}
- // if (!Part.SimulationObject.Telemetry.IsInAtmosphere) return;
- }
- protected virtual void OnSlowUpdate(double fixedDeltaT) {
- }
- protected virtual void OnDailyUpdate(double deltaT) {
- AddDamage(deltaT / 1080000d, "Engineering_Age");
- CheckFailPoint();
- bool isBoiling = "0040-Methalox|0050-Methane|0060-Monopropellant|0065-Nose Cone".Contains(Part.PartData.family);
- if (isBoiling) isBoiling = Part.PartResourceContainer.GetResourceStoredMass(RePlugin.fuelList.Last()) > 0;
- if (isLeaking || isBoiling)
- DrainResource(deltaT / 21600);
- }
- internal void AddDamage(double damage, string dmgType = null) {
- DataDmg.damage += damage;
- if (dmgType != null) AddRecords(Math.Abs(damage), dmgType);
- }
- internal void SetDamage(double damage) => DataDmg.damage = damage;
- internal double GetDamage(bool mod = true) => DataDmg.damage * (mod ? 0.75 + Modifier * 0.5 : 1);
- internal void AddRecords(double amount, string type) {
- if (DataDmg.records.ContainsKey(type))
- DataDmg.records[type] += amount;
- else DataDmg.records[type] = amount;
- }
- private void CheckFailPoint() {
- if (RePlugin.repairers.Any(r => r.TargetGuid == Part.Guid)) return;
- // double failPoint = Modifier * 125;
- if (ReUtil.IsPALActive(Part.SimulationObject.Vessel, 9) && Math.Abs(FailPoint - GetDamage() - 1) < 0.07) {
- SetDamage(FailPoint - 0.9);
- Game.UniverseModel.SetTimePaused(true);
- PushNotify("/FaultDetected");
- } else if (Math.Abs(FailPoint - GetDamage()) < 0.07 || (GetDamage() < 1 && FailPoint < 1)) {
- ApplyFault();
- if (GetDamage() > 100) return;
- if (RePlugin.fuelList.All(r => !Part.PartResourceContainer.IsResourceContained(r))) return;
- isLeaking = true;
- }
- }
- internal void ApplyFault() {
- UnityEngine.Random.InitState(Part.Guid.GetHashCode() + Game.SessionGuidString.GetHashCode());
- AddDamage(15 + UnityEngine.Random.value * 100 * (1 - RePlugin.TryGetPartRecord(Part.PartData.partName, true) * 0.5), "Engineering_Faults");
- }
- private void DrainResource(double deltaT) {
- if (Part.PartResourceContainer.GetStoredResourcesTotalMass() < 0.01) return;
- ResourceDefinitionID resID = RePlugin.fuelList.FirstOrDefault(r => Part.PartResourceContainer.GetResourceStoredUnits(r) > 0);
- double resUnits = Part.PartOwner.ContainerGroup.GetResourceStoredUnits(resID);
- double unitsToRemove = resUnits * (isLeaking ? 0.0005 * GetDamage() : Math.Max(0, Part.ThermalData.Temperature - 50) / 30000) * deltaT;
- Part.PartOwner.ContainerGroup.RemoveResourceUnits(resID, unitsToRemove);
- if (!isLeaking) AddRecords((unitsToRemove / resUnits) * 100, "Flight_Boiloff");
- }
- internal void PushNotify(string locKey) {
- NotificationData notify = new NotificationData { Tier = NotificationTier.Alert, TimeStamp = Game.UniverseModel.UniverseTime,
- Importance = "/Heavy|Engine/IgnitionFailed".Contains(locKey) ? NotificationImportance.High :
- "/Medium|/FaultDetected".Contains(locKey) ? NotificationImportance.Medium : NotificationImportance.Low
- };
- notify.AlertTitle.LocKey = "PartModules/Damage" + locKey;
- if (locKey == "/FaultDetected") notify.AlertTitle.ObjectParams = new object[1] { Part?.PartOwner?.SimulationObject?.Vessel?.DisplayName };
- bool showName = "/Repaired|Engine/IgnitionFailed".Contains(locKey);
- notify.FirstLine.LocKey = showName ? $"Parts/Title/{Part?.DisplayName}" : "PartModules/Damage/Serial";
- if (!showName) notify.FirstLine.ObjectParams = new object[1] { Part?.Guid.Substring(24) };
- Game.Notifications.ProcessNotification(notify);
- }
- }
- [Serializable]
- public class Data_DamageEngine : Data_Damage {
- //[LocalizedField("PartModules/DamageEngine/UnlockThrottle")]
- //[PAMDisplayControl(SortIndex = 4)]
- //[KSPState(CopyToSymmetrySet = true)]
- //[HideInInspector]
- //public ModuleProperty<bool> toggleUnlockThrot = new ModuleProperty<bool>(false);
- public override Type ModuleType => typeof(Module_DamageEngine);
- }
- [DisallowMultipleComponent]
- public class Module_DamageEngine : Module_Damage {
- [SerializeField]
- protected Data_DamageEngine dataDamageEngine;
- protected Module_Engine moduleEngine;
- protected Data_Engine dataEngine;
- protected ModuleProperty<bool> toggleOverThrot, toggleUnlockThrot;
- protected float maxThrust;
- protected float minThrust;
- private bool isIgnited;
- private bool reduceDmg;
- private int fuelStarvedTicks;
- private string engTypeKey;
- public override Type PartComponentModuleType => typeof(PartComponentModule_DamageEngine);
- public override Data_Damage DataDmg => dataDamageEngine;
- public virtual Data_DamageEngine DataDmgEng => dataDamageEngine;
- public override PartComponentModule_Damage CompModuleDmg => ComponentModule as PartComponentModule_Damage;
- protected override void AddDataModules() => DataModules.TryAddUnique(dataDamageEngine, out dataDamageEngine);
- protected override void OnInitialize() {
- base.OnInitialize();
- toggleUnlockThrot = new ModuleProperty<bool>(false);
- string unlockThrotLabel = "PartModules/DamageEngine/UnlockThrottle";
- toggleUnlockThrot.ContextKey = unlockThrotLabel;
- DataDmgEng.AddProperty(unlockThrotLabel, toggleUnlockThrot);
- DataDmgEng.SetSortIndex(toggleUnlockThrot, 4);
- toggleUnlockThrot.OnChangedValue += OnToggleUnlockThrot;
- // DataDmgEng.toggleUnlockThrot.OnChangedValue += OnToggleUnlockThrot;
- toggleOverThrot = new ModuleProperty<bool>(false);
- string overThrotLabel = "PartModules/DamageEngine/Overthrottle";
- toggleOverThrot.ContextKey = overThrotLabel;
- DataDmgEng.AddProperty(overThrotLabel, toggleOverThrot);
- DataDmgEng.SetSortIndex(toggleOverThrot, 4);
- toggleOverThrot.OnChangedValue += OnToggleOverThrot;
- ResetEngSetup();
- }
- protected override void OnStart() {
- base.OnStart();
- TryGetComponent(out moduleEngine);
- moduleEngine.DataModules.TryGetByType(out dataEngine);
- if (PartBackingMode == PartBackingModes.Flight)
- engTypeKey = $"{(part?.SimObjectComponent?.PartData?.family == "0120-Jet Engine" ? "Aeronautics" : "Propulsion")}_{part?.SimObjectComponent?.PartData?.family?.Substring(5).Replace(" ", "")}";
- ResetEngSetup();
- }
- protected override void OnShutdown() {
- if (toggleUnlockThrot != null)
- toggleUnlockThrot.OnChangedValue -= OnToggleUnlockThrot;
- //if (DataDmgEng?.toggleUnlockThrot != null)
- // DataDmgEng.toggleUnlockThrot.OnChangedValue -= OnToggleUnlockThrot;
- if (toggleOverThrot != null)
- toggleOverThrot.OnChangedValue -= OnToggleOverThrot;
- }
- protected override void OnModuleFixedUpdate(float fixedDeltaTime) {
- // RePlugin.Logger.LogInfo(dataEngine.FinalThrustValue);
- if (dataEngine?.CurrentPropellantState?.pendingRequest ?? false) {
- fuelStarvedTicks = 0;
- if (!isIgnited) OnIgnition();
- if (toggleOverThrot.GetValue())
- CompModuleDmg.AddDamage(fixedDeltaTime * 3, engTypeKey);
- if (toggleUnlockThrot.GetValue() && !reduceDmg)
- if (moduleEngine.throttleSetting < MinSafeThrotPct)
- CompModuleDmg.AddDamage(fixedDeltaTime * 20 * (MinSafeThrotPct - moduleEngine.throttleSetting), engTypeKey);
- CompModuleDmg.AddDamage(fixedDeltaTime * (CompModuleDmg.GetDamage() > 85 ? 0.7 : 0.1) * (reduceDmg ? 0.25 : 1), engTypeKey);
- } else if (fuelStarvedTicks < 7)
- fuelStarvedTicks++;
- else isIgnited = false;
- base.OnModuleFixedUpdate(fixedDeltaTime);
- }
- public float MinSafeThrotPct => minThrust / maxThrust;
- protected override void OnModuleSlowUpdate(double deltaT) {
- if (lastSlowUpdateDmg != 0 && lastSlowUpdateDmg < CompModuleDmg.FailPoint && CompModuleDmg.GetDamage() > CompModuleDmg.FailPoint)
- CompModuleDmg.ApplyFault();
- base.OnModuleSlowUpdate(deltaT);
- if (dataEngine?.engineModes.Count() > 1)
- ResetEngSetup();
- if (RePlugin.UIPart?.Guid == part.SimObjectComponent.Guid)
- RePlugin.UIEngInstability = toggleOverThrot.GetValue() ? 0.15 : toggleUnlockThrot.GetValue() ? Mathf.Clamp01(MinSafeThrotPct - moduleEngine.throttleSetting) : 0.0;
- }
- private void OnIgnition() {
- isIgnited = true;
- bool isSRB = moduleEngine.currentEngineModeData.engineType == EngineType.SolidBooster;
- if (reduceDmg && !isSRB) return;
- double gForce = vessel.SimObjectComponent.geeForce;
- int rand = UnityEngine.Random.Range(0, moduleEngine?.currentEngineModeData?.propellant?.mixtureName == "Hydrolox" ? 38 : 37);
- if (!isSRB && rand > Math.Min(gForce * 1000, 35) - CompModuleDmg.GetDamage() * 0.3) {
- moduleEngine.DeactivateEngine();
- CompModuleDmg.PushNotify("Engine/IgnitionFailed");
- }
- CompModuleDmg.AddDamage(isSRB ? 20 + rand * 0.5 : Math.Max(10.01, rand * 15 * (0.1 - Math.Min(gForce, 0.035))), engTypeKey);
- if (gForce < 0.035) CompModuleDmg.AddRecords((0.035 - gForce) * 100, "Flight_Ullage");
- }
- protected void OnToggleOverThrot(bool isToggleOn) {
- if (isToggleOn) {
- if (toggleUnlockThrot.GetValue()) {
- OnToggleUnlockThrot(false);
- toggleUnlockThrot.SetValue(false);
- } else TryStoreThrust();
- moduleEngine.currentEngineModeData.maxThrust *= 1.1f;
- moduleEngine.currentEngineModeData.minThrust = moduleEngine.currentEngineModeData.maxThrust;
- } else RestoreDefaultThrust();
- dataEngine.SetConsumptionRate();
- }
- protected void OnToggleUnlockThrot(bool isToggleOn) {
- if (isToggleOn) {
- if (toggleOverThrot?.GetValue() ?? false) {
- OnToggleOverThrot(false);
- toggleOverThrot?.SetValue(false);
- } else TryStoreThrust();
- moduleEngine.currentEngineModeData.minThrust = 0;
- } else RestoreDefaultThrust();
- dataEngine.SetConsumptionRate();
- }
- protected void ResetEngSetup() {
- reduceDmg = !"Methalox|Hydrolox|Hydrogen|SolidFuel".Contains(moduleEngine?.currentEngineModeData?.propellant?.mixtureName ?? "-");
- DataDmgEng?.SetVisible(toggleUnlockThrot, !"MonoPropellant|SolidFuel|MethaneAir|HydrogenAir".Contains(moduleEngine?.currentEngineModeData?.propellant?.mixtureName ?? "-"));
- DataDmgEng?.SetVisible(toggleOverThrot, moduleEngine?.currentEngineModeData?.propellant?.mixtureName == "Methalox");
- }
- private void TryStoreThrust() {
- maxThrust = moduleEngine.currentEngineModeData.maxThrust;
- if (moduleEngine.currentEngineModeData.minThrust > 0)
- minThrust = moduleEngine.currentEngineModeData.minThrust;
- }
- private void RestoreDefaultThrust() {
- moduleEngine.currentEngineModeData.maxThrust = maxThrust;
- moduleEngine.currentEngineModeData.minThrust = minThrust;
- }
- }
- public class PartComponentModule_DamageEngine : PartComponentModule_Damage {
- private Data_DamageEngine dataDamageEngine;
- public override Type PartBehaviourModuleType => typeof(Module_DamageEngine);
- public override Data_Damage DataDmg => dataDamageEngine;
- public override void OnStart(double universalTime) {
- DataModules.TryGetByType(out dataDamageEngine);
- base.OnStart(universalTime);
- }
- }
- [Serializable]
- public class Data_DamageEVA : ModuleData {
- public override Type ModuleType => typeof(Module_DamageEVA);
- }
- [DisallowMultipleComponent]
- public class Module_DamageEVA : PartBehaviourModule {
- [SerializeField]
- protected Data_DamageEVA dataDamageEVA;
- private double lastSlowUpdateUT;
- private float updateDeltaT;
- public override Type PartComponentModuleType => typeof(PartComponentModule_DamageEVA);
- public virtual PartComponentModule_DamageEVA CompModuleDmg => ComponentModule as PartComponentModule_DamageEVA;
- protected override void AddDataModules() => DataModules.TryAddUnique(dataDamageEVA, out dataDamageEVA);
- protected override void OnInitialize() {
- lastSlowUpdateUT = Game.UniverseModel.UniverseTime;
- updateDeltaT = (float)CompModuleDmg?.Modifier;
- }
- protected override void OnStart() {
- }
- protected override void OnModuleUpdate(float deltaTime) {
- updateDeltaT += deltaTime;
- if (updateDeltaT > 1) {
- OnModuleSlowUpdate(Game.UniverseModel.UniverseTime - lastSlowUpdateUT);
- lastSlowUpdateUT = Game.UniverseModel.UniverseTime;
- updateDeltaT = 0;
- }
- }
- protected override void OnModuleFixedUpdate(float fixedDeltaTime) {
- if (part?.IsSimObjectDestroyed() ?? true) return;
- //double heatDmgThreshold = part.SimObjectComponent.PartData.maxTemp * 0.6;
- //if (part.SimObjectComponent.ThermalData.Temperature > heatDmgThreshold) {
- // double dmg = fixedDeltaTime * (Math.Pow(1.047, ((part.SimObjectComponent.ThermalData.Temperature - heatDmgThreshold) / (part.SimObjectComponent.PartData.maxTemp - heatDmgThreshold)) * 75) - 1);
- // CompModuleDmg.AddDamage(dmg, "Wounded_Heat");
- //}
- }
- protected virtual void OnModuleSlowUpdate(double fixedDeltaT) {
- if (RePlugin.UIPart?.Guid == part.SimObjectComponent.Guid) {
- if (RePlugin.inspectTicks == -1)
- RePlugin.inspectTicks = 7;
- // RePlugin.UIPartDmg = RePlugin.saveData.kerbals.FirstOrDefault(k => k.Name == part.SimObjectComponent.PartOwner.SimulationObject.Vessel.DisplayName)?.damage.Values.Sum() ?? 0;
- }
- }
- }
- public class PartComponentModule_DamageEVA : PartComponentModule {
- private Data_DamageEVA dataDamageEVA;
- // private KerbalDamage kerbalDamage;
- internal double Modifier { get; private set; }
- // internal double FailPoint { get; private set; }
- private ResourceDefinitionID ecResID;
- public override Type PartBehaviourModuleType => typeof(Module_DamageEVA);
- public override void OnStart(double universalTime) {
- DataModules.TryGetByType(out dataDamageEVA);
- UnityEngine.Random.InitState(Part.Guid.GetHashCode());
- Modifier = UnityEngine.Random.value;
- // FailPoint = Modifier * 125;
- // kerbalLife = ReUtil.GetKerbalLife(Game.SessionManager.KerbalRosterManager.GetAllKerbalsInSimObject(Part.GlobalId).First().NameKey);
- ecResID = Game.ResourceDefinitionDatabase.GetAllResourceIDs().FirstOrDefault(r => Game.ResourceDefinitionDatabase.GetDefinitionData(r).name == "ElectricCharge");
- }
- public override void OnUpdate(double universalTime, double deltaUniversalTime) {
- if (Part?.IsDestroyedOrBeingDestroyed ?? true) return;
- if (!RePlugin.PALMiniActive) return;
- if (Game.ViewController?.GetActiveVehicle()?.GetSimVessel()?.Guid == null || Part?.PartOwner?.Guid == null) return;
- if (Game.ViewController.GetActiveVehicle().GetSimVessel().Guid != Part.PartOwner.Guid) return;
- if (Part.PartOwner.ContainerGroup.RemoveResourceUnits(ecResID, deltaUniversalTime * 0.2) < deltaUniversalTime * 0.19)
- RePlugin.UpdatePALMini(false);
- }
- protected virtual void OnSlowUpdate(double fixedDeltaT) {
- }
- }
- }
- // ---
- using BepInEx;
- using BepInEx.Configuration;
- using BepInEx.Logging;
- using HarmonyLib;
- using I2.Loc;
- using KSP;
- using KSP.Game;
- using KSP.Game.Science;
- using KSP.Messages;
- using KSP.OAB;
- using KSP.Sim;
- using KSP.Sim.impl;
- using KSP.Sim.ResourceSystem;
- using Newtonsoft.Json;
- using SpaceWarp;
- using SpaceWarp.API.Assets;
- using SpaceWarp.API.Mods;
- using SpaceWarp.API.Game.Messages;
- using SpaceWarp.API.SaveGameManager;
- using SpaceWarp.API.UI;
- using SpaceWarp.API.UI.Appbar;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using System.Threading.Tasks;
- using UnityEngine;
- using TMPro;
- using System.Data;
- using System.IO;
- using KSP.Modules;
- using KSP.UI;
- using SpaceWarp.Modules;
- namespace KSRe {
- [BepInPlugin(ID, ID, VERSION)]
- [BepInDependency(SpaceWarpPlugin.ModGuid, SpaceWarpPlugin.ModVer)]
- public class RePlugin : BaseSpaceWarpPlugin {
- public const string ID = "KSRe";
- public const string VERSION = "0.26.2";
- public static RePlugin Instance { get; private set; }
- internal static new ManualLogSource Logger;
- // public ConfigEntry<bool> techDiscovery;
- public static ConfigEntry<bool> fuelRatiosByVol;
- // public static ConfigEntry<bool> destroyableParts;
- public static ConfigEntry<KeyCode> repairKeyCode;
- public static ConfigEntry<KeyCode> appKeyCode;
- public static List<KerbalDamage> Kerbals { get; private set; }
- public static List<ReAgency> Agencies { get; private set; }
- private ResourceContainerChangedMessage lastResMsg;
- private ushort fuelContIDVal;
- internal static List<ResourceDefinitionID> fuelList;
- internal static ReSaveData saveData;
- private GUIStyle UIStyle, scrollStyle, barStyle, btnStyle, btnXStyle, btnLStyle, btnRStyle, btnKStyle, btnMStyle, btnFStyle;
- private Vector2 UIScrollPos;
- private Color UIBgColor;
- private Texture2D UIAppTex;
- private Rect UIRect;
- private bool inGame, showUI, minUI, diagMode, showApp, lockUI;
- private float slowUpdateDeltaT;
- private double lastSlowUpdateUT;
- private GUIData guiData;
- internal static bool PALMiniActive, PALMiniUpdate;
- internal static int inspectTicks;
- internal static double UIPartDmg, UIEngInstability;
- internal static Tuple<float, float> UIPartImpacts;
- private string prevCelTransNames;
- private VesselComponent activeVessel;
- internal static PartComponent UIPart;
- internal static List<Repairer> repairers;
- public void Awake() {
- Harmony.CreateAndPatchAll(typeof(RePlugin).Assembly);
- Logger = base.Logger;
- // techDiscovery = Config.Bind("Campaign", "Tech Discovery", true, "Whether technologies are discovered gradually in the tree");
- fuelRatiosByVol = Config.Bind("General", "Show Fuel Ratios by Volume", true, "Whether to display engine fuel ratios by volume (instead of mass)");
- // destroyableParts = Config.Bind("General", "Ruined Parts are Destroyable", true, "Whether ruined parts may be destroyed from further damage");
- repairKeyCode = Config.Bind("General", "Repair Key", KeyCode.G, "Key to begin EVA repairs on a damaged part");
- appKeyCode = Config.Bind("General", "Kerbal Life Key", KeyCode.G, "Key to toggle the Kerbal Life App");
- // techDiscovery.SettingChanged += delegate { if (Game?.GlobalGameState.GetGameState().GameState == GameState.ResearchAndDevelopment) UpdateTechDiscovery(); };
- StateChanges.ResearchAndDevelopmentEntered += EnteredRnD;
- UIBgColor = new Color(0, 0, 0, 1);
- UIAppTex = new Texture2D(1, 1, TextureFormat.RGBAFloat, false);
- UIAppTex.SetPixel(0, 0, new Color(1, 1, 1, 0.95f));
- UIAppTex.Apply();
- UIRect = new Rect((Screen.width * 0.71f) - (360 / 2), Screen.height * 0.25f, 0, 0); // - 92
- repairers = new List<Repairer>();
- diagMode = true;
- prevCelTransNames = "-";
- UIPartImpacts = Tuple.Create(0f, 0f);
- string dataPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "data");
- StartCoroutine(CallbackUtil.DelayedCallback(1, delegate {
- ReUtil.dmgSciRates = JsonConvert.DeserializeObject<Dictionary<string, float>>(File.ReadAllText(Path.Combine(dataPath, "dmg_sci_rates.json"))); }));
- StartCoroutine(CallbackUtil.DelayedCallback(2, delegate {
- ReUtil.careerSpecTechs = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(File.ReadAllText(Path.Combine(dataPath, "sci_types_tech_prereqs.json"))); }));
- StartCoroutine(CallbackUtil.DelayedCallback(3, delegate {
- ReUtil.sciLvls = JsonConvert.DeserializeObject<Dictionary<int, float>>(File.ReadAllText(Path.Combine(dataPath, "sci_lvls_buffs.json"))); }));
- StartCoroutine(CallbackUtil.DelayedCallback(4, delegate {
- ReUtil.mfParts = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(File.ReadAllText(Path.Combine(dataPath, "part_mfr_agencies.json"))); }));
- StartCoroutine(CallbackUtil.DelayedCallback(5, delegate {
- ReUtil.partKerbStats = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(File.ReadAllText(Path.Combine(dataPath, "part_kerb_statuses.json"))); }));
- StartCoroutine(CallbackUtil.DelayedCallback(6, delegate {
- ReUtil.crewAgencies = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(File.ReadAllText(Path.Combine(dataPath, "crew_agencies.json")));
- }));
- }
- public override void OnInitialized() {
- Instance = this;
- Game.Messages.PersistentSubscribe<GameStateChangedMessage>(ChangedGameState);
- Game.Messages.PersistentSubscribe<UISliderReleasedMessage>(ReleasedUISlider);
- Game.Messages.PersistentSubscribe<ResourceContainerChangedMessage>(ChangedResCont);
- // game.Messages.PersistentSubscribe<PartPlacedMessage>(PlacedPart);
- Game.Messages.PersistentSubscribe<PartSeparatedMessage>(SeparatedPart);
- Game.Messages.PersistentSubscribe<PartBehaviourInitializedMessage>(PartBehaviourInitialized);
- // Game.Messages.PersistentSubscribe<VABSymmetryModeChangedMessage>(ChangedSymmetryMode);
- Game.Messages.PersistentSubscribe<VesselChangedMessage>(ChangedVessel);
- Game.Messages.PersistentSubscribe<PartUnderMouseChanged>(ChangedMousePart);
- Game.Messages.PersistentSubscribe<VesselCreatedMessage>(CreatedVessel);
- Game.Messages.PersistentSubscribe<SOIEnteredMessage>(EnteredSOI);
- Game.Messages.PersistentSubscribe<ResearchReportScoredMessage>(ScoredResearchReport);
- Game.Messages.PersistentSubscribe<VesselRecoveredMessage>(RecoveredVessel);
- // Game.Messages.PersistentSubscribe<MissionCompleteMessage>(CompletedMission);
- Game.Messages.PersistentSubscribe<SciencePointCapacityUpdateMessage>(UpdatedSciencePoints);
- Game.Messages.PersistentSubscribe<KerbalAddedToRoster>(AddedNewKerbal);
- Game.Messages.PersistentSubscribe<KerbalRemovedFromRoster>(RemovedKerbal);
- Game.Messages.PersistentSubscribe<KerbalLocationChanged>(RelocatedKerbal);
- Appbar.RegisterAppButton(LocalizationManager.GetTranslation("Diagnostic/Title"), "BTN-ReDiagnostic", AssetManager.GetAsset<Texture2D>($"KSRe/images/icon2_w.png"), ToggleGUI);
- //Appbar.RegisterKSCAppButton(LocalizationManager.GetTranslation("Diagnostic/Title"), "BTN-ReDiagnostic", AssetManager.GetAsset<Texture2D>($"KSRe/images/icon2.png"), ToggleGUI);
- //Appbar.RegisterOABAppButton(LocalizationManager.GetTranslation("Diagnostic/Title"), "BTN-ReDiagnostic", AssetManager.GetAsset<Texture2D>($"KSRe/images/icon2_w.png"), ToggleGUI);
- Appbar.RegisterAppButton(LocalizationManager.GetTranslation("KerbalLife/Title"), "BTN-KerbalLife", AssetManager.GetAsset<Texture2D>($"KSRe/images/icon_w.png"), ToggleApp);
- Appbar.RegisterKSCAppButton(LocalizationManager.GetTranslation("KerbalLife/Title"), "BTN-KerbalLife", AssetManager.GetAsset<Texture2D>($"KSRe/images/icon.png"), ToggleApp);
- Appbar.RegisterOABAppButton(LocalizationManager.GetTranslation("KerbalLife/Title"), "BTN-KerbalLife", AssetManager.GetAsset<Texture2D>($"KSRe/images/icon_w.png"), ToggleApp);
- UIStyle = new GUIStyle(Skins.ConsoleSkin.window) { padding = new RectOffset(8, 8, 8, 8), contentOffset = new Vector2(0, -5), fixedWidth = 360 };
- UIStyle.normal.background = UIAppTex;
- // barStyle = new GUIStyle(Skins.ConsoleSkin.box) { padding = new RectOffset(4,4,10,0) };
- scrollStyle = new GUIStyle(Skins.ConsoleSkin.scrollView);
- scrollStyle.normal.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnEmpty.png");
- btnStyle = new GUIStyle(Skins.ConsoleSkin.button);
- btnXStyle = new GUIStyle(Skins.ConsoleSkin.button);
- btnLStyle = new GUIStyle(Skins.ConsoleSkin.button);
- btnRStyle = new GUIStyle(Skins.ConsoleSkin.button);
- btnKStyle = new GUIStyle(Skins.ConsoleSkin.button);
- btnMStyle = new GUIStyle(Skins.ConsoleSkin.button);
- btnFStyle = new GUIStyle(Skins.ConsoleSkin.button);
- btnStyle.normal.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnNorm.png");
- btnStyle.hover.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnHover.png");
- btnStyle.active.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnActive.png");
- btnStyle.onNormal.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnActive.png");
- btnStyle.onActive.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnActive.png");
- btnStyle.onHover.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnHover.png");
- btnXStyle.normal.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnNorm.png");
- btnXStyle.hover.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnXHover.png");
- btnXStyle.active.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnXActive.png");
- btnLStyle.normal.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnLNorm.png");
- btnLStyle.hover.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnLHover.png");
- btnLStyle.active.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnLActive.png");
- btnRStyle.normal.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnRNorm.png");
- btnRStyle.hover.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnRHover.png");
- btnRStyle.active.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/btnRActive.png");
- btnKStyle.normal.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/icon.png");
- btnKStyle.hover.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/icon_h.png");
- btnKStyle.active.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/icon_h.png");
- btnMStyle.normal.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/icon3.png");
- btnMStyle.hover.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/icon3_h.png");
- btnMStyle.active.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/icon3_h.png");
- btnFStyle.normal.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/icon5.png");
- btnFStyle.hover.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/icon5_h.png");
- btnFStyle.active.background = AssetManager.GetAsset<Texture2D>($"KSRe/images/icon5_h.png");
- // ModSaves.RegisterSaveLoadGameData<ReSaveData>(ID, OnSaveData, OnLoadData);
- saveData = ModSaves.RegisterSaveLoadGameData(ID, null, null, saveData);
- ReUtil.agencyFlags = new Dictionary<string, Texture2D>();
- Dictionary<string, string> flags = new Dictionary<string, string>() {
- ["KSC"] = "flag_AGY_Default",
- ["BobsGirders"] = "flag_MFG_Bobs.png",
- ["1Proton"] = "flag_MFG_1Proton.png",
- ["HyperShovel"] = "flag_MFG_Hyper.png",
- ["JoelsLenses"] = "flag_MFG_Joel.png",
- ["Kitbashi"] = "flag_MFG_Kitbashi.png",
- ["MajorComms"] = "flag_MFG_Major.png",
- ["C7"] = "flag_MFG_C7.png",
- ["Ionic"] = "flag_MFG_Ionic.png",
- ["JebsJunkyard"] = "flag_MFG_Jebediah.png",
- ["Kerbodyne"] = "flag_MFG_Kerbodyne_v2.png",
- ["Lightyear"] = "flag_MFG_LightYear.png",
- ["Periapsis"] = "flag_MFG_Periapsis.png",
- ["ReactionSystems"] = "flag_MFG_Reaction.png",
- ["Rockomax"] = "flag_MFG_Rockomax.png",
- ["STEADLER"] = "flag_MFG_STEADLER_v2.png",
- };
- Dictionary<string, string> flagsExt = new Dictionary<string, string>() {
- ["KerbalMotion"] = "flag_KerbalMotion.png",
- };
- foreach (var pair in flags)
- GameManager.Instance.Assets.Load<Texture2D>(pair.Value, t => { ReUtil.agencyFlags[pair.Key] = t; });
- foreach (var pair in flagsExt)
- ReUtil.agencyFlags[pair.Key] = AssetManager.GetAsset<Texture2D>($"KSRe/images/{pair.Value}");
- // GameManager.Instance.Assets.Load<Texture2D>("flag_MFG_Reaction.png", tex => { testAsset = tex; });
- // Kerbals = new KerbalOverseer();
- }
- private void OnGUI() {
- if (!showUI && !showApp) return;
- GUI.skin = Skins.ConsoleSkin;
- if (showUI) GUI.backgroundColor = UIBgColor;
- UIRect = showUI ? GUILayout.Window(GUIUtility.GetControlID(FocusType.Passive), UIRect, GUIContent, guiData.WindowTitle, UIStyle, GUILayout.Height(0)) :
- GUILayout.Window(GUIUtility.GetControlID(FocusType.Passive), UIRect, AppContent, guiData.AppTitle, UIStyle, GUILayout.Height(0));
- }
- public void Update() {
- if (!inGame) return;
- slowUpdateDeltaT += Time.deltaTime;
- if (slowUpdateDeltaT > 1) SlowUpdate();
- GameState? gameState = Game?.GlobalGameState?.GetGameState()?.GameState;
- if (gameState != GameState.FlightView && Input.GetKeyDown(appKeyCode.Value)) ToggleApp();
- if (gameState != GameState.FlightView) return;
- if (showUI && (activeVessel?.IsKerbalEVA ?? false) && diagMode && Input.GetKeyDown(repairKeyCode.Value)) {
- if (UIPart != null && inspectTicks == 0) {
- if (UIPart.PartOwner.SimulationObject.Vessel.IsKerbalEVA) {
- lockUI = !lockUI;
- ReUtil.PushNotify(UIPart.PartOwner.SimulationObject.Vessel.DisplayName, lockUI ? "Hello" : "Bye", NotificationImportance.Low);
- } else if (!repairers.Any(r => r.Guid == activeVessel.Guid) &&
- UIPart.PartOwner.SimulationObject.Vessel.SimulationObject.Telemetry.CommNetConnectionStatus == ConnectionNodeStatus.Connected) {
- // lockUI = true;
- repairers.Add(new Repairer(activeVessel.DisplayName, activeVessel.Guid, UIPart.Guid));
- guiData.UpdateEVARepairers();
- }
- } else if (UIPart == null && ReUtil.IsGameSandbox() || (Game.ScienceManager?.IsNodeUnlocked("tNode_pal5000_13") ?? false)) {
- if (PALMiniActive)
- UpdatePALMini(false);
- else if (activeVessel.SimulationObject.PartOwner.ContainerGroup.GetResourceStoredUnits(
- Game.ResourceDefinitionDatabase.GetAllResourceIDs().FirstOrDefault(r => Game.ResourceDefinitionDatabase.GetDefinitionData(r).name == "ElectricCharge")) > 0)
- UpdatePALMini(true);
- }
- }
- if (!Game?.ResourceManager?.IsVisible ?? false) return;
- foreach (PartComponent part in Game?.ViewController?.GetActiveVehicle()?.GetSimVessel()?.SimulationObject.PartOwner.Parts) {
- if (part == null) continue;
- ResourceContainer resCont = part.PartResourceContainer;
- if (resCont == null) continue;
- if (resCont.GetResourcesContainedCount() == 0 || part.PartResourceContainer.GetStoredResourcesTotalMass() == 0) continue;
- if (!fuelList.All(f => resCont.IsResourceContained(f))) continue;
- if (fuelList.Where(r => resCont.GetResourceStoredMass(r) > 0).Count() > 1)
- resCont.DumpAllResources();
- }
- }
- //public void FixedUpdate() {
- // if (!inGame || Game.UniverseModel?.TimeScale <= 1) return;
- //}
- private void SlowUpdate() {
- slowUpdateDeltaT = 0;
- // if (saveData.modVersion != VERSION) InitOrUpdateSave();
- if (lastSlowUpdateUT == 0)
- lastSlowUpdateUT = Game.UniverseModel.UniverseTime;
- else {
- UpdateKerbalStatus(Game.UniverseModel.UniverseTime - lastSlowUpdateUT);
- lastSlowUpdateUT = Game.UniverseModel.UniverseTime;
- }
- if (showApp && !ReUtil.IsGameSandbox() && ReUtil.IsPlayerAgency(guiData.Agency)) {
- guiData.UpdateDiscovery();
- guiData.UpdateSciLevel();
- }
- if (Game.UniverseModel.UniverseTime > saveData.lastDailyUpdateUT + 21600) {
- DailySlowUpdate(Game.UniverseModel.UniverseTime - saveData.lastDailyUpdateUT);
- saveData.lastDailyUpdateUT = Math.Round(Game.UniverseModel.UniverseTime);
- }
- if (!showUI) return;
- if (activeVessel == null || (UIPart?.IsDestroyedOrBeingDestroyed ?? false))
- UpdateGUIVessel();
- if (!diagMode) guiData.UpdateListMode();
- else if (UIPart != null) {
- if (activeVessel?.IsKerbalEVA ?? false) {
- if (Position.Distance(activeVessel.transform.Position, UIPart.transform.Position) > UIPart.PartData.PartSizeDiameter + 1.5) {
- UIPart = null;
- inspectTicks = -1;
- if (lockUI) {
- lockUI = false;
- // ReUtil.PushNotify(UIPart.PartOwner.SimulationObject.Vessel.DisplayName, "Bye", NotificationImportance.Low);
- }
- } else {
- guiData.UpdateEVADamage();
- if (inspectTicks > 0) inspectTicks--;
- }
- guiData.UpdateEVARepairers();
- } else if (!(activeVessel?.IsKerbalEVA ?? true))
- guiData.UpdateForVessel(ReUtil.IsPALActive(UIPart?.PartOwner?.SimulationObject?.Vessel));
- }
- }
- private void DailySlowUpdate(double deltaT) {
- double oneDayRate = deltaT / 21600;
- foreach (KerbalDamage kerbd in saveData.kerbals) {
- if (kerbd.status.StartsWith("KSC")) {
- // UnityEngine.Random.InitState((kerbd.Name + kerbd.Trait + "Psychology_Therapy").GetHashCode());
- // kerbd.status = "KSC STANDBY";
- double impactDmg = TryGetKerbalDamage(kerbd, "Medicine_Impacts");
- UnityEngine.Random.InitState((kerbd.Name + kerbd.Trait + "Medicine_Impacts").GetHashCode());
- if (impactDmg > UnityEngine.Random.value * 5) {
- AddKerbalDamage(kerbd, "Medicine_Impacts", -oneDayRate * 0.25);
- if (TryGetKerbalDamage(kerbd, "Medicine_Atrophy") < 25)
- AddKerbalDamage(kerbd, "Medicine_Atrophy", oneDayRate * 0.25);
- kerbd.status = "KSC>MED BAY";
- continue;
- } else if (kerbd.status == "KSC>MED BAY") {
- KerbalLifeRewards("Medicine_Impacts", force: true);
- kerbd.status = "KSC>STANDBY";
- ReUtil.PushNotify(kerbd.Name, "Recovery/Impacts", NotificationImportance.Low, false);
- continue;
- }
- double atrophyDmg = TryGetKerbalDamage(kerbd, "Medicine_Atrophy");
- if (atrophyDmg > 0) {
- AddKerbalDamage(kerbd, "Medicine_Atrophy", -oneDayRate * 0.5);
- kerbd.status = "KSC>RECOVERY";
- continue;
- } else if (kerbd.status == "KSC>RECOVERY") {
- KerbalLifeRewards("Medicine_Atrophy", force: true);
- kerbd.status = "KSC>STANDBY";
- ReUtil.PushNotify(kerbd.Name, "Recovery/Atrophy", NotificationImportance.Low, false);
- continue;
- }
- double socialDmg = TryGetKerbalDamage(kerbd, "Psychology_Social");
- if (socialDmg > 25 && Math.Abs(TryGetKerbalDamage(kerbd, "Psychology_Therapy")) < socialDmg) {
- AddKerbalDamage(kerbd, "Psychology_Therapy", -oneDayRate);
- kerbd.status = "KSC>THERAPY";
- continue;
- } else if (kerbd.status == "KSC>THERAPY") {
- KerbalLifeRewards("Psychology_Therapy", force:true);
- kerbd.status = "KSC>STANDBY";
- ReUtil.PushNotify(kerbd.Name, "Recovery/Therapy", NotificationImportance.Low, false);
- continue;
- }
- UnityEngine.Random.InitState((kerbd.Name + kerbd.Trait + "Medicine_Atrophy").GetHashCode());
- if (atrophyDmg > UnityEngine.Random.value * -10) {
- AddKerbalDamage(kerbd, "Medicine_Atrophy", -oneDayRate * 0.5);
- kerbd.status = "KSC>FITNESS";
- continue;
- } else if (kerbd.status == "KSC>FITNESS") {
- kerbd.status = "KSC>STANDBY";
- continue;
- }
- if (kerbd.status == "KSC>STANDBY")
- kerbd.status = "KSC>READY";
- } else {
- Game.SessionManager.KerbalRosterManager.TryGetKerbalByName(kerbd.Name, out KerbalInfo kerbi);
- SimulationObjectModel simObj = Game.ViewController.Universe.FindSimObject(kerbi.Location.SimObjectId);
- double geeForce = simObj?.Part?.PartOwner?.SimulationObject?.Vessel?.geeForce ?? 0;
- if (TryGetKerbalDamage(kerbd, "Medicine_Atrophy") < (1 - Mathf.Clamp01((float)geeForce)) * 50)
- AddKerbalDamage(kerbd, "Medicine_Atrophy", oneDayRate * (0.25 - geeForce));
- }
- }
- }
- private void OnLoadData(ReSaveData data) {
- Logger.LogInfo("Loading...");
- }
- private void OnSaveData(ReSaveData data) {
- Logger.LogInfo("Saving...");
- //data.lastDailyUpdateUT = saveData.lastDailyUpdateUT;
- //data.modVersion = saveData.modVersion;
- //data.agencies = saveData.agencies;
- //data.kerbals = saveData.kerbals;
- }
- private void ChangedGameState(MessageCenterMessage message) {
- GameStateChangedMessage msg = (GameStateChangedMessage)message;
- UnityEngine.Random.InitState(int.Parse($"{DateTime.Now.Minute}{DateTime.Now.Second}{DateTime.Now.Millisecond}"));
- inGame = msg?.CurrentState != GameState.MainMenu;
- if (!((msg?.CurrentState == GameState.FlightView && msg?.PreviousState == GameState.Map3DView) ||
- (msg?.CurrentState == GameState.Map3DView && msg?.PreviousState == GameState.FlightView))) {
- UIPart = null;
- showUI = false;
- } else if (showUI && msg.CurrentState == GameState.Map3DView)
- minUI = true;
- showApp = false;
- repairers.Clear();
- if (guiData == null) guiData = new GUIData();
- if (!inGame) {
- saveData.agencies = null;
- saveData.kerbals = null;
- saveData.modVersion = null;
- saveData.lastDailyUpdateUT = 0;
- guiData.Reset();
- } else if (saveData.modVersion != VERSION) InitOrUpdateSave();
- // if (msg?.CurrentState == GameState.KerbalSpaceCenter || msg?.CurrentState == GameState.MissionControl || msg?.CurrentState == GameState.ResearchAndDevelopment)
- // TryUpdateRocketScienceHeaders();
- if (fuelContIDVal != 0) return;
- if (Game.ResourceDefinitionDatabase.GetAllResourceIDs().Count() == 0) return;
- // stock bug (v0.2.0): game.ResourceDefinitionDatabase.GetResourceIDFromName()
- ResourceDefinitionID recipeID = Game.ResourceDefinitionDatabase.GetAllResourceIDs().FirstOrDefault(r => Game.ResourceDefinitionDatabase.GetDefinitionData(r).name == "FuelContainer");
- if (recipeID.Value == 0) return;
- fuelContIDVal = recipeID.Value;
- fuelList = Game.ResourceDefinitionDatabase.GetDefinitionData(recipeID).recipeProperties.IngredientsResourceIDs.ToList();
- // cryoResIDVal = Game.ResourceDefinitionDatabase.GetAllResourceIDs().FirstOrDefault(r => Game.ResourceDefinitionDatabase.GetDefinitionData(r).name == "Hydrogen").Value;
- }
- private void PartBehaviourInitialized(MessageCenterMessage message) {
- PartBehaviourInitializedMessage msg = (PartBehaviourInitializedMessage)message;
- // Logger.LogInfo("init: " + msg.Part.SimObjectComponent.PartData.partName);
- if (msg.Part.SimObjectComponent.PartData.partName != "booster_1v_solid_flea") return;
- msg.Part.gameObject.transform.localScale = new Vector3(0.5f, 1, 0.5f);
- }
- private void PlacedPart(MessageCenterMessage message) {
- PartPlacedMessage msg = (PartPlacedMessage)message;
- if (msg.messagePart.PartName != "booster_1v_solid_flea") return;
- msg.messagePart.PartTransform.localScale = new Vector3(0.5f, 1, 0.5f);
- }
- private void SeparatedPart(MessageCenterMessage message) {
- PartSeparatedMessage msg = (PartSeparatedMessage)message;
- // Logger.LogInfo("sep: " + msg.messagePart.PartName);
- if (msg?.messagePart?.PartName != "booster_1v_solid_flea") return;
- msg.messagePart.PartTransform.localScale = new Vector3(0.5f, 1, 0.5f);
- }
- private void ChangedSymmetryMode(MessageCenterMessage message) {
- IObjectAssemblyPart part = Game?.OAB?.Current.Stats?.LastPartGrabbed;
- // Logger.LogInfo("sym: " + part?.PartName);
- // if (part?.PartName != "booster_1v_solid_flea") return;
- VABSymmetryModeChangedMessage msg = (VABSymmetryModeChangedMessage)message;
- // Logger.LogInfo("mode: " + (int)Game?.OAB?.Current?.Stats?.SymmetryMode.GetValue());
- if ((int)Game?.OAB?.Current?.Stats?.SymmetryMode.GetValue() < 2) return;
- Logger.LogInfo("symcount: " + part.SymmetrySet.Parts.Count);
- Logger.LogInfo("symfleacount: " + part.SymmetrySet.Parts.Count(p => p.PartName == "booster_1v_solid_flea"));
- // Logger.LogInfo("symparts: " + part.SymmetrySet.Visualizer.SingleCopyMap.Keys.Where(p => p.PartName == "booster_1v_solid_flea").ToList().Count);
- // part.SymmetrySet.Visualizer.SingleCopyMap.Keys.Where(p => p.PartName == "booster_1v_solid_flea").ToList().ForEach(p => p.PartTransform.localScale = new Vector3(0.5f, 1, 0.5f));
- }
- private void EnteredRnD(GameStateEnteredMessage message) {
- string rdScrollBarPath = "GameManager/Default Game Instance(Clone)/UI Manager(Clone)/Main Canvas/RDCenterUI(Clone)/Container/TechTree/ELE-Scrollbar-Horizontal";
- GameObject.Find(rdScrollBarPath)?.SetActive(false);
- string tierContPath = "GameManager/Default Game Instance(Clone)/UI Manager(Clone)/Main Canvas/RDCenterUI(Clone)/Container/TechTree/TierScroll/TierSelectionContainer";
- RectTransform tierContTrans = GameObject.Find(tierContPath)?.GetComponent<RectTransform>();
- if (transform != null) tierContTrans.sizeDelta = new Vector2(0, 28);
- for (int i = 0; i < tierContTrans.childCount; i++) {
- RectTransform t1 = tierContTrans.GetChild(i)?.FindChildRecursive("Text (TMP)")?.GetComponent<RectTransform>();
- RectTransform t2 = tierContTrans.GetChild(i)?.FindChildRecursive("Text On")?.GetComponent<RectTransform>();
- if (t1 == null || t2 == null) continue;
- t1.anchoredPosition = new Vector2(0, 8);
- t2.anchoredPosition = new Vector2(0, 8);
- }
- //for (int i = 0; i < 4; i++)
- // Instantiate(tierContTrans.GetChild(i).gameObject, tierContTrans.GetChild(i).parent);
- StartCoroutine(CallbackUtil.DelayedCallback(1, delegate {
- string treePath = "GameManager/Default Game Instance(Clone)/UI Manager(Clone)/Main Canvas/RDCenterUI(Clone)/Container/TechTree/TreeContainer/TreeContent";
- Transform tree = GameObject.Find(treePath)?.transform;
- if (tree == null) return;
- for (int i = 1; i < tree.childCount; i++) {
- Transform t = tree.GetChild(i);
- if (t == null) continue;
- RectTransform t1 = t.GetComponent<RectTransform>();
- if (t1 != null) t1.sizeDelta = new Vector2(164, 76); // 82
- RectTransform t2 = t.FindChildRecursive("ToggleOn")?.GetComponent<RectTransform>();
- if (t2 != null) t2.sizeDelta = new Vector2(164, 76); // 82
- RectTransform t3 = t.FindChildRecursive("Icon")?.GetComponent<RectTransform>();
- if (t3 != null) { t3.anchoredPosition = new Vector2(15, -7); t3.sizeDelta = new Vector2(20, 20); }
- RectTransform t4 = t.FindChildRecursive("ToggleOnIcon")?.GetComponent<RectTransform>();
- if (t4 != null) { t4.anchoredPosition = new Vector2(65, -17); /* 27, -19 */ t4.sizeDelta = new Vector2(20, 20); }
- RectTransform t5 = t.FindChildRecursive("Text (TMP)")?.GetComponent<RectTransform>();
- if (t5 != null) t5.anchoredPosition = new Vector2(3, -18); // -20
- RectTransform t6 = t.FindChildRecursive("ToggleOnText")?.GetComponent<RectTransform>();
- if (t6 != null) t6.anchoredPosition = new Vector2(3, -18); // -20
- RectTransform t7 = t.FindChildRecursive("CostContainer")?.GetComponent<RectTransform>();
- if (t7 != null) { t7.sizeDelta = new Vector2(75, 16); t7.anchoredPosition = new Vector2(-11, -10); }
- RectTransform t8 = t.FindChildRecursive("Cost")?.GetComponent<RectTransform>(); // textmesh component inside "cost"
- if (t8 != null) { t8.sizeDelta = new Vector2(45, 16); t8.anchoredPosition = new Vector2(45, -8); }
- }
- }));
- StartCoroutine(CallbackUtil.DelayedCallback(2, delegate {
- List<TechNodeData> techNodes = new List<TechNodeData>();
- if (Game?.ScienceManager?.TechNodeDataStore?.TryGetTechNodeDataCollection(out IReadOnlyCollection<TechNodeData> tNodes) ?? false)
- techNodes = tNodes?.ToList();
- string treePath = "GameManager/Default Game Instance(Clone)/UI Manager(Clone)/Main Canvas/RDCenterUI(Clone)/Container/TechTree/TreeContainer/TreeContent";
- Transform tree = GameObject.Find(treePath)?.transform;
- if (tree == null) return;
- int totalSci = ReUtil.GetTotalScience();
- for (int i = 1; i < tree.childCount; i++) {
- GameObject tNodeObj = tree.GetChild(i)?.gameObject;
- if (tNodeObj == null) continue;
- TechNodeData tNode = techNodes.FirstOrDefault(n => n.ID == tNodeObj.name);
- if (tNode == null) continue;
- bool isDiscovered = tNode.RequiredSciencePoints < 10 || totalSci > tNode.RequiredSciencePoints * 2.5;
- if (!isDiscovered && totalSci > tNode.RequiredSciencePoints * 1.5) {
- UnityEngine.Random.InitState((Game.SessionGuidString + tNode.RequiredSciencePoints).GetHashCode());
- isDiscovered = totalSci >= tNode.RequiredSciencePoints * (1.5 + UnityEngine.Random.value);
- }
- tNodeObj.SetActive(isDiscovered);
- }
- for (int i = 0; i < tree.GetChild(0).childCount; i++) {
- Transform t = tree.GetChild(0).GetChild(i);
- if (t == null) continue;
- string[] name = t.name.Split(new string[] { "_to_" }, StringSplitOptions.None);
- bool reqsShown = tree.gameObject.GetChild(name[0]).activeSelf && tree.gameObject.GetChild(name[1]).activeSelf;
- t.gameObject.SetActive(reqsShown/* || !techDiscovery.Value*/);
- }
- }));
- }
- private void ChangedResCont(MessageCenterMessage message) {
- if (Game.GlobalGameState.GetGameState().GameState != GameState.VehicleAssemblyBuilder) return;
- ResourceContainerChangedMessage resMsg = (ResourceContainerChangedMessage)message;
- if (resMsg == null) return;
- lastResMsg = resMsg;
- }
- private void ReleasedUISlider(MessageCenterMessage message) {
- if (Game.GlobalGameState.GetGameState().GameState != GameState.VehicleAssemblyBuilder) return;
- if (lastResMsg == null) return;
- if (!Game.ResourceDefinitionDatabase.GetRecipesForIngredient(lastResMsg.ResourceId, out List<ResourceDefinitionID> recipeList)) return;
- if (!recipeList.Any(r => r.Value == fuelContIDVal)) return;
- fuelList.Where(r => r != lastResMsg.ResourceId).ToList().ForEach(r => lastResMsg.Container.DumpResource(r));
- lastResMsg = null;
- }
- private void ChangedVessel(MessageCenterMessage message) => UpdateGUIVessel();
- private void ChangedMousePart(MessageCenterMessage message) {
- if (!showUI || !(activeVessel?.IsKerbalEVA ?? false) || lockUI) return;
- inspectTicks = -1;
- PartUnderMouseChanged msg = (PartUnderMouseChanged)message;
- if (msg?.newPartUnderMouse == null) { UIPart = null; return; }
- PartComponent part = msg.newPartUnderMouse.SimObjectComponent;
- // if (part.PartName == "eva_kerbal") { UIPart = null; return; }
- UIPart = Position.Distance(activeVessel.transform.Position, part.transform.Position) > part.PartData.PartSizeDiameter + 1 ? null : part;
- if (UIPart != null) guiData.UpdateEVAPart();
- }
- private void CreatedVessel(MessageCenterMessage message) {
- if (ReUtil.IsGameSandbox()) return;
- VesselCreatedMessage msg = (VesselCreatedMessage)message;
- float diffScale;
- if (!Game.SessionManager.TryGetDifficultyOptionState("ScienceRewards", out diffScale)) diffScale = 1f;
- int sciGain = (int)Math.Round(Math.Ceiling(Math.Min((msg?.SerializedVessel?.parts?.Count ?? 0) * 0.015, 3)) * (ReUtil.GetSciBonus("Engineering") + 1) * diffScale);
- if (sciGain < 1) return;
- ReUtil.AddScience(sciGain);
- AddRocketScience("Engineering_Assembly", sciGain);
- }
- private void EnteredSOI(MessageCenterMessage message) {
- if (ReUtil.IsGameSandbox()) return;
- SOIEnteredMessage msg = (SOIEnteredMessage)message;
- if (msg?.bodyExited == null) return;
- float diffScale;
- if (!Game.SessionManager.TryGetDifficultyOptionState("ScienceRewards", out diffScale)) diffScale = 1f;
- int sciGain = (int)Math.Round(Math.Ceiling((msg.vessel?.VesselScienceRegionSituation.SituationScalar ?? 0) *
- (prevCelTransNames.Contains(msg.bodyExited.bodyName) && prevCelTransNames.Contains(msg.bodyEntered.bodyName) ? 0.5 : 2.0)) * (ReUtil.GetSciBonus("Control") + 1) * diffScale);
- if (sciGain < 1) return;
- prevCelTransNames = $"{msg.bodyExited.bodyName}-{msg.bodyEntered.bodyName}";
- ReUtil.AddScience(sciGain);
- AddRocketScience("Control_SOI", sciGain);
- }
- private void ScoredResearchReport(MessageCenterMessage message) {
- ResearchReportScoredMessage msg = (ResearchReportScoredMessage)message;
- CompletedResearchReport report = Game.ScienceManager.GetSubmittedResearchReports().FirstOrDefault(r => r.ResearchReportKey == msg?.ResearchReportKey);
- string key = $"{(report.ResearchReportKey.Contains("CrewObservation") ? "Psychology" : $"Science{report.ResearchReportType.ToString().Replace("Type", "")}")}_{report.ResearchReportKey.Split('_')[0]}";
- if (report.ResearchReportKey.Contains("AtmosphereSurvey"))
- key = $"Aeronautics_{report.ResearchReportType.ToString().Replace("Type", "")}";
- string sciType = key.Split('_')[0];
- int sciBoost = (int)Math.Round(report.FinalScienceValue * ReUtil.GetSciBonus(sciType));
- if (sciBoost > 0) ReUtil.AddScience(sciBoost);
- AddRocketScience(key, (int)Math.Round(report.FinalScienceValue * (ReUtil.GetSciBonus(sciType) + 1)));
- }
- private void CompletedMission(MessageCenterMessage message) {
- MissionCompleteMessage msg = (MissionCompleteMessage)message;
- }
- private void RecoveredVessel(MessageCenterMessage message) {
- if (ReUtil.IsGameSandbox()) return;
- VesselRecoveredMessage msg = (VesselRecoveredMessage)message;
- VesselComponent vessel = Game.UniverseModel.FindVesselComponent(msg.VesselID);
- if (vessel?.SimulationObject?.IsKerbal ?? true) return;
- Dictionary<string, double> recSci = new Dictionary<string, double> { ["Engineering_Age"] = 0 };
- foreach (PartComponent part in vessel.SimulationObject.PartOwner.Parts)
- if (part.TryGetModule(out PartComponentModule_DamageEngine moduleDmgEng) && moduleDmgEng != null) {
- if (moduleDmgEng.DataDmg.records.Any(r => r.Key.StartsWith("Aeronautics") || r.Key.StartsWith("Propulsion")))
- AddPartRecord(part.PartData.partName, moduleDmgEng.DataDmg.records.FirstOrDefault(r => r.Key.StartsWith("Aeronautics") || r.Key.StartsWith("Propulsion")).Value);
- foreach (var pair in moduleDmgEng.DataDmg.records) {
- double val = pair.Value * (ReUtil.dmgSciRates.ContainsKey(pair.Key) ? ReUtil.dmgSciRates[pair.Key] : 0.05);
- if (recSci.ContainsKey(pair.Key))
- recSci[pair.Key] += val;
- else recSci[pair.Key] = val;
- //int sci = (int)Math.Ceiling(pair.Value * (ReUtil.dmgSciRates.ContainsKey(pair.Key) ? ReUtil.dmgSciRates[pair.Key] : 0.05));
- //AddRocketScience(pair.Key, sci);
- //sciGain += sci;
- }
- } else if (part.TryGetModule(out PartComponentModule_Damage moduleDmg) && moduleDmg != null) {
- foreach (string sciType in new string[] { "Propulsion_RCS", "Electrical_Wheel", "Aeronautics_LandingGear", "Aeronautics_Parachute" })
- if (moduleDmg.DataDmg.records.TryGetValue(sciType, out double rec))
- AddPartRecord(part.PartData.partName, rec);
- foreach (var pair in moduleDmg.DataDmg.records) {
- double val = pair.Value * (ReUtil.dmgSciRates.ContainsKey(pair.Key) ? ReUtil.dmgSciRates[pair.Key] : 0.05);
- if (recSci.ContainsKey(pair.Key))
- recSci[pair.Key] += val;
- else recSci[pair.Key] = val;
- }
- }
- int sciGain = 0;
- //if (recSci["Engineering_Age"] == 0)
- // recSci.Remove("Engineering_Age");
- float diffScale;
- if (!Game.SessionManager.TryGetDifficultyOptionState("ScienceRewards", out diffScale)) diffScale = 1f;
- foreach (var pair in recSci) {
- int val = Math.Max(1, (int)Math.Round(pair.Value * (ReUtil.GetSciBonus(pair.Key.Split('_')[0]) + 1) * diffScale));
- AddRocketScience(pair.Key, val);
- sciGain += val;
- }
- if (sciGain == 0) return;
- ReUtil.AddScience(sciGain);
- }
- private void UpdatedSciencePoints(MessageCenterMessage message) =>
- StartCoroutine(CallbackUtil.DelayedCallback(1, delegate {
- // SciencePointCapacityUpdateMessage msg = (SciencePointCapacityUpdateMessage)message;
- ReAgency playerAgency = ReUtil.PlayerReAgency();
- if (playerAgency == null) return;
- int missionSci = Math.Max(0, ReUtil.GetTotalScience() - playerAgency.rocketScience.Where(s => s.Key != "Command_Missions").Select(s => s.Value).Sum()); // - Game.SessionManager.GetMyAgencyAdditionalSciencePoints()
- if (!playerAgency.rocketScience.ContainsKey("Command_Missions"))
- playerAgency.rocketScience["Command_Missions"] = 0;
- if (playerAgency.rocketScience["Command_Missions"] != missionSci) {
- int sciBoost = Math.Max(0, (int)Math.Round((missionSci - playerAgency.rocketScience["Command_Missions"]) * ReUtil.GetSciBonus("Command")));
- if (sciBoost > 0) ReUtil.AddScience(sciBoost);
- playerAgency.rocketScience["Command_Missions"] = missionSci + sciBoost;
- }
- }));
- private void AddedNewKerbal(MessageCenterMessage message) {
- KerbalAddedToRoster msg = (KerbalAddedToRoster)message;
- if (msg == null) return;
- ReUtil.PushNotify(msg.Kerbal.NameKey, "Hello", NotificationImportance.Low);
- SetupKerbalDamage(msg.Kerbal);
- }
- private void RemovedKerbal(MessageCenterMessage message) {
- KerbalRemovedFromRoster msg = (KerbalRemovedFromRoster)message;
- if (msg == null) return;
- ReUtil.PushNotify(msg.Kerbal.NameKey, "Quit", NotificationImportance.High);
- saveData.kerbals.RemoveAll(k => k.Name == msg.Kerbal.NameKey);
- saveData.kerbals.ForEach(k => AddKerbalDamage(k, "Psychology_Social_KerbonautLost", 50));
- // EmptyAgencyCheck();
- }
- private void RelocatedKerbal(MessageCenterMessage message) {
- KerbalLocationChanged msg = (KerbalLocationChanged)message;
- if (msg == null) return;
- SimulationObjectModel simObj = Game.ViewController.Universe.FindSimObject(msg.Kerbal.Location.SimObjectId);
- SimulationObjectModel oldSimObj = Game.ViewController.Universe.FindSimObject(msg.OldLocation.SimObjectId);
- if (simObj == null) return;
- if (oldSimObj != null && msg.OldLocation.SimObjectId != Game.SessionManager.KerbalRosterManager.KSCGuid && msg.Kerbal.Location.SimObjectId != Game.SessionManager.KerbalRosterManager.KSCGuid) {
- ResourceDefinitionID resID = Game.ResourceDefinitionDatabase.GetAllResourceIDs().FirstOrDefault(r =>
- Game.ResourceDefinitionDatabase.GetDefinitionData(r).name == "MonoPropellant");
- if (simObj.Part?.PartName == "eva_kerbal")
- simObj.Part.PartOwner.ContainerGroup.AddResourceUnits(resID,
- oldSimObj.Part.PartOwner.ContainerGroup.RemoveResourceUnits(resID, simObj.Part.PartOwner.ContainerGroup.GetResourceCapacityUnits(resID)));
- else simObj.Part.PartOwner.ContainerGroup.AddResourceUnits(resID, oldSimObj.Part.PartOwner.ContainerGroup.GetResourceStoredUnits(resID));
- }
- KerbalDamage kerbd = saveData.kerbals.FirstOrDefault(k => k.Name == msg.Kerbal.NameKey);
- if (kerbd == null) return;
- if (HasKerbalDamage(kerbd, "Psychology_Role_Wings") || simObj.Part?.PartName != "eva_kerbal") return;
- StartCoroutine(CallbackUtil.DelayedCallback(1, delegate {
- ScienceSitutation? sit = simObj.Part?.PartOwner?.SimulationObject?.Vessel?.VesselScienceRegionSituation.ResearchLocation?.ScienceSituation;
- if (sit != ScienceSitutation.LowOrbit && sit != ScienceSitutation.HighOrbit) return;
- AddKerbalDamage(kerbd, "Psychology_Role_WingsPending", -5, true);
- ReUtil.PushNotify(kerbd.Name, "WingsPending", NotificationImportance.Low);
- }));
- // Game.SessionManager.KerbalRosterManager.GetAllKerbals().ForEach(k => Logger.LogInfo(k.Location.SimObjectId));
- }
- private void ToggleGUI() {
- GameState state = Game.GlobalGameState.GetGameState().GameState;
- if (state == GameState.Map3DView) return;
- else if (state == GameState.KerbalSpaceCenter || state == GameState.VehicleAssemblyBuilder) diagMode = false;
- UpdateGUIVessel();
- showUI = !showUI;
- // GameObject.Find("BTN-ReDiagnostic")?.GetComponent<UIValue_WriteBool_Toggle>()?.SetValue(showUI);
- if (showApp && showUI) {
- showApp = false;
- // GameObject.Find("BTN-ReKerbalLife")?.GetComponent<UIValue_WriteBool_Toggle>()?.SetValue(showApp);
- }
- }
- private void ToggleGUI(bool show) => ToggleGUI();
- private void GUIContent(int windowID) {
- GameState state = Game.GlobalGameState.GetGameState().GameState;
- bool modeBtn = false;
- bool minBtn = false;
- GUILayout.BeginHorizontal();
- if (!minUI)
- modeBtn = GUILayout.Button(guiData.ModeBtn, btnStyle, GUILayout.Width(28));
- GUILayout.FlexibleSpace();
- if (state != GameState.Map3DView)
- minBtn = GUILayout.Button(minUI ? guiData.MaxBtn : guiData.MinBtn, btnStyle, GUILayout.Width(28));
- bool closeBtn = GUILayout.Button(guiData.CloseBtn, btnXStyle, GUILayout.Width(28));
- GUILayout.EndHorizontal();
- if (modeBtn) {
- diagMode = !diagMode;
- if (!diagMode) guiData.UpdateListMode();
- else if (activeVessel.IsKerbalEVA) guiData.UpdateEVAPart();
- else guiData.UpdateVesselPart(ReUtil.IsPALActive(UIPart.PartOwner.SimulationObject.Vessel));
- } else if (minBtn) minUI = !minUI;
- else if (closeBtn) showUI = false;
- if (!showUI || minUI || modeBtn || (activeVessel == null && state != GameState.KerbalSpaceCenter && state != GameState.VehicleAssemblyBuilder)) {
- lockUI = false;
- inspectTicks = -1;
- GUI.DragWindow(new Rect(0, 0, 10000, 500));
- return;
- }
- if ((activeVessel?.IsKerbalEVA ?? false) && diagMode && UIPart == null) {
- GUILayout.Label(guiData.InspectHint);
- if (ReUtil.IsGameSandbox() || (Game.ScienceManager?.IsNodeUnlocked("tNode_pal5000_13") ?? false))
- GUILayout.Label(guiData.PALMiniHint);
- GUI.DragWindow(new Rect(0, 0, 10000, 500)); return;
- }
- GUILayout.BeginHorizontal(); GUILayout.BeginVertical();
- if (diagMode) {
- if (activeVessel?.IsKerbalEVA ?? false) GUIContentEVA();
- else {
- if (ReUtil.IsPALActive(activeVessel)) // UIPart?.PartOwner?.SimulationObject?.Vessel
- GUIContentPAL();
- GUIContentVessel();
- }
- } else GUIContentListMode();
- GUILayout.EndVertical(); GUILayout.EndHorizontal();
- GUI.DragWindow(new Rect(0, 0, 10000, 500));
- }
- private void GUIContentEVA() {
- GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label(guiData.PartTitle); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
- GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label(guiData.Subtitle); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
- bool isIdleEVA = !repairers.Any(r => r.Guid == activeVessel.Guid);
- bool isBeingRepaired = repairers.Count(r => r.TargetGuid == UIPart.Guid) > 0;
- bool isInspected = inspectTicks == 0;
- bool isKerbal = UIPart.PartName == "eva_kerbal";
- if (isBeingRepaired || isInspected)
- GUILayout.Label(guiData.Damage);
- if (isIdleEVA && (isInspected || isBeingRepaired))
- GUILayout.Label(isKerbal || UIPart.PartOwner.SimulationObject.Vessel.SimulationObject.Telemetry.CommNetConnectionStatus == ConnectionNodeStatus.Connected ?
- guiData.RepairHint : guiData.CommNetReq);
- // int sel = 0;
- if (lockUI) {
- KerbalDamage currentKerb = saveData.kerbals.FirstOrDefault(k => k.Name == UIPart.PartOwner.SimulationObject.Vessel.DisplayName);
- //GUILayout.BeginHorizontal(); GUILayout.Space(120); GUILayout.Label("Assess"); GUILayout.Label("Analyze"); GUILayout.Label("Discuss"); GUILayout.EndHorizontal();
- //GUILayout.BeginHorizontal();
- //GUILayout.BeginVertical(); GUILayout.Label("Veteran"); GUILayout.Label("Wings"); GUILayout.Label("Kerbonaut"); GUILayout.EndVertical();
- //sel = GUILayout.SelectionGrid(sel, new string[] { ">¤<", ">¤<", ">¤<", ">¤<", ">¤<", ">¤<", ">¤<", ">¤<", ">¤<" }, 3, GUILayout.Width(250));
- //GUILayout.EndHorizontal();
- GUILayout.BeginVertical();
- List<string> dmgTypes = new List<string>();
- foreach (string subTitle in new string[] { "Medicine/Negative", "Psychology/Positive", "Psychology/Negative" }) {
- if (subTitle == "Psychology/Negative" && !HasKerbalDamage(currentKerb, "Psychology_Social")) continue;
- GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
- GUILayout.Label($"{(subTitle.Contains("Positive") ? "☼" : "◊")} {LocalizationManager.GetTranslation($"KerbalLife/{subTitle}").ToUpper()} {(subTitle.Contains("Positive") ? "☼" : "◊")}");
- GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
- if (subTitle.Contains("Medicine"))
- dmgTypes = new List<string> { "Medicine_Atrophy", "Medicine_Impacts" };
- else if (subTitle.Contains("Positive"))
- dmgTypes = new List<string> { "Psychology_Role_Kerbonaut_Chief", "Psychology_Role_Kerbonaut_Grad", "Psychology_Role_Veteran", "Psychology_Role_Wings",
- "Psychology_Therapy" }.Where(s => HasKerbalDamage(currentKerb, s)).ToList();
- else dmgTypes = new string[] { "Psychology_Social_Harassed", "Psychology_Social_Fired_Self", "Psychology_Social_Fired_Other", "Psychology_Social_KerbonautLost" }.Where(s => HasKerbalDamage(currentKerb, s)).ToList();
- foreach (string type in dmgTypes) {
- bool btn2 = false;
- GUILayout.BeginHorizontal();
- GUILayout.Label(LocalizationManager.GetTranslation($"KerbalLife/{type.Replace('_', '/')}"));
- GUILayout.FlexibleSpace();
- bool btn1 = GUILayout.Button(subTitle.Contains("Negative") ? "Tolerance" : "Attitude");
- GUILayout.Space(20);
- if (!type.StartsWith("Psychology_Role"))
- btn2 = GUILayout.Button(type.Contains("Therapy") ? "Progress" : "Current");
- GUILayout.EndHorizontal();
- if (btn1) UIPartDmg = subTitle.Contains("Negative") ? (100 - KerbalDamageModifier(currentKerb, type) * 100) : KerbalDamageModifier(currentKerb, type) * 100;
- else if (btn2) UIPartDmg = type.Contains("Therapy") ? Math.Abs(TryGetKerbalDamage(currentKerb, type) * 100) : (100 - TryGetKerbalDamage(currentKerb, type) * 100);
- }
- }
- GUILayout.EndVertical();
- }
- if (isBeingRepaired) {
- GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label(guiData.Repairing); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
- foreach (string repName in guiData.Repairers)
- GUILayout.Label(repName);
- } else if (isIdleEVA && !isInspected) {
- GUILayout.BeginHorizontal();
- GUILayout.Label($"{guiData.Inspecting}{(inspectTicks % 3 == 0 ? "." : inspectTicks % 3 == 2 ? ".." : "...")}");
- GUILayout.HorizontalSlider(inspectTicks, 7, 0, GUILayout.Width(180));
- GUILayout.EndHorizontal();
- }
- }
- private void GUIContentPAL() {
- GUILayout.BeginHorizontal();
- GUILayout.Space(10);
- GUILayout.Label(guiData.Wireframe);
- GUILayout.Space(10);
- GUILayout.BeginVertical();
- GUILayout.Space(8);
- GUILayout.Label(guiData.Impacts);
- if (ReUtil.IsPALActive(level: 3, bypassVessel: true))
- GUILayout.Label(guiData.Temperature);
- if (UIPart.PartName != "eva_kerbal") {
- if (ReUtil.IsPALActive(level: 2, bypassVessel: true))
- GUILayout.Label(guiData.GeeForces);
- if (ReUtil.IsPALActive(level: 4, bypassVessel: true))
- GUILayout.Label(guiData.AngularVel);
- if (ReUtil.IsPALActive(level: 6, bypassVessel: true))
- GUILayout.Label(guiData.Instability);
- if (ReUtil.IsPALActive(level: 5, bypassVessel: true))
- GUILayout.Label(guiData.Ullage);
- if (ReUtil.IsPALActive(level: 10, bypassVessel: true))
- GUILayout.Label(guiData.Boiloff);
- }
- GUILayout.EndVertical();
- GUILayout.EndHorizontal();
- }
- private void GUIContentVessel() {
- bool navSerL = false;
- bool navSerR = false;
- bool navCatL = false;
- bool navCatR = false;
- bool isPart = UIPart != null && UIPart?.PartName != "eva_kerbal";
- if (isPart) GUILayout.Label(guiData.Age);
- GUILayout.Space(4);
- GUILayout.BeginHorizontal();
- GUILayout.Label(guiData.SerialTitle);
- if (isPart) navSerL = GUILayout.Button(guiData.NavLBtn, btnStyle, GUILayout.Width(28));
- GUILayout.FlexibleSpace();
- GUILayout.Label(guiData.SerialDesc);
- GUILayout.FlexibleSpace();
- if (isPart) navSerR = GUILayout.Button(guiData.NavRBtn, btnStyle, GUILayout.Width(28));
- GUILayout.EndHorizontal();
- GUILayout.Space(4);
- GUILayout.BeginHorizontal();
- GUILayout.Label(guiData.CategoryTitle);
- if (isPart) navCatL = GUILayout.Button(guiData.NavLBtn, btnStyle, GUILayout.Width(28));
- GUILayout.FlexibleSpace();
- GUILayout.Label(guiData.CategoryDesc);
- GUILayout.FlexibleSpace();
- if (isPart) navCatR = GUILayout.Button(guiData.NavRBtn, btnStyle, GUILayout.Width(28));
- GUILayout.EndHorizontal();
- if (navSerL || navSerR || navCatL || navCatR) {
- List<PartComponent> parts = UIPart.PartOwner.SimulationObject.Vessel.SimulationObject.PartOwner.Parts.ToList();
- if (navSerL || navSerR) {
- parts = parts.Where(p => p.PartData.category == UIPart.PartData.category).ToList();
- int i = parts.FindIndex(p => p.Guid == UIPart.Guid);
- if (navSerL) UIPart = parts[i - 1 > -1 ? i - 1 : parts.Count - 1];
- else UIPart = parts[i + 1 < parts.Count ? i + 1 : 0];
- } else {
- parts = parts.GroupBy(p => p.PartData.category).Select(g => g.First()).ToList();
- int i = parts.FindIndex(p => p.PartData.category == UIPart.PartData.category);
- if (navCatL) UIPart = parts[i - 1 > -1 ? i - 1 : parts.Count - 1];
- else UIPart = parts[i + 1 < parts.Count ? i + 1 : 0];
- }
- guiData.UpdateVesselPart(ReUtil.IsPALActive(UIPart.PartOwner.SimulationObject.Vessel));
- }
- }
- private void GUIContentListMode() {
- GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label(guiData.VesselsNearby); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
- foreach (VesselComponent vessel in guiData.VesselsList) {
- GUILayout.BeginHorizontal();
- GUILayout.Space(10);
- GUILayout.Label(vessel.DisplayName);
- GUILayout.FlexibleSpace();
- if (vessel.Guid == activeVessel.Guid && UIPart?.PartOwner?.SimulationObject?.Vessel?.Guid == activeVessel.Guid)
- GUILayout.Label(guiData.Current);
- else if (vessel.Guid == UIPart?.PartOwner?.SimulationObject?.Vessel?.Guid)
- GUILayout.Label(guiData.Connected);
- else if (!activeVessel.IsKerbalEVA) {
- bool vslSwitch = GUILayout.Button(guiData.Contact);
- if (vslSwitch) {
- UIPart = vessel.SimulationObject?.PartOwner?.Parts?.First();
- guiData.UpdateVesselPart(ReUtil.IsPALActive(activeVessel));
- }
- }
- GUILayout.Space(10);
- GUILayout.EndHorizontal();
- }
- GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label(guiData.KerbalsOnEVA); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
- // foreach (Tuple<string, string> evaData in guiData.EVAsList) {
- foreach (VesselComponent evaVessel in guiData.EVAsList) {
- bool evaSwitch = false;
- GUILayout.BeginHorizontal();
- GUILayout.Space(10);
- GUILayout.Label(evaVessel.DisplayName);
- GUILayout.FlexibleSpace();
- GUILayout.Label(repairers.Any(r => r.Guid == evaVessel.Guid) ? guiData.Repairing : guiData.Idle);
- GUILayout.Space(10);
- if (!activeVessel.IsKerbalEVA)
- if (evaVessel.Guid == UIPart?.PartOwner?.SimulationObject?.Vessel?.Guid)
- GUILayout.Label(guiData.ModeBtn + " ");
- else evaSwitch = GUILayout.Button(guiData.ModeBtn, btnStyle, GUILayout.Width(28));
- GUILayout.EndHorizontal();
- if (evaSwitch) {
- UIPart = evaVessel.SimulationObject?.PartOwner?.Parts?.First();
- guiData.UpdateVesselPart(ReUtil.IsPALActive(activeVessel));
- }
- }
- }
- private void UpdateGUIVessel() {
- activeVessel = Game.ViewController?.GetActiveVehicle()?.GetSimVessel();
- lockUI = false;
- if (PALMiniActive) UpdatePALMini(false);
- // lockUI = (activeVessel?.IsKerbalEVA ?? false) && repairers.Any(r => r.Guid == activeVessel.Guid);
- if (activeVessel?.IsKerbalEVA ?? true) { UIPart = null; guiData.UpdateWindowTitle(); return; }
- UIPart = activeVessel?.SimulationObject?.PartOwner?.Parts?.First();
- bool hasPAL = ReUtil.IsPALActive(activeVessel);
- guiData.UpdateWindowTitle(hasPAL);
- guiData.UpdateVesselPart(hasPAL);
- }
- internal static void UpdatePALMini(bool setActive) {
- PALMiniActive = setActive;
- PALMiniUpdate = true;
- Instance.StartCoroutine(CallbackUtil.DelayedCallback(1, delegate { PALMiniUpdate = false; }));
- }
- private void ToggleApp() {
- KerbalDamageCheckIn();
- if (guiData.Agency == null) {
- guiData.Agency = ReUtil.PlayerReAgency();
- guiData.Kerbal = ReUtil.GetKerbalForAgency(guiData.Agency);
- }
- if (!ReUtil.IsGameSandbox() && ReUtil.IsPlayerAgency(guiData.Agency)) {
- guiData.UpdateDiscovery();
- guiData.UpdateSciLevel();
- }
- showApp = !showApp;
- // GameObject.Find("BTN-ReKerbalLife")?.GetComponent<UIValue_WriteBool_Toggle>()?.SetValue(showApp);
- if (showUI && showApp) {
- showUI = false;
- // GameObject.Find("BTN-ReDiagnostic")?.GetComponent<UIValue_WriteBool_Toggle>()?.SetValue(showUI);
- }
- }
- private void ToggleApp(bool show) => ToggleApp();
- private void AppContent(int windowID) {
- bool modeBtn = false;
- GUILayout.BeginHorizontal();
- GUIStyle[] btns = new GUIStyle[] { btnStyle, btnKStyle, btnMStyle, btnFStyle };
- if (!minUI && !ReUtil.IsGameSandbox())
- modeBtn = GUILayout.Button(guiData.ModeIndex == 0 ? "<color=#0D0D0D>∞</color>" : "", btns[guiData.ModeIndex], GUILayout.Width(28), GUILayout.Height(28));
- else if (ReUtil.IsGameSandbox())
- GUILayout.Label(guiData.Icon);
- GUILayout.FlexibleSpace();
- bool minBtn = GUILayout.Button($"<color=#0D0D0D>{(minUI ? "□" : " - ")}</color>", btnStyle, GUILayout.Width(28));
- bool closeBtn = GUILayout.Button("<color=#0D0D0D>x</color>", btnXStyle, GUILayout.Width(28));
- GUILayout.EndHorizontal();
- if (modeBtn) guiData.ModeIndex = guiData.ModeIndex == 3 ? 0 : guiData.ModeIndex + 1;
- else if (minBtn) minUI = !minUI;
- else if (closeBtn) showApp = false;
- if (!showApp || minUI || modeBtn) { GUI.DragWindow(new Rect(0, 0, 10000, 500)); return; }
- AppContentHeader();
- AppContentAgency();
- GUI.DragWindow(new Rect(0, 0, 10000, 500));
- }
- private void AppContentHeader() {
- bool isPlayer = ReUtil.IsPlayerAgency(guiData.Agency);
- Texture2D tex = guiData.Kerbal == null ? isPlayer ? GameManager.Instance.Game.AgencyManager.FindAgencyEntryFirst().AgencyFlag.texture :
- ReUtil.agencyFlags[guiData.Agency?.Name] : guiData.Kerbal?.Portrait.texture;
- // if (tex == null) GUILayout.Label("", GUILayout.Height(294));
- string aName = isPlayer ? (guiData.Agency?.Name ?? "") : LocalizationManager.GetTranslation($"Missions/MissionGranter/Name/{guiData.Agency.Name}");
- List<KerbalDamage> agencyKerbals = ReUtil.GetKerbalsForAgency(guiData.Agency);
- bool isChief = guiData.Kerbal?.NameKey == agencyKerbals?.FirstOrDefault()?.Name;
- KerbalDamage currentKerb = guiData.Kerbal == null ? null : agencyKerbals?.FirstOrDefault(k => k?.Name == guiData.Kerbal?.NameKey);
- // AddKerbalDamage(currentKerb, "Psychology_Social_Stalk", 0.0005);
- // GUILayout.Label(guiData.Dots, GUILayout.Height(6), GUILayout.Width(344));
- if (guiData.Kerbal == null) GUILayout.Space(28);
- GUILayout.Label(tex, GUILayout.Height(guiData.Kerbal == null ? 225 : 281)); // , GUILayout.Width(344)
- if (guiData.Kerbal == null) GUILayout.Space(28);
- // GUILayout.Label(guiData.Dots, GUILayout.Height(6));
- GUILayout.Label(guiData.Dots, GUILayout.Height(8));
- GUILayout.BeginHorizontal();
- GUILayout.BeginVertical(); GUILayout.Space(17);
- bool navL = GUILayout.Button("", btnLStyle, GUILayout.Width(28));
- GUILayout.Space(17); GUILayout.EndVertical();
- GUILayout.FlexibleSpace();
- // if (aName.Length > 26) aName = aName.Substring(0, 26) + "...";
- GUILayout.BeginVertical(); GUILayout.FlexibleSpace();
- GUILayout.Label($"<color=#0D0D0D><size=20>{aName}</size></color>");
- GUILayout.FlexibleSpace(); GUILayout.EndVertical();
- GUILayout.FlexibleSpace();
- GUILayout.BeginVertical(); GUILayout.Space(17);
- bool navR = GUILayout.Button("", btnRStyle, GUILayout.Width(28));
- GUILayout.Space(17); GUILayout.EndVertical();
- GUILayout.EndHorizontal();
- if (!ReUtil.IsGameSandbox()) {
- List<Tuple<Texture2D, string>> agencyTypes = new List<Tuple<Texture2D, string>> { Tuple.Create(guiData.Icon, "KerbalLife/Kerbonaut"),
- Tuple.Create(AssetManager.GetAsset<Texture2D>($"KSRe/images/icon3.png"), "KerbalLife/Manufacturer"),
- Tuple.Create(AssetManager.GetAsset<Texture2D>($"KSRe/images/icon4.png"), "Menu/Escape/Science"),
- Tuple.Create(AssetManager.GetAsset<Texture2D>($"KSRe/images/icon5.png"), "Flight/FlightReport/Crew") };
- if (!isPlayer && guiData.Agency.Name != "KSC") agencyTypes.RemoveAt(3);
- if (!isPlayer) agencyTypes.RemoveAt(2);
- if (!isPlayer && !ReUtil.crewAgencies.ContainsKey(guiData.Agency.Name)) agencyTypes.RemoveAt(0);
- if (!ReUtil.mfParts.ContainsKey(guiData.Agency.Name)) agencyTypes.RemoveAt(agencyTypes.Count > 1 ? 1 : 0);
- GUILayout.BeginHorizontal();
- foreach (var agencyType in agencyTypes) {
- GUILayout.FlexibleSpace();
- GUILayout.Label(agencyType.Item1);
- GUILayout.Label($"<color=#0D0D0D><size=13>{LocalizationManager.GetTranslation(agencyType.Item2).ToUpper()}</size></color>");
- }
- GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
- }
- GUILayout.Label(guiData.Dots, GUILayout.Height(8));
- if (navL || navR) {
- List<ReAgency> navList = guiData.ModeIndex == 0 ? saveData.agencies : guiData.ModeIndex == 1 ?
- saveData.agencies.Where(a => ReUtil.crewAgencies.ContainsKey(a.Name) || a.Name == guiData.Agency.Name || ReUtil.IsPlayerAgency(a)).ToList() : guiData.ModeIndex == 2 ?
- saveData.agencies.Where(a => ReUtil.mfParts.ContainsKey(a.Name) || a.Name == guiData.Agency.Name || ReUtil.IsPlayerAgency(a)).ToList() :
- saveData.agencies.Where(a => a.Name == "KSC" || ReUtil.IsPlayerAgency(a) || a.Name == guiData.Agency.Name).ToList();
- int i = navList.FindIndex(a => a.Name == guiData.Agency.Name);
- if (navL) guiData.Agency = navList[i - 1 > -1 ? i - 1 : navList.Count - 1];
- else guiData.Agency = navList[i + 1 < navList.Count ? i + 1 : 0];
- if (guiData.AgencyIndex == 3 && !ReUtil.IsPlayerAgency(guiData.Agency) && guiData.Agency.Name != "KSC")
- guiData.AgencyIndex = 0;
- if (guiData.AgencyIndex == 1 && !ReUtil.IsPlayerAgency(guiData.Agency) && !ReUtil.mfParts.ContainsKey(guiData.Agency.Name))
- guiData.AgencyIndex = 0;
- if (guiData.AgencyIndex == 0 && !ReUtil.IsPlayerAgency(guiData.Agency) && !ReUtil.crewAgencies.ContainsKey(guiData.Agency.Name))
- guiData.AgencyIndex = 1;
- guiData.Kerbal = guiData.AgencyIndex != 0 ? null : ReUtil.GetKerbalForAgency(guiData.Agency);
- }
- }
- private void AppContentAgency() {
- bool isPlayer = ReUtil.IsPlayerAgency(guiData.Agency);
- string[] titles = new string[] { isPlayer ? "Flight/FlightReport/Crew" : "KerbalLife/Roster", "Career/PartGrade", "Menu/VAB/Description", "KerbalLife/CrewStatus", "Career/Title", "Flight/FlightReport/Flight Status" };
- GUILayout.BeginHorizontal();
- bool navL = GUILayout.Button("", btnLStyle, GUILayout.Width(28));
- GUILayout.FlexibleSpace();
- GUILayout.Label($"<color=#0D0D0D><size=19>{LocalizationManager.GetTranslation(titles[(isPlayer && guiData.AgencyIndex == 1 ? 4 : isPlayer && guiData.AgencyIndex == 3 ? 5 : guiData.AgencyIndex)]).ToUpper()}</size></color>");
- GUILayout.FlexibleSpace();
- bool navR = GUILayout.Button("", btnRStyle, GUILayout.Width(28));
- GUILayout.EndHorizontal();
- GUILayout.Label(guiData.Dots, GUILayout.Height(8));
- if (guiData.AgencyIndex == 0) AppContentRoster();
- else if (guiData.AgencyIndex == 3) AppContentCrew();
- else if (guiData.AgencyIndex == 2) {
- string desc = isPlayer ? LocalizationManager.GetTranslation("Menu/NewCampaign/Agency Name Menu Description").Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries)[0] :
- LocalizationManager.GetTranslation($"Missions/MissionGranter/Description/{guiData.Agency.Name}");
- GUILayout.Label($"<color=#0D0D0D><size=14>{desc}</size></color>"); // -------------------------------------------\n<i></i>\n-------------------------------------------
- } else if (isPlayer) AppContentScience();
- else if (guiData.Agency.partRecords.Count == 0)
- GUILayout.Label($"<color=#0D0D0D><size=14>{LocalizationManager.GetTranslation("Career/PartGradeHint", new object[] { LocalizationManager.GetTranslation($"Missions/MissionGranter/Name/{guiData.Agency.Name}") })}</size></color>");
- else foreach (var pair in guiData.Agency.partRecords) {
- float rec = (float)TryGetPartRecord(pair.Key, true);
- GUILayout.BeginHorizontal();
- GUILayout.Label($"<color=#0D0D0D>{LocalizationManager.GetTranslation($"Parts/Title/{pair.Key}")}</color>"); // : <b>{ReUtil.GetPartGradeStr(rec)}</b>
- GUILayout.HorizontalSlider(rec, 0f, 1f, GUILayout.Width(150));
- GUILayout.Box(AssetManager.GetAsset<Texture2D>($"KSRe/images/grade_{ReUtil.GetGradeStr(rec)}.png"), GUILayout.Width(28), GUILayout.Height(28));
- GUILayout.EndHorizontal();
- }
- if (navL || navR) {
- int cap = isPlayer || guiData.Agency.Name == "KSC" ? 3 : 2;
- if (navL) guiData.AgencyIndex = guiData.AgencyIndex - 1 > -1 ? guiData.AgencyIndex - 1 : cap;
- else guiData.AgencyIndex = guiData.AgencyIndex + 1 < cap + 1 ? guiData.AgencyIndex + 1 : 0;
- if (guiData.AgencyIndex == 1 && (ReUtil.IsGameSandbox() || (!isPlayer && !ReUtil.mfParts.ContainsKey(guiData.Agency.Name))))
- guiData.AgencyIndex = navL ? 0 : 2;
- if (guiData.AgencyIndex == 0 && !isPlayer && !ReUtil.crewAgencies.ContainsKey(guiData.Agency.Name))
- guiData.AgencyIndex = navL ? 2 : 1;
- guiData.Kerbal = guiData.AgencyIndex != 0 ? null : ReUtil.GetKerbalForAgency(guiData.Agency);
- //if (guiData.AgencyIndex == 0)
- // ReUtil.PushNotify(guiData.Kerbal.NameKey, "Hello", NotificationImportance.Low);
- }
- }
- private void AppContentScience() {
- int count = ReUtil.PlayerReAgency().rocketScience.Select(s => s.Key.Split('_')[0]).Distinct().Count();
- bool navL = false;
- bool navR = false;
- GUILayout.BeginHorizontal();
- GUILayout.Label($"<color=#0D0D0D><size=13>{LocalizationManager.GetTranslation("Missions/TriumphWindow/AcceptScienceReward").ToUpper()}:</size></color>");
- GUILayout.FlexibleSpace();
- GUILayout.Label(AssetManager.GetAsset<Texture2D>($"KSRe/images/rocket_sci.png"));
- GUILayout.Label($"<color=#0D0D0D><size=17>{ReUtil.GetTotalScience()}</size></color>");
- GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal();
- GUILayout.Label(guiData.Discovery);
- int progress = (int)Math.Round(guiData.DiscoveryValue * 200);
- GUILayout.Box("", GUILayout.Width(progress), GUILayout.Height(10));
- GUILayout.Space(200 - progress);
- // GUILayout.HorizontalSlider(guiData.DiscoveryValue, 0f, 1f, GUILayout.Width(200));
- GUILayout.EndHorizontal();
- GUILayout.Label(guiData.Dots, GUILayout.Height(8));
- GUILayout.BeginHorizontal();
- if (count > 1) navL = GUILayout.Button("", btnLStyle, GUILayout.Width(28));
- GUILayout.FlexibleSpace(); GUILayout.Label(guiData.SciTitle); GUILayout.FlexibleSpace();
- if (count > 1) navR = GUILayout.Button("", btnRStyle, GUILayout.Width(28));
- GUILayout.EndHorizontal();
- GUILayout.BeginHorizontal();
- GUILayout.Label(guiData.Level);
- GUILayout.Box(AssetManager.GetAsset<Texture2D>($"KSRe/images/{guiData.SciLvl}.png"), GUILayout.Width(28), GUILayout.Height(28));
- progress = (int)Math.Round(guiData.SciLvlProgress * 160);
- GUILayout.Box("", GUILayout.Width(progress), GUILayout.Height(10));
- GUILayout.Space(160 - progress);
- // GUILayout.HorizontalSlider(guiData.SciLvlProgress, 0f, 1f, GUILayout.Width(160));
- GUILayout.EndHorizontal();
- GUILayout.BeginVertical();
- foreach (var pair in guiData.SciSubtypes) {
- GUILayout.BeginHorizontal();
- GUILayout.Label(pair.Item1);
- GUILayout.Box(AssetManager.GetAsset<Texture2D>($"KSRe/images/{Math.Truncate(pair.Item2)}.png"), GUILayout.Width(28), GUILayout.Height(28));
- progress = (int)Math.Round((pair.Item2 - (float)Math.Truncate(pair.Item2)) * 100);
- GUILayout.Box("", GUILayout.Width(progress), GUILayout.Height(10));
- GUILayout.Space(100 - progress);
- // GUILayout.HorizontalSlider(pair.Item2 - (float)Math.Truncate(pair.Item2), 0f, 1f, GUILayout.Width(100));
- GUILayout.EndHorizontal();
- }
- GUILayout.EndVertical();
- if (navL || navR) { // ReUtil.careerSpecTechs.Where(s => !s.Key.Contains("_")).Count();
- if (navL) guiData.SciIndex = guiData.SciIndex - 1 > -1 ? guiData.SciIndex - 1 : count - 1;
- else guiData.SciIndex = guiData.SciIndex + 1 < count ? guiData.SciIndex + 1 : 0;
- guiData.UpdateSciLevel();
- }
- }
- private void AppContentCrew() {
- if (guiData.Agency.Name == "KSC") {
- int count = saveData.kerbals.Count(k => k.status.StartsWith("KSC>"));
- if (count == 0)
- GUILayout.Label($"<color=#0D0D0D><size=14>{LocalizationManager.GetTranslation($"KerbalLife/NoCrewKSCHint")}</size></color>");
- // foreach (string status in new string[] { "READY", "STANDBY", "FITNESS", "THERAPY", "RECOVERY", "MED BAY" }) {
- //if (saveData.kerbals.Count(k => k.status == $"KSC>{status}") > 0) {
- // GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
- // GUILayout.Label($"<color=#0D0D0D><size=14>{status}</size></color>");
- // GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
- //}
- else if (count > 8) UIScrollPos = GUILayout.BeginScrollView(UIScrollPos, scrollStyle, GUILayout.Height(260));
- foreach (KerbalDamage kerbal in saveData.kerbals.Where(k => k.status?.StartsWith("KSC>") ?? false)) {
- GUILayout.BeginHorizontal();
- GUILayout.Label(AssetManager.GetAsset<Texture2D>($"KSRe/images/icon_d{ReUtilKerb.GetDamageInt(kerbal.damage.Values.Sum())}{(kerbal.damage.ContainsKey("Psychology_Role_Wings") ? "w" : "")}.png"), GUILayout.Width(28), GUILayout.Height(28));
- // GUILayout.FlexibleSpace();
- GUILayout.Label($"<color=#0D0D0D>{kerbal.Name}</color>");
- GUILayout.FlexibleSpace();
- GUILayout.Label($"<color=#0D0D0D><size=14>{kerbal.status?.Split('>').Last() ?? ""}</size></color>");
- GUILayout.Space(4);
- GUILayout.EndHorizontal();
- }
- if (count > 8) GUILayout.EndScrollView();
- // }
- } else {
- int count = saveData.kerbals.Count(k => !k.status.StartsWith("KSC>"));
- if (count == 0)
- GUILayout.Label($"<color=#0D0D0D><size=14>{LocalizationManager.GetTranslation($"KerbalLife/NoCrewFlightsHint")}</size></color>");
- else if (count > 6) UIScrollPos = GUILayout.BeginScrollView(UIScrollPos, scrollStyle, GUILayout.Height(260));
- foreach (string status in saveData.kerbals.Select(k => k.status.Split('>').First()).Where(s => s != "KSC" && s != "EVA").Distinct()) {
- GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
- GUILayout.Label($"<color=#0D0D0D><size=14>{status}</size></color>");
- GUILayout.FlexibleSpace();
- GUILayout.Label(AssetManager.GetAsset<Texture2D>($"KSRe/images/cel_{saveData.kerbals.FirstOrDefault(k => k.status.StartsWith(status))?.celName ?? "Kerbin"}.png"), GUILayout.Width(28), GUILayout.Height(28));
- GUILayout.EndHorizontal();
- foreach (KerbalDamage kerbal in saveData.kerbals.Where(k => k.status.StartsWith(status))) {
- GUILayout.BeginHorizontal();
- GUILayout.Label(AssetManager.GetAsset<Texture2D>($"KSRe/images/icon_d{ReUtilKerb.GetDamageInt(kerbal.damage.Values.Sum())}{(kerbal.damage.ContainsKey("Psychology_Role_Wings") ? "w" : "")}.png"), GUILayout.Width(28), GUILayout.Height(28));
- GUILayout.Label($"<color=#0D0D0D>{kerbal.Name}</color>");
- GUILayout.FlexibleSpace();
- GUILayout.Label($"<color=#0D0D0D><size=14>{kerbal.status?.Split('>').Last() ?? ""}</size></color>");
- GUILayout.Space(4);
- GUILayout.EndHorizontal();
- }
- }
- if (saveData.kerbals.Count(k => k.status.StartsWith("EVA>")) > 0) {
- GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
- GUILayout.Label($"<color=#0D0D0D><size=14>{LocalizationManager.GetTranslation("Diagnostic/KerbalsOnEVA")}</size></color>");
- GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
- }
- foreach (KerbalDamage kerbal in saveData.kerbals.Where(k => k.status.StartsWith("EVA>"))) {
- GUILayout.BeginHorizontal();
- GUILayout.Label(AssetManager.GetAsset<Texture2D>($"KSRe/images/icon_d{ReUtilKerb.GetDamageInt(kerbal.damage.Values.Sum())}{(kerbal.damage.ContainsKey("Psychology_Role_Wings") ? "w" : "")}.png"), GUILayout.Width(28), GUILayout.Height(28));
- GUILayout.Label($"<color=#0D0D0D>{kerbal.Name}</color>");
- GUILayout.FlexibleSpace();
- GUILayout.Label($"<color=#0D0D0D><size=14>{kerbal.status?.Replace("EVA>", "") ?? ""}</size></color>");
- GUILayout.Space(20);
- GUILayout.Label(AssetManager.GetAsset<Texture2D>($"KSRe/images/cel_{kerbal.celName ?? "Kerbin"}.png"), GUILayout.Width(28), GUILayout.Height(28));
- GUILayout.EndHorizontal();
- }
- if (count > 6) GUILayout.EndScrollView();
- }
- }
- private void AppContentRoster() {
- bool navL = false;
- bool navR = false;
- bool swapBtn = false;
- bool isSandbox = ReUtil.IsGameSandbox();
- List<KerbalDamage> agencyKerbals = ReUtil.GetKerbalsForAgency(guiData.Agency);
- bool isPlayer = ReUtil.IsPlayerAgency(guiData.Agency);
- bool isChief = guiData.Kerbal?.NameKey == agencyKerbals?.FirstOrDefault()?.Name;
- KerbalDamage currentKerb = guiData.Kerbal == null ? null : agencyKerbals?.FirstOrDefault(k => k?.Name == guiData.Kerbal?.NameKey);
- int count = saveData.kerbals.Count(k => k.agencyName == guiData.Agency.Name);
- if (count == 0)
- GUILayout.Label($"<color=#0D0D0D><size=14>{LocalizationManager.GetTranslation($"KerbalLife/NoKerbonautsHint", new object[] { isPlayer ? ReUtil.PlayerAgencyName() : LocalizationManager.GetTranslation($"Missions/MissionGranter/Name/{guiData.Agency.Name}") })}</size></color>");
- else {
- if (guiData.Kerbal != null) {
- GUILayout.BeginHorizontal(); GUILayout.BeginVertical();
- GUILayout.Label($"<color=#0D0D0D><size=13>{LocalizationManager.GetTranslation($"KerbalLife/{(isChief ? "ChiefKerbonaut" : "Kerbonaut")}").ToUpper()}:</size></color>");
- GUILayout.Label(guiData.Training);
- //if (!saveData.playerConfirmed && leader != null)
- // guiData.newKerbName = GUILayout.TextField(guiData.newKerbName ?? "", 21, GUILayout.Width(180));
- //else if (!saveData.playerConfirmed && leader != null) GUILayout.Label(guiData.Surname);
- GUILayout.EndVertical(); GUILayout.FlexibleSpace(); GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
- GUILayout.Label($"<color=#0D0D0D><size=18>{guiData.Kerbal?.NameKey}</size></color>");
- GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
- GUILayout.Label($"<color=#0D0D0D>{LocalizationManager.GetTranslation($"Career/{currentKerb?.Trait}/Crew")}</color>");
- GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.FlexibleSpace();
- if (currentKerb?.status == "KSC>READY" && !(isPlayer && guiData.CrewIndex > 0)) { // && (isPlayer || !isChief || isSandbox)
- GUILayout.BeginVertical(); GUILayout.FlexibleSpace();
- swapBtn = GUILayout.Button($"<size=13><b>{(isPlayer ? "F" : "H")}IRE</b></size>");
- GUILayout.FlexibleSpace(); GUILayout.EndVertical();
- }
- GUILayout.EndHorizontal(); GUILayout.Label(guiData.Dots, GUILayout.Height(8));
- }
- if (isPlayer) {
- string[] titles = new string[] { "KerbalLife/Roster", "Career/Medicine/Title", "Career/Psychology/Title" };
- GUILayout.BeginHorizontal();
- navL = GUILayout.Button("", btnLStyle, GUILayout.Width(28));
- GUILayout.FlexibleSpace();
- GUILayout.Label($"<color=#0D0D0D><size=19>{LocalizationManager.GetTranslation(titles[guiData.CrewIndex]).ToUpper()}</size></color>");
- GUILayout.FlexibleSpace();
- navR = GUILayout.Button("", btnRStyle, GUILayout.Width(28));
- GUILayout.EndHorizontal();
- }
- if (!isPlayer || guiData.CrewIndex == 0) {
- if (count > 5) UIScrollPos = GUILayout.BeginScrollView(UIScrollPos, scrollStyle, GUILayout.Height(160));
- foreach (KerbalDamage kerbal in saveData.kerbals.Where(k => k.agencyName == guiData.Agency.Name)) {
- bool kerbBtn = false;
- GUILayout.BeginHorizontal();
- if (guiData.Kerbal?.NameKey != kerbal.Name)
- kerbBtn = GUILayout.Button("<color=#0D0D0D>>¤<</color>", btnStyle, GUILayout.Width(28), GUILayout.Height(28));
- else GUILayout.Label(AssetManager.GetAsset<Texture2D>($"KSRe/images/icon{(kerbal.damage.ContainsKey("Psychology_Role_Wings") ? "_ww" : "")}.png"), GUILayout.Width(28), GUILayout.Height(28));
- GUILayout.FlexibleSpace(); GUILayout.Label($"<color=#0D0D0D>{kerbal.Name}</color>"); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
- if (kerbBtn) {
- Game.SessionManager.KerbalRosterManager.TryGetKerbalByName(kerbal.Name, out guiData.Kerbal);
- // ReUtil.PushNotify(guiData.Kerbal.NameKey, "Hello", NotificationImportance.Low);
- }
- }
- if (count > 5) GUILayout.EndScrollView();
- } else if (currentKerb != null) {
- GUILayout.BeginVertical();
- Dictionary<string, float> dmgTypes = new Dictionary<string, float>();
- foreach (string subTitle in new string[] { "Medicine/Negative", "Psychology/Positive", "Psychology/Negative" }) {
- if ((guiData.CrewIndex == 1 && subTitle.Contains("Psychology")) || (guiData.CrewIndex == 2 && !subTitle.Contains("Psychology"))) continue;
- if (subTitle == "Psychology/Negative" && !HasKerbalDamage(currentKerb, "Psychology_Social")) continue;
- GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace();
- GUILayout.Label($"<color=#0D0D0D><size=14>{(subTitle.Contains("Positive") ? "☼" : "◊")} {LocalizationManager.GetTranslation($"KerbalLife/{subTitle}").ToUpper()} {(subTitle.Contains("Positive") ? "☼" : "◊")}</size></color>");
- GUILayout.FlexibleSpace(); GUILayout.EndHorizontal();
- if (guiData.CrewIndex == 1)
- dmgTypes = new string[] { "Medicine_Atrophy", "Medicine_Impacts" }.ToDictionary(s => s, s => 1 - KerbalDamageModifier(currentKerb, s));
- else if (subTitle.Contains("Positive"))
- dmgTypes = new string[] { "Psychology_Role_Kerbonaut_Chief", "Psychology_Role_Kerbonaut_Grad", "Psychology_Role_Veteran", "Psychology_Role_Wings", "Psychology_Therapy"
- }.Where(s => HasKerbalDamage(currentKerb, s)).ToDictionary(s => s, s => KerbalDamageModifier(currentKerb, s));
- else if (subTitle.Contains("Negative"))
- dmgTypes = new string[] { "Psychology_Social_Harassed", "Psychology_Social_Fired_Self", "Psychology_Social_Fired_Other", "Psychology_Social_KerbonautLost"
- }.Where(s => HasKerbalDamage(currentKerb, s)).ToDictionary(s => s, s => 1 - KerbalDamageModifier(currentKerb, s));
- foreach (var pair in dmgTypes) {
- GUILayout.BeginHorizontal();
- GUILayout.Label($"<color=#0D0D0D><size=13>:: {LocalizationManager.GetTranslation($"KerbalLife/{pair.Key.Replace('_', '/')}")}</size></color>");
- GUILayout.FlexibleSpace();
- GUILayout.HorizontalSlider(pair.Value, 0f, 1f, GUILayout.Width(100));
- GUILayout.Box($"<color=white>{ReUtilKerb.GetPsychologyStr(pair.Value)}</color>", GUILayout.Width(28), GUILayout.Height(28));
- GUILayout.EndHorizontal();
- }
- }
- GUILayout.EndVertical();
- }
- }
- if (navL || navR) {
- guiData.CrewIndex = guiData.CrewIndex == 2 ? 0 : 2;
- //if (navL) guiData.CrewIndex = guiData.CrewIndex > 0 ? guiData.CrewIndex - 1 : 2;
- //else guiData.CrewIndex = guiData.CrewIndex < 2 ? guiData.CrewIndex + 1 : 0;
- } else if (swapBtn) {
- bool update = false;
- double socialDmg = TryGetKerbalDamage(currentKerb, "Psychology_Social");
- if (isPlayer) {
- ReUtil.PushNotify(currentKerb.Name, "Sad", NotificationImportance.Medium);
- double dmg = (currentKerb.damage.Where(p => p.Key.StartsWith("Psychology_Role")).Sum(p => Math.Abs(p.Value)) + TryGetKerbalDamage(currentKerb, "Psychology_Social_Fired")) * 3;
- saveData.kerbals.Where(k => k.Name != currentKerb.Name).ToList().ForEach(k => AddKerbalDamage(k, "Psychology_Social_Fired_Other", dmg / 10));
- AddKerbalDamage(currentKerb, "Psychology_Social_Fired_Self", dmg);
- update = true;
- } else if (isChief) {
- ReUtil.PushNotify(currentKerb.Name, "No", NotificationImportance.High);
- AddKerbalDamage(currentKerb, "Psychology_Social_Harassed", socialDmg + 5);
- } else if (socialDmg > 50) {
- ReUtil.PushNotify(currentKerb.Name, "Bully", NotificationImportance.High);
- saveData.kerbals.Where(k => k.Name != currentKerb.Name).ToList().ForEach(k => AddKerbalDamage(k, "Psychology_Social_Harassed", 10));
- //} else if (isChief && saveData.kerbals.FindIndex(k => k.Name == guiData.Kerbal.NameKey) > saveData.kerbals.FindIndex(k => k.Name == ReUtil.GetKerbalsForAgency(ReUtil.PlayerReAgency()).FirstOrDefault()?.Name)) {
- // ReUtil.PushNotify(currentKerb.Name, "No", NotificationImportance.High);
- } else if (socialDmg > 25) {
- ReUtil.PushNotify(currentKerb.Name, "No", NotificationImportance.High);
- AddKerbalDamage(currentKerb, "Psychology_Social_Harassed", socialDmg + 5);
- } else {
- ReUtil.PushNotify(currentKerb.Name, "Yes", NotificationImportance.Low);
- update = true;
- }
- if (update) {
- ReAgency[] agencies = saveData.agencies.Where(a => a.Name != "KSC" && ReUtil.crewAgencies.ContainsKey(a.Name)).ToArray();
- string otherAgencyName = agencies[UnityEngine.Random.Range(0, agencies.Length - 1)].Name;
- //if (agencyKerbals.Count == 1)
- // saveData.kerbals.LastOrDefault(k => k.agencyName == otherAgencyName).agencyName = guiData.Agency.Name;
- if (currentKerb != null)
- currentKerb.agencyName = !isPlayer ? ReUtil.PlayerAgencyName() : otherAgencyName;
- // EmptyAgencyCheck();
- guiData.Kerbal = null; // ReUtil.GetKerbalForAgency(guiData.Agency)
- }
- }
- }
- private void KerbalDamageCheckIn() {
- List<KerbalInfo> kerbis = Game.SessionManager.KerbalRosterManager.GetAllKerbals();
- saveData.kerbals.RemoveAll(kd => kerbis.All(ki => ki.NameKey != kd.Name));
- //if (saveData.kerbals.Count < kerbis.Count)
- kerbis?.ForEach(k => SetupKerbalDamage(k));
- // EmptyAgencyCheck();
- }
- private void SetupKerbalDamage(KerbalInfo kerbi) {
- string[] vets = new string[] { "Valentina Kerman", "Jebediah Kerman", "Bill Kerman", "Bob Kerman" };
- KerbalDamage kerbd = saveData.kerbals.FirstOrDefault(k => k.Name == kerbi.NameKey);
- if (kerbd != null) {
- if (vets.Contains(kerbd.Name) && !kerbd.damage.ContainsKey("Psychology_Role_Veteran"))
- AddKerbalDamage(kerbd, "Psychology_Role_Veteran", -10, true);
- if (TryGetKerbalDamage(kerbd, "Medicine_Atrophy") == 0)
- AddKerbalDamage(kerbd, "Medicine_Atrophy", -10, true);
- return;
- }
- List<ReAgency> crewAgencies = saveData.agencies.Where(a => ReUtil.crewAgencies.ContainsKey(a.Name)).ToList();
- ReAgency agency = null;
- string key = ReUtil.crewAgencies.Any(p => p.Value.Contains(kerbi.NameKey)) ? ReUtil.crewAgencies.FirstOrDefault(p => p.Value.Contains(kerbi.NameKey)).Key : null;
- if (key != null)
- agency = saveData.agencies.FirstOrDefault(a => a.Name == key);
- //if (vets.Contains(kerbi.NameKey))
- // agency = saveData.agencies.FirstOrDefault(a => a.Name == "KSC");
- //else if (kerbi.NameKey == "Tim C. Kerman")
- // agency = saveData.agencies.FirstOrDefault(a => a.Name == "KSC");
- if (agency == null && ReUtil.GetKerbalsForAgency(ReUtil.PlayerReAgency())?.Count == 0)
- agency = ReUtil.PlayerReAgency();
- if (agency == null)
- agency = crewAgencies.Where(a => a.Name != "KSC").LastOrDefault(a => saveData.kerbals.All(k => k.agencyName != a.Name));
- if (agency == null) {
- UnityEngine.Random.InitState(kerbi.NameKey.GetHashCode());
- agency = crewAgencies.Where(a => a.Name != "KSC").ElementAt(UnityEngine.Random.Range(0, crewAgencies.Count - 1));
- }
- kerbd = new KerbalDamage(kerbi.NameKey, ReUtil.RandomTrait(), agency.Name) { status = "KSC>READY", celName = "Kerbin" };
- if (vets.Contains(kerbi.NameKey))
- AddKerbalDamage(kerbd, "Psychology_Role_Veteran", -10, true);
- AddKerbalDamage(kerbd, "Medicine_Atrophy", -10, true);
- saveData.kerbals.Add(kerbd);
- if (!showApp && ReUtil.IsPlayerAgency(agency) && ReUtil.GetKerbalsForAgency(agency)?.Count == 1)
- ToggleApp();
- }
- //private static void EmptyAgencyCheck() {
- // if (saveData.kerbals.Count == 0) return;
- // for (int i = 0; i < (saveData.agencies.Count - saveData.kerbals.Select(k => k.agencyName).Distinct().Count()); i++) {
- // string fullAgName = saveData.agencies.LastOrDefault(a => saveData.kerbals.Count(k => k.agencyName == a.Name) > 1).Name;
- // string emptyAgName = saveData.agencies.FirstOrDefault(a => saveData.kerbals.Count(k => k.agencyName == a.Name) == 0).Name;
- // saveData.kerbals.LastOrDefault(k => k.agencyName == fullAgName).agencyName = emptyAgName;
- // }
- //}
- private void UpdateKerbalStatus(double fixedDeltaT) {
- foreach (KerbalDamage kerbd in saveData.kerbals) {
- if (kerbd.damage.Keys.All(k => !k.StartsWith("Psychology_Role_Kerbonaut"))) {
- if (kerbd.Name == saveData.kerbals.Where(k => k.agencyName == kerbd.agencyName)?.FirstOrDefault()?.Name) {
- AddKerbalDamage(kerbd, "Psychology_Role_Kerbonaut_Chief", -10, true);
- } else AddKerbalDamage(kerbd, "Psychology_Role_Kerbonaut_Grad", -5, true);
- }
- Game.SessionManager.KerbalRosterManager.TryGetKerbalByName(kerbd.Name, out KerbalInfo kerbi);
- if (kerbi == null) continue;
- if (kerbi.Location.SimObjectId.Guid == Game.SessionManager.KerbalRosterManager.KSCGuid.Guid) {
- if (!kerbd.status.StartsWith("KSC>"))
- kerbd.status = "KSC>STANDBY";
- kerbd.celName = "Kerbin";
- if (kerbd.damage.ContainsKey("Psychology_Role_WingsPending")) {
- kerbd.damage.Remove("Psychology_Role_WingsPending");
- AddKerbalDamage(kerbd, "Psychology_Role_Wings", -10, true);
- ReUtil.PushNotify(kerbd.Name, "Wings", NotificationImportance.Low, false);
- }
- continue;
- }
- SimulationObjectModel simObj = Game.ViewController.Universe.FindSimObject(kerbi.Location.SimObjectId);
- kerbd.celName = simObj?.Part?.PartCelestialBody?.Name;
- if (repairers.Any(r => r.Name == kerbd.Name))
- kerbd.status = "EVA>REPAIRS";
- else {
- string partName = simObj?.Part?.PartName;
- if (partName == null || ReUtil.partKerbStats.All(s => !s.Value.Contains(partName ?? "-")))
- kerbd.status = "UNKNOWN";
- else {
- kerbd.status = $"{(partName == "eva_kerbal" ? "EVA" : simObj?.Part?.PartOwner?.SimulationObject?.Vessel?.DisplayName)}>";
- //kerbd.status += simObj?.Part?.PartOwner?.SimulationObject?.Vessel?.SimulationObject?.Telemetry.CommNetConnectionStatus == ConnectionNodeStatus.Connected ||
- // partName == "eva_kerbal" ? ReUtil.partKerbStats.FirstOrDefault(s => s.Value.Contains(partName)).Key : "COMMS BLACKOUT";
- kerbd.status += ReUtil.partKerbStats.FirstOrDefault(s => s.Value.Contains(partName)).Key;
- }
- }
- if (kerbd.status.Contains("PILOT")) {
- PartComponentModule_Command moduleCmd = null;
- Data_Command dataCmd = null;
- simObj?.Part?.TryGetModule(out moduleCmd);
- if (moduleCmd == null) continue;
- moduleCmd?.DataModules.TryGetByType(out dataCmd);
- if (dataCmd == null) continue;
- if (!dataCmd.isCommandEnabled.GetValue() || simObj?.Part?.PartOwner?.SimulationObject?.Vessel?.GetControlOwner()?.Guid != simObj?.Part?.Guid)
- kerbd.status = kerbd.status.Replace("PILOT", "PASSENGER");
- else if (dataCmd.IsHibernating)
- kerbd.status = kerbd.status.Replace("PILOT", "STANDBY PILOT");
- else {
- List<int> occSeats = Game.SessionManager.KerbalRosterManager.GetAllKerbalsInSimObject(kerbi.Location.SimObjectId).Select(k => k.Location.PositionIndex).ToList();
- if (occSeats.Count == 1 || kerbi.Location.PositionIndex == occSeats.Min())
- kerbd.status = kerbd.status.Replace("PILOT", "CAPTAIN");
- else kerbd.status = kerbd.status.Replace("PILOT", "CO-PILOT");
- }
- }
- //double geeForce = simObj?.Part?.PartOwner?.SimulationObject?.Vessel?.geeForce ?? 0;
- //if (kerbd.status == "EXERCISE" && TryGetKerbalDamage(kerbd, "Medicine_Atrophy") < (1 - Mathf.Clamp01((float)geeForce)) * 25)
- // AddKerbalDamage(kerbd, "Medicine_Atrophy", (fixedDeltaT / 21600) * (0.25 - geeForce));
- }
- }
- private void InitOrUpdateSave() {
- Version.TryParse(saveData.modVersion ?? VERSION, out Version version);
- if (saveData.modVersion != null && version?.Minor == 24 && version?.Build <= 13) {
- ReAgency player = ReUtil.PlayerReAgency();
- Dictionary<string, string> fixSciType = new Dictionary<string, string>() {
- ["Engineering_Wheel"] = "Electrical_Wheel", ["Flight_SOI"] = "Control_SOI",
- ["Command_CrewObservation"] = "Psychology_CrewObservation"
- };
- foreach (var pair in fixSciType.Where(p => player?.rocketScience?.ContainsKey(p.Key) ?? false)) {
- if (player.rocketScience.ContainsKey(pair.Value))
- player.rocketScience[pair.Value] += player.rocketScience[pair.Key];
- else player.rocketScience[pair.Value] = player.rocketScience[pair.Key];
- player.rocketScience.Remove(pair.Key);
- }
- saveData.modVersion = VERSION;
- }
- if (saveData.modVersion != null && version?.Minor == 24 && version?.Build >= 16) {
- ReAgency player = ReUtil.PlayerReAgency();
- Dictionary<string, string> fixSciType = new Dictionary<string, string>() {
- ["Electrical Wheel"] = "Electrical_Wheel", ["ScienceData_AtmosphereSurvey"] = "Aeronautics_Data",
- ["ScienceSample_AtmosphereSurvey"] = "Aeronautics_Sample"
- };
- foreach (var pair in fixSciType.Where(p => player?.rocketScience?.ContainsKey(p.Key) ?? false)) {
- if (player.rocketScience.ContainsKey(pair.Value))
- player.rocketScience[pair.Value] += player.rocketScience[pair.Key];
- else player.rocketScience[pair.Value] = player.rocketScience[pair.Key];
- player.rocketScience.Remove(pair.Key);
- }
- saveData.modVersion = VERSION;
- return;
- }
- saveData.modVersion = VERSION;
- saveData.lastDailyUpdateUT = Math.Round(Game.UniverseModel.UniverseTime);
- ReAgency playerAgency = new ReAgency(Game.AgencyManager.FindAgencyEntryFirst().AgencyName);
- List<ReAgency> agencies = (ReUtil.IsGameSandbox() ? ReUtil.crewAgencies.Keys : ReUtil.crewAgencies.Keys.Take(3)).Select(a => new ReAgency(a)).ToList();
- if (!ReUtil.IsGameSandbox()) {
- agencies.Add(new ReAgency("ReactionSystems"));
- agencies.Add(new ReAgency("Lightyear"));
- }
- if (saveData.agencies == null) {
- if (!ReUtil.IsGameSandbox()) {
- playerAgency.rocketScience = new Dictionary<string, int>() { ["Engineering_Assembly"] = 0 };
- ReUtil.PushNotify($"Missions/MissionGranter/Name/ReactionSystems", "NewAgency", NotificationImportance.Low, false);
- ReUtil.PushNotify($"Missions/MissionGranter/Name/Lightyear", "NewAgency", NotificationImportance.Low, false);
- }
- saveData.agencies = new List<ReAgency>() { playerAgency };
- } else {
- ReAgency oldPlayerAgency = saveData.agencies.FirstOrDefault(a => a.rocketScience.Count != 0);
- playerAgency.rocketScience = oldPlayerAgency.rocketScience;
- saveData.agencies.Remove(oldPlayerAgency);
- saveData.agencies.RemoveAll(a => a.partRecords.Count == 0);
- saveData.agencies.Add(playerAgency);
- agencies.RemoveAll(a => saveData.agencies.Any(sa => sa.Name == a.Name));
- }
- saveData.agencies.AddRange(agencies);
- if (saveData.kerbals == null)
- saveData.kerbals = new List<KerbalDamage>();
- // if (saveData.pals == null) saveData.pals = new Dictionary<string, double>();
- }
- internal static void AddKerbalDamage(string name, string type, double amount) {
- KerbalDamage kerb = saveData.kerbals.FirstOrDefault(k => k.Name == name);
- if (kerb == null) return;
- AddKerbalDamage(kerb, type, amount);
- }
- internal static void AddKerbalDamage(KerbalDamage kerb, string type, double amount, bool set = false) {
- if (kerb == null) return;
- amount *= KerbalDamageModifier(kerb, type) * 2;
- if (kerb.damage.ContainsKey(type) && !set)
- kerb.damage[type] += amount;
- else kerb.damage[type] = amount;
- if (kerb.damage.Values.Sum() > 100) {
- Game.SessionManager.KerbalRosterManager.TryGetKerbalByName(kerb.Name, out KerbalInfo kerbal);
- if (kerbal == null) return;
- Game.SessionManager.KerbalRosterManager.DestroyKerbal(kerbal.Id);
- return;
- }
- if (set || amount > 0 || !new string[] { "Medicine_Impacts", "Medicine_Atrophy", "Psychology_Therapy" }.Contains(type)) return;
- KerbalLifeRewards(type, kerb.damage[type] - amount, kerb.damage[type]);
- }
- internal static void KerbalLifeRewards(string type, double prevDmg = 0, double newDmg = 0, bool force = false) {
- bool check = false;
- if (!force)
- for (int i = -10; i < 10; i++)
- if (prevDmg > i * 10 && newDmg < i * 10) {
- check = true; break;
- }
- if (!check && !force) return;
- float diffScale;
- if (!Game.SessionManager.TryGetDifficultyOptionState("ScienceRewards", out diffScale)) diffScale = 1f;
- int sciGain = Math.Max(2, (int)Math.Round((ReUtil.GetSciBonus(type) + 1) * diffScale * (force ? 2 : 1)));
- ReUtil.AddScience(sciGain);
- AddRocketScience(type, sciGain);
- }
- internal static bool HasKerbalDamage(KerbalDamage kerb, string type) => TryGetKerbalDamage(kerb, type) != 0;
- internal static double TryGetKerbalDamage(KerbalDamage kerb, string type) {
- if (kerb.damage.All(p => !p.Key.StartsWith(type))) return 0;
- return kerb.damage.Where(p => p.Key.StartsWith(type)).Sum(p => p.Value);
- }
- internal static float KerbalDamageModifier(KerbalDamage kerb, string type) {
- UnityEngine.Random.InitState((kerb.Name + kerb.Trait + type).GetHashCode());
- return UnityEngine.Random.value;
- }
- internal static void AddPartRecord(string partName, double amount) {
- if (ReUtil.IsGameSandbox()) return;
- string mfKey = ReUtil.GetPartMfrKey(partName);
- if (mfKey == null || mfKey == "") return;
- ReAgency mfAgency = saveData.agencies?.FirstOrDefault(a => a.Name == mfKey);
- if (mfAgency == null) {
- mfAgency = new ReAgency(mfKey);
- saveData.agencies.Add(mfAgency);
- ReUtil.PushNotify($"Missions/MissionGranter/Name/{mfKey}", "NewAgency", NotificationImportance.Low, false);
- }
- if (mfAgency.partRecords == null)
- mfAgency.partRecords = new Dictionary<string, double>();
- if (!mfAgency.partRecords.ContainsKey(partName)) {
- mfAgency.partRecords[partName] = amount;
- ReUtil.PushNotify($"Missions/MissionGranter/Name/{mfKey}", "NewPartGrade", NotificationImportance.Low, false, LocalizationManager.GetTranslation($"Parts/Title/{partName}"));
- } else mfAgency.partRecords[partName] += amount;
- }
- internal static void AddRocketScience(string sciType, int amount) {
- if (ReUtil.IsGameSandbox()) return;
- ReAgency playerAgency = ReUtil.PlayerReAgency();
- if (playerAgency == null) return;
- if (playerAgency.rocketScience.ContainsKey(sciType))
- playerAgency.rocketScience[sciType] += amount;
- else playerAgency.rocketScience[sciType] = amount;
- }
- internal static double TryGetPartRecord(string partName, bool asPct = false) {
- double record = 0;
- if (saveData.agencies?.Any(a => a.partRecords.ContainsKey(partName)) ?? false)
- record = saveData.agencies.FirstOrDefault(a => a.partRecords.ContainsKey(partName)).partRecords[partName];
- if (asPct && record > 0) record = Math.Min(Math.Sqrt(record / 10) / 10, 1);
- return record;
- }
- public class GUIData {
- public int SciIndex, AgencyIndex, ModeIndex, CrewIndex;
- public KerbalInfo Kerbal;
- public ReAgency Agency;
- public string WindowTitle { get; private set; }
- public string AppTitle { get; private set; }
- public string ModeBtn { get; private set; }
- public string MinBtn { get; private set; }
- public string MaxBtn { get; private set; }
- public string CloseBtn { get; private set; }
- public string NavLBtn { get; private set; }
- public string NavRBtn { get; private set; }
- public string OkBtn { get; private set; }
- public Texture2D Icon { get; private set; }
- public Texture2D Dots { get; private set; }
- public string Name { get; private set; }
- public string Surname { get; private set; }
- public string Training { get; private set; }
- public string Discovery { get; private set; }
- public string InspectHint { get; private set; }
- public string PALMiniHint { get; private set; }
- public string PartTitle { get; private set; }
- public string Subtitle { get; private set; }
- public string Damage { get; private set; }
- public string RepairHint { get; private set; }
- public string CommNetReq { get; private set; }
- public string RepairStatus { get; private set; }
- public string RepairTitle { get; private set; }
- public List<string> Repairers { get; private set; }
- public string Inspecting { get; private set; }
- public Texture2D Wireframe { get; private set; }
- public string Impacts { get; private set; }
- public string Temperature { get; private set; }
- public string GeeForces { get; private set; }
- public string AngularVel { get; private set; }
- public string Instability { get; private set; }
- public string Ullage { get; private set; }
- public string Boiloff { get; private set; }
- public string Age { get; private set; }
- public string SerialTitle { get; private set; }
- public string SerialDesc { get; private set; }
- public string CategoryTitle { get; private set; }
- public string CategoryDesc { get; private set; }
- public string VesselsNearby { get; private set; }
- public List<VesselComponent> VesselsList { get; private set; }
- public List<VesselComponent> EVAsList { get; private set; }
- public string Current { get; private set; }
- public string Connected { get; private set; }
- public string Contact { get; private set; }
- public string KerbalsOnEVA { get; private set; }
- // public List<Tuple<string, string>> EVAsList { get; private set; }
- public string Repairing { get; private set; }
- public string Idle { get; private set; }
- public float DiscoveryValue { get; private set; }
- public string Level { get; private set; }
- public string SciTitle { get; private set; }
- public int SciLvl { get; private set; }
- public float SciLvlProgress { get; private set; }
- public List<Tuple<string, float>> SciSubtypes { get; private set; }
- public GUIData() {
- Repairers = new List<string>();
- VesselsList = new List<VesselComponent>();
- EVAsList = new List<VesselComponent>();
- // EVAsList = new List<Tuple<string, string>>();
- UpdateWindowTitle();
- AppTitle = $"<color=#0D0D0D><size=13> {LocalizationManager.GetTranslation("KerbalLife/Title").ToUpper()} --------------------/ </size></color>";
- ModeBtn = "<color=#D6E0FF>>¤<</color>";
- MinBtn = "<color=#D6E0FF>-</color>";
- MaxBtn = "<color=#D6E0FF>□</color>";
- CloseBtn = "<color=#D6E0FF>x</color>";
- NavLBtn = "<color=#D6E0FF><</color>";
- NavRBtn = "<color=#D6E0FF>></color>";
- OkBtn = LocalizationManager.GetTranslation("Application/OK");
- Icon = AssetManager.GetAsset<Texture2D>($"KSRe/images/icon.png");
- Dots = AssetManager.GetAsset<Texture2D>($"KSRe/images/dots.png");
- Name = $"<color=#0D0D0D>{LocalizationManager.GetTranslation("Menu/SaveLoad/Name")}:</color> ";
- Surname = $"<color=#0D0D0D>{LocalizationManager.GetTranslation("Career/Surname")}</color> ";
- Training = $"<color=#0D0D0D><size=13>{LocalizationManager.GetTranslation("Career/Training").ToUpper()}:</size></color> ";
- Discovery = $"<color=#0D0D0D><size=13>{LocalizationManager.GetTranslation("Career/Discovery").ToUpper()}:</size></color> ";
- InspectHint = $"<color=yellow>{LocalizationManager.GetTranslation("Diagnostic/InspectHint")}</color>";
- PALMiniHint = $"<color=yellow>{LocalizationManager.GetTranslation("Diagnostic/PALMiniHint", new object[1] { repairKeyCode.Value.Description() })}</color>";
- RepairStatus = $"<color=#D6E0FF>- {LocalizationManager.GetTranslation("PartModules/Damage/Repairing")} -</color>";
- RepairHint = $"<color=yellow>{LocalizationManager.GetTranslation("Diagnostic/RepairHint", new object[1] { repairKeyCode.Value.Description() })}</color>";
- CommNetReq = $"<color=#D45455>{LocalizationManager.GetTranslation("Diagnostic/CommNetRequired")}</color>";
- Inspecting = LocalizationManager.GetTranslation("PartModules/Damage/Inspecting");
- SerialTitle = $"{LocalizationManager.GetTranslation("PartModules/Damage/Serial", new object[1] { "" })} ";
- CategoryTitle = $"{LocalizationManager.GetTranslation("VAB/PartsPicker/type")}: ";
- VesselsNearby = $"<color=#D6E0FF>- {LocalizationManager.GetTranslation("Diagnostic/VesselsNearby")} -</color>";
- Current = LocalizationManager.GetTranslation("Diagnostic/Current");
- Connected = LocalizationManager.GetTranslation("Diagnostic/Connected");
- Contact = $"<color=#D6E0FF>{LocalizationManager.GetTranslation("Diagnostic/Contact")}</color>";
- KerbalsOnEVA = $"<color=#D6E0FF>- {LocalizationManager.GetTranslation("Diagnostic/KerbalsOnEVA")} -</color>";
- Repairing = LocalizationManager.GetTranslation("PartModules/Damage/Repairing");
- Idle = LocalizationManager.GetTranslation("Diagnostic/Idle");
- }
- public void Reset() {
- Agency = null;
- Kerbal = null;
- ModeIndex = 0;
- AgencyIndex = 0;
- }
- public void UpdateWindowTitle(bool hasPAL = false) => WindowTitle = $"<color=#D6E0FF><size=13> {LocalizationManager.GetTranslation(hasPAL ? "Diagnostic/PAL5000" : "Diagnostic/Title").ToUpper()} --------------------/ </size></color>";
- public void UpdateEVAPart() {
- bool isKerbal = UIPart.PartName == "eva_kerbal";
- PartTitle = $"<b>{(isKerbal ? Game.SessionManager.KerbalRosterManager.GetAllKerbalsInSimObject(UIPart.SimulationObject.GlobalId).First().NameKey : LocalizationManager.GetTranslation($"Parts/Title/{UIPart.PartName}"))}</b>";
- Subtitle = $"<color=#5B5FDB>#</color> <color=#C6CEDC><size=13>{LocalizationManager.GetTranslation($"Parts/Subtitle/{UIPart.PartName}").ToUpper()}</size></color>";
- Inspecting = LocalizationManager.GetTranslation(isKerbal ? "KerbalLife/CheckIn" : "PartModules/Damage/Inspecting");
- RepairHint = $"<color=yellow>{LocalizationManager.GetTranslation(isKerbal ? "KerbalLife/ChatHint" : "Diagnostic/RepairHint", new object[1] { repairKeyCode.Value.Description() })}</color>";
- Repairing = LocalizationManager.GetTranslation(isKerbal ? "KerbalLife/Chatting" : "PartModules/Damage/Repairing");
- if (!isKerbal) return;
- UIPartDmg = 100 - saveData.kerbals.FirstOrDefault(k => k.Name == UIPart.PartOwner.SimulationObject.Vessel.DisplayName)?.damage.Values.Sum() ?? 0;
- }
- public void UpdateEVADamage() =>
- Damage = $"{LocalizationManager.GetTranslation("PartModules/Damage/Name")}: {(UIPart.PartName == "eva_kerbal" ? ReUtilKerb.GetPsychologyStr((float)UIPartDmg * 0.01f) : ReUtil.GetDamageStr(UIPartDmg))}"; // <color=#b4d455>Happy :)</color>
- public void UpdateEVARepairers() => Repairers = repairers.Where(r => r.TargetGuid == UIPart.Guid).Select(r => r.Name).ToList();
- public void UpdateForPAL() {
- bool isKerbal = UIPart.PartName == "eva_kerbal";
- Wireframe = AssetManager.GetAsset<Texture2D>($"KSRe/images/wf_{(isKerbal ? "eva" : UIPart.PartData.category + "")}.png");
- Impacts = $"{LocalizationManager.GetTranslation("Diagnostic/Impacts")}: " +
- (UIPartImpacts.Item1 != UIPartImpacts.Item2 ? $"{ReUtil.GetColorForRange(UIPart.CrashTolerance * 0.667, UIPart.CrashTolerance, UIPartImpacts.Item1)}{UIPartImpacts.Item1:N1}</color>-" : "") +
- $"{ReUtil.GetColorForRange(UIPart.CrashTolerance * 0.667, UIPart.CrashTolerance, UIPartImpacts.Item2)}{UIPartImpacts.Item2:N1}</color> {LocalizationManager.GetTranslation("Unit/Symbol/MetersPerSecond")}";
- Temperature = $"{LocalizationManager.GetTranslation("Diagnostic/Temperature")}: {ReUtil.GetColorForRange(UIPart.MaxTemp * 0.6, UIPart.MaxTemp * 0.8, UIPart.Temperature)}{UIPart.Temperature:N0}{LocalizationManager.GetTranslation("Unit/Symbol/Kelvin")}</color>";
- double gees = UIPart.PartOwner.SimulationObject.Vessel.geeForce;
- GeeForces = $"{LocalizationManager.GetTranslation("Diagnostic/GeeForces")}: {ReUtil.GetColorForRange(UIPart.CrashTolerance, UIPart.CrashTolerance * 1.25, gees)}{gees:N2}</color>";
- double rot = UIPart.PartOwner.SimulationObject.Vessel.AngularVelocity.relativeAngularVelocity.magnitude;
- AngularVel = $"{LocalizationManager.GetTranslation("Diagnostic/Rotation")}: <color=#{(rot < 0.015 ? "b4d4" : "d4a4")}55>{rot:N3}</color>";
- Instability = $"{LocalizationManager.GetTranslation("Diagnostic/Instability")}: {ReUtil.GetColorForRange(0, 1, UIEngInstability)}{UIEngInstability:P0}</color>";
- Ullage = $"{LocalizationManager.GetTranslation("Diagnostic/Ullage")}: {ReUtil.GetUllageStr(UIPart.PartOwner.SimulationObject.Vessel.geeForce)}";
- bool isBoiling = "0040-Methalox|0050-Methane|0060-Monopropellant|0065-Nose Cone".Contains(UIPart.PartData.family) && UIPart.PartResourceContainer.GetResourceStoredMass(fuelList.Last()) > 0;
- Boiloff = $"{LocalizationManager.GetTranslation("Diagnostic/Boiloff")}: {ReUtil.GetColorForRange(50, 650, isBoiling ? UIPart.Temperature : 0)}{(isBoiling ? Math.Max(0, UIPart.ThermalData.Temperature - 50) / 300 : 0):N1}% / {LocalizationManager.GetTranslation("Units/Symbol/Days")}</color>";
- }
- public void UpdateForVessel(bool hasPAL) {
- Age = $"{LocalizationManager.GetTranslation("Diagnostic/Age")}: {ReUtil.GetColorForRange(0, 118000000, UIPart.PartOwner.SimulationObject.Vessel.TimeSinceLaunch) + Units.FormatTimeString(UIPart.PartOwner.SimulationObject.Vessel.TimeSinceLaunch)}</color>";
- if (hasPAL) UpdateForPAL();
- }
- public void UpdateVesselPart(bool hasPAL) {
- bool isKerbal = UIPart.PartName == "eva_kerbal";
- SerialTitle = $"{LocalizationManager.GetTranslation("PartModules/Damage/Serial", new object[1] { "" })} "; // isKerbal ? LocalizationManager.GetTranslation("VAB/SaveAndLoad/Name") :
- SerialDesc = UIPart.Guid.Substring(24); // isKerbal ? UIPart.PartOwner.SimulationObject.Vessel.DisplayName :
- CategoryDesc = LocalizationManager.GetTranslation(isKerbal ? "Diagnostic/EVASuit" : $"PartsManager/{UIPart.PartData.category}");
- UIPartImpacts = Tuple.Create(0f, 0f);
- UIEngInstability = 0.0;
- UpdateForVessel(hasPAL);
- }
- public void UpdateListMode() {
- VesselsList = Game.ViewController.VesselsInRange.Where(v => !v.IsKerbalEVA).ToList();
- EVAsList = Game.ViewController.VesselsInRange.Where(v => v.IsKerbalEVA).ToList();
- //EVAsList = Game.ViewController.VesselsInRange.Where(v => v.IsKerbalEVA).Select(v => Tuple.Create(v.DisplayName,
- // repairers.Any(r => r.Guid == v.Guid) ? Repairing : Idle)).ToList();
- }
- public void UpdateDiscovery() {
- List<TechNodeData> techNodes = new List<TechNodeData>();
- if (Game.ScienceManager?.TechNodeDataStore?.TryGetTechNodeDataCollection(out IReadOnlyCollection<TechNodeData> tNodes) ?? false)
- techNodes = tNodes?.ToList();
- if (techNodes.Count == 0) { DiscoveryValue = 0f; return; }
- List<int> costs = techNodes.Select(t => t.RequiredSciencePoints).Distinct().ToList();
- for (int i = 0; i < costs.Count; i++) {
- UnityEngine.Random.InitState((Game.SessionGuidString + costs[i]).GetHashCode());
- costs[i] = (int)Math.Round(costs[i] * (1.5 + UnityEngine.Random.value));
- }
- int sci = ReUtil.GetTotalScience();
- int prev = costs.TakeWhile(c => c < sci).LastOrDefault();
- int next = Math.Max(techNodes.Select(t => t.RequiredSciencePoints * 2).Distinct().SkipWhile(c => c <= sci).FirstOrDefault(), 10);
- DiscoveryValue = Mathf.Clamp01((float)(sci - prev) / (next - prev));
- }
- public void UpdateSciLevel() {
- ReAgency player = ReUtil.PlayerReAgency();
- string sciName = ReUtil.PlayerReAgency().rocketScience.Select(s => s.Key.Split('_')[0]).Distinct().ElementAt(SciIndex);
- SciTitle = $"<color=#0D0D0D><size=19>{LocalizationManager.GetTranslation($"Career/{sciName}/Title").ToUpper()}</size></color>";
- int sci = player.rocketScience.Where(s => s.Key.StartsWith(sciName)).Select(s => s.Value).Sum();
- SciLvl = Mathf.Clamp(ReUtil.sciLvls.Keys.TakeWhile(l => l <= sci).Count() - 1, 0, ReUtil.sciLvls.Count - 3);
- int prev = ReUtil.sciLvls.Keys.ElementAt(SciLvl);
- int next = SciLvl == ReUtil.sciLvls.Count - 3 ? 0 : ReUtil.sciLvls.Keys.ElementAt(SciLvl + 1); //ReUtil.sciLvlBonuses.Keys.Skip(SciLvl + 1).FirstOrDefault()
- SciLvlProgress = Mathf.Clamp01((float)(sci - prev) / (next - prev));
- if (ReUtil.PlayerTrait() == sciName) SciLvl += 2;
- // Level = $"<color=#0D0D0D>{LocalizationManager.GetTranslation("Career/Level")}: {SciLvl} (+{ReUtil.sciLvls.ElementAt(SciLvl).Value:P0})</color>";
- Level = $"<color=#0D0D0D>[ +{ReUtil.sciLvls.ElementAt(SciLvl).Value:P0} ] <size=14>{LocalizationManager.GetTranslation("Career/Level").ToUpper()}:</size></color>";
- //List<int> subLvls = ReUtil.sciLvlBonuses.Keys.Take(ReUtil.sciLvlBonuses.Count - 2).ToList();
- //List<int> halfLvls = subLvls.Skip(1).Select(i => i / 2).ToList();
- //subLvls.AddRange(halfLvls);
- //subLvls = subLvls.Distinct().ToList();
- //subLvls.Sort();
- SciSubtypes = new List<Tuple<string, float>>();
- foreach (var pair in player.rocketScience.Where(s => s.Key.StartsWith(sciName))) {
- int subLvl = Mathf.Clamp(ReUtil.sciLvls.Keys.TakeWhile(l => l <= pair.Value).Count() - 1, 0, ReUtil.sciLvls.Keys.Count - 3);
- int prevSub = ReUtil.sciLvls.Keys.ElementAt(subLvl);
- int nextSub = subLvl == ReUtil.sciLvls.Keys.Count - 3 ? 0 : ReUtil.sciLvls.Keys.ElementAt(subLvl + 1);
- SciSubtypes.Add(Tuple.Create($"<color=#0D0D0D><size=13>:: {LocalizationManager.GetTranslation(ReUtil.GetSciLocKey(pair.Key))}</size></color>", // {subLvl}
- subLvl + Mathf.Clamp01((float)(pair.Value - prevSub) / (nextSub - prevSub))));
- }
- }
- }
- public class ReSaveData {
- public string modVersion;
- public double lastDailyUpdateUT;
- public List<ReAgency> agencies;
- public List<KerbalDamage> kerbals;
- // public Dictionary<string, double> pals;
- // public Dictionary<string, double> partRecords;
- }
- public class KerbalOverseer {
- public List<KerbalDamage> Manifest { get; private set; }
- public KerbalOverseer() {
- Manifest = new List<KerbalDamage>();
- //Game.Messages.PersistentSubscribe<KerbalAddedToRoster>(AddedKerbal);
- //Game.Messages.PersistentSubscribe<KerbalRemovedFromRoster>(RemovedKerbal);
- //Game.Messages.PersistentSubscribe<KerbalLocationChanged>(MovedKerbal);
- }
- }
- public class KerbalSaveData {
- public string Name { get; private set; }
- public string Trait { get; private set; }
- public string agency;
- public Dictionary<string, double> damage;
- public KerbalSaveData(string name, string trait, string agency) {
- Name = name;
- Trait = trait;
- this.agency = agency;
- damage = new Dictionary<string, double>();
- }
- }
- public class ReAgencyData {
- public string Name { get; private set; }
- public Dictionary<string, int> rocketScience;
- public Dictionary<string, double> partRecords;
- public ReAgencyData(string name) {
- Name = name;
- rocketScience = new Dictionary<string, int>();
- partRecords = new Dictionary<string, double>();
- }
- }
- }
- }
Add Comment
Please, Sign In to add comment