private static ModuleGeneratorData LoadModuleGenerator(int partIndex, ProtoPartSnapshot protoPartSnapshot, VesselData vesselData, Part protoPart) { var moduleGenerators = protoPart?.FindModulesImplementing <ModuleGenerator>(); if (moduleGenerators is null || moduleGenerators.Any() == false) { return(null); } List <int> protoPartModuleSnapshotIndexes = new List <int>(); List <ProtoPartModuleSnapshot> protoPartModuleSnapshots = new List <ProtoPartModuleSnapshot>(); for (int i = 0; i < protoPartSnapshot.modules.Count; i++) { ProtoPartModuleSnapshot protoPartModuleSnapshot = protoPartSnapshot.modules[i]; if (protoPartModuleSnapshot.moduleName == nameof(ModuleGenerator)) { protoPartModuleSnapshotIndexes.Add(i); protoPartModuleSnapshots.Add(protoPartModuleSnapshot); } } var moduleGeneratorData = new ModuleGeneratorData { PartIndex = partIndex, ProtoPart = protoPart, ProtoPartSnapshot = protoPartSnapshot, PersistentPartId = protoPartSnapshot.persistentId, ProtoPartModuleSnapshotIndexes = protoPartModuleSnapshotIndexes, ModuleGenerators = moduleGenerators }; // calculate tweakScale multiplier if (vesselData.PartSizeMultipliers.TryGetValue(protoPartSnapshot.persistentId, out double partSizeMultiplier)) { var tweakScaleExponents = TweaksSaleHelper.GetTweakScaleExponents(nameof(ModuleGenerator)); if (tweakScaleExponents.Exponents.TryGetValue("outputResources.rate", out double outputExponent)) { moduleGeneratorData.OutputMultiplier = Math.Pow(partSizeMultiplier, outputExponent); } if (tweakScaleExponents.Exponents.TryGetValue("inputResources.rate", out double inputExponent)) { moduleGeneratorData.InputMultiplier = Math.Pow(partSizeMultiplier, inputExponent); } } // readout persistent data for (int i = 0; i < moduleGenerators.Count; i++) { ModuleGenerator moduleGenerator = moduleGenerators[i]; ProtoPartModuleSnapshot protoPartModuleSnapshot = protoPartModuleSnapshots[i]; moduleGenerator.generatorIsActive = bool.Parse(protoPartModuleSnapshot.moduleValues.GetValue(nameof(moduleGenerator.generatorIsActive))); moduleGenerator.throttle = float.Parse(protoPartModuleSnapshot.moduleValues.GetValue(nameof(moduleGenerator.throttle))); } vesselData.Generators.Add(protoPartSnapshot.persistentId, moduleGeneratorData); return(moduleGeneratorData); }
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); } } } }