Skip to content

Commit

Permalink
Showing 8 changed files with 107 additions and 10 deletions.
76 changes: 76 additions & 0 deletions Source/Tooling/ModuleTooling.cs
Original file line number Diff line number Diff line change
@@ -133,5 +133,81 @@ public ModifierChangeWhen GetModuleCostChangeWhen()
{
return ModifierChangeWhen.FIXED;
}

/// <summary>
/// Use for purchasing multiple toolings at once. Does it's best to determine the best order to buy them so that the cost would be minimal.
/// Also deducuts the funds required for purchase.
/// Has an option for running a simulation to calculate the accurate cost of toolings while the tooling DB and funds are left untouched.
/// </summary>
/// <param name="toolingColl">Collection of toolings to purchase.</param>
/// <param name="isSimulation">Whether to simulate the purchase to get the accurate cost of all toolings.</param>
/// <returns>Total cost of all the toolings purchased.</returns>
public static float PurchaseToolingBatch(List<ModuleTooling> toolingColl, bool isSimulation = false)
{
ConfigNode toolingBackup = null;
if (isSimulation)
{
toolingBackup = new ConfigNode();
ToolingDatabase.Save(toolingBackup);
}

float totalCost = 0;
try
{
// Currently all cost reducers are applied correctly when the tooling types are first sorted in alphabetical order
toolingColl.Sort((mt1, mt2) => mt1.toolingType.CompareTo(mt2.toolingType));

//TODO: find the most optimal order to purchase toolings that have diameter and length.
// If there are diameters 2.9; 3 and 3.1 only 3 needs to be purchased and others will fit inside the stretch margin.

toolingColl.ForEach(mt =>
{
if (mt.IsUnlocked()) return;

totalCost += mt.GetToolingCost();
mt.PurchaseTooling();
});

if (totalCost > 0 && !isSimulation)
{
Funding.Instance.AddFunds(-totalCost, TransactionReasons.RnDPartPurchase);
}
}
finally
{
if (isSimulation)
{
ToolingDatabase.Load(toolingBackup);
}
}

return totalCost;
}

/// <summary>
/// Checks whether two toolings are considered the same by checking their types and dimensions (if applicable).
/// Dimension comparison is done with an error margin of 4%.
/// </summary>
/// <param name="a">Tooling 1</param>
/// <param name="b">Tooling 2</param>
/// <returns>True if toolings match</returns>
public static bool IsSame(ModuleTooling a, ModuleTooling b)
{
if (a.toolingType != b.toolingType) return false;

if (a is ModuleToolingDiamLen || b is ModuleToolingDiamLen)
{
var d1 = a as ModuleToolingDiamLen;
var d2 = b as ModuleToolingDiamLen;
if (d1 == null || d2 == null) return false;

d1.GetDimensions(out float diam1, out float len1);
d2.GetDimensions(out float diam2, out float len2);

return ToolingDatabase.IsSameSize(diam1, len1, diam2, len2);
}

return true;
}
}
}
2 changes: 1 addition & 1 deletion Source/Tooling/ModuleToolingDiamLen.cs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ namespace RP0
{
public abstract class ModuleToolingDiamLen : ModuleTooling
{
protected abstract void GetDimensions(out float diam, out float len);
public abstract void GetDimensions(out float diam, out float len);

public virtual string GetDimensions()
{
3 changes: 2 additions & 1 deletion Source/Tooling/ModuleToolingGeneric.cs
Original file line number Diff line number Diff line change
@@ -40,7 +40,8 @@ public override void OnLoad(ConfigNode node)
if (!string.IsNullOrEmpty(partModuleName))
pm = part.Modules[partModuleName];
}
protected override void GetDimensions(out float diam, out float len)

public override void GetDimensions(out float diam, out float len)
{
diam = 0f;
len = 0f;
3 changes: 2 additions & 1 deletion Source/Tooling/ModuleToolingPFSide.cs
Original file line number Diff line number Diff line change
@@ -23,7 +23,8 @@ public override void OnLoad(ConfigNode node)
base.OnLoad(node);
pm = part.Modules["ProceduralFairingSide"];
}
protected override void GetDimensions(out float diam, out float len)

public override void GetDimensions(out float diam, out float len)
{
diam = 0f;
len = 0f;
3 changes: 2 additions & 1 deletion Source/Tooling/ModuleToolingPTank.cs
Original file line number Diff line number Diff line change
@@ -20,7 +20,8 @@ public override void OnAwake()

procTank = part.Modules["ProceduralPart"];
}
protected override void GetDimensions(out float diam, out float len)

public override void GetDimensions(out float diam, out float len)
{
diam = 0f;
len = 0f;
3 changes: 2 additions & 1 deletion Source/Tooling/ModuleToolingSSTUTank.cs
Original file line number Diff line number Diff line change
@@ -24,7 +24,8 @@ public override void OnLoad(ConfigNode node)
// ******* 1.4+ SSTUTank = part.Modules["SSTUModularPart"];
SSTUTank = part.Modules["SSTUModularFuelTank"];
}
protected override void GetDimensions(out float diam, out float len)

public override void GetDimensions(out float diam, out float len)
{
diam = 0f;
len = 0f;
13 changes: 13 additions & 0 deletions Source/Tooling/ToolingDatabase.cs
Original file line number Diff line number Diff line change
@@ -99,6 +99,19 @@ public enum ToolingLevel
Full = 2
};

/// <summary>
/// Compares two tooling sizes and checks whether their diameter and length are within a predefined epsilon (currently 4%).
/// </summary>
/// <param name="diam1">Diameter of tooling 1</param>
/// <param name="len1">Length of tooling 1</param>
/// <param name="diam2">Diameter of tooling 2</param>
/// <param name="len2">Length of tooling 2</param>
/// <returns>True if the two tooling sizes are considered the same.</returns>
public static bool IsSameSize(float diam1, float len1, float diam2, float len2)
{
return EpsilonCompare(diam1, diam2) == 0 && EpsilonCompare(len1, len2) == 0;
}

public static ToolingLevel HasTooling(string type, float diam, float len)
{
List<ToolingDiameter> lst;
14 changes: 9 additions & 5 deletions Source/Tooling/ToolingGUI.cs
Original file line number Diff line number Diff line change
@@ -121,7 +121,11 @@ public tabs toolingTab()
try {
if (GUILayout.Button("Tool All"))
{
var totalToolingCost = untooledParts.Slinq().Select(up => up.toolingCost).Sum();
var untooledParts = EditorLogic.fetch.ship.Parts.Slinq().SelectMany(p => p.FindModulesImplementing<ModuleTooling>().Slinq())
.Where(mt => !mt.IsUnlocked())
.ToList();

float totalToolingCost = ModuleTooling.PurchaseToolingBatch(untooledParts, isSimulation: true);
bool canAfford = Funding.Instance.Funds >= totalToolingCost;
PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f),
new Vector2(0.5f, 0.5f),
@@ -139,11 +143,11 @@ public tabs toolingTab()
{
if (canAfford)
{
Funding.Instance.AddFunds(-totalToolingCost, TransactionReasons.RnDPartPurchase);
EditorLogic.fetch.ship.Parts.Slinq().SelectMany(p => p.FindModulesImplementing<ModuleTooling>().Slinq()).Where(mt => !mt.IsUnlocked()).ForEach(mt => {
mt.PurchaseTooling();
ModuleTooling.PurchaseToolingBatch(untooledParts);
untooledParts.ForEach(mt =>
{
mt.Events["ToolingEvent"].guiActiveEditor = false;
});
});
GameEvents.onEditorShipModified.Fire(EditorLogic.fetch.ship);
}
}, 140.0f, 30.0f, true),

0 comments on commit df13cd1

Please sign in to comment.