Exemplo n.º 1
0
        private double CalculateElectricalPowerCurrentlyNeeded()
        {
            double electrical_power_currently_needed;

            var powerBufferRatio = Math.Min(1 - getResourceBarRatio(FNResourceManager.FNRESOURCE_MEGAJOULES), 1);

            double exponent;

            if (TimeWarp.fixedDeltaTime > 10000)
            {
                exponent = 1;
            }
            else if (TimeWarp.fixedDeltaTime > 100)
            {
                exponent = 0.5;
            }
            else if (TimeWarp.fixedDeltaTime > 1)
            {
                exponent = 0.25;
            }
            else if (TimeWarp.fixedDeltaTime > 0.1)
            {
                exponent = 0.125;
            }
            else
            {
                exponent = 0;
            }

            var scaledPowerBufferRatio = Math.Pow(powerBufferRatio, exponent);

            var possibleSpareResourceCapacityFilling = Math.Min(getSpareResourceCapacity(FNResourceManager.FNRESOURCE_MEGAJOULES) * scaledPowerBufferRatio, MaxStableMegaWattPower * scaledPowerBufferRatio);

            if (attachedThermalSource.ShouldApplyBalance(chargedParticleMode ? ElectricGeneratorType.charged_particle : ElectricGeneratorType.thermal))
            {
                var chargedPowerPerformance = attachedThermalSource.EfficencyConnectedChargedEnergyGenerator * attachedThermalSource.ChargedPowerRatio;
                var thermalPowerPerformance = attachedThermalSource.EfficencyConnectedThermalEnergyGenerator * (1 - attachedThermalSource.ChargedPowerRatio);

                var totalPerformance = chargedPowerPerformance + thermalPowerPerformance;

                var balancePerformanceRatio = chargedParticleMode
                    ? chargedPowerPerformance / totalPerformance
                    : thermalPowerPerformance / totalPerformance;

                electrical_power_currently_needed = (getCurrentUnfilledResourceDemand(FNResourceManager.FNRESOURCE_MEGAJOULES) + possibleSpareResourceCapacityFilling) * balancePerformanceRatio;
            }
            else
            {
                electrical_power_currently_needed = getCurrentUnfilledResourceDemand(FNResourceManager.FNRESOURCE_MEGAJOULES) + possibleSpareResourceCapacityFilling;
            }

            return(electrical_power_currently_needed);
        }
Exemplo n.º 2
0
        private double CalculateElectricalPowerCurrentlyNeeded()
        {
            double electrical_power_currently_needed;

            if (attachedThermalSource.ShouldApplyBalance(chargedParticleMode ? ElectricGeneratorType.charged_particle : ElectricGeneratorType.thermal))
            {
                var chargedPowerPerformance = attachedThermalSource.EfficencyConnectedChargedEnergyGenerator * attachedThermalSource.ChargedPowerRatio;
                var thermalPowerPerformance = attachedThermalSource.EfficencyConnectedThermalEnergyGenerator * (1 - attachedThermalSource.ChargedPowerRatio);

                var totalPerformance = chargedPowerPerformance + thermalPowerPerformance;

                var balancePerformanceRatio = chargedParticleMode
                    ? chargedPowerPerformance / totalPerformance
                    : thermalPowerPerformance / totalPerformance;

                electrical_power_currently_needed = (getCurrentUnfilledResourceDemand(FNResourceManager.FNRESOURCE_MEGAJOULES) + getSpareResourceCapacity(FNResourceManager.FNRESOURCE_MEGAJOULES)) * balancePerformanceRatio;
            }
            else
            {
                electrical_power_currently_needed = getCurrentUnfilledResourceDemand(FNResourceManager.FNRESOURCE_MEGAJOULES) + getSpareResourceCapacity(FNResourceManager.FNRESOURCE_MEGAJOULES);
            }

            return(electrical_power_currently_needed);
        }
Exemplo n.º 3
0
        public override void OnFixedUpdate()
        {
            base.OnFixedUpdate();
            if (IsEnabled && myAttachedReactor != null && FNRadiator.hasRadiatorsForVessel(vessel))
            {
                updateGeneratorPower();

                // check if MaxStableMegaWattPower is changed
                var maxStableMegaWattPower = MaxStableMegaWattPower;
                if (maxStableMegaWattPower != _previousMaxStableMegaWattPower)
                {
                    _powerState = PowerStates.powerChange;
                }

                _previousMaxStableMegaWattPower = maxStableMegaWattPower;

                if (maxStableMegaWattPower > 0 && (TimeWarp.fixedDeltaTime != previousTimeWarp || _powerState != PowerStates.powerOnline))
                {
                    _powerState = PowerStates.powerOnline;

                    var powerBufferingBonus = myAttachedReactor.PowerBufferBonus * maxStableMegaWattPower;
                    requiredMegawattCapacity = (float)Math.Max(0.0001, TimeWarp.fixedDeltaTime * maxStableMegaWattPower + powerBufferingBonus);
                    var previousMegawattCapacity = Math.Max(0.0001, previousTimeWarp * maxStableMegaWattPower + powerBufferingBonus);

                    if (megajouleResource != null)
                    {
                        megajouleResource.maxAmount = requiredMegawattCapacity;

                        if (maxStableMegaWattPower > 0.1)
                        {
                            megajouleResource.amount = requiredMegawattCapacity > previousMegawattCapacity
                                    ? Math.Max(0, Math.Min(requiredMegawattCapacity, megajouleResource.amount + requiredMegawattCapacity - previousMegawattCapacity))
                                    : Math.Max(0, Math.Min(requiredMegawattCapacity, (megajouleResource.amount / megajouleResource.maxAmount) * requiredMegawattCapacity));
                        }
                    }

                    //PartResource wasteheatResource = part.Resources.list.FirstOrDefault(r => r.resourceName == FNResourceManager.FNRESOURCE_WASTEHEAT);
                    //if (wasteheatResource != null)
                    //{
                    //    var previousMaxAmount = wasteheatResource.maxAmount;
                    //    wasteheatResource.maxAmount = TimeWarp.fixedDeltaTime * part.mass * 1000;
                    //    this.part.RequestResource(FNResourceManager.FNRESOURCE_WASTEHEAT, previousTimeWarp > TimeWarp.fixedDeltaTime ? previousMaxAmount - wasteheatResource.maxAmount : 0);
                    //}

                    PartResource electricChargeResource = part.Resources.list.FirstOrDefault(r => r.resourceName == "ElectricCharge");
                    if (electricChargeResource != null)
                    {
                        //if (maxStableMegaWattPower <= 0)
                        electricChargeResource.maxAmount = requiredMegawattCapacity;
                        electricChargeResource.amount    = maxStableMegaWattPower <= 0 ? 0 : Math.Min(electricChargeResource.maxAmount, electricChargeResource.amount);
                    }
                }
                previousTimeWarp = TimeWarp.fixedDeltaTime;

                // don't produce any power when our reactor has stopped
                if (maxStableMegaWattPower <= 0)
                {
                    PowerDown();
                    return;
                }
                else
                {
                    powerDownFraction = 1;
                }

                double electrical_power_currently_needed;

                if (myAttachedReactor.ShouldApplyBalance(chargedParticleMode ? ElectricGeneratorType.charged_particle : ElectricGeneratorType.thermal))
                {
                    var chargedPowerPerformance = myAttachedReactor.EfficencyConnectedChargedEnergyGenrator * myAttachedReactor.ChargedPowerRatio;
                    var thermalPowerPerformance = myAttachedReactor.EfficencyConnectedThermalEnergyGenrator * (1 - myAttachedReactor.ChargedPowerRatio);

                    var totalPerformance        = chargedPowerPerformance + thermalPowerPerformance;
                    var balancePerformanceRatio = (chargedParticleMode ? chargedPowerPerformance / totalPerformance : thermalPowerPerformance / totalPerformance);

                    electrical_power_currently_needed = (getCurrentUnfilledResourceDemand(FNResourceManager.FNRESOURCE_MEGAJOULES) + getSpareResourceCapacity(FNResourceManager.FNRESOURCE_MEGAJOULES)) * balancePerformanceRatio;
                }
                else
                {
                    electrical_power_currently_needed = getCurrentUnfilledResourceDemand(FNResourceManager.FNRESOURCE_MEGAJOULES) + getSpareResourceCapacity(FNResourceManager.FNRESOURCE_MEGAJOULES);
                }


                double electricdt       = 0;
                double electricdtps     = 0;
                double max_electricdtps = 0;

                if (!chargedParticleMode) // thermal mode
                {
                    double carnotEff = 1.0 - coldBathTemp / hotBathTemp;
                    _totalEff = carnotEff * pCarnotEff * myAttachedReactor.ThermalEnergyEfficiency;

                    myAttachedReactor.NotifyActiveThermalEnergyGenrator(_totalEff, ElectricGeneratorType.thermal);

                    if (_totalEff <= 0 || coldBathTemp <= 0 || hotBathTemp <= 0 || maxThermalPower <= 0)
                    {
                        return;
                    }

                    double thermal_power_currently_needed = electrical_power_currently_needed / _totalEff; // _totalEff;

                    double thermal_power_requested = Math.Max(Math.Min(maxThermalPower, thermal_power_currently_needed) * TimeWarp.fixedDeltaTime, 0.0);

                    requestedPower_f = (float)thermal_power_requested / TimeWarp.fixedDeltaTime;

                    double input_power = consumeFNResource(thermal_power_requested, FNResourceManager.FNRESOURCE_THERMALPOWER);

                    if (!(myAttachedReactor.EfficencyConnectedChargedEnergyGenrator > 0) && input_power < thermal_power_requested)
                    {
                        input_power += consumeFNResource(thermal_power_requested - input_power, FNResourceManager.FNRESOURCE_CHARGED_PARTICLES);
                    }

                    double wastedt = input_power * _totalEff;

                    consumeFNResource(wastedt, FNResourceManager.FNRESOURCE_WASTEHEAT);
                    electricdt       = input_power * _totalEff;
                    electricdtps     = Math.Max(electricdt / TimeWarp.fixedDeltaTime, 0.0);
                    max_electricdtps = maxThermalPower * _totalEff;
                }
                else // charged particle mode
                {
                    _totalEff = isupgraded ? upgradedDirectConversionEff : directConversionEff;

                    myAttachedReactor.NotifyActiveChargedEnergyGenrator(_totalEff, ElectricGeneratorType.charged_particle);

                    if (_totalEff <= 0)
                    {
                        return;
                    }

                    double charged_power_currently_needed = electrical_power_currently_needed; // _totalEff / ;

                    var charged_power_requested = Math.Max(Math.Min(maxChargedPower, charged_power_currently_needed) * TimeWarp.fixedDeltaTime, 0.0);

                    requestedPower_f = (float)charged_power_requested / TimeWarp.fixedDeltaTime;

                    double input_power = consumeFNResource(charged_power_requested, FNResourceManager.FNRESOURCE_CHARGED_PARTICLES);

                    electricdt   = input_power * _totalEff;
                    electricdtps = Math.Max(electricdt / TimeWarp.fixedDeltaTime, 0.0);
                    double wastedt = input_power * _totalEff;
                    max_electricdtps = maxChargedPower * _totalEff;
                    consumeFNResource(wastedt, FNResourceManager.FNRESOURCE_WASTEHEAT);
                }
                outputPower = -(float)supplyFNResourceFixedMax(electricdtps * TimeWarp.fixedDeltaTime, max_electricdtps * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES) / TimeWarp.fixedDeltaTime;
            }
            else
            {
                previousTimeWarp = TimeWarp.fixedDeltaTime;
                if (IsEnabled && !vessel.packed)
                {
                    if (!FNRadiator.hasRadiatorsForVessel(vessel))
                    {
                        IsEnabled = false;
                        Debug.Log("[WarpPlugin] Generator Shutdown: No radiators available!");
                        ScreenMessages.PostScreenMessage("Generator Shutdown: No radiators available!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                        PowerDown();
                    }

                    if (myAttachedReactor == null)
                    {
                        IsEnabled = false;
                        Debug.Log("[WarpPlugin] Generator Shutdown: No reactor available!");
                        ScreenMessages.PostScreenMessage("Generator Shutdown: No reactor available!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                        PowerDown();
                    }
                }
                else
                {
                    PowerDown();
                }
            }
        }