private static void ProcessUnloadedSolarPanels(VesselData vesselData) { if (DetectKerbalism.Found) { return; } if (!vesselData.SolarPanels.Any()) { return; } foreach (StarLight starlight in KopernicusHelper.Stars) { double starlightRelativeLuminosity = KopernicusHelper.GetSolarDistanceMultiplier( vesselPosition: vesselData.Position, star: starlight.star, astronomicalUnit: KopernicusHelper.AstronomicalUnit); starlightRelativeLuminosity *= starlight.relativeLuminosity; // ignore stars that are too far away to give any meaningful energy if (starlightRelativeLuminosity < 0.001) { continue; } // ignore if there is no line of sight between the star and the vessel if (!KopernicusHelper.LineOfSightToSun(vesselData.Position, starlight.star)) { continue; } foreach (KeyValuePair <uint, SolarPanelData> keyValuePair in vesselData.SolarPanels) { SolarPanelData solarPanelData = keyValuePair.Value; foreach (ModuleDeployableSolarPanel solarPanel in solarPanelData.ModuleDeployableSolarPanels) { if (solarPanel.chargeRate <= 0) { continue; } if (solarPanel.deployState != ModuleDeployablePart.DeployState.EXTENDED) { continue; } double trackingModifier = solarPanel.isTracking ? 1 : 0.25; double powerChange = trackingModifier * solarPanel.chargeRate * starlightRelativeLuminosity * solarPanel.efficiencyMult * solarPanelData.ChargeRateMultiplier; vesselData.UpdateAvailableResource(solarPanel.resourceName, powerChange); vesselData.ResourceChange(solarPanel.resourceName, powerChange); } } } }
private static void ProcessUnloadedResourceConverters(VesselData vesselData, double elapsedTime) { if (DetectKerbalism.Found) { return; } foreach (KeyValuePair <uint, ModuleResourceConverterData> keyValuePair in vesselData.ResourceConverters) { ModuleResourceConverterData resourceConverterData = keyValuePair.Value; resourceConverterData.ProtoPartSnapshot = vesselData.Vessel.protoVessel.protoPartSnapshots[resourceConverterData.PartIndex]; for (var i = 0; i < resourceConverterData.ModuleResourceConverters.Count; i++) { ModuleResourceConverter resourceConverter = resourceConverterData.ModuleResourceConverters[i]; // load protoPartModuleSnapshot var moduleIndex = resourceConverterData.ProtoPartModuleSnapshotIndexes[i]; ProtoPartModuleSnapshot protoPartModuleSnapshot = resourceConverterData.ProtoPartSnapshot.modules[moduleIndex]; // read persistent IsActivated setting bool.TryParse(protoPartModuleSnapshot.moduleValues.GetValue(nameof(resourceConverter.IsActivated)), out resourceConverter.IsActivated); if (resourceConverter.IsActivated == false) { continue; } // read persistent EfficiencyBonus setting float.TryParse(protoPartModuleSnapshot.moduleValues.GetValue(nameof(resourceConverter.EfficiencyBonus)), out resourceConverter.EfficiencyBonus); if (resourceConverter.EfficiencyBonus <= 0) { continue; } // determine processRatio ratio double processRatio = 1; // check if we meet the requirements foreach (var resourceRatio in resourceConverter.Recipe.Requirements) { vesselData.AvailableResources.TryGetValue(resourceRatio.ResourceName, out double availableAmount); if (availableAmount < resourceRatio.Ratio * resourceConverterData.ReqMultiplier) { processRatio = 0; break; } } if (processRatio <= 0) { continue; } // check if we meet the output storage foreach (ResourceRatio resourceRatio in resourceConverter.Recipe.Outputs) { if (resourceRatio.DumpExcess) { continue; } vesselData.AvailableStorage.TryGetValue(resourceRatio.ResourceName, out double availableStorage); double requestedRate = resourceConverter.EfficiencyBonus * resourceRatio.Ratio * elapsedTime * resourceConverterData.OutputMultiplier; double spaceRatio = resourceRatio.Ratio > 0 ? Math.Min(1, availableStorage / requestedRate) : 1; if (spaceRatio < processRatio) { processRatio = spaceRatio; } } if (processRatio <= 0) { continue; } // check if we meet the input foreach (ResourceRatio resourceRatio in resourceConverter.Recipe.Inputs) { vesselData.AvailableResources.TryGetValue(resourceRatio.ResourceName, out double availableAmount); double requestedRate = resourceConverter.EfficiencyBonus * resourceRatio.Ratio * elapsedTime * resourceConverterData.InputMultiplier; double foundRatio = requestedRate > 0 ? Math.Min(1, availableAmount / requestedRate) : 1; if (foundRatio < processRatio) { processRatio = foundRatio; } } if (processRatio <= 0) { continue; } // extract resource from available resources foreach (ResourceRatio inputResource in resourceConverter.Recipe.Inputs) { double resourceChange = -inputResource.Ratio * resourceConverter.EfficiencyBonus * processRatio; vesselData.UpdateAvailableResource(inputResource.ResourceName, resourceChange); vesselData.ResourceChange(inputResource.ResourceName, resourceChange); } // generate resources foreach (ResourceRatio outputResource in resourceConverter.Recipe.Outputs) { double resourceChange = outputResource.Ratio * resourceConverter.EfficiencyBonus * processRatio; vesselData.UpdateAvailableResource(outputResource.ResourceName, resourceChange); vesselData.ResourceChange(outputResource.ResourceName, resourceChange); } } } }
private static void ProcessUnloadedModuleGenerators(VesselData vesselData, double elapsedTime) { if (DetectKerbalism.Found) { return; } foreach (KeyValuePair <uint, ModuleGeneratorData> keyValuePair in vesselData.Generators) { ModuleGeneratorData generatorData = keyValuePair.Value; generatorData.ProtoPartSnapshot = vesselData.Vessel.protoVessel.protoPartSnapshots[generatorData.PartIndex]; for (var i = 0; i < generatorData.ModuleGenerators.Count; i++) { ModuleGenerator moduleGenerator = generatorData.ModuleGenerators[i]; // load protoPartModuleSnapshot var moduleIndex = generatorData.ProtoPartModuleSnapshotIndexes[i]; ProtoPartModuleSnapshot protoPartModuleSnapshot = generatorData.ProtoPartSnapshot.modules[moduleIndex]; // refresh persistent setting generatorIsActive moduleGenerator.generatorIsActive = bool.Parse(protoPartModuleSnapshot.moduleValues.GetValue(nameof(moduleGenerator.generatorIsActive))); if (moduleGenerator.generatorIsActive == false) { continue; } // refresh persistent setting throttle moduleGenerator.throttle = float.Parse(protoPartModuleSnapshot.moduleValues.GetValue(nameof(moduleGenerator.throttle))); if (moduleGenerator.throttle <= 0) { continue; } // determine found ratio double finalFoundRatio = 1; foreach (ModuleResource moduleResource in moduleGenerator.resHandler.inputResources) { vesselData.AvailableResources.TryGetValue(moduleResource.name, out double availableAmount); double requestedRate = moduleGenerator.throttle * moduleResource.rate * elapsedTime * generatorData.InputMultiplier; double foundRatio = requestedRate > 0 ? Math.Min(1, availableAmount / requestedRate) : 1; if (foundRatio < finalFoundRatio) { finalFoundRatio = foundRatio; } } if (finalFoundRatio <= 0) { continue; } // extract resource from available resources foreach (ModuleResource inputResource in moduleGenerator.resHandler.inputResources) { double resourceChange = -inputResource.rate * moduleGenerator.throttle * finalFoundRatio * generatorData.InputMultiplier; vesselData.UpdateAvailableResource(inputResource.name, resourceChange); vesselData.ResourceChange(inputResource.name, resourceChange); } // generate resources foreach (ModuleResource outputResource in moduleGenerator.resHandler.outputResources) { double resourceChange = outputResource.rate * moduleGenerator.throttle * finalFoundRatio * generatorData.OutputMultiplier; vesselData.UpdateAvailableResource(outputResource.name, resourceChange); vesselData.ResourceChange(outputResource.name, resourceChange); } } } }