コード例 #1
0
        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);
            }
        }
コード例 #2
0
        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());
        }
コード例 #3
0
        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);
                    }
                }
            }
        }
コード例 #4
0
        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());
        }
コード例 #5
0
        private string BuildTechName(ProceduralAvionicsTechNode techNode)
        {
            var sbuilder = StringBuilderCache.Acquire();

            sbuilder.Append(techNode.name);
            sbuilder.Append(BuildSasAndScienceString(techNode));

            return(sbuilder.ToStringAndRelease());
        }
コード例 #6
0
        private string GetTooltipTextForTechNode(ProceduralAvionicsTechNode techNode)
        {
            if (!_tooltipTexts.TryGetValue(techNode.name, out string tooltip))
            {
                tooltip = ConstructTooltipForAvionicsTL(techNode);
                _tooltipTexts[techNode.name] = tooltip;
            }

            return(tooltip);
        }
コード例 #7
0
        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);
            }
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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());
        }
コード例 #10
0
        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());
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        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);
        }
コード例 #13
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);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
 private static string BuildSasAndScienceString(ProceduralAvionicsTechNode techNode) => techNode.hasScienceContainer ? " {SC}" : "";
コード例 #16
0
 private string BuildTechName(ProceduralAvionicsTechNode techNode) => techNode.dispName ?? techNode.name;
コード例 #17
0
 private static float GetEnabledkW(ProceduralAvionicsTechNode techNode, float controllableMass) => GetPolynomial(controllableMass, techNode.powerExponent, techNode.powerConstant, techNode.powerFactor) / 1000f;
コード例 #18
0
        internal static bool PurchaseConfig(string avionicsConfigName, ProceduralAvionicsTechNode techNode)
        {
            string ecmName = GetEcmName(avionicsConfigName, techNode);

            return(EntryCostManager.Instance.PurchaseConfig(ecmName));
        }
コード例 #19
0
 private static string GetEcmName(string avionicsConfigName, ProceduralAvionicsTechNode techNode)
 {
     return($"{avionicsConfigName}-{techNode.name}");
 }
コード例 #20
0
 private static float GetAvionicsMass(ProceduralAvionicsTechNode techNode, float controllableMass) => GetPolynomial(controllableMass, techNode.massExponent, techNode.massConstant, techNode.massFactor) / 1000f;