public void Load(ConfigNode node) { ProceduralAvionicsUtils.Log("Loading Config nodes"); ConfigNode.LoadObjectFromConfig(this, node); techNodes = new Dictionary <string, ProceduralAvionicsTechNode>(); if (name == null) { name = node.GetValue("name"); } if (node.HasNode("TECHLIMIT")) { foreach (ConfigNode tNode in node.GetNodes("TECHLIMIT")) { ProceduralAvionicsTechNode techNode = new ProceduralAvionicsTechNode(); techNode.Load(tNode); techNodes.Add(techNode.name, techNode); ProceduralAvionicsUtils.Log("Loaded TechNode: " + techNode.name); } List <ProceduralAvionicsTechNode> techNodeList = techNodes.Values.ToList(); techNodesSerialized = ObjectSerializer.Serialize(techNodeList); ProceduralAvionicsUtils.Log("Serialized TechNodes"); } else { ProceduralAvionicsUtils.Log("No technodes found for " + name); } }
private string ConstructTooltipForAvionicsTL(ProceduralAvionicsTechNode techNode) { var sb = StringBuilderCache.Acquire(); if (techNode.IsScienceCore) { sb.AppendLine($"Mass: {GetAvionicsMass(techNode, 0) * 1000:0.#}kg"); sb.AppendLine($"Power consumption: {GetEnabledkW(techNode, 0) * 1000:0.#}W"); } else { float calcMass = _newControlMass; if (calcMass <= 0) { calcMass = techNode.interplanetary ? 0.5f : 100f; } sb.AppendLine($"At {calcMass:0.##}t controllable mass:"); sb.AppendLine($" Mass: {GetAvionicsMass(techNode, calcMass) * 1000:0.#}kg"); sb.AppendLine($" Power consumption: {GetEnabledkW(techNode, calcMass) * 1000:0.#}W"); } sb.AppendLine($"Axial control: {BoolToYesNoString(techNode.allowAxial)}"); sb.AppendLine($"Can hibernate: {BoolToYesNoString(techNode.disabledPowerFactor > 0)}"); sb.Append($"Sample container: {BoolToYesNoString(techNode.hasScienceContainer)}"); return(sb.ToStringAndRelease()); }
internal static void SetUnlockedTechState(string param) { ProceduralAvionicsUtils.Log("Setting unlocked tech state"); unlockedTech = new Dictionary <string, string>(); if (param != null) { string[] typeStrings = param.Split('|'); if (typeStrings.Length > 1) { for (int i = 0; i < typeStrings.Length; i += 2) { unlockedTech.Add(typeStrings[i], typeStrings[i + 1]); } } } ProceduralAvionicsUtils.Log("unlocked tech has ", unlockedTech.Keys.Count.ToString(), " nodes"); //At this point, we can go through our configs and see if we have any that need to be unlocked foreach (ProceduralAvionicsConfig config in allTechNodes) { if (!unlockedTech.ContainsKey(config.name)) { //We don't have max level for this config, should we? ProceduralAvionicsTechNode freeTech = config.TechNodes.Values.Where(techNode => techNode.unlockCost == 0).FirstOrDefault(); if (freeTech != null) { unlockedTech.Add(config.name, freeTech.name); } } } }
private static string BuildTonnageString(ProceduralAvionicsTechNode techNode) { StringBuilder sbuilder = StringBuilderCache.Acquire(); if (techNode.minimumTonnage != 0) { sbuilder.Append(String.Format("{0:N}", techNode.minimumTonnage)); if (techNode.maximumTonnage != float.MaxValue) { sbuilder.Append("-"); } else { sbuilder.Append("+"); } } if (techNode.maximumTonnage != float.MaxValue) { sbuilder.Append(String.Format("{0:N}", techNode.maximumTonnage)); } if (sbuilder.Length == 0) { return("Unlimited"); } else { sbuilder.Append("T"); } return(sbuilder.ToStringAndRelease()); }
private string BuildTechName(ProceduralAvionicsTechNode techNode) { var sbuilder = StringBuilderCache.Acquire(); sbuilder.Append(techNode.name); sbuilder.Append(BuildSasAndScienceString(techNode)); return(sbuilder.ToStringAndRelease()); }
private string GetTooltipTextForTechNode(ProceduralAvionicsTechNode techNode) { if (!_tooltipTexts.TryGetValue(techNode.name, out string tooltip)) { tooltip = ConstructTooltipForAvionicsTL(techNode); _tooltipTexts[techNode.name] = tooltip; } return(tooltip); }
private void DrawAvionicsConfigSelector(ProceduralAvionicsConfig curCfg, ProceduralAvionicsTechNode techNode) { bool switchedConfig = false; int unlockCost = ProceduralAvionicsTechManager.GetUnlockCost(curCfg.name, techNode); _gc ??= new GUIContent(); _gc.tooltip = GetTooltipTextForTechNode(techNode); bool isCurrent = techNode == CurrentProceduralAvionicsTechNode; if (isCurrent) { _gc.text = BuildTechName(techNode); GUILayout.BeginHorizontal(); GUILayout.Toggle(true, _gc, HighLogic.Skin.button); DrawUnlockButton(curCfg.name, techNode, unlockCost); GUILayout.EndHorizontal(); _gc.text = $"Sample container: {BoolToYesNoString(techNode.hasScienceContainer)}"; _gc.tooltip = "Whether samples can be transferred and stored in the avionics unit."; GUILayout.Label(_gc, HighLogic.Skin.label); _gc.text = $"Can hibernate: {BoolToYesNoString(techNode.disabledPowerFactor > 0)}"; _gc.tooltip = "Whether the avionics unit can enter hibernation mode that greatly reduces power consumption."; GUILayout.Label(_gc, HighLogic.Skin.label); _gc.text = $"Axial control: {BoolToYesNoString(techNode.allowAxial)}"; _gc.tooltip = "Whether fore-aft translation is allowed despite having insufficient controllable mass or being outside the max range of Near-Earth avionics."; GUILayout.Label(_gc, HighLogic.Skin.label); } else { _gc.text = $"Switch to {BuildTechName(techNode)}"; GUILayout.BeginHorizontal(); switchedConfig = GUILayout.Button(_gc, HighLogic.Skin.button); switchedConfig |= DrawUnlockButton(curCfg.name, techNode, unlockCost); GUILayout.EndHorizontal(); } if (switchedConfig) { Log("Configuration window changed, updating part window"); _shouldResetUIHeight = true; _showROTankSizeWarning = false; _showSizeWarning = false; SetupConfigNameFields(); avionicsTechLevel = techNode.name; CurrentProceduralAvionicsConfig = curCfg; avionicsConfigName = curCfg.name; AvionicsConfigChanged(); MonoUtilities.RefreshContextWindows(part); } }
internal static int GetUnlockCost(string avionicsConfigName, ProceduralAvionicsTechNode techNode) { if (HighLogic.CurrentGame.Mode != Game.Modes.CAREER) { return(0); } string ecmName = GetEcmName(avionicsConfigName, techNode); double cost = EntryCostManager.Instance.ConfigEntryCost(ecmName); return((int)cost); }
private static string BuildSasAndScienceString(ProceduralAvionicsTechNode techNode) { StringBuilder sbuilder = StringBuilderCache.Acquire(); sbuilder.Append(" {SAS: "); sbuilder.Append(techNode.SASServiceLevel); if (techNode.hasScienceContainer) { sbuilder.Append(", SC"); } sbuilder.Append("}"); return(sbuilder.ToString()); }
private string BuildTechName(ProceduralAvionicsTechNode techNode) { StringBuilder sbuilder = StringBuilderCache.Acquire(); sbuilder.Append(techNode.name); if (techNode.maximumTonnage != float.MaxValue || techNode.minimumTonnage != 0) { sbuilder.Append(" ["); sbuilder.Append(BuildTonnageString(techNode)); sbuilder.Append("]"); } sbuilder.Append(BuildSasAndScienceString(techNode)); return(sbuilder.ToStringAndRelease()); }
private static bool PurchaseConfig(string curCfgName, ProceduralAvionicsTechNode techNode) { bool success = false; if (!HighLogic.CurrentGame.Parameters.Difficulty.BypassEntryPurchaseAfterResearch) { success = ProceduralAvionicsTechManager.PurchaseConfig(curCfgName, techNode); } if (success) { ProceduralAvionicsTechManager.SetMaxUnlockedTech(curCfgName, techNode.name); } return(success); }
private int GetUnlockCost(string avionicsConfigName, ProceduralAvionicsTechNode techNode) { string currentUnlockedTech = ProceduralAvionicsTechManager .GetMaxUnlockedTech(avionicsConfigName); int alreadyPaidCost = 0; if (!String.IsNullOrEmpty(currentUnlockedTech)) { alreadyPaidCost = ProceduralAvionicsTechManager .GetProceduralAvionicsConfig(avionicsConfigName) .TechNodes[currentUnlockedTech].unlockCost; } int priceDiff = techNode.unlockCost - alreadyPaidCost; return(priceDiff > 0 ? priceDiff : 0); }
private bool DrawUnlockButton(string curCfgName, ProceduralAvionicsTechNode techNode, int unlockCost) { bool switchedConfig = false; if (unlockCost <= 0) { return(switchedConfig); } GUI.enabled = techNode.IsAvailable && Funding.Instance.Funds > unlockCost; if (GUILayout.Button($"Unlock ({BuildCostString(unlockCost)})", HighLogic.Skin.button, GUILayout.Width(120))) { switchedConfig = PurchaseConfig(curCfgName, techNode); } GUI.enabled = true; return(switchedConfig); }
private ProceduralAvionicsTechNode GetBestTechConfig(Dictionary <String, ProceduralAvionicsTechNode> techNodes, bool limitToCurrentTech) { if (techNodes == null) { return(null); } ProceduralAvionicsTechNode bestTechNode = null; foreach (var techNode in techNodes.Values) { if (bestTechNode == null || techNode.tonnageToMassRatio > bestTechNode.tonnageToMassRatio) { if (!limitToCurrentTech || ResearchAndDevelopment.GetTechnologyState(techNode.name) == RDTech.State.Available) { bestTechNode = techNode; } } } return(bestTechNode); }
private static string BuildSasAndScienceString(ProceduralAvionicsTechNode techNode) => techNode.hasScienceContainer ? " {SC}" : "";
private string BuildTechName(ProceduralAvionicsTechNode techNode) => techNode.dispName ?? techNode.name;
private static float GetEnabledkW(ProceduralAvionicsTechNode techNode, float controllableMass) => GetPolynomial(controllableMass, techNode.powerExponent, techNode.powerConstant, techNode.powerFactor) / 1000f;
internal static bool PurchaseConfig(string avionicsConfigName, ProceduralAvionicsTechNode techNode) { string ecmName = GetEcmName(avionicsConfigName, techNode); return(EntryCostManager.Instance.PurchaseConfig(ecmName)); }
private static string GetEcmName(string avionicsConfigName, ProceduralAvionicsTechNode techNode) { return($"{avionicsConfigName}-{techNode.name}"); }
private static float GetAvionicsMass(ProceduralAvionicsTechNode techNode, float controllableMass) => GetPolynomial(controllableMass, techNode.massExponent, techNode.massConstant, techNode.massFactor) / 1000f;