示例#1
0
 public SpecialistBonusExplanation(float bb, float ef, string e, BestCrewSkillLevels bestLevels)
 {
     SpecialistBonusBase        = bb;
     SpecialistEfficiencyFactor = ef;
     Effect = e;
     if (bestLevels.skillLevelNames.ContainsKey(e))
     {
         BestLevel  = bestLevels.skillLevelNames[e].level;
         BestKerbal = bestLevels.skillLevelNames[e].kerbals.ElementAt(0);
     }
 }
示例#2
0
 private void ToggleDisplay()
 {
     if (display)
     {
         display             = false;
         bestCrewSkillLevels = null;
     }
     else
     {
         display = true;
     }
 }
示例#3
0
 private BestCrewSkillLevels GetBestCrewSkillLevels(Vessel vessel)
 {
     if (bestCrewSkillLevels == null)
     {
         bestCrewSkillLevels = new BestCrewSkillLevels();
         foreach (var c in vessel.GetVesselCrew())
         {
             foreach (var e in c.experienceTrait.Effects)
             {
                 bestCrewSkillLevels.updateWith(e.Name, c.name, c.experienceLevel);
             }
         }
     }
     return(bestCrewSkillLevels);
 }
示例#4
0
        private static void ExplainHarvester(
            ModuleResourceHarvester_USI harvester,
            Part part,
            string resourceName,
            float locationResourceAbundance,
            double partTemperature,
            float maxTemp,
            float thermalEfficiency,
            float extractionAbundanceMultiplier,
            SpecialistBonusExplanation specialistBonus,
            Vessel vessel,
            BestCrewSkillLevels bestCrewSkillLevels)
        {
            var tot = 1d;
            var totFactorsExplanation = new List <string>();


            PrintLine(50, "Resource abundance at location", String.Format("{0}", locationResourceAbundance));
            PrintLine(50, "Harvester abundance multiplier", String.Format("\"{0}% base efficiency\"", extractionAbundanceMultiplier * 100));
            PrintLine(50, " -> Rate", String.Format("\"{0}/s\"", extractionAbundanceMultiplier * locationResourceAbundance));

            PrintLine(50, "\"Core Temperature\"", String.Format("{0:0.00}", partTemperature));
            // PrintLine(50, "Max temperature", String.Format("{0:0.00}", maxTemp));
            PrintLine(50, " -> \"Thermal Efficiency\"", String.Format("{0}%", 100 * thermalEfficiency), "(from some curves)");
            tot *= thermalEfficiency;
            totFactorsExplanation.Add("ThermalEfficiency");

            if (specialistBonus != null)
            {
                PrintLine(50, "Specialist bonus", String.Format("{0:0.##}", specialistBonus.GetValue()), specialistBonus.Explain());
                tot *= specialistBonus.GetValue();
                totFactorsExplanation.Add("SpecialistBonus");
            }

            AddMksModuleFactors(harvester, vessel, part, bestCrewSkillLevels, ref tot, totFactorsExplanation);

            var totExplanation = String.Join(" * ", totFactorsExplanation.ToArray());

            PrintLine(50, " -> Total load", String.Format("{0:0.##%}", tot), totExplanation);

            PrintLine(50, " -> Actual obtention rate", String.Format("+{0}/s", FormatResourceRate(tot * extractionAbundanceMultiplier * locationResourceAbundance)), "Rate * load");
            PrintSingleResourceRate(60, resourceName, "+", tot * extractionAbundanceMultiplier * locationResourceAbundance);
        }
示例#5
0
        public static void DisplayConverterModule(ModuleResourceConverter_USI converter, Vessel vessel, Part part, BestCrewSkillLevels bestCrewSkillLevels)
        {
            if (!converter.IsActivated)
            {
                PrintLine(20, converter.ConverterName + ": Not activated");
                return;
            }
            if (typeof(ModuleEfficiencyPart).IsInstanceOfType(converter))
            {
                PrintLine(20, converter.ConverterName + ": Active effiency part (not a real converter)");
                return;
            }
            if (typeof(ModuleHabitation).IsInstanceOfType(converter))
            {
                PrintLine(20, converter.ConverterName + ": Active hab part (not a real converter)");
                return;
            }
            PrintLine(20, converter.ConverterName + ": Activated");

            var tot = 1d;
            var totFactorsExplanation = new List <string>();

            if (converter.UseSpecialistBonus)
            {
                SpecialistBonusExplanation specBonus = new SpecialistBonusExplanation(
                    converter.SpecialistBonusBase,
                    converter.SpecialistEfficiencyFactor,
                    converter.ExperienceEffect,
                    bestCrewSkillLevels);
                PrintLine(40, "Specialist bonus", String.Format("{0:0.##}", specBonus.GetValue()), specBonus.Explain());
                tot *= specBonus.GetValue();
                totFactorsExplanation.Add("spec_bonus");
            }

            AddRequiredResourcesFactors(converter.reqList, part, ref tot, totFactorsExplanation);

            AddMksModuleFactors(converter, vessel, part, bestCrewSkillLevels, ref tot, totFactorsExplanation);

            var totExplanation = String.Join(" * ", totFactorsExplanation.ToArray());

            PrintLine(40, " -> Total load", String.Format("{0:0.##%}", tot), totExplanation);
            PrintResourceRates(60, tot, converter);
        }
示例#6
0
        private static double ExplainEffPartsBonus(string converterETag, Vessel vessel, Part part, BestCrewSkillLevels bestCrewSkillLevels, float geoBonus)
        {
            // MKSModule == efficiency parts benefiter + kolonization bonuses benefiter
            // refreshed every 5 seconds
            // set the MKS bonus (of all IEfficiencyBonusConsumer modules) to : GetEfficiencyBonus()
            //           GetEfficiencyBonus() = totBonus = geoBonus * GetPlanetaryBonus() * GetEfficiencyRate()
            //      GetPlanetaryBonus is either geo (again!) or bota or kolo depending on BonusEffect (seems to always be FundsBoost)
            //      GetEfficiencyRate is

            /* curConverters
             *    all vessels in 500 range who have a MKSModule with same eTag
             *    sum of all MKSModule's (with same eTag) eMultiplier
             * _colonyConverterEff
             *    records the best curConverters ever seen
             * curEParts
             *    all vessels in 500 range who have a ModuleEfficiencyPart with same eTag
             *    sum of all ModuleEfficiencyPart's (even with different eTag, even inactive?) eMultiplier * EfficiencyMultiplier(=load)
             * _effPartTotal
             *    records the best curEParts seen (although 1 "best seen" will update the 2)
             * ret 1 + _effPartTotal / _colonyConverterEff
             * */

            PrintLine(40, "Efficiency parts");

            List <double> effPartsContributions = new List <double>();

            foreach (var effPartVessel in GetKolonyVessels(vessel, EFF_RANGE))
            {
                foreach (var epm in effPartVessel.vessel.FindPartModulesImplementing <ModuleEfficiencyPart>())
                {
                    var ep = epm.part;
                    if (epm.eTag == converterETag)
                    {
                        if (epm.EfficiencyBonus < float.Epsilon)
                        {
                            continue;
                        }
                        if (!epm.IsActivated)
                        {
                            continue;
                        }
                        effPartsContributions.Add(GetEffPartContribution(ep, epm, bestCrewSkillLevels, geoBonus, effPartVessel));
                    }
                }
            }
            var numerator    = effPartsContributions.Sum();
            var numeratorStr = PrintSum(effPartsContributions);

            if (numerator < float.Epsilon)
            {
                PrintLine(60, "No active efficiency parts");
                return(1d);
            }

            List <double> convertersContribution = new List <double>();

            foreach (var effPartVessel in GetKolonyVessels(vessel, EFF_RANGE))
            {
                foreach (var convMks in effPartVessel.vessel.FindPartModulesImplementing <MKSModule>())
                {
                    var convs = convMks.part.FindModulesImplementing <BaseConverter>();
                    foreach (var conv in convs)
                    {
                        if (!conv.IsActivated)
                        {
                            continue;
                        }
                        if (convMks.eTag == converterETag)
                        {
                            PrintLine(60, String.Format("User of [{0}] {1}/{2}{3}", converterETag, Misc.Name(convMks.part), conv.ConverterName, effPartVessel.ExplainOther()));
                            PrintLine(80, "eMultiplier", String.Format("{0}", convMks.eMultiplier)); // 13.144
                            convertersContribution.Add(convMks.eMultiplier);
                        }
                    }
                }
            }
            var denominator    = convertersContribution.Sum();
            var denominatorStr = PrintSum(convertersContribution);

            if (denominator < float.Epsilon)
            {
                PrintLine(60, "ERROR: no active converter found");
                return(1d);
            }
            var effPartsBonus = 1d + (numerator / denominator);

            PrintLine(40, "Efficiency parts bonus", String.Format("{0:0.##}", effPartsBonus), String.Format("1 + {0} / {1}", numeratorStr, denominatorStr));
            return(effPartsBonus);
        }
示例#7
0
        private static double GetEffPartContribution(Part ep, ModuleEfficiencyPart epm, BestCrewSkillLevels bestCrewSkillLevels, float geoBonus, KolonyVessel effPartVessel)
        {
            var otherVesselExplanation = effPartVessel.ExplainOther();

            PrintLine(60, String.Format("Active {0} in {1}{2}", epm.ConverterName, Misc.Name(ep), otherVesselExplanation));
            var totEff = 1d;

            if (typeof(ModuleEfficiencyPart).GetField("Governor") != null)
            {
                var gov = (float)typeof(ModuleEfficiencyPart).GetField("Governor").GetValue(epm);
                PrintLine(80, "Governor", String.Format("{0:0.##}", gov));
                totEff *= gov;
            }
            if (epm.UseSpecialistBonus)
            {
                SpecialistBonusExplanation specBonus = new SpecialistBonusExplanation(
                    epm.SpecialistBonusBase,
                    epm.SpecialistEfficiencyFactor,
                    epm.ExperienceEffect,
                    bestCrewSkillLevels);
                PrintLine(80, "Crew bonus", String.Format("{0:0.##}", specBonus.GetValue()), specBonus.Explain());
                totEff *= specBonus.GetValue();
            }
            if (epm.reqList != null)
            {
                foreach (var res in epm.reqList)
                {
                    var amountInPart = ep.Resources[res.ResourceName].amount;
                    var bonus        = amountInPart / res.Ratio;
                    PrintLine(80, res.ResourceName, String.Format("{0:0.##}", bonus), String.Format("{0:0.##}/{1:0.##}", amountInPart, res.Ratio));
                    totEff *= bonus;
                }
            }
            {
                PrintLine(80, "Bonus", String.Format("{0:0.##}", epm.EfficiencyBonus), "bays");
                totEff *= epm.EfficiencyBonus;
            }
            PrintLine(80, "eMultiplier", String.Format("{0}", epm.eMultiplier)); // 0.83
            PrintLine(80, " -> Total contribution", String.Format("{0:0.##}", epm.eMultiplier * totEff));
            return(epm.eMultiplier * totEff);
        }
示例#8
0
        protected static void AddMksModuleFactors(PartModule module, Vessel vessel, Part part, BestCrewSkillLevels bestCrewSkillLevels, ref double tot, List <string> totFactorsExplanation)
        {
            if (!BenefitsFromMksModuleBonuses(module))
            {
                return;
            }
            if (part.FindModuleImplementing <MKSModule>() != null)
            {
                // MKSModule == efficiency parts benefiter + kolonization bonuses benefiter
                // 1. Kolonization bonuses
                var mksModule = part.FindModuleImplementing <MKSModule>();
                var geoBonus  = KolonizationManager.GetGeologyResearchBonus(vessel.mainBody.flightGlobalsIndex);
                var koloBonus = KolonizationManager.GetKolonizationResearchBonus(vessel.mainBody.flightGlobalsIndex);
                var botaBonus = KolonizationManager.GetBotanyResearchBonus(vessel.mainBody.flightGlobalsIndex);
                PrintLine(40, "Geology bonus", String.Format("{0:0.##}", geoBonus));
                tot *= geoBonus;
                totFactorsExplanation.Add("geo_bonus");

                if (mksModule.BonusEffect == "RepBoost")
                {
                    PrintLine(40, "Kolonization bonus", String.Format("{0:0.##}", koloBonus));
                    tot *= koloBonus;
                    totFactorsExplanation.Add("kolo_bonus");
                }
                else if (mksModule.BonusEffect == "ScienceBoost")
                {
                    PrintLine(40, "Botany bonus", String.Format("{0:0.##}", botaBonus));
                    tot *= botaBonus;
                    totFactorsExplanation.Add("bota_bonus");
                }
                else
                {
                    tot *= geoBonus;
                    totFactorsExplanation.Add("geo_bonus");
                }
                // 2. Efficiency parts
                if (mksModule.eTag != "")
                {
                    var effPartsBonus = ExplainEffPartsBonus(mksModule.eTag, vessel, part, bestCrewSkillLevels, geoBonus);
                    tot *= effPartsBonus;
                    if (Math.Abs(effPartsBonus - 1d) > double.Epsilon)
                    {
                        totFactorsExplanation.Add("eff_parts_bonus");
                    }
                }
                if (typeof(MKSModule).GetField("Governor") != null)
                {
                    var gov = (float)typeof(MKSModule).GetField("Governor").GetValue(mksModule);
                    PrintLine(40, "Governor", String.Format("{0:0.##}", gov));
                    tot *= gov;
                    totFactorsExplanation.Add("governor");
                }
            }
        }
示例#9
0
        public static void DisplayConverterModule(ModuleBulkConverter converter, Vessel vessel, Part part, BestCrewSkillLevels bestCrewSkillLevels)
        {
            if (!converter.IsActivated)
            {
                PrintLine(20, converter.ConverterName + ": Not activated");
                return;
            }
            PrintLine(20, converter.ConverterName + ": Activated");

            var tot = 1d;
            var totFactorsExplanation = new List <string>();

            if (converter.UseSpecialistBonus)
            {
                SpecialistBonusExplanation specBonus = new SpecialistBonusExplanation(
                    converter.SpecialistBonusBase,
                    converter.SpecialistEfficiencyFactor,
                    converter.ExperienceEffect,
                    bestCrewSkillLevels);
                PrintLine(40, "Specialist bonus", String.Format("{0:0.##}", specBonus.GetValue()), specBonus.Explain());
                tot *= specBonus.GetValue();
                totFactorsExplanation.Add("spec_bonus");
            }

            AddRequiredResourcesFactors(converter.reqList, part, ref tot, totFactorsExplanation);

            AddMksModuleFactors(converter, vessel, part, bestCrewSkillLevels, ref tot, totFactorsExplanation);

            var totExplanation = String.Join(" * ", totFactorsExplanation.ToArray());

            PrintLine(40, " -> Total load", String.Format("{0:0.##%}", tot), totExplanation);

            Dictionary <string, double> resourceYields = GetResourceYields(vessel.mainBody.flightGlobalsIndex, converter.Yield, converter.MinAbundance, converter.inputList);
            List <ResourceRatio>        actualOutputs  = GetOutputs(resourceYields, converter.outputList);

            PrintResourceRates(60, tot, converter.inputList, actualOutputs);
        }
示例#10
0
        public static void DisplayHarvesterModule(ModuleResourceHarvester_USI harvester, Vessel vessel, Part part, BestCrewSkillLevels bestCrewSkillLevels)
        {
            if (!harvester.IsActivated)
            {
                PrintLine(20, harvester.ResourceName + ": Not activated");
                return;
            }
            PrintLine(20, harvester.ResourceName + ": Activated");

            // For debug
            //Line("EfficiencyMultiplier", harvester.GetEfficiencyMultiplier().ToString()); // thermal eff * eff due to specialist
            //Line("res status", harvester.ResourceStatus.ToString()); x/sec displayed by KSP. trash
            //Line("eff bonus", harvester.GetEfficiencyBonus().ToString()); // same a SwapBay ?

            SpecialistBonusExplanation specBonus = harvester.UseSpecialistBonus ? new SpecialistBonusExplanation(
                harvester.SpecialistBonusBase,
                harvester.SpecialistEfficiencyFactor,
                harvester.ExperienceEffect,
                bestCrewSkillLevels) : null;

            ExplainHarvester(
                harvester,
                part,
                harvester.ResourceName,
                ResourceCache.GetAbundance(harvester.ResourceName, vessel),
                harvester.GetCoreTemperature(),
                harvester.ThermalEfficiency.maxTime,
                harvester.ThermalEfficiency.Evaluate((float)harvester.GetCoreTemperature()),
                harvester.Efficiency,
                specBonus,
                vessel,
                bestCrewSkillLevels);
        }