Esempio n. 1
0
        public void ExtractSeawater(double rateMultiplier, double powerFraction, double productionModifier, bool allowOverflow, double timeDifference, bool offlineCollecting)
        {
            _effectiveMaxPower = productionModifier * PowerRequirements;

            _current_power = _effectiveMaxPower * powerFraction;
            _current_rate  = CurrentPower / EnergyPerTon;

            // determine the amount of liquid processed every frame
            _availableIntakeLiquidMass = GetTotalLiquidScoopedPerSecond() * _intakeLiquidDefinition.density;

            // this should determine how much resource this process can consume
            var fixedMaxLiquidConsumptionRate = _current_rate * timeDifference * _intakeLiquidDefinition.density;

            // supplement any missing LiquidIntake by intake
            var shortage = fixedMaxLiquidConsumptionRate > _availableIntakeLiquidMass ? fixedMaxLiquidConsumptionRate - _availableIntakeLiquidMass : 0;

            if (shortage > 0)
            {
                _availableIntakeLiquidMass += _part.RequestResource(_intakeLiquidDefinition.id, shortage, ResourceFlowMode.ALL_VESSEL);
            }

            var liquidConsumptionRatio = offlineCollecting ? 1
                    : fixedMaxLiquidConsumptionRate > 0
                    ? Math.Min(fixedMaxLiquidConsumptionRate, _availableIntakeLiquidMass) / fixedMaxLiquidConsumptionRate : 0;

            fixedConsumptionRate = _current_rate * timeDifference * liquidConsumptionRatio;

            if (fixedConsumptionRate <= 0)
            {
                return;
            }

            _currentResourceProductionRate = 0;

            _productionRateDict.Clear();

            // get the resource for the current body
            _localResources = OceanicResourceHandler.GetOceanicCompositionForBody(FlightGlobals.currentMainBody);

            foreach (OceanicResource resource in _localResources)
            {
                if (resource.ResourceName == null)
                {
                    continue; // this resource does not interest us anymore
                }
                if (resource.Definition == null)
                {
                    continue; // this resource is missing a resource definition
                }
                // determine the spare room - gets parts that contain the current resource, gets the sum of their maxAmount - (current)amount and multiplies by density of resource
                var currentResourceSpareRoom = _part.GetConnectedResources(resource.ResourceName).Sum(r => r.maxAmount - r.amount) * resource.Definition.density;

                // how much we should add per cycle
                var currentResourceMaxRate = fixedConsumptionRate * resource.ResourceAbundance;

                // how much we actually CAN add per cycle (into the spare room in the vessel's tanks) - if the allowOverflow setting is on, dump it all in even though it won't fit (excess is lost), otherwise use the smaller of two values (spare room remaining and the full rate)
                var currentResourcePossibleRate = allowOverflow ? currentResourceMaxRate : Math.Min(currentResourceSpareRoom, currentResourceMaxRate);

                // calculate the ratio of rates, if the denominator is zero, assign zero outright to prevent problems
                var currentResourceRatio = currentResourceMaxRate <= 0 ? 0 : currentResourcePossibleRate / currentResourceMaxRate;

                // calculate the consumption rate of the intake liquid
                _intakeLqdConsumptionRate = (currentResourceRatio * fixedConsumptionRate / _intakeLiquidDefinition.density) / timeDifference * _intakeLiquidDefinition.density;

                if (offlineCollecting) // if collecting offline, multiply by the elapsed time
                {
                    _intakeLqdConsumptionRate = fixedConsumptionRate * timeDifference;
                    ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_KSPIE_SeawaterExtract_Postmsg1", _intakeLiquidDefinition.name, timeDifference.ToString("F0"), _intakeLqdConsumptionRate.ToString("F2")), 60.0f, ScreenMessageStyle.UPPER_CENTER);//"The ocean extractor processed " +  + " for " +  + " seconds, processing " +  + " units in total."
                }

                // calculate the rate of production
                var currentResourceTempProductionRate = _intakeLqdConsumptionRate * resource.ResourceAbundance;

                // add the produced resource
                var currentProductionRate = -_part.RequestResource(resource.ResourceName, -currentResourceTempProductionRate * timeDifference / resource.Definition.density, ResourceFlowMode.ALL_VESSEL) / timeDifference * resource.Definition.density;

                _productionRateDict.Add(resource.ResourceName, currentProductionRate);

                _currentResourceProductionRate += currentProductionRate;
            }
        }
        private void Window(int windowID)
        {
            bold_label           = new GUIStyle(GUI.skin.label);
            bold_label.fontStyle = FontStyle.Bold;

            if (GUI.Button(new Rect(windowPosition.width - 20, 2, 18, 18), "x"))
            {
                render_window = false;
            }

            GUILayout.BeginVertical();
            if (vessel.Splashed)
            {
                if (analysis_count > analysis_length)
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Liquid", bold_label, GUILayout.Width(150));
                    GUILayout.Label("Abundance", bold_label, GUILayout.Width(150));
                    GUILayout.EndHorizontal();
                    GUILayout.Space(5);

                    foreach (OceanicResource oceanic_resource in OceanicResourceHandler.GetOceanicCompositionForBody(vessel.mainBody.flightGlobalsIndex))
                    {
                        GUILayout.BeginHorizontal();
                        GUILayout.Label(oceanic_resource.DisplayName, GUILayout.Width(150));
                        string resource_abundance_str;
                        if (oceanic_resource.ResourceAbundance > 0.001)
                        {
                            resource_abundance_str = (oceanic_resource.ResourceAbundance * 100.0).ToString() + "%";
                        }
                        else
                        {
                            if (oceanic_resource.ResourceAbundance > 0.000001)
                            {
                                resource_abundance_str = (oceanic_resource.ResourceAbundance * 1e6).ToString() + " ppm";
                            }
                            else
                            {
                                resource_abundance_str = (oceanic_resource.ResourceAbundance * 1e9).ToString() + " ppb";
                            }
                        }
                        GUILayout.Label(resource_abundance_str, GUILayout.Width(150));
                        GUILayout.EndHorizontal();
                    }
                }
                else
                {
                    double percent_analysed = (double)analysis_count / analysis_length * 100;
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Analysing...", GUILayout.Width(150));
                    GUILayout.Label(percent_analysed.ToString("0.00") + "%", GUILayout.Width(150));
                    GUILayout.EndHorizontal();
                }
            }
            else
            {
                GUILayout.Label("--No Ocean to Sample--", GUILayout.ExpandWidth(true));
                analysis_count = 0;
            }
            GUILayout.EndVertical();
            GUI.DragWindow();
        }
        public void ExtractSeawater(double rateMultiplier, double powerFraction, double productionModifier, bool allowOverflow, double timeDifference, bool offlineCollecting)
        {
            _effectiveMaxPower = productionModifier * PowerRequirements;

            _current_power = _effectiveMaxPower * powerFraction;
            _current_rate  = CurrentPower / PluginHelper.ElectrolysisEnergyPerTon;

            // get the resource for the current body
            localResources = OceanicResourceHandler.GetOceanicCompositionForBody(FlightGlobals.currentMainBody);

            // determine the amount of liquid processed every frame
            _availableIntakeLiquidMass = GetTotalLiquidScoopedPerSecond() * _intakeLiquidDefinition.density;

            // this should determine how much resource this process can consume
            var fixedMaxLiquidConsumptionRate = _current_rate * timeDifference * _intakeLiquidDefinition.density;

            // supplement any missig liquidintake by intake
            var shortage = fixedMaxLiquidConsumptionRate > _availableIntakeLiquidMass ? fixedMaxLiquidConsumptionRate - _availableIntakeLiquidMass : 0;

            if (shortage > 0)
            {
                _availableIntakeLiquidMass += _part.RequestResource(_intakeLiquidDefinition.id, shortage, ResourceFlowMode.ALL_VESSEL);
            }

            var liquidConsumptionRatio = offlineCollecting ? 1
                    : fixedMaxLiquidConsumptionRate > 0
                        ? Math.Min(fixedMaxLiquidConsumptionRate, _availableIntakeLiquidMass) / fixedMaxLiquidConsumptionRate : 0;

            _fixedConsumptionRate = _current_rate * timeDifference * liquidConsumptionRatio;

            if (_fixedConsumptionRate <= 0)
            {
                return;
            }

            foreach (OceanicResource resource in localResources)
            {
                // get the name of the resource
                var currentResourceName = resource.ResourceName;

                if (currentResourceName == null)
                {
                    continue; // this resource does not interest us anymore
                }
                var currentDefinition = PartResourceLibrary.Instance.GetDefinition(currentResourceName);
                if (currentDefinition == null)
                {
                    continue; // this resource is missing a resource definition
                }
                // determine the spare room - gets parts that contain the current resource, gets the sum of their maxAmount - (current)amount and multiplies by density of resource
                var currentResourceSpareRoom = _part.GetConnectedResources(currentResourceName).Sum(r => r.maxAmount - r.amount) * currentDefinition.density;

                double currentResourcePercentage = 0;
                if (FlightGlobals.currentMainBody.flightGlobalsIndex != lastBodyID) // the calculations in here don't have to be run every update - we can instead store the percentage in a persistent dictionary with the resource name as key and retrieve it from there
                {
                    // determine the percentage (how much of the resource will be produced from the intake liquid)
                    currentResourcePercentage = OceanicResourceHandler.getOceanicResourceContent(FlightGlobals.currentMainBody.flightGlobalsIndex, currentResourceName);

                    // we'll store the value for next time
                    if (resourcePercentages.ContainsKey(currentResourceName))                // check if the dictionary is storing a value with this key already
                    {
                        resourcePercentages.Remove(currentResourceName);                     // then first do a remove
                    }
                    resourcePercentages.Add(currentResourceName, currentResourcePercentage); // add the current percentage to a dictionary, for easy access
                }
                else // if we have been here already, just fetch the value from the dictionary
                {
                    double percentage;
                    if (resourcePercentages.TryGetValue(currentResourceName, out percentage))
                    {
                        currentResourcePercentage = percentage;
                    }
                    else
                    {
                        Debug.Log("[KSPI] - Could not retrieve resource percentage from dictionary, setting to zero");
                        currentResourcePercentage = 0;
                    }
                }
                // how much we should add per cycle
                var currentResourceMaxRate = _fixedConsumptionRate * currentResourcePercentage;

                // how much we actually CAN add per cycle (into the spare room in the vessel's tanks) - if the allowOverflow setting is on, dump it all in even though it won't fit (excess is lost), otherwise use the smaller of two values (spare room remaining and the full rate)
                var currentResourcePossibleRate = allowOverflow ? currentResourceMaxRate : Math.Min(currentResourceSpareRoom, currentResourceMaxRate);

                // calculate the ratio of rates, if the denominator is zero, assign zero outright to prevent problems
                var currentResourceRatio = (currentResourceMaxRate == 0) ? 0 : currentResourcePossibleRate / currentResourceMaxRate;

                // calculate the consumption rate of the intake liquid
                _intakeLqdConsumptionRate = (currentResourceRatio * _fixedConsumptionRate / _intakeLiquidDefinition.density) / timeDifference * _intakeLiquidDefinition.density;

                if (offlineCollecting) // if collecting offline, multiply by the elapsed time
                {
                    _intakeLqdConsumptionRate = _fixedConsumptionRate * timeDifference;
                    ScreenMessages.PostScreenMessage("The ocean extractor processed " + _intakeLiquidDefinition.name + " for " + timeDifference.ToString("F0") + " seconds, processing " + _intakeLqdConsumptionRate.ToString("F2") + " units in total.", 60.0f, ScreenMessageStyle.UPPER_CENTER);
                }

                // calculate the rate of production
                var currentResourceTempProductionRate = _intakeLqdConsumptionRate * currentResourcePercentage;

                // add the produced resource
                currentResourceProductionRate = -_part.RequestResource(currentResourceName, -currentResourceTempProductionRate * timeDifference / currentDefinition.density, ResourceFlowMode.ALL_VESSEL) / timeDifference * currentDefinition.density;
            }

            if (lastBodyID != FlightGlobals.currentMainBody.flightGlobalsIndex)
            {
                // update lastBodyID to this planets ID (i.e. remember this body)
                lastBodyID = FlightGlobals.currentMainBody.flightGlobalsIndex;
            }
        }