diff --git a/Source/Modules/ModuleSystemHeatHarvester.cs b/Source/Modules/ModuleSystemHeatHarvester.cs index 26c231c..42d40ee 100644 --- a/Source/Modules/ModuleSystemHeatHarvester.cs +++ b/Source/Modules/ModuleSystemHeatHarvester.cs @@ -4,6 +4,7 @@ using System.Text; using UnityEngine; using KSP.Localization; +using Unity.Profiling; namespace SystemHeat { @@ -49,10 +50,10 @@ public void ToggleEditorThermalSim() [KSPField(isPersistant = false, guiActive = true, guiActiveEditor = true, guiName = "Harvester Efficiency")] public string HarvesterEfficiency = "-1%"; - // base paramters - private List inputs; - private List outputs; protected ModuleSystemHeat heatModule; + + private static readonly ProfilerMarker BaseFixedUpdateMarker = new("ModuleResourceHarvester.FixedUpdate"); + public override string GetInfo() { string info = base.GetInfo(); @@ -60,117 +61,131 @@ public override string GetInfo() int pos = info.IndexOf("\n\n"); if (pos < 0) return info; - else - return info.Substring(0, pos) + Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_PartInfoAdd", - Utils.ToSI(systemPower, "F0"), - systemOutletTemperature.ToString("F0"), - shutdownTemperature.ToString("F0") - ) + info.Substring(pos); + + var extraInfo = Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_PartInfoAdd", + Utils.ToSI(systemPower, "F0"), + systemOutletTemperature.ToString("F0"), + shutdownTemperature.ToString("F0") + ); + return info.Substring(0, pos) + extraInfo + info.Substring(pos); } + public void Start() { + heatModule = ModuleUtils.FindHeatModule(part, systemHeatModuleID); - heatModule = ModuleUtils.FindHeatModule(this.part, systemHeatModuleID); + Utils.Log("[ModuleSystemHeatHarvester] Setup completed", LogType.Modules); + Events["ToggleEditorThermalSim"].guiName = Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_Field_SimulateEditor", ConverterName); + Fields["HarvesterEfficiency"].guiName = Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_Field_Efficiency", ConverterName); + } + public override void FixedUpdate() + { if (HighLogic.LoadedSceneIsFlight) { - SetupResourceRatios(); + FixedUpdateFlight(); } else { - SetupResourceRatios(); + UpdateFlux(); + Fields["HarvesterEfficiency"].guiActiveEditor = editorThermalSim; } + } - Utils.Log("[ModuleSystemHeatHarvester] Setup completed", LogType.Modules); - Events["ToggleEditorThermalSim"].guiName = Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_Field_SimulateEditor", base.ConverterName); - Fields["HarvesterEfficiency"].guiName = Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_Field_Efficiency", base.ConverterName); + void Update() + { + if (!part.IsPAWVisible()) + return; + + HarvesterEfficiency = Localizer.Format( + "#LOC_SystemHeat_ModuleSystemHeatHarvester_Field_Efficiency_Value", + (GetHeatThrottle() * 100f).ToString("F1") + ); } - public override void FixedUpdate() + + void OnDisable() { - base.FixedUpdate(); - if (heatModule != null) - { - if (HighLogic.LoadedSceneIsFlight) - { - GenerateHeatFlight(); - UpdateSystemHeatFlight(); - } - else if (HighLogic.LoadedSceneIsEditor) - { - GenerateHeatEditor(); - - Fields["HarvesterEfficiency"].guiActiveEditor = editorThermalSim; - } - } + heatModule?.AddFlux(moduleID, 0f, 0f, false); + HarvesterEfficiency = "-"; } - void Update() + void FixedUpdateFlight() { - if (heatModule != null && part.IsPAWVisible()) + if (heatModule == null) { - HarvesterEfficiency = Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_Field_Efficiency_Value", (systemEfficiency.Evaluate(heatModule.currentLoopTemperature) * 100f).ToString("F1")); + // This disables this module entirely, so it won't be called every frame. + enabled = false; + return; } - } - protected void GenerateHeatEditor() - { - if (base.IsActivated) - heatModule.AddFlux(moduleID, systemOutletTemperature, systemPower, true); - else - heatModule.AddFlux(moduleID, 0f, 0f, false); + CheckOverheat(); + + if (!IsActivated && !AlwaysActive) + enabled = false; + + using (BaseFixedUpdateMarker.ConditionalAuto()) + base.FixedUpdate(); } - protected void GenerateHeatFlight() + void UpdateFlux() => UpdateFlux(lastTimeFactor); + void UpdateFlux(double timeFactor) { - if (base.ModuleIsActive()) + if (heatModule == null) + return; + + if (ModuleIsActive()) { - float fluxScale = 1f; - if (base.lastTimeFactor == 0d) - { - fluxScale = 0f; - } - heatModule.AddFlux(moduleID, systemOutletTemperature, systemPower * fluxScale, true); + float scale = timeFactor != 0.0 ? 1f : 0f; + if (HighLogic.LoadedSceneIsEditor) + scale = 1f; + + heatModule.AddFlux(moduleID, systemOutletTemperature, systemPower * scale, true); } else { heatModule.AddFlux(moduleID, 0f, 0f, false); } } - protected void UpdateSystemHeatFlight() + + void CheckOverheat() { - if (base.ModuleIsActive()) - { - if (heatModule.currentLoopTemperature > shutdownTemperature) - { - ScreenMessages.PostScreenMessage( - new ScreenMessage( - Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_Message_Shutdown", - part.partInfo.title), - 3.0f, - ScreenMessageStyle.UPPER_CENTER)); - ToggleResourceConverterAction(new KSPActionParam(0, KSPActionType.Activate)); - - Utils.Log("[ModuleSystemHeatConverter]: Overheated, shutdown fired", LogType.Modules); - - } - base.recipe = ModuleUtils.RecalculateRatios(systemEfficiency.Evaluate(heatModule.currentLoopTemperature), inputs, outputs, inputList, outputList, base.recipe); - } + if (!ModuleIsActive()) + return; + if (heatModule.currentLoopTemperature <= shutdownTemperature) + return; + + ScreenMessages.PostScreenMessage( + new ScreenMessage( + Localizer.Format( + "#LOC_SystemHeat_ModuleSystemHeatHarvester_Message_Shutdown", + part.partInfo.title), + 3.0f, + ScreenMessageStyle.UPPER_CENTER)); + StopResourceConverter(); + + Utils.Log("[ModuleSystemHeatConverter]: Overheated, shutdown fired", LogType.Modules); } - private void SetupResourceRatios() + public override void StartResourceConverter() { + enabled = true; + base.StartResourceConverter(); + } - inputs = new List(); - outputs = new List(); + // In stock this would use the ModuleCoreHeat on the same part. We don't + // want that, and just override it to point to our own efficiency multiplier. + public override float GetHeatThrottle() + { + if (heatModule == null) + return 1f; - for (int i = 0; i < inputList.Count; i++) - { - inputs.Add(new ResourceBaseRatio(inputList[i].ResourceName, inputList[i].Ratio)); - } - for (int i = 0; i < outputList.Count; i++) - { - outputs.Add(new ResourceBaseRatio(outputList[i].ResourceName, outputList[i].Ratio)); - } + return systemEfficiency.Evaluate(heatModule.currentLoopTemperature); + } + + protected override void PostProcess(ConverterResults result, double deltaTime) + { + base.PostProcess(result, deltaTime); + UpdateFlux(result.TimeFactor); } } }