Skip to content

Commit

Permalink
Showing 4 changed files with 115 additions and 144 deletions.
119 changes: 88 additions & 31 deletions Source/EntryCosts/EntryCostDatabase.cs
Original file line number Diff line number Diff line change
@@ -9,51 +9,38 @@ namespace RP0
public class EntryCostDatabase
{
#region Fields
public static Dictionary<string, PartEntryCostHolder> partlist = null;
#region Instance
private static EntryCostDatabase _instance = null;
public static EntryCostDatabase Instance
{
get
{
if (_instance == null)
_instance = new EntryCostDatabase();

return _instance;
}
}
#endregion
protected static Dictionary<string, PartEntryCostHolder> holders = null;
protected static Dictionary<string, AvailablePart> nameToPart = null;
protected static HashSet<string> unlocks = null;
#endregion

#region Setup
public EntryCostDatabase()
{
Initialize();
}
public void Initialize()
public static void Initialize()
{
if (partlist == null)
{
partlist = new Dictionary<string, PartEntryCostHolder>();
if (nameToPart == null)
FillPartList();
}

if (holders == null)
FillHolders();

if (unlocks == null)
unlocks = new HashSet<string>();
}
public void FillPartList()
protected static void FillPartList()
{
// precalc our node dictionary
Dictionary<string, ConfigNode> partnodes = new Dictionary<string, ConfigNode>();
foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("ENTRYCOSTMODS"))
foreach (ConfigNode n in node.GetNodes("PART"))
if (n.HasValue("name"))
partnodes[n.GetValue("name")] = n;
nameToPart = new Dictionary<string, AvailablePart>();

// now fill our dictionary of parts
if (PartLoader.Instance == null || PartLoader.LoadedPartsList == null)
{
Debug.LogError("*RP-0 EC: ERROR: Partloader instance null or list null!");
return;
}
for (int a = PartLoader.LoadedPartsList.Count - 1; a >= 0; --a)
for (int a = PartLoader.LoadedPartsList.Count; a-- > 0;)
{
AvailablePart ap = PartLoader.LoadedPartsList[a];
if (ap == null)
@@ -63,10 +50,22 @@ public void FillPartList()
Part part = ap.partPrefab;
if (part != null)
{
ConfigNode partnode = null;
string name = GetPartName(ap);
if (partnodes.TryGetValue(name, out partnode))
partlist[name] = new PartEntryCostHolder(partnode, ap);
nameToPart[name] = ap;
}
}
}

protected static void FillHolders()
{
holders = new Dictionary<string, PartEntryCostHolder>();

foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("ENTRYCOSTMODS"))
{
foreach (ConfigNode.Value v in node.values)
{
PartEntryCostHolder p = new PartEntryCostHolder(v.name, v.value);
holders[p.name] = p;
}
}
}
@@ -85,20 +84,78 @@ public static string GetPartName(AvailablePart ap)
{
return GetPartName(ap.name);
}

public static string GetPartName(string partName)
{
partName = partName.Replace(".", "-");
return partName.Replace("_", "-");
}
#endregion

#region Interface
public static bool IsUnlocked(string name)
{
return unlocks.Contains(name) || RealFuels.RFUpgradeManager.Instance.ConfigUnlocked(name);
}

public static void SetUnlocked(string name)
{
// RF's current unlock system doesn't allow checking unlock status.
// HOWEVER if a name is not in the database, ConfigUnlocked returns true.
// That means we can know a config is present and locked by that
// returning false. So we take advantage.
if (!RealFuels.RFUpgradeManager.Instance.ConfigUnlocked(name))
RealFuels.RFUpgradeManager.Instance.SetConfigUnlock(name, true);

unlocks.Add(name); // add regardless
}

public static int GetCost(string name)
{
PartEntryCostHolder h;
if (holders.TryGetValue(name, out h))
return h.GetCost();

return 0;
}

public static void UpdateEntryCost(AvailablePart ap)
{
string name = GetPartName(ap);
PartEntryCostHolder h;
if (holders.TryGetValue(name, out h))
ap.SetEntryCost(h.GetCost());
}

public static void Save(ConfigNode node)
{
foreach (string s in unlocks)
{
node.AddValue(s, true);
}
}

public static void Load(ConfigNode node)
{
unlocks.Clear();

if (node == null)
return;

foreach (ConfigNode.Value v in node.values)
{
unlocks.Add(v.name);
}
}
#endregion
}

[KSPAddon(KSPAddon.Startup.MainMenu, true)]
public class EntryCostInitializer
{
public void Start()
{
EntryCostDatabase.Instance.Initialize();
EntryCostDatabase.Initialize();
}
}
}
29 changes: 5 additions & 24 deletions Source/EntryCosts/EntryCostModifier.cs
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ public override void OnAwake()
{
base.OnAwake();

EntryCostDatabase.Instance.Initialize(); // should not be needed though.
EntryCostDatabase.Initialize(); // should not be needed though.

GameEvents.OnPartPurchased.Add(new EventData<AvailablePart>.OnEvent(onPartPurchased));
}
@@ -26,11 +26,14 @@ public void OnDestroy()
public override void OnLoad(ConfigNode node)
{
base.OnLoad(node);
EntryCostDatabase.Load(node.GetNode("Unlocks"));
UpdatePartEntryCosts();
}
public override void OnSave(ConfigNode node)
{
base.OnSave(node);
EntryCostDatabase.Save(node.AddNode("Unlocks"));

}
#endregion

@@ -51,32 +54,10 @@ public void UpdatePartEntryCosts()
Part part = ap.partPrefab;
if (part != null)
{
string name = EntryCostDatabase.GetPartName(ap);
PartEntryCostHolder ec;
if (EntryCostDatabase.partlist.TryGetValue(name, out ec))
ec.UpdateCost();
EntryCostDatabase.UpdateEntryCost(ap);
}
}
}
public static double PartEntryCost(string partName)
{
PartEntryCostHolder ec = null;
if (EntryCostDatabase.partlist.TryGetValue(partName, out ec))
return ec.EntryCost();

Debug.LogError("*RP-0 EC: ERROR: entry cost modifier for " + partName + " does not exist!");
return 0d;
}

public static bool IsUnlocked(string partname)
{
PartEntryCostHolder partEC = null;
if (ResearchAndDevelopment.Instance != null)
if (EntryCostDatabase.partlist.TryGetValue(partname, out partEC))
return ResearchAndDevelopment.PartModelPurchased(partEC.ap);

return false;
}
#endregion
}
}
107 changes: 18 additions & 89 deletions Source/EntryCosts/PartEntryCostHolder.cs
Original file line number Diff line number Diff line change
@@ -9,108 +9,37 @@ public class PartEntryCostHolder
#region Fields
public string name;

public double entryCost = 0d;
public int cost = 0;

public double maxSubtraction = double.MaxValue;

public AvailablePart ap;

public Dictionary<string, double> entryCostMultipliers = new Dictionary<string, double>();
public Dictionary<string, double> entryCostSubtractors = new Dictionary<string, double>();
public List<string> children;
#endregion

#region Constructors
public PartEntryCostHolder(ConfigNode node, AvailablePart part, string Name = "")
public PartEntryCostHolder(string name, string val)
{
Load(node);
if(Name != "")
name = Name;
entryCost = part.entryCost;
ap = part;
this.name = name;

int tmp;
if (int.TryParse(val, out tmp))
cost = tmp;
else
children = new List<string>(val.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries));
}
#endregion

#region Methods
public void LoadMultipliers(ConfigNode node)
{
if (node == null)
return;

double dtmp;
foreach (ConfigNode.Value v in node.values)
{
if (double.TryParse(v.value, out dtmp))
entryCostMultipliers[v.name] = dtmp;
}
}
public void LoadSubtractors(ConfigNode node)
public int GetCost()
{
if (node == null)
return;

double dtmp;
foreach (ConfigNode.Value v in node.values)
{
if (double.TryParse(v.value, out dtmp))
entryCostSubtractors[v.name] = dtmp;
}
}

#region ConfigNode methods
public void Load(ConfigNode node)
{
double dtmp;

if (node.HasValue("name"))
name = node.GetValue("name");
if (EntryCostDatabase.IsUnlocked(name))
return 0;

if (node.HasValue("entryCost"))
{
if (double.TryParse(node.GetValue("entryCost"), out dtmp))
entryCost = dtmp;
}
int c = cost;

if (node.HasValue("maxSubtraction"))
if (double.TryParse(node.GetValue("maxSubtraction"), out dtmp))
maxSubtraction = dtmp;
if (children != null)
foreach (string s in children)
c += EntryCostDatabase.GetCost(name);

if (node.HasNode("entryCostMultipliers"))
LoadMultipliers(node.GetNode("entryCostMultipliers"));

if (node.HasNode("entryCostSubtractors"))
LoadSubtractors(node.GetNode("entryCostSubtractors"));
}
#endregion

protected double ModCost(double cost, double subtractMultipler = 1.0d)
{
double subtract = 0d;
foreach (KeyValuePair<string, double> kvp in entryCostSubtractors)
{
if (EntryCostModifier.IsUnlocked(kvp.Key))
subtract += kvp.Value * subtractMultipler;
}
subtract = Math.Min(maxSubtraction, subtract);
cost -= subtract;

foreach (KeyValuePair<string, double> kvp in entryCostMultipliers)
{
if (EntryCostModifier.IsUnlocked(kvp.Key))
cost *= kvp.Value;
}
if (cost > 0d)
return cost;

return 0d;
}
public double EntryCost()
{
return ModCost(entryCost);
}
public void UpdateCost()
{
if (ap != null)
ap.SetEntryCost((int)EntryCost());
return c;
}
#endregion
}
4 changes: 4 additions & 0 deletions Source/RP0.csproj
Original file line number Diff line number Diff line change
@@ -107,6 +107,10 @@
<HintPath>..\..\..\..\..\..\Games\Steam\steamapps\common\Kerbal Space Program\KSP_x64_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="RealFuels">
<HintPath>..\..\..\..\..\..\Games\Tree_122\GameData\RealFuels\Plugins\RealFuels.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System">
<Private>False</Private>
</Reference>

0 comments on commit e66d1e0

Please sign in to comment.