private void ApplyCorrectProcTankVolume(float extraVolumeLiters, float ecAmount) { var fiUtil = typeof(ModuleFuelTanks).GetField("utilization", BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); float utilizationPercent = (float)fiUtil.GetValue(_rfPM); float utilization = utilizationPercent / 100; float avVolume = GetAvionicsVolume(); // The amount of final available volume that RF tanks get is calculated in 4 steps: // 1) ModuleProceduralAvionics.GetAvailableVolume() // 2) SphericalTankUtilities.GetSphericalTankVolume() // 3) RF tank's utilization (the slider in the PAW) // 4) RF (internal) tank's per-resource utilization value. // This is currently set at 1000 for EC which means that 1l of volume can hold 1000 units of EC. // The code below runs all these but in reversed order. float lVolStep4 = ecAmount / _ecTank.utilization; float lVolStep3 = (lVolStep4 + extraVolumeLiters) / utilization; float m3VolStep3 = lVolStep3 / 1000; // RF volumes are in liters but avionics uses m³ float m3VolStep2 = SphericalTankUtilities.GetRequiredVolumeFromSphericalTankVolume(m3VolStep3); float m3TotalVolume = Math.Max((InternalTanksAvailableVolumeUtilization * avVolume + m3VolStep2) / InternalTanksAvailableVolumeUtilization, m3VolStep2 / InternalTanksTotalVolumeUtilization); Log($"Applying volume {m3TotalVolume}; avionics: {avVolume * 1000}l; tanks: {(m3TotalVolume - avVolume) * 1000}l"); SeekVolume(m3TotalVolume); }
private void SendRemainingVolume() { if (cachedVolume == float.MaxValue) { return; } Events[nameof(OnPartVolumeChanged)].active = false; InternalTanksVolume = SphericalTankUtilities.GetSphericalTankVolume(GetAvailableVolume()); SendVolumeChangedEvent(InternalTanksVolume); Events[nameof(OnPartVolumeChanged)].active = true; }
private void SendRemainingVolume() { if (_started && cachedVolume < float.MaxValue) { Events[nameof(OnPartVolumeChanged)].active = false; InternalTanksVolume = SphericalTankUtilities.GetSphericalTankVolume(GetAvailableVolume()); float availVol = GetAvailableVolume(); Log($"SendRemainingVolume(): Cached Volume: {cachedVolume}. AvionicsVolume: {GetAvionicsVolume()}. AvailableVolume: {availVol}. Internal Tanks: {InternalTanksVolume}"); SendVolumeChangedEvent(InternalTanksVolume); Events[nameof(OnPartVolumeChanged)].active = true; } }
private float GetInternalTankDiameter(float externalDiameter, float length) { var maxDiameter = Mathf.Min(externalDiameter * 2 / 3, length); var internalTankDiameter = SphericalTankUtilities.GetSphericalTankRadius(_procAvionics.InternalTanksVolume) * 2; while (internalTankDiameter > maxDiameter) { internalTankDiameter /= 2; } return(internalTankDiameter); }
private float GetInternalTankModuleCost() { if (_procAvionics.InternalTanksVolume == 0) { return(0); } GetDimensions(out var externalDiameter, out var length); var internalTankDiameter = GetInternalTankDiameter(externalDiameter, length); var tankCount = _procAvionics.InternalTanksVolume / SphericalTankUtilities.GetSphereVolume(internalTankDiameter / 2); var costMultDL = TankToolingDefinition?.costMultiplierDL ?? 0f; return(GetDimensionModuleCost(internalTankDiameter, length, costMultDL) * tankCount); }
private void SendRemainingVolume() { Profiler.BeginSample("RP0ProcAvi SendRemainingVolume"); if (_started && _cachedVolume < float.MaxValue) { Events[nameof(OnPartVolumeChanged)].active = false; InternalTanksVolume = SphericalTankUtilities.GetSphericalTankVolume(GetAvailableVolume()); float availVol = GetAvailableVolume(); Log($"SendRemainingVolume(): Cached Volume: {_cachedVolume}. AvionicsVolume: {GetAvionicsVolume()}. AvailableVolume: {availVol}. Internal Tanks: {InternalTanksVolume}"); SendVolumeChangedEvent(InternalTanksVolume); _rfPM?.CalculateMass(); Events[nameof(OnPartVolumeChanged)].active = true; } Profiler.EndSample(); }