예제 #1
0
        private RadiatorManager(FNRadiator radiator)
        {
            UpdatingRadiator = radiator;

            // determine number of upgrade techs
            NrAvailableUpgradeTechs = 1;
            if (PluginHelper.upgradeAvailable(PluginHelper.RadiatorUpgradeTech4))
            {
                NrAvailableUpgradeTechs++;
            }
            if (PluginHelper.upgradeAvailable(PluginHelper.RadiatorUpgradeTech3))
            {
                NrAvailableUpgradeTechs++;
            }
            if (PluginHelper.upgradeAvailable(PluginHelper.RadiatorUpgradeTech2))
            {
                NrAvailableUpgradeTechs++;
            }
            if (PluginHelper.upgradeAvailable(PluginHelper.RadiatorUpgradeTech1))
            {
                NrAvailableUpgradeTechs++;
            }

            // determine fusion tech levels
            if (NrAvailableUpgradeTechs == 5)
            {
                CurrentGenerationType = GenerationType.Mk5;
            }
            else if (NrAvailableUpgradeTechs == 4)
            {
                CurrentGenerationType = GenerationType.Mk4;
            }
            else if (NrAvailableUpgradeTechs == 3)
            {
                CurrentGenerationType = GenerationType.Mk3;
            }
            else if (NrAvailableUpgradeTechs == 2)
            {
                CurrentGenerationType = GenerationType.Mk2;
            }
            else
            {
                CurrentGenerationType = GenerationType.Mk1;
            }

            MaxVacuumTemperatureTitanium = PluginHelper.RadiatorTemperatureMk3;
            if (CurrentGenerationType == GenerationType.Mk5)
            {
                MaxVacuumTemperatureGraphene = PluginHelper.RadiatorTemperatureMk5;
            }
            else if (CurrentGenerationType == GenerationType.Mk4)
            {
                MaxVacuumTemperatureGraphene = PluginHelper.RadiatorTemperatureMk4;
            }
            else if (CurrentGenerationType == GenerationType.Mk3)
            {
                MaxVacuumTemperatureTitanium = MaxVacuumTemperatureGraphene = PluginHelper.RadiatorTemperatureMk3;
            }
            else if (CurrentGenerationType == GenerationType.Mk2)
            {
                MaxVacuumTemperatureTitanium = MaxVacuumTemperatureGraphene = PluginHelper.RadiatorTemperatureMk2;
            }
            else
            {
                MaxVacuumTemperatureTitanium = MaxVacuumTemperatureGraphene = PluginHelper.RadiatorTemperatureMk1;
            }
        }
예제 #2
0
        public override void OnFixedUpdateResourceSuppliable(float fixedDeltaTime)
        {
            if (IsEnabled && attachedPowerSource != null && FNRadiator.hasRadiatorsForVessel(vessel))
            {
                UpdateGeneratorPower();

                // check if MaxStableMegaWattPower is changed
                maxStableMegaWattPower = fullPowerBuffer && attachedPowerSource != null
                    ? attachedPowerSource.StableMaximumReactorPower
                    : MaxStableMegaWattPower;

                if (maintainsMegaWattPowerBuffer)
                {
                    UpdateMegaWattPowerBuffer();
                }

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

                double electricdtps     = 0;
                double max_electricdtps = 0;

                if (!chargedParticleMode) // thermal mode
                {
                    carnotEff = Math.Max(Math.Min(1.0f - coldBathTemp / hotBathTemp, 1), 0);

                    _totalEff = Math.Min(pCarnotEff, carnotEff * pCarnotEff * attachedPowerSource.ThermalEnergyEfficiency);

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

                    attachedPowerSource.NotifyActiveThermalEnergyGenerator(_totalEff, ElectricGeneratorType.thermal);

                    double thermal_power_currently_needed_per_second = CalculateElectricalPowerCurrentlyNeeded();

                    var effective_thermal_power_needed = thermal_power_currently_needed_per_second / _totalEff;

                    var adjusted_thermal_power_needed = applies_balance
                        ? effective_thermal_power_needed
                        : effective_thermal_power_needed * (1 - attachedPowerSource.ChargedPowerRatio);

                    double thermal_power_requested_per_second = Math.Max(Math.Min(maxThermalPower, adjusted_thermal_power_needed), attachedPowerSource.MinimumPower * (1 - attachedPowerSource.ChargedPowerRatio));
                    double reactor_power_requested_per_second = Math.Max(Math.Min(maxReactorPower, effective_thermal_power_needed), attachedPowerSource.MinimumPower);

                    requested_power_per_second = thermal_power_requested_per_second;

                    attachedPowerSource.RequestedThermalHeat = thermal_power_requested_per_second;

                    double thermal_power_received_per_second = consumeFNResourcePerSecond(thermal_power_requested_per_second, FNResourceManager.FNRESOURCE_THERMALPOWER);

                    if (attachedPowerSource.EfficencyConnectedChargedEnergyGenerator == 0 && thermal_power_received_per_second < reactor_power_requested_per_second && attachedPowerSource.ChargedPowerRatio > 0.001)
                    {
                        var requested_charged_power_per_second = Math.Min(reactor_power_requested_per_second - thermal_power_received_per_second, maxChargedPower);

                        if (requested_charged_power_per_second < 0.000025)
                        {
                            thermal_power_received_per_second += requested_charged_power_per_second;
                        }
                        else
                        {
                            thermal_power_received_per_second += consumeFNResourcePerSecond(requested_charged_power_per_second, FNResourceManager.FNRESOURCE_CHARGED_PARTICLES);
                        }
                    }

                    var effective_input_power_per_second = thermal_power_received_per_second * _totalEff;

                    if (!CheatOptions.IgnoreMaxTemperature)
                    {
                        consumeFNResourcePerSecond(effective_input_power_per_second, FNResourceManager.FNRESOURCE_WASTEHEAT);
                    }

                    electricdtps = Math.Max(effective_input_power_per_second, 0.0);

                    var effectiveMaxThermalPower = attachedPowerSource.EfficencyConnectedChargedEnergyGenerator == 0 ? maxReactorPower : maxThermalPower;

                    max_electricdtps = effectiveMaxThermalPower * _totalEff;
                }
                else // charged particle mode
                {
                    _totalEff = isupgraded ? upgradedDirectConversionEff : directConversionEff;

                    attachedPowerSource.NotifyActiveChargedEnergyGenerator(_totalEff, ElectricGeneratorType.charged_particle);

                    if (_totalEff <= 0)
                    {
                        return;
                    }

                    double charged_power_currently_needed = CalculateElectricalPowerCurrentlyNeeded();

                    requested_power_per_second = Math.Max(Math.Min(maxChargedPower, charged_power_currently_needed / _totalEff), attachedPowerSource.MinimumPower * attachedPowerSource.ChargedPowerRatio);

                    double received_power_per_second = consumeFNResourcePerSecond(requested_power_per_second, FNResourceManager.FNRESOURCE_CHARGED_PARTICLES);

                    var effective_input_power_per_second = received_power_per_second * _totalEff;

                    if (!CheatOptions.IgnoreMaxTemperature)
                    {
                        consumeFNResourcePerSecond(effective_input_power_per_second, FNResourceManager.FNRESOURCE_WASTEHEAT);
                    }

                    electricdtps     = Math.Max(effective_input_power_per_second, 0.0);
                    max_electricdtps = maxChargedPower * _totalEff;
                }
                outputPower = -supplyFNResourcePerSecondWithMax(electricdtps, max_electricdtps, FNResourceManager.FNRESOURCE_MEGAJOULES);
            }
            else
            {
                if (attachedPowerSource != null)
                {
                    attachedPowerSource.RequestedThermalHeat = 0;
                }

                previousDeltaTime = 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 (attachedPowerSource == 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();
                }
            }
        }
예제 #3
0
        public override void OnFixedUpdate()
        {
            //  base.OnFixedUpdate();
            temperatureStr = part.temperature.ToString("0.00") + "K / " + part.maxTemp.ToString("0.00") + "K";
            MinIsp         = BaseFloatCurve.Evaluate((float)Altitude);

            // part.ona

            if (curEngineT == null || !curEngineT.isEnabled)
            {
                return;
            }

            throttle = curEngineT.currentThrottle > MinThrottleRatio ? curEngineT.currentThrottle : 0;

            if (throttle > 0)
            {
                if (vessel.atmDensity > maxAtmosphereDensity)
                {
                    ShutDown("Inertial Fusion cannot operate in atmosphere!");
                }

                if (radhazard && rad_safety_features)
                {
                    ShutDown("Engines throttled down as they presently pose a radiation hazard");
                }

                if (SelectedIsp <= 10)
                {
                    ShutDown("Engine Stall");
                }
            }

            KillKerbalsWithRadiation(throttle);

            if (throttle > 0)
            {
                // Calculate Fusion Ratio
                enginePowerRequirement = CurrentPowerRequirement;
                var requestedPowerPerSecond = enginePowerRequirement;

                var availablePower          = getAvailableResourceSupply(ResourceManager.FNRESOURCE_MEGAJOULES);
                var resourceBarRatio        = getResourceBarRatio(ResourceManager.FNRESOURCE_MEGAJOULES);
                var effectivePowerThrotling = resourceBarRatio > ResourceManager.ONE_THIRD ? 1 : resourceBarRatio * 3;

                var requestedPower = Math.Min(requestedPowerPerSecond, availablePower * effectivePowerThrotling);

                double recievedPowerPerSecond = CheatOptions.InfiniteElectricity
                    ? requestedPowerPerSecond
                    : consumeFNResourcePerSecond(requestedPower, ResourceManager.FNRESOURCE_MEGAJOULES);

                var plasma_ratio = recievedPowerPerSecond / requestedPowerPerSecond;
                fusionRatio = plasma_ratio;

                laserWasteheat = recievedPowerPerSecond * (1 - LaserEfficiency);

                // Lasers produce Wasteheat
                if (!CheatOptions.IgnoreMaxTemperature)
                {
                    supplyFNResourcePerSecond(laserWasteheat, ResourceManager.FNRESOURCE_WASTEHEAT);
                }

                // The Aborbed wasteheat from Fusion
                var rateMultplier        = MinIsp / SelectedIsp;
                var neutronbsorbionBonus = 1 - NeutronAbsorptionFractionAtMinIsp * (1 - ((SelectedIsp - MinIsp) / (MaxIsp - MinIsp)));
                absorbedWasteheat = FusionWasteHeat * wasteHeatMultiplier * fusionRatio * throttle * neutronbsorbionBonus;
                supplyFNResourcePerSecond(absorbedWasteheat, ResourceManager.FNRESOURCE_WASTEHEAT);

                // change ratio propellants Hydrogen/Fusion
                SetRatio(InterstellarResourcesConfiguration.Instance.LqdDeuterium, (float)standard_deuterium_rate / rateMultplier);
                SetRatio(InterstellarResourcesConfiguration.Instance.LqdTritium, (float)standard_tritium_rate / rateMultplier);

                // Update ISP
                var currentIsp = SelectedIsp;
                UpdateISP();

                maximumThrust = MaximumThrust;

                // Update FuelFlow
                var maxFuelFlow = fusionRatio * maximumThrust / currentIsp / PluginHelper.GravityConstant;

                curEngineT.maxFuelFlow = (float)maxFuelFlow;
                curEngineT.maxThrust   = (float)maximumThrust;

                if (!curEngineT.getFlameoutState && plasma_ratio < 0.75 && recievedPowerPerSecond > 0)
                {
                    curEngineT.status = "Insufficient Electricity";
                }
            }
            else
            {
                enginePowerRequirement = 0;
                absorbedWasteheat      = 0;
                laserWasteheat         = 0;
                fusionRatio            = 0;
                var currentIsp = SelectedIsp;

                maximumThrust = MaximumThrust;

                UpdateISP();
                curEngineT.maxThrust = (float)maximumThrust;
                var rateMultplier = MinIsp / SelectedIsp;

                var maxFuelFlow = maximumThrust / currentIsp / PluginHelper.GravityConstant;
                curEngineT.maxFuelFlow = (float)maxFuelFlow;
                SetRatio(InterstellarResourcesConfiguration.Instance.LqdDeuterium, (float)standard_deuterium_rate / rateMultplier);
                SetRatio(InterstellarResourcesConfiguration.Instance.LqdTritium, (float)standard_tritium_rate / rateMultplier);
            }

            coldBathTemp          = FNRadiator.getAverageRadiatorTemperatureForVessel(vessel);
            maxTempatureRadiators = FNRadiator.getAverageMaximumRadiatorTemperatureForVessel(vessel);
            radiatorPerformance   = Math.Max(1 - (coldBathTemp / maxTempatureRadiators), 0.000001);
            partEmissiveConstant  = part.emissiveConstant;
            base.OnFixedUpdate();
        }
        public override void OnFixedUpdate()
        {
            temperatureStr = part.temperature.ToString("0.00") + "K / " + part.maxTemp.ToString("0.00") + "K";

            resourceBuffers.UpdateVariable(ResourceManager.FNRESOURCE_WASTEHEAT, this.part.mass);
            resourceBuffers.UpdateBuffers();

            if (curEngineT == null)
            {
                return;
            }

            float throttle = curEngineT.currentThrottle > 0 ? Mathf.Max(curEngineT.currentThrottle, 0.01f) : 0;

            //double atmo_thrust_factor = Math.Min(1.0, Math.Max(1.0 - Math.Pow(vessel.atmDensity, 0.2), 0));

            if (throttle > 0)
            {
                if (vessel.atmDensity > maxAtmosphereDensity)
                {
                    ShutDown("Inertial Fusion cannot operate in atmosphere!");
                }

                if (radhazard && rad_safety_features)
                {
                    ShutDown("Engines throttled down as they presently pose a radiation hazard");
                }
            }

            KillKerbalsWithRadiation(throttle);

            coldBathTemp          = (float)FNRadiator.getAverageRadiatorTemperatureForVessel(vessel);
            maxTempatureRadiators = (float)FNRadiator.getAverageMaximumRadiatorTemperatureForVessel(vessel);

            if (throttle > 0)
            {
                // Calculate Fusion Ratio
                var recievedPower = CheatOptions.InfiniteElectricity
                    ? powerRequirement
                    : consumeFNResourcePerSecond(powerRequirement, ResourceManager.FNRESOURCE_MEGAJOULES);

                var plasma_ratio = recievedPower / powerRequirement;
                var fusionRatio  = plasma_ratio >= 1 ? 1 : plasma_ratio > 0.75 ? Math.Pow(plasma_ratio, 6.0) : 0;

                if (!CheatOptions.IgnoreMaxTemperature)
                {
                    // Lasers produce Wasteheat
                    supplyFNResourcePerSecond(recievedPower * (1 - efficiency), ResourceManager.FNRESOURCE_WASTEHEAT);

                    // The Aborbed wasteheat from Fusion
                    supplyFNResourcePerSecond(FusionWasteHeat * wasteHeatMultiplier * fusionRatio, ResourceManager.FNRESOURCE_WASTEHEAT);
                }

                // change ratio propellants Hydrogen/Fusion
                curEngineT.propellants.FirstOrDefault(pr => pr.name == InterstellarResourcesConfiguration.Instance.LqdDeuterium).ratio = (float)(standard_deuterium_rate / throttle / throttle);
                curEngineT.propellants.FirstOrDefault(pr => pr.name == InterstellarResourcesConfiguration.Instance.LqdTritium).ratio   = (float)(standard_tritium_rate / throttle / throttle);

                // Update ISP
                var newISP     = new FloatCurve();
                var currentIsp = Math.Max(minISP * fusionRatio / throttle, minISP / 10);
                newISP.Add(0, (float)currentIsp);
                curEngineT.atmosphereCurve = newISP;

                // Update FuelFlow
                var maxFuelFlow = fusionRatio * MaximumThrust / currentIsp / PluginHelper.GravityConstant;
                curEngineT.maxFuelFlow = Math.Max((float)maxFuelFlow, 0.0000001f);

                if (!curEngineT.getFlameoutState)
                {
                    if (plasma_ratio < 0.75 && recievedPower > 0)
                    {
                        curEngineT.status = "Insufficient Electricity";
                    }
                }
            }
            else
            {
                var currentIsp = minISP * 100;

                var newISP = new FloatCurve();
                newISP.Add(0, (float)currentIsp);
                curEngineT.atmosphereCurve = newISP;

                var maxFuelFlow = MaximumThrust / currentIsp / PluginHelper.GravityConstant;
                curEngineT.maxFuelFlow = (float)maxFuelFlow;

                curEngineT.propellants.FirstOrDefault(pr => pr.name == InterstellarResourcesConfiguration.Instance.LqdDeuterium).ratio = (float)(standard_deuterium_rate);
                curEngineT.propellants.FirstOrDefault(pr => pr.name == InterstellarResourcesConfiguration.Instance.LqdTritium).ratio   = (float)(standard_tritium_rate);
            }

            radiatorPerformance  = (float)Math.Max(1 - (float)(coldBathTemp / maxTempatureRadiators), 0.000001);
            partEmissiveConstant = (float)part.emissiveConstant;
        }
예제 #5
0
        public override void OnFixedUpdate()
        {
            base.OnFixedUpdate();
            if (IsEnabled && myAttachedReactor != null && FNRadiator.hasRadiatorsForVessel(vessel))
            {
                updateGeneratorPower();
                double electricdt        = 0;
                double electricdtps      = 0;
                double max_electricdtps  = 0;
                double input_power       = 0;
                double currentmegajoules = getSpareResourceCapacity(FNResourceManager.FNRESOURCE_MEGAJOULES) / TimeWarp.fixedDeltaTime;
                double electrical_power_currently_needed = (getCurrentUnfilledResourceDemand(FNResourceManager.FNRESOURCE_MEGAJOULES) + currentmegajoules);
                if (!chargedParticleMode)
                {
                    double carnotEff = 1.0 - coldBathTemp / hotBathTemp;
                    totalEff = carnotEff * pCarnotEff;
                    if (totalEff <= 0 || coldBathTemp <= 0 || hotBathTemp <= 0 || maxThermalPower <= 0)
                    {
                        return;
                    }
                    double thermal_power_currently_needed = electrical_power_currently_needed / totalEff;
                    double thermaldt = Math.Max(Math.Min(maxThermalPower, thermal_power_currently_needed) * TimeWarp.fixedDeltaTime, 0.0);
                    input_power = consumeFNResource(thermaldt, FNResourceManager.FNRESOURCE_THERMALPOWER);
                    if (input_power < thermaldt)
                    {
                        input_power += consumeFNResource(thermaldt - 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
                {
                    totalEff = 0.85;
                    double charged_power_currently_needed = electrical_power_currently_needed / totalEff;
                    input_power  = consumeFNResource(Math.Max(charged_power_currently_needed * TimeWarp.fixedDeltaTime, 0), 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);
                    //supplyFNResource(wastedt, FNResourceManager.FNRESOURCE_WASTEHEAT);
                }
                outputPower = -(float)supplyFNResourceFixedMax(electricdtps * TimeWarp.fixedDeltaTime, max_electricdtps * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES) / TimeWarp.fixedDeltaTime;
            }
            else
            {
                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);
                    }

                    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);
                    }
                }
            }
        }
        public override void OnFixedUpdateResourceSuppliable(double fixedDeltaTime)
        {
            temperatureStr = part.temperature.ToString("0.00") + "K / " + part.maxTemp.ToString("0.00") + "K";
            MinIsp         = BaseFloatCurve.Evaluate((float)Altitude);

            resourceBuffers.UpdateVariable(ResourceManager.FNRESOURCE_WASTEHEAT, this.part.mass);
            resourceBuffers.UpdateBuffers();

            if (curEngineT == null || !curEngineT.isEnabled)
            {
                return;
            }

            if (curEngineT.requestedThrottle > 0)
            {
                //if (vessel.atmDensity > maxAtmosphereDensity || vessel.atmDensity > _currentActiveConfiguration.maxAtmosphereDensity)
                //    ShutDown(Localizer.Format("#LOC_KSPIE_FusionECU2_PostMsg1"));//"Inertial Fusion cannot operate in atmosphere!"

                if (radhazard && rad_safety_features)
                {
                    ShutDown(Localizer.Format("#LOC_KSPIE_FusionECU2_PostMsg2"));//"Engines throttled down as they presently pose a radiation hazard"
                }
                //if (MinIsp <= 100)
                //    ShutDown(Localizer.Format("#LOC_KSPIE_FusionECU2_PostMsg3"));//"Engine Stall"
            }

            KillKerbalsWithRadiation(fusionRatio);

            hasIspThrottling = HasIspThrottling();

            ShowIspThrottle = hasIspThrottling;

            availablePower = Math.Max(getResourceAvailability(ResourceManager.FNRESOURCE_MEGAJOULES), getAvailablePrioritisedStableSupply(ResourceManager.FNRESOURCE_MEGAJOULES));

            currentMaximumPowerProduction  = GetCurrentMaximumPowerProduction();
            currentMaximumPowerRequirement = GetCurrentMaximumPowerRequirement();

            requiredPowerPerSecond = curEngineT.currentThrottle * currentMaximumPowerRequirement;

            if (curEngineT.currentThrottle > 0)
            {
                requestedPowerPerSecond = Math.Min(requiredPowerPerSecond, availablePower);

                recievedPowerPerSecond = requestedPowerPerSecond <= 0 ? 0
                    : CheatOptions.InfiniteElectricity
                        ? requiredPowerPerSecond
                        : consumeFNResourcePerSecond(requestedPowerPerSecond, ResourceManager.FNRESOURCE_MEGAJOULES);

                fusionRatio = requiredPowerPerSecond > 0 ? Math.Min(1, recievedPowerPerSecond / requiredPowerPerSecond) : 1;

                var inefficiency = 1 - LaserEfficiency;

                laserWasteheat         = recievedPowerPerSecond * inefficiency;
                producedPowerPerSecond = fusionRatio * currentMaximumPowerProduction;

                if (!CheatOptions.InfiniteElectricity && currentMaximumPowerProduction > 0)
                {
                    supplyFNResourcePerSecondWithMax(producedPowerPerSecond, currentMaximumPowerProduction, ResourceManager.FNRESOURCE_MEGAJOULES);
                }

                // Lasers produce Wasteheat
                if (!CheatOptions.IgnoreMaxTemperature && laserWasteheat > 0)
                {
                    supplyFNResourcePerSecondWithMax(laserWasteheat, currentMaximumPowerRequirement * inefficiency, ResourceManager.FNRESOURCE_WASTEHEAT);
                }

                // The Aborbed wasteheat from Fusion
                rateMultplier        = hasIspThrottling ? Math.Pow(SelectedIsp / MinIsp, 2) : 1;
                neutronbsorbionBonus = hasIspThrottling ? 1 - NeutronAbsorptionFractionAtMinIsp * (1 - ((SelectedIsp - MinIsp) / (MaxIsp - MinIsp))) : 0.5;
                absorbedWasteheat    = FusionWasteHeat * wasteHeatMultiplier * fusionRatio * curEngineT.currentThrottle * neutronbsorbionBonus;
                supplyFNResourcePerSecond(absorbedWasteheat, ResourceManager.FNRESOURCE_WASTEHEAT);

                SetRatios();

                currentIsp = hasIspThrottling ? SelectedIsp : MinIsp;
                UpdateAtmosphereCurve(currentIsp);
                maximumThrust = hasIspThrottling ? MaximumThrust : FullTrustMaximum;

                // Update FuelFlow
                maxFuelFlow = fusionRatio * maximumThrust / currentIsp / GameConstants.STANDARD_GRAVITY;

                if ((maxAtmosphereDensity >= 0 && vessel.atmDensity > maxAtmosphereDensity) ||
                    (_currentActiveConfiguration.maxAtmosphereDensity >= 0 && vessel.atmDensity > _currentActiveConfiguration.maxAtmosphereDensity))
                {
                    ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_KSPIE_FusionECU2_PostMsg1"), 1.0f, ScreenMessageStyle.UPPER_CENTER);
                    curEngineT.maxFuelFlow = 1e-10f;
                    curEngineT.maxThrust   = Mathf.Max((float)maximumThrust, 0.0001f);
                    HideExhaust();
                }
                else if (MinIsp < _currentActiveConfiguration.minIsp)
                {
                    ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_KSPIE_FusionECU2_PostMsg3"), 1.0f, ScreenMessageStyle.UPPER_CENTER);
                    curEngineT.maxFuelFlow = 1e-10f;
                    curEngineT.maxThrust   = Mathf.Max((float)maximumThrust, 0.0001f);
                    HideExhaust();
                }
                else
                {
                    curEngineT.maxFuelFlow = Mathf.Max((float)maxFuelFlow, 1e-10f);
                    curEngineT.maxThrust   = Mathf.Max((float)maximumThrust, 0.0001f);
                }

                if (!curEngineT.getFlameoutState && fusionRatio < 0.9 && recievedPowerPerSecond > 0)
                {
                    curEngineT.status = Localizer.Format("#LOC_KSPIE_FusionECU2_statu1");//"Insufficient Electricity"
                }
            }
            else
            {
                absorbedWasteheat       = 0;
                laserWasteheat          = 0;
                requestedPowerPerSecond = 0;
                recievedPowerPerSecond  = 0;

                fusionRatio = requiredPowerPerSecond > 0 ? Math.Min(1, availablePower / requiredPowerPerSecond) : 1;

                currentIsp    = hasIspThrottling ? SelectedIsp : MinIsp;
                maximumThrust = hasIspThrottling ? MaximumThrust : FullTrustMaximum;

                UpdateAtmosphereCurve(currentIsp);

                rateMultplier = hasIspThrottling ? Math.Pow(SelectedIsp / MinIsp, 2) : 1;

                maxFuelFlow = fusionRatio * maximumThrust / currentIsp / GameConstants.STANDARD_GRAVITY;

                if ((maxAtmosphereDensity >= 0 && vessel.atmDensity > maxAtmosphereDensity) ||
                    (_currentActiveConfiguration.maxAtmosphereDensity >= 0 && vessel.atmDensity > _currentActiveConfiguration.maxAtmosphereDensity))
                {
                    curEngineT.maxFuelFlow = 1e-10f;
                    curEngineT.maxThrust   = Mathf.Max((float)maximumThrust, 0.0001f);
                    HideExhaust();
                }
                else if (MinIsp < _currentActiveConfiguration.minIsp)
                {
                    curEngineT.maxFuelFlow = 1e-10f;
                    curEngineT.maxThrust   = Mathf.Max((float)maximumThrust, 0.0001f);
                    HideExhaust();
                }
                else
                {
                    curEngineT.maxFuelFlow = Mathf.Max((float)maxFuelFlow, 1e-10f);
                    curEngineT.maxThrust   = Mathf.Max((float)maximumThrust, 0.0001f);
                }

                SetRatios();
            }

            coldBathTemp          = FNRadiator.getAverageRadiatorTemperatureForVessel(vessel);
            maxTempatureRadiators = FNRadiator.getAverageMaximumRadiatorTemperatureForVessel(vessel);
            radiatorPerformance   = Math.Max(1 - (coldBathTemp / maxTempatureRadiators), 0.000001);
            partEmissiveConstant  = part.emissiveConstant;
            //base.OnFixedUpdate();
        }
        public override void OnFixedUpdate()
        {
            temperatureStr = part.temperature.ToString("0.00") + "K / " + part.maxTemp.ToString("0.00") + "K";
            MinIsp         = OrigFloatCurve.Evaluate((float)Altitude);

            // part.ona

            if (curEngineT == null)
            {
                return;
            }

            throttle = curEngineT.currentThrottle > MinThrottleRatio ? curEngineT.currentThrottle : 0;

            if (throttle > 0)
            {
                if (vessel.atmDensity > maxAtmosphereDensity)
                {
                    ShutDown("Inertial Fusion cannot operate in atmosphere!");
                }

                if (radhazard && rad_safety_features)
                {
                    ShutDown("Engines throttled down as they presently pose a radiation hazard");
                }

                if (SelectedIsp <= 10)
                {
                    ShutDown("Engine Stall");
                }
            }

            KillKerbalsWithRadiation(throttle);

            resourceBuffers.UpdateVariable(ResourceManager.FNRESOURCE_WASTEHEAT, this.part.mass);
            resourceBuffers.UpdateBuffers();

            if (throttle > 0)
            {
                // Calculate Fusion Ratio
                enginePowerRequirement = CurrentPowerRequirement;

                var recievedPowerFixed = CheatOptions.InfiniteElectricity
                    ? enginePowerRequirement
                    : consumeFNResourcePerSecond(enginePowerRequirement, ResourceManager.FNRESOURCE_MEGAJOULES);

                var plasma_ratio = recievedPowerFixed / enginePowerRequirement;
                fusionRatio = plasma_ratio >= 1 ? 1 : plasma_ratio > 0.75f ? Mathf.Pow((float)plasma_ratio, 6) : 0;

                laserWasteheat = recievedPowerFixed * (1 - LaserEfficiency);

                // Lasers produce Wasteheat
                if (!CheatOptions.IgnoreMaxTemperature)
                {
                    supplyFNResourcePerSecond(enginePowerRequirement, ResourceManager.FNRESOURCE_WASTEHEAT);
                }

                // The Absorbed wasteheat from Fusion
                var rateMultplier        = MinIsp / SelectedIsp;
                var neutronbsorbionBonus = 1 - NeutronAbsorptionFractionAtMinIsp * (1 - ((SelectedIsp - MinIsp) / (MaxIsp - MinIsp)));
                absorbedWasteheat = FusionWasteHeat * wasteHeatMultiplier * fusionRatio * throttle * neutronbsorbionBonus;
                supplyFNResourcePerSecond(absorbedWasteheat, ResourceManager.FNRESOURCE_WASTEHEAT);

                // change ratio propellants Hydrogen/Fusion
                curEngineT.propellants.FirstOrDefault(pr => pr.name == InterstellarResourcesConfiguration.Instance.LqdDeuterium).ratio = (float)standard_deuterium_rate / rateMultplier;
                curEngineT.propellants.FirstOrDefault(pr => pr.name == InterstellarResourcesConfiguration.Instance.LqdTritium).ratio   = (float)standard_tritium_rate / rateMultplier;

                // Update ISP
                var currentIsp = SelectedIsp;
                UpdateISP();

                // Update FuelFlow
                var maxFuelFlow = fusionRatio * MaximumThrust / currentIsp / GameConstants.STANDARD_GRAVITY;
                maximumThrust = (float)MaximumThrust;

                curEngineT.maxFuelFlow = (float)maxFuelFlow;
                curEngineT.maxThrust   = maximumThrust;


                if (!curEngineT.getFlameoutState && plasma_ratio < 0.75 && recievedPowerFixed > 0)
                {
                    curEngineT.status = "Insufficient Electricity";
                }
            }
            else
            {
                enginePowerRequirement = 0;
                absorbedWasteheat      = 0;
                laserWasteheat         = 0;
                fusionRatio            = 0;
                var currentIsp = SelectedIsp;

                UpdateISP();
                curEngineT.maxThrust = (float)MaximumThrust;
                var rateMultplier = MinIsp / SelectedIsp;

                var maxFuelFlow = MaximumThrust / currentIsp / GameConstants.STANDARD_GRAVITY;
                curEngineT.maxFuelFlow = (float)maxFuelFlow;
                curEngineT.propellants.FirstOrDefault(pr => pr.name == InterstellarResourcesConfiguration.Instance.LqdDeuterium).ratio = (float)(standard_deuterium_rate) / rateMultplier;
                curEngineT.propellants.FirstOrDefault(pr => pr.name == InterstellarResourcesConfiguration.Instance.LqdTritium).ratio   = (float)(standard_tritium_rate) / rateMultplier;
            }

            coldBathTemp          = (float)FNRadiator.getAverageRadiatorTemperatureForVessel(vessel);
            maxTempatureRadiators = (float)FNRadiator.getAverageMaximumRadiatorTemperatureForVessel(vessel);
            radiatorPerformance   = Mathf.Max(1 - (coldBathTemp / maxTempatureRadiators), 0.000001f);
            partEmissiveConstant  = (float)part.emissiveConstant;
        }
        public override void OnFixedUpdate()
        {
            temperatureStr = part.temperature.ToString("0.00") + "K / " + part.maxTemp.ToString("0.00") + "K";

            if (curEngineT == null)
            {
                return;
            }

            throttle = curEngineT.currentThrottle > MinThrottleRatio ? curEngineT.currentThrottle : 0;

            if (throttle > 0)
            {
                if (vessel.atmDensity > maxAtmosphereDensity)
                {
                    ShutDown("Inertial Fusion cannot operate in atmosphere!");
                }

                if (radhazard && rad_safety_features)
                {
                    ShutDown("Engines throttled down as they presently pose a radiation hazard");
                }
            }

            KillKerbalsWithRadiation(throttle);

            if (throttle > 0)
            {
                // Calculate Fusion Ratio
                enginePowerRequirement = CurrentPowerRequirement;
                var requestedPowerFixed = enginePowerRequirement * TimeWarp.fixedDeltaTime;

                var recievedPowerFixed = CheatOptions.InfiniteElectricity
                    ? requestedPowerFixed
                    : consumeFNResource(requestedPowerFixed, FNResourceManager.FNRESOURCE_MEGAJOULES);

                var plasma_ratio = recievedPowerFixed / requestedPowerFixed;
                fusionRatio = plasma_ratio >= 1 ? 1 : plasma_ratio > 0.75f ? Mathf.Pow((float)plasma_ratio, 6) : 0;

                var laserWasteheatFixed = recievedPowerFixed * (1 - LaserEfficiency);
                laserWasteheat = laserWasteheatFixed / TimeWarp.fixedDeltaTime;



                // The Aborbed wasteheat from Fusion
                var rateMultplier        = minISP / SelectedIsp;
                var neutronbsorbionBonus = 1 - NeutronAbsorptionFractionAtMinIsp * (1 - ((SelectedIsp - minISP) / (MaxIsp - minISP)));
                absorbedWasteheat = FusionWasteHeat * wasteHeatMultiplier * fusionRatio * throttle * neutronbsorbionBonus;

                // Lasers produce Wasteheat
                if (!CheatOptions.IgnoreMaxTemperature)
                {
                    supplyFNResource(laserWasteheatFixed, FNResourceManager.FNRESOURCE_WASTEHEAT);
                    supplyFNResource(absorbedWasteheat * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_WASTEHEAT);
                }

                // change ratio propellants Hydrogen/Fusion
                curEngineT.propellants.FirstOrDefault(pr => pr.name == InterstellarResourcesConfiguration.Instance.LqdDeuterium).ratio = (float)standard_deuterium_rate / rateMultplier;
                curEngineT.propellants.FirstOrDefault(pr => pr.name == InterstellarResourcesConfiguration.Instance.LqdTritium).ratio   = (float)standard_tritium_rate / rateMultplier;

                // Update ISP
                var        currentIsp = SelectedIsp;
                FloatCurve newISP     = new FloatCurve();
                newISP.Add(0, currentIsp);
                newISP.Add(1, 0);
                curEngineT.atmosphereCurve = newISP;

                // Update FuelFlow
                var maxFuelFlow = fusionRatio * MaximumThrust / currentIsp / PluginHelper.GravityConstant;
                curEngineT.maxFuelFlow = maxFuelFlow;
                curEngineT.maxThrust   = MaximumThrust;

                maximumThrust = MaximumThrust;

                if (!curEngineT.getFlameoutState && plasma_ratio < 0.75 && recievedPowerFixed > 0)
                {
                    curEngineT.status = "Insufficient Electricity";
                }
            }
            else
            {
                enginePowerRequirement = 0;
                absorbedWasteheat      = 0;
                laserWasteheat         = 0;
                fusionRatio            = 0;

                var        currentIsp = SelectedIsp;
                FloatCurve newISP     = new FloatCurve();
                newISP.Add(0, (float)currentIsp);
                newISP.Add(1, 0);
                curEngineT.atmosphereCurve = newISP;
                curEngineT.maxThrust       = MaximumThrust;
                var rateMultplier = minISP / SelectedIsp;

                var maxFuelFlow = MaximumThrust / currentIsp / PluginHelper.GravityConstant;
                curEngineT.maxFuelFlow = maxFuelFlow;
                curEngineT.propellants.FirstOrDefault(pr => pr.name == InterstellarResourcesConfiguration.Instance.LqdDeuterium).ratio = (float)(standard_deuterium_rate) / rateMultplier;
                curEngineT.propellants.FirstOrDefault(pr => pr.name == InterstellarResourcesConfiguration.Instance.LqdTritium).ratio   = (float)(standard_tritium_rate) / rateMultplier;
            }

            coldBathTemp          = (float)FNRadiator.getAverageRadiatorTemperatureForVessel(vessel);
            maxTempatureRadiators = (float)FNRadiator.getAverageMaximumRadiatorTemperatureForVessel(vessel);
            radiatorPerformance   = Mathf.Max(1 - (coldBathTemp / maxTempatureRadiators), 0.000001f);
            partEmissiveConstant  = (float)part.emissiveConstant;
        }
예제 #9
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();
                }
            }
        }
예제 #10
0
        public override void OnFixedUpdate()
        {
            temperatureStr = part.temperature.ToString("0.00") + "K / " + part.maxTemp.ToString("0.00") + "K";
            MinIsp         = BaseFloatCurve.Evaluate((float)Altitude);

            resourceBuffers.UpdateVariable(ResourceManager.FNRESOURCE_WASTEHEAT, this.part.mass);
            resourceBuffers.UpdateBuffers();

            if (curEngineT == null || !curEngineT.isEnabled)
            {
                return;
            }

            throttle = curEngineT.currentThrottle > MinThrottleRatio ? curEngineT.currentThrottle : 0;

            if (throttle > 0)
            {
                if (maxAtmosphereDensity >= 0 && vessel.atmDensity > maxAtmosphereDensity)
                {
                    ShutDown("Inertial Fusion cannot operate in atmosphere!");
                }

                if (radhazard && rad_safety_features)
                {
                    ShutDown("Engines throttled down as they presently pose a radiation hazard");
                }

                if (SelectedIsp <= 10)
                {
                    ShutDown("Engine Stall");
                }
            }

            KillKerbalsWithRadiation(fusionRatio);

            hasIspThrottling = HasIspThrottling();

            ShowIspThrottle = hasIspThrottling;

            if (throttle > 0)
            {
                // Calculate Fusion Ratio
                enginePowerRequirement = CurrentPowerRequirement;
                var requestedPowerPerSecond = enginePowerRequirement;

                var availablePower          = getAvailableStableSupply(ResourceManager.FNRESOURCE_MEGAJOULES);
                var resourceBarRatio        = getResourceBarRatio(ResourceManager.FNRESOURCE_MEGAJOULES);
                var effectivePowerThrotling = resourceBarRatio > ResourceManager.ONE_THIRD ? 1 : resourceBarRatio * 3;

                var requestedPower = Math.Min(requestedPowerPerSecond, availablePower * effectivePowerThrotling);

                var recievedPowerPerSecond = CheatOptions.InfiniteElectricity || requestedPower <= 0
                    ? requestedPowerPerSecond
                    : consumeFNResourcePerSecond(requestedPower, ResourceManager.FNRESOURCE_MEGAJOULES);

                fusionRatio = requestedPowerPerSecond > 0 ? recievedPowerPerSecond / requestedPowerPerSecond : 1;

                laserWasteheat = recievedPowerPerSecond * (1 - LaserEfficiency);

                // Lasers produce Wasteheat
                if (!CheatOptions.IgnoreMaxTemperature)
                {
                    supplyFNResourcePerSecond(laserWasteheat, ResourceManager.FNRESOURCE_WASTEHEAT);
                }

                // The Aborbed wasteheat from Fusion
                rateMultplier        = hasIspThrottling ? Math.Pow(SelectedIsp / MinIsp, 2) : 1;
                neutronbsorbionBonus = hasIspThrottling ? 1 - NeutronAbsorptionFractionAtMinIsp * (1 - ((SelectedIsp - MinIsp) / (MaxIsp - MinIsp))) : 0.5;
                absorbedWasteheat    = FusionWasteHeat * wasteHeatMultiplier * fusionRatio * throttle * neutronbsorbionBonus;
                supplyFNResourcePerSecond(absorbedWasteheat, ResourceManager.FNRESOURCE_WASTEHEAT);

                SetRatios();

                currentIsp = hasIspThrottling ? SelectedIsp : MinIsp;
                UpdateAtmosphereCurve(currentIsp);
                maximumThrust = hasIspThrottling ? MaximumThrust : FullTrustMaximum;

                // Update FuelFlow
                var maxFuelFlow = fusionRatio * maximumThrust / currentIsp / GameConstants.STANDARD_GRAVITY;

                curEngineT.maxFuelFlow = (float)maxFuelFlow;
                curEngineT.maxThrust   = (float)maximumThrust;

                if (!curEngineT.getFlameoutState && fusionRatio < 0.75 && recievedPowerPerSecond > 0)
                {
                    curEngineT.status = "Insufficient Electricity";
                }
            }
            else
            {
                enginePowerRequirement = 0;
                absorbedWasteheat      = 0;
                laserWasteheat         = 0;
                fusionRatio            = 0;
                currentIsp             = hasIspThrottling ? SelectedIsp : MinIsp;
                maximumThrust          = hasIspThrottling ? MaximumThrust : FullTrustMaximum;

                UpdateAtmosphereCurve(currentIsp);
                curEngineT.maxThrust = (float)maximumThrust;
                rateMultplier        = hasIspThrottling ? Math.Pow(SelectedIsp / MinIsp, 2) : 1;

                var maxFuelFlow = maximumThrust / currentIsp / GameConstants.STANDARD_GRAVITY;
                curEngineT.maxFuelFlow = (float)maxFuelFlow;

                SetRatios();
            }

            coldBathTemp          = FNRadiator.getAverageRadiatorTemperatureForVessel(vessel);
            maxTempatureRadiators = FNRadiator.getAverageMaximumRadiatorTemperatureForVessel(vessel);
            radiatorPerformance   = Math.Max(1 - (coldBathTemp / maxTempatureRadiators), 0.000001);
            partEmissiveConstant  = part.emissiveConstant;
            base.OnFixedUpdate();
        }
예제 #11
0
        public override void OnFixedUpdate()
        {
            base.OnFixedUpdate();

            powerCustomSettingFraction = powerPercentage / 100;

            if (IsEnabled && attachedThermalSource != null && FNRadiator.hasRadiatorsForVessel(vessel))
            {
                UpdateGeneratorPower();

                // check if MaxStableMegaWattPower is changed
                var maxStableMegaWattPower = MaxStableMegaWattPower;

                if (maintainsMegaWattPowerBuffer)
                {
                    UpdateMegaWattPowerBuffer(maxStableMegaWattPower);
                }

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

                double electricdtps     = 0;
                double max_electricdtps = 0;

                if (!chargedParticleMode) // thermal mode
                {
                    carnotEff = Math.Max(Math.Min(1.0f - coldBathTemp / hotBathTemp, 1), 0);
                    _totalEff = carnotEff * pCarnotEff * attachedThermalSource.ThermalEnergyEfficiency;

                    if (_totalEff <= 0.01 || coldBathTemp <= 0 || hotBathTemp <= 0 || maxThermalPower <= 0)
                    {
                        //requestedPower_f = 0;
                        //electricdtps = 0;
                        //max_electricdtps = 0;
                        //attachedThermalSource.RequestedThermalHeat = 0;
                        return;
                    }

                    attachedThermalSource.NotifyActiveThermalEnergyGenrator(_totalEff, ElectricGeneratorType.thermal);

                    double thermal_power_currently_needed = CalculateElectricalPowerCurrentlyNeeded();

                    double thermal_power_requested_fixed = Math.Max(Math.Min(maxThermalPower, thermal_power_currently_needed / _totalEff) * TimeWarp.fixedDeltaTime, 0);

                    requestedPower_f = (float)thermal_power_requested_fixed / TimeWarp.fixedDeltaTime;

                    attachedThermalSource.RequestedThermalHeat = thermal_power_requested_fixed / TimeWarp.fixedDeltaTime;
                    double input_power = consumeFNResource(thermal_power_requested_fixed, FNResourceManager.FNRESOURCE_THERMALPOWER);

                    if (!(attachedThermalSource.EfficencyConnectedChargedEnergyGenerator > 0) && input_power < thermal_power_requested_fixed)
                    {
                        input_power += consumeFNResource(thermal_power_requested_fixed - input_power, FNResourceManager.FNRESOURCE_CHARGED_PARTICLES);
                    }

                    var effective_input_power = input_power * _totalEff;

                    consumeFNResource(effective_input_power, FNResourceManager.FNRESOURCE_WASTEHEAT);

                    electricdtps     = Math.Max(effective_input_power / TimeWarp.fixedDeltaTime, 0.0);
                    max_electricdtps = maxThermalPower * _totalEff * powerCustomSettingFraction;
                }
                else // charged particle mode
                {
                    _totalEff = isupgraded ? upgradedDirectConversionEff : directConversionEff;

                    attachedThermalSource.NotifyActiveChargedEnergyGenrator(_totalEff, ElectricGeneratorType.charged_particle);

                    if (_totalEff <= 0)
                    {
                        return;
                    }

                    double charged_power_currently_needed = CalculateElectricalPowerCurrentlyNeeded();

                    //var minimumPowerRequirement = maxChargedPower * _totalEff * attachedThermalSource.MinimumThrottle;

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

                    requestedPower_f = (float)charged_power_requested / TimeWarp.fixedDeltaTime;

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

                    var effective_input_power = input_power * _totalEff;

                    consumeFNResource(effective_input_power, FNResourceManager.FNRESOURCE_WASTEHEAT);

                    electricdtps     = Math.Max(effective_input_power / TimeWarp.fixedDeltaTime, 0.0);
                    max_electricdtps = maxChargedPower * _totalEff * powerCustomSettingFraction;
                }
                outputPower = -(float)supplyFNResourceFixedMax(electricdtps * TimeWarp.fixedDeltaTime, max_electricdtps * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES) / TimeWarp.fixedDeltaTime;
            }
            else
            {
                if (attachedThermalSource != null)
                {
                    attachedThermalSource.RequestedThermalHeat = 0;
                }

                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 (attachedThermalSource == 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();
                }
            }
        }
예제 #12
0
        public void updateGeneratorPower()
        {
            if (attachedThermalSource == null)
            {
                return;
            }

            var wasteHeateModifier = 1.0f - (float)getResourceBarRatio(FNResourceManager.FNRESOURCE_WASTEHEAT);

            hotBathTemp  = attachedThermalSource.HotBathTemperature + wasteHeateModifier * FNRadiator.getAverageMaximumRadiatorTemperatureForVessel(vessel);
            coldBathTemp = (float)FNRadiator.getAverageRadiatorTemperatureForVessel(vessel);

            if (HighLogic.LoadedSceneIsEditor)
            {
                UpdateHeatExchangedThrustDivisor();
            }

            maxThermalPower = attachedThermalSource.MaximumThermalPower * (powerPercentage / 100);
            if (attachedThermalSource.EfficencyConnectedChargedEnergyGenrator == 0)
            {
                maxThermalPower += attachedThermalSource.MaximumChargedPower;
            }
            maxChargedPower = attachedThermalSource.MaximumChargedPower;
        }