Skip to content

Commit

Permalink
Fixed issue with part variants where it wasn't changing the mass of t…
Browse files Browse the repository at this point in the history
…he part variant, resulting in negative numbers on occasion
  • Loading branch information
linuxgurugamer committed Mar 17, 2020
1 parent 88a0a3a commit c8fd32c
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 19 deletions.
Binary file modified .vs/KRnD/v16/Server/sqlite3/storage.ide
Binary file not shown.
3 changes: 3 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
Changelog

1.16.0.3
Fixed issue with part variants where it wasn't changing the mass of the part variant, resulting in negative numbers on occasion

1.16.0.2
Moved initialization of GUIStyles into Start
Made window 70 pixels higher, thanks to @leatherneck6017 for the change
Expand Down
2 changes: 1 addition & 1 deletion KRnD.version
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"MAJOR": 1,
"MINOR": 16,
"PATCH": 0,
"BUILD": 2
"BUILD": 3
},
"KSP_VERSION_MIN": {
"MAJOR": 1,
Expand Down
88 changes: 75 additions & 13 deletions Source/KRnD.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,45 @@ public static KRnDModule getKRnDModule(Part part)
return null;
}

// Parts can have multiple variants which we return as a list, needed
// because some variants change the part mass
public static Dictionary<string, KRnDVariant> getVariants(Part part)
{
if (part == null) return null;
if (part.partInfo.partPrefab == null) return null;

if (part.partInfo.Variants == null) return null;

Dictionary<string, KRnDVariant> variants = new Dictionary<string, KRnDVariant>();

for (int i = 0; i < part.partInfo.Variants.Count; i++)
{
var partVariant = part.partInfo.Variants[i];
KRnDVariant v = new KRnDVariant(partVariant.Name, partVariant.Mass);
variants.Add(partVariant.Name, v);
}
return variants;
}

static void UpdatePartVariantMasses(Part part, PartStats originalStats, float dryMassFactor)
{
if (part.partInfo.partPrefab == null || part.partInfo.Variants == null)
return;

if (originalStats.kRnDVariants == null)
originalStats.kRnDVariants = new Dictionary<string, KRnDVariant>();

for (int i = 0; i < part.partInfo.Variants.Count; i++)
{
var partVariant = part.partInfo.Variants[i];
if (originalStats.kRnDVariants.TryGetValue(partVariant.Name, out KRnDVariant v) == false)
v = new KRnDVariant(partVariant.Name, partVariant.Mass);
v.UpdateMass(dryMassFactor);
originalStats.kRnDVariants[partVariant.Name] = v;
partVariant.Mass = v.mass;
}
}

// Multi-Mode engines have multiple Engine-Modules which we return as a list.
public static List<ModuleEngines> getEngineModules(Part part)
{
Expand Down Expand Up @@ -497,6 +536,11 @@ public static void updatePart(Part part, KRnDUpgrade upgradesToApply)
part.mass = originalStats.mass * dryMassFactor;
part.prefabMass = part.mass; // New in ksp 1.1, if this is correct is just guesswork however...

part.partInfo.variant.Mass = originalStats.currentVariantMass * dryMassFactor;
UpdatePartVariantMasses(part, originalStats, dryMassFactor);
part.baseVariant.Mass = originalStats.variantBaseMass * dryMassFactor;


// Dry Mass also improves fairing mass:
ModuleProceduralFairing fairngModule = KRnD.getFairingModule(part);
if (fairngModule)
Expand All @@ -519,9 +563,9 @@ public static void updatePart(Part part, KRnDUpgrade upgradesToApply)
for (int i = 0; i < originalStats.maxFuelFlows.Count; i++)
{
float maxFuelFlow = originalStats.maxFuelFlows[i] * (1 + KRnD.calculateImprovementFactor(rndModule.fuelFlow_improvement, rndModule.fuelFlow_improvementScale, upgradesToApply.fuelFlow));
if (engineModules != null)
if (engineModules != null)
engineModules[i].maxFuelFlow = maxFuelFlow;
else if (rcsModule)
else if (rcsModule)
rcsModule.thrusterPower = maxFuelFlow; // There is only one rcs-module
}
}
Expand Down Expand Up @@ -645,7 +689,7 @@ public static void updatePart(Part part, KRnDUpgrade upgradesToApply)
for (int i = 0; i < generator.resHandler.outputResources.Count; i++)
{
ModuleResource outputResource = generator.resHandler.outputResources[i];

double originalRate;
if (!originalStats.generatorEfficiency.TryGetValue(outputResource.name, out originalRate)) continue;
outputResource.rate = (float)(originalRate * (1 + KRnD.calculateImprovementFactor(rndModule.generatorEfficiency_improvement, rndModule.generatorEfficiency_improvementScale, upgradesToApply.generatorEfficiency)));
Expand All @@ -670,7 +714,7 @@ public static void updatePart(Part part, KRnDUpgrade upgradesToApply)
for (int i = 0; i < converterList.Count; i++)
{
ModuleResourceConverter converter = converterList[i];

Dictionary<String, double> origiginalOutputResources;
if (!originalStats.converterEfficiency.TryGetValue(converter.ConverterName, out origiginalOutputResources)) continue;

Expand Down Expand Up @@ -711,10 +755,10 @@ public static void updatePart(Part part, KRnDUpgrade upgradesToApply)
rndModule.fuelCapacity_upgrades = upgradesToApply.fuelCapacity;
double improvementFactor = (1 + KRnD.calculateImprovementFactor(rndModule.fuelCapacity_improvement, rndModule.fuelCapacity_improvementScale, upgradesToApply.fuelCapacity));

for (int i = 0; i < fuelResources.Count; i++)
for (int i = 0; i < fuelResources.Count; i++)
{
PartResource fuelResource = fuelResources[i];

if (!originalStats.fuelCapacities.ContainsKey(fuelResource.resourceName)) continue;
double originalCapacity = originalStats.fuelCapacities[fuelResource.resourceName];
double newCapacity = originalCapacity * improvementFactor;
Expand Down Expand Up @@ -748,13 +792,14 @@ public static void updateVessel(Vessel vessel)
{
if (!vessel.isActiveVessel) return; // Only the currently active vessel matters, the others are not simulated anyway.
if (KRnD.upgrades == null) throw new Exception("upgrades-dictionary missing");

Debug.Log("[KRnD] updating vessel '" + vessel.vesselName.ToString() + "'");

// Iterate through all parts:
for (int i = 0; i < vessel.parts.Count; i++)
{
Part part = vessel.parts[i];

// We only have to update parts which have the RnD-Module:
KRnDModule rndModule = KRnD.getKRnDModule(part);
if (rndModule == null) continue;
Expand Down Expand Up @@ -811,6 +856,22 @@ private void EditorPartEvent(ConstructionEventType ev, Part part)
}
}

private void OnVariantApplied(Part part, PartVariant pv)
{
if (part == null || part != KRnDGUI.selectedPart) return;
foreach (var v in part.partInfo.Variants)
{
if (v.Name == pv.Name)
{
//partStats.currentVariant = p.partInfo.variant.Name;
//partStats.currentVariantMass = kv.mass;

//v.Mass
break;
}

}
}
public List<string> getBlacklistedModules()
{
List<string> blacklistedModules = new List<string>();
Expand Down Expand Up @@ -864,19 +925,19 @@ public void Awake()
for (int i = 0; i < PartLoader.LoadedPartsList.Count; i++)
{
AvailablePart aPart = PartLoader.LoadedPartsList[i];

Part part = aPart.partPrefab;
List<ModuleEngines> engineModules = KRnD.getEngineModules(part);
if (engineModules == null) continue;
for (int i1 = 0; i1 < engineModules.Count; i1++)
{
ModuleEngines engineModule = engineModules[i1];

if (engineModule.propellants == null) continue;
for (int i2 = 0; i2 < engineModule.propellants.Count; i2++)
{
Propellant propellant = engineModule.propellants[i2];

if (propellant.name == "ElectricCharge") continue; // Electric Charge is improved by batteries.
if (propellant.name == "IntakeAir") continue; // This is no real fuel-type.
if (!fuelResources.Contains(propellant.name)) fuelResources.Add(propellant.name);
Expand All @@ -888,7 +949,7 @@ public void Awake()
for (int i = 0; i < KRnD.fuelResources.Count; i++)
{
String fuelName = KRnD.fuelResources[i];

if (listString != "") listString += ", ";
listString += fuelName;
}
Expand All @@ -904,15 +965,15 @@ public void Awake()
for (int i = 0; i < PartLoader.LoadedPartsList.Count; i++)
{
AvailablePart aPart = PartLoader.LoadedPartsList[i];

Part part = aPart.partPrefab;
Boolean skip = false;
string blacklistedModule = "N/A";

for (int i1 = 0; i1 < part.Modules.Count; i1++)
{
PartModule partModule = part.Modules[i1];

if (blacklistedModules.Contains(partModule.moduleName))
{
blacklistedModule = partModule.moduleName;
Expand Down Expand Up @@ -965,6 +1026,7 @@ public void Awake()
// Register event-handlers:
GameEvents.onVesselChange.Add(this.OnVesselChange);
GameEvents.onEditorPartEvent.Add(this.EditorPartEvent);
GameEvents.onVariantApplied.Add(this.OnVariantApplied);

KRnD.initialized = true;
}
Expand Down
13 changes: 8 additions & 5 deletions Source/KRnDGUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,11 @@ private String getPartInfo(Part part, KRnDUpgrade upgradesToApply = null)
ModuleProceduralFairing fairingModule = KRnD.getFairingModule(part);
List<PartResource> fuelResources = KRnD.getFuelResources(part);

float partMass = part.mass + part.partInfo.variant.Mass;

// Basic stats:
info = "<color=#FFFFFF><b>Dry Mass:</b> " + part.mass.ToString("0.#### t") + "\n";
//info = "<color=#FFFFFF><b>Dry Mass:</b> " + part.mass.ToString("0.#### t") + "\n";
info = "<color=#FFFFFF><b>Dry Mass:</b> " + partMass.ToString("0.#### t") + "\n";
info += "<b>Max Temp.:</b> " + part.maxTemp.ToString("0.#") + "/" + part.skinMaxTemp.ToString("0.#") + " °K\n";
if (landingLegModule != null) info += "<b>Crash Tolerance:</b> " + part.crashTolerance.ToString("0.#### m/s") + "\n";
if (electricChargeResource != null) info += "<b>Electric Charge:</b> " + electricChargeResource.maxAmount.ToString() + "\n";
Expand Down Expand Up @@ -801,15 +804,15 @@ private void OnWindow(int windowId)
new Exception("unexpected option '" + selectedUpgradeOption + "'");
break;
}

String newInfo = getPartInfo(part, nextUpgrade); // Calculate part-info if the selected stat was upgraded.
#if true
string newInfo = getPartInfo(part, currentUpgrade);
//String newInfo = getPartInfo(part, nextUpgrade); // Calculate part-info if the selected stat was upgraded.
newInfo = highlightChanges(currentInfo, newInfo);

// Current stats:
GUILayout.BeginArea(new Rect(10 + optionsWidth + 10, 30, windowStyle.fixedWidth, 20));
GUILayout.Label("<color=#FFFFFF><b>Current:</b> " + currentUpgradeCount.ToString() + " (" + currentImprovement.ToString("+0.##%;-0.##%;-") + ")</color>", labelStyle);
GUILayout.EndArea();

float areaWidth = (windowStyle.fixedWidth - 20 - optionsWidth) / 2;
float areaHeight = optionsHeight;
GUILayout.BeginArea(new Rect(10 + optionsWidth, 30 + 20, areaWidth, areaHeight));
Expand Down Expand Up @@ -852,7 +855,6 @@ private void OnWindow(int windowId)
AvailablePart ap = PartLoader.LoadedPartsList[i];
if (ap.name == part.partInfo.name)
{
Debug.Log("Part found");
foreach (var m in ap.moduleInfos)
{
if (m.moduleName == "R&D")
Expand All @@ -869,6 +871,7 @@ private void OnWindow(int windowId)
GUILayout.EndArea();
}
}
#endif

GUILayout.EndVertical();
GUI.DragWindow();
Expand Down
23 changes: 23 additions & 0 deletions Source/KRnDModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ public override void OnStart(PartModule.StartState state)
}
}

public void Start()
{
GameEvents.onVariantApplied.Add(this.OnVariantApplied);
}
// Returns the upgrade-stats which this module represents.
public KRnDUpgrade getCurrentUpgrades()
{
Expand Down Expand Up @@ -347,6 +351,25 @@ public override string GetInfo()
{
return GetInfo(this.part);
}

private void OnVariantApplied(Part p, PartVariant pv)
{
if (p == null || p.partInfo.partPrefab == null || p != this.part) return;

String partName = KRnD.sanatizePartName(p.name);

if (KRnD.originalStats.TryGetValue(partName, out PartStats partStats))
{
if (partStats.kRnDVariants != null && partStats.kRnDVariants.TryGetValue(pv.Name, out KRnDVariant kv))
{
partStats.currentVariant = pv.Name;
partStats.currentVariantMass = kv.mass;
this.part.partInfo.variant = pv; // ??? why doesn't KSP do this
}
}
else throw new Exception("no original-stats for part '" + partName + "'");
}

#endif
}
}
37 changes: 37 additions & 0 deletions Source/PartStats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,35 @@

namespace KRnD
{
public class KRnDVariant
{
public string name;
public float mass;
public float origMass;

public KRnDVariant(string name, float mass)
{
this.name = name;
this.mass = mass;
origMass = mass;
}
public void UpdateMass(float adjust)
{
this.mass = origMass * adjust;
}
}

// This class is used to store all relevant base-stats of a part used to calculate all other stats with
// incrementel upgrades as well as a backup for resoting the original stats (eg after loading a savegame).
public class PartStats
{

public float mass = 0;
public Dictionary<string, KRnDVariant> kRnDVariants;
public string currentVariant;
public float currentVariantMass = 0;
public float variantBaseMass = 0;

public List<float> maxFuelFlows = null;
public List<FloatCurve> atmosphereCurves = null;
public float torque = 0;
Expand All @@ -37,7 +61,20 @@ public class PartStats

public PartStats(Part part)
{
if (part == null || part.partInfo.partPrefab == null)
return;

this.mass = part.mass;

kRnDVariants = KRnD.getVariants(part);
if (part.partInfo.variant != null)
{
currentVariant = part.partInfo.variant.Name;
currentVariantMass = part.partInfo.variant.Mass;
variantBaseMass = part.baseVariant.Mass;
}
else
currentVariantMass = 0;
this.skinMaxTemp = part.skinMaxTemp;
this.intMaxTemp = part.maxTemp;

Expand Down

0 comments on commit c8fd32c

Please sign in to comment.