Exemplo n.º 1
0
        private static ModuleResourceConverterData LoadModuleResourceConverters(int partIndex, ProtoPartSnapshot protoPartSnapshot, VesselData vesselData, Part protoPart)
        {
            var moduleResourceConverter = protoPart?.FindModulesImplementing <ModuleResourceConverter>();

            if (moduleResourceConverter is null || moduleResourceConverter.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(ModuleResourceConverter))
                {
                    protoPartModuleSnapshotIndexes.Add(i);
                    protoPartModuleSnapshots.Add(protoPartModuleSnapshot);
                }
            }

            var resourceConverterData = new ModuleResourceConverterData
            {
                PartIndex                      = partIndex,
                ProtoPart                      = protoPart,
                ProtoPartSnapshot              = protoPartSnapshot,
                PersistentPartId               = protoPartSnapshot.persistentId,
                ModuleResourceConverters       = moduleResourceConverter,
                ProtoPartModuleSnapshotIndexes = protoPartModuleSnapshotIndexes
            };

            // calculate tweakScale multipliers
            if (vesselData.PartSizeMultipliers.TryGetValue(protoPartSnapshot.persistentId, out double partSizeMultiplier))
            {
                var tweakScaleExponents = TweaksSaleHelper.GetTweakScaleExponents(nameof(ModuleResourceConverter));

                if (tweakScaleExponents.Exponents.TryGetValue("inputList", out double inputExponent))
                {
                    resourceConverterData.InputMultiplier = Math.Pow(partSizeMultiplier, inputExponent);
                }

                if (tweakScaleExponents.Exponents.TryGetValue("outputList", out double outExponent))
                {
                    resourceConverterData.OutputMultiplier = Math.Pow(partSizeMultiplier, outExponent);
                }

                if (tweakScaleExponents.Exponents.TryGetValue("reqList", out double reqExponent))
                {
                    resourceConverterData.ReqMultiplier = Math.Pow(partSizeMultiplier, reqExponent);
                }
            }

            // readout persistent data
            for (int i = 0; i < moduleResourceConverter.Count; i++)
            {
                ModuleResourceConverter resourceConverter       = moduleResourceConverter[i];
                ProtoPartModuleSnapshot protoPartModuleSnapshot = protoPartModuleSnapshots[protoPartModuleSnapshotIndexes[i]];

                resourceConverter.IsActivated     = bool.Parse(protoPartModuleSnapshot.moduleValues.GetValue(nameof(resourceConverter.IsActivated)));
                resourceConverter.EfficiencyBonus = float.Parse(protoPartModuleSnapshot.moduleValues.GetValue(nameof(resourceConverter.EfficiencyBonus)));
            }

            vesselData.ResourceConverters.Add(protoPartSnapshot.persistentId, resourceConverterData);

            return(resourceConverterData);
        }
Exemplo n.º 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);
                    }
                }
            }
        }