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); } }
private void ToggleDisplay() { if (display) { display = false; bestCrewSkillLevels = null; } else { display = true; } }
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); }
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); }
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); }
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); }
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); }
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"); } } }
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); }
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); }