Skip to content

Commit

Permalink
Minor FuelInfo Refactor
Browse files Browse the repository at this point in the history
Add valid flag instead of checking ratioFactor or "efficiency" values
Simplify label creation
  • Loading branch information
DRVeyl committed Jul 3, 2022
1 parent 0aa8e6d commit 5fbffa0
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 37 deletions.
54 changes: 25 additions & 29 deletions Source/Tanks/FuelInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,30 @@ internal class FuelInfo
public readonly Dictionary<Propellant, double> propellantVolumeMults = new Dictionary<Propellant, double>();
public readonly double efficiency;
public readonly double ratioFactor;
public readonly bool valid;

// looks to see if we should ignore this fuel when creating an autofill for an engine
private static bool IgnoreFuel(string name) => MFSSettings.ignoreFuelsForFill.Contains(name);

private readonly List<string> labelString = new List<string>(10);
private string BuildLabel()
{
var text = StringBuilderCache.Acquire();
bool first = true;
labelString.Clear();
foreach (KeyValuePair<Propellant,double> kvp in propellantVolumeMults)
{
Propellant tfuel = kvp.Key;
double mult = kvp.Value;
if (PartResourceLibrary.Instance.GetDefinition(tfuel.name).resourceTransferMode != ResourceTransferMode.NONE && !IgnoreFuel(tfuel.name))
{
if (!first)
text.Append(" / ");
first = false;
text.Append(Math.Round(100000 * tfuel.ratio * mult / efficiency, 0) * 0.001).Append("% ").Append(tfuel.name);
}
labelString.Add($"{Math.Round(100 * tfuel.ratio * kvp.Value / efficiency, 3)}% {tfuel.name}");
}
return text.ToStringAndRelease();
return string.Join(" / ", labelString);
}

public FuelInfo(List<Propellant> props, ModuleFuelTanks tank, PartModule source)
{
// tank math:
// efficiency = sum[utilization * ratio]
// then final volume per fuel = fuel_ratio / fuel_utilization / efficiency
// efficiency = sum[ratio * volumePerUnit] == volume per [TotalRatio] unit draw of resources, not normalized
// volume per unit of fuel = fuel_ratio * volumePerUnit / sum[fuel_ratio * volumePerUnit]

this.source = source;
string _title = source.part.partInfo.title;
if (source.part.Modules.GetModule("ModuleEngineConfigs") is PartModule pm && pm != null)
Expand All @@ -51,26 +47,26 @@ public FuelInfo(List<Propellant> props, ModuleFuelTanks tank, PartModule source)
ratioFactor = 0.0;
efficiency = 0.0;

// Error conditions: Resource not defined in library, or resource has no tank and is not in IgnoreFuel
var missingRes = props.FirstOrDefault(p => PartResourceLibrary.Instance.GetDefinition(p.name) == null);
var noTanks = props.Where(p => !tank.tankList.ContainsKey(p.name));
bool noTanksAndNotIgnored = noTanks.Any(p => !IgnoreFuel(p.name));
if (missingRes != null)
Debug.LogError($"[MFT/RF] FuelInfo: Unknown RESOURCE: {missingRes.name}");

valid = missingRes == null && !noTanksAndNotIgnored;
if (!valid)
return;

foreach (Propellant tfuel in props)
{
PartResourceDefinition def = PartResourceLibrary.Instance.GetDefinition(tfuel.name);
if (def == null) {
Debug.LogError($"Unknown RESOURCE: {tfuel.name}");
ratioFactor = 0.0;
break;
}
if (!IgnoreFuel(tfuel.name))
if (PartResourceLibrary.Instance.GetDefinition(tfuel.name).resourceTransferMode != ResourceTransferMode.NONE
&& tank.tankList.TryGetValue(tfuel.name, out FuelTank t))
{
if (tank.tankList.TryGetValue(tfuel.name, out FuelTank t))
{
double volumeMultiplier = 1d / t.utilization;
efficiency += tfuel.ratio * volumeMultiplier;
ratioFactor += tfuel.ratio;
propellantVolumeMults.Add(tfuel, volumeMultiplier);
} else {
ratioFactor = 0.0;
break;
}
double volumePerUnit = 1d / t.utilization;
efficiency += tfuel.ratio * volumePerUnit;
ratioFactor += tfuel.ratio;
propellantVolumeMults.Add(tfuel, volumePerUnit);
}
}
Label = BuildLabel();
Expand Down
13 changes: 5 additions & 8 deletions Source/Tanks/ModuleFuelTanks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -429,9 +429,9 @@ private void UpdateTankType (bool initializeAmounts = false)

// Copy the tank list from the tank definitiion
if (!MFSSettings.tankDefinitions.TryGetValue(type, out TankDefinition def)) {
string msg = $"[ModuleFuelTanks] Somehow tried to set tank type to {type} but it has no definition.";
type = MFSSettings.tankDefinitions.ContainsKey(oldType) ? oldType : typesAvailable.First();
def = MFSSettings.tankDefinitions[type];
string msg = $"[ModuleFuelTanks] Tried to set tank type to {type} but it has no definition.";
string replacementType = oldType ?? typesAvailable.First();
type = MFSSettings.tankDefinitions.ContainsKey(replacementType) ? replacementType : typesAvailable.First();
Debug.LogError($"{msg} Reset to {type}");
}

Expand Down Expand Up @@ -827,9 +827,6 @@ private void SetUtilization(float value)
utilization = value;
}

// looks to see if we should ignore this fuel when creating an autofill for an engine
private static bool IgnoreFuel(string name) => MFSSettings.ignoreFuelsForFill.Contains(name);

internal readonly Dictionary<PartModule, FuelInfo> usedBy = new Dictionary<PartModule, FuelInfo>();
internal readonly HashSet<FuelTank> usedByTanks = new HashSet<FuelTank>();

Expand Down Expand Up @@ -865,7 +862,7 @@ public void UpdateUsedBy()
f = new FuelInfo((m as ModuleEngines).propellants, this, m);
else if (m is ModuleRCS)
f = new FuelInfo((m as ModuleRCS).propellants, this, m);
if (f?.ratioFactor > 0d)
if (f?.valid == true)
UpdateFuelInfo(f, m);
}
}
Expand Down Expand Up @@ -924,7 +921,7 @@ public void ConfigureFor(Part engine)

internal void ConfigureFor(FuelInfo fi)
{
if (fi.ratioFactor == 0.0 || fi.efficiency == 0) // can't configure for this engine
if (!fi.valid) // can't configure for this engine
return;

double availableVolume = AvailableVolume;
Expand Down

0 comments on commit 5fbffa0

Please sign in to comment.