Пример #1
0
        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);
                    }
                }
            }
        }
Пример #2
0
        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);
                    }
                }
            }
        }
Пример #3
0
        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);
                    }
                }
            }
        }