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(); } } }
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(); } } }