Skip to content

Commit c8fd32c

Browse files
Fixed issue with part variants where it wasn't changing the mass of the part variant, resulting in negative numbers on occasion
1 parent 88a0a3a commit c8fd32c

File tree

7 files changed

+147
-19
lines changed

7 files changed

+147
-19
lines changed
692 KB
Binary file not shown.

ChangeLog.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
Changelog
22

3+
1.16.0.3
4+
Fixed issue with part variants where it wasn't changing the mass of the part variant, resulting in negative numbers on occasion
5+
36
1.16.0.2
47
Moved initialization of GUIStyles into Start
58
Made window 70 pixels higher, thanks to @leatherneck6017 for the change

KRnD.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"MAJOR": 1,
1212
"MINOR": 16,
1313
"PATCH": 0,
14-
"BUILD": 2
14+
"BUILD": 3
1515
},
1616
"KSP_VERSION_MIN": {
1717
"MAJOR": 1,

Source/KRnD.cs

Lines changed: 75 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,45 @@ public static KRnDModule getKRnDModule(Part part)
7878
return null;
7979
}
8080

81+
// Parts can have multiple variants which we return as a list, needed
82+
// because some variants change the part mass
83+
public static Dictionary<string, KRnDVariant> getVariants(Part part)
84+
{
85+
if (part == null) return null;
86+
if (part.partInfo.partPrefab == null) return null;
87+
88+
if (part.partInfo.Variants == null) return null;
89+
90+
Dictionary<string, KRnDVariant> variants = new Dictionary<string, KRnDVariant>();
91+
92+
for (int i = 0; i < part.partInfo.Variants.Count; i++)
93+
{
94+
var partVariant = part.partInfo.Variants[i];
95+
KRnDVariant v = new KRnDVariant(partVariant.Name, partVariant.Mass);
96+
variants.Add(partVariant.Name, v);
97+
}
98+
return variants;
99+
}
100+
101+
static void UpdatePartVariantMasses(Part part, PartStats originalStats, float dryMassFactor)
102+
{
103+
if (part.partInfo.partPrefab == null || part.partInfo.Variants == null)
104+
return;
105+
106+
if (originalStats.kRnDVariants == null)
107+
originalStats.kRnDVariants = new Dictionary<string, KRnDVariant>();
108+
109+
for (int i = 0; i < part.partInfo.Variants.Count; i++)
110+
{
111+
var partVariant = part.partInfo.Variants[i];
112+
if (originalStats.kRnDVariants.TryGetValue(partVariant.Name, out KRnDVariant v) == false)
113+
v = new KRnDVariant(partVariant.Name, partVariant.Mass);
114+
v.UpdateMass(dryMassFactor);
115+
originalStats.kRnDVariants[partVariant.Name] = v;
116+
partVariant.Mass = v.mass;
117+
}
118+
}
119+
81120
// Multi-Mode engines have multiple Engine-Modules which we return as a list.
82121
public static List<ModuleEngines> getEngineModules(Part part)
83122
{
@@ -497,6 +536,11 @@ public static void updatePart(Part part, KRnDUpgrade upgradesToApply)
497536
part.mass = originalStats.mass * dryMassFactor;
498537
part.prefabMass = part.mass; // New in ksp 1.1, if this is correct is just guesswork however...
499538

539+
part.partInfo.variant.Mass = originalStats.currentVariantMass * dryMassFactor;
540+
UpdatePartVariantMasses(part, originalStats, dryMassFactor);
541+
part.baseVariant.Mass = originalStats.variantBaseMass * dryMassFactor;
542+
543+
500544
// Dry Mass also improves fairing mass:
501545
ModuleProceduralFairing fairngModule = KRnD.getFairingModule(part);
502546
if (fairngModule)
@@ -519,9 +563,9 @@ public static void updatePart(Part part, KRnDUpgrade upgradesToApply)
519563
for (int i = 0; i < originalStats.maxFuelFlows.Count; i++)
520564
{
521565
float maxFuelFlow = originalStats.maxFuelFlows[i] * (1 + KRnD.calculateImprovementFactor(rndModule.fuelFlow_improvement, rndModule.fuelFlow_improvementScale, upgradesToApply.fuelFlow));
522-
if (engineModules != null)
566+
if (engineModules != null)
523567
engineModules[i].maxFuelFlow = maxFuelFlow;
524-
else if (rcsModule)
568+
else if (rcsModule)
525569
rcsModule.thrusterPower = maxFuelFlow; // There is only one rcs-module
526570
}
527571
}
@@ -645,7 +689,7 @@ public static void updatePart(Part part, KRnDUpgrade upgradesToApply)
645689
for (int i = 0; i < generator.resHandler.outputResources.Count; i++)
646690
{
647691
ModuleResource outputResource = generator.resHandler.outputResources[i];
648-
692+
649693
double originalRate;
650694
if (!originalStats.generatorEfficiency.TryGetValue(outputResource.name, out originalRate)) continue;
651695
outputResource.rate = (float)(originalRate * (1 + KRnD.calculateImprovementFactor(rndModule.generatorEfficiency_improvement, rndModule.generatorEfficiency_improvementScale, upgradesToApply.generatorEfficiency)));
@@ -670,7 +714,7 @@ public static void updatePart(Part part, KRnDUpgrade upgradesToApply)
670714
for (int i = 0; i < converterList.Count; i++)
671715
{
672716
ModuleResourceConverter converter = converterList[i];
673-
717+
674718
Dictionary<String, double> origiginalOutputResources;
675719
if (!originalStats.converterEfficiency.TryGetValue(converter.ConverterName, out origiginalOutputResources)) continue;
676720

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

714-
for (int i = 0; i < fuelResources.Count; i++)
758+
for (int i = 0; i < fuelResources.Count; i++)
715759
{
716760
PartResource fuelResource = fuelResources[i];
717-
761+
718762
if (!originalStats.fuelCapacities.ContainsKey(fuelResource.resourceName)) continue;
719763
double originalCapacity = originalStats.fuelCapacities[fuelResource.resourceName];
720764
double newCapacity = originalCapacity * improvementFactor;
@@ -748,13 +792,14 @@ public static void updateVessel(Vessel vessel)
748792
{
749793
if (!vessel.isActiveVessel) return; // Only the currently active vessel matters, the others are not simulated anyway.
750794
if (KRnD.upgrades == null) throw new Exception("upgrades-dictionary missing");
795+
751796
Debug.Log("[KRnD] updating vessel '" + vessel.vesselName.ToString() + "'");
752797

753798
// Iterate through all parts:
754799
for (int i = 0; i < vessel.parts.Count; i++)
755800
{
756801
Part part = vessel.parts[i];
757-
802+
758803
// We only have to update parts which have the RnD-Module:
759804
KRnDModule rndModule = KRnD.getKRnDModule(part);
760805
if (rndModule == null) continue;
@@ -811,6 +856,22 @@ private void EditorPartEvent(ConstructionEventType ev, Part part)
811856
}
812857
}
813858

859+
private void OnVariantApplied(Part part, PartVariant pv)
860+
{
861+
if (part == null || part != KRnDGUI.selectedPart) return;
862+
foreach (var v in part.partInfo.Variants)
863+
{
864+
if (v.Name == pv.Name)
865+
{
866+
//partStats.currentVariant = p.partInfo.variant.Name;
867+
//partStats.currentVariantMass = kv.mass;
868+
869+
//v.Mass
870+
break;
871+
}
872+
873+
}
874+
}
814875
public List<string> getBlacklistedModules()
815876
{
816877
List<string> blacklistedModules = new List<string>();
@@ -864,19 +925,19 @@ public void Awake()
864925
for (int i = 0; i < PartLoader.LoadedPartsList.Count; i++)
865926
{
866927
AvailablePart aPart = PartLoader.LoadedPartsList[i];
867-
928+
868929
Part part = aPart.partPrefab;
869930
List<ModuleEngines> engineModules = KRnD.getEngineModules(part);
870931
if (engineModules == null) continue;
871932
for (int i1 = 0; i1 < engineModules.Count; i1++)
872933
{
873934
ModuleEngines engineModule = engineModules[i1];
874-
935+
875936
if (engineModule.propellants == null) continue;
876937
for (int i2 = 0; i2 < engineModule.propellants.Count; i2++)
877938
{
878939
Propellant propellant = engineModule.propellants[i2];
879-
940+
880941
if (propellant.name == "ElectricCharge") continue; // Electric Charge is improved by batteries.
881942
if (propellant.name == "IntakeAir") continue; // This is no real fuel-type.
882943
if (!fuelResources.Contains(propellant.name)) fuelResources.Add(propellant.name);
@@ -888,7 +949,7 @@ public void Awake()
888949
for (int i = 0; i < KRnD.fuelResources.Count; i++)
889950
{
890951
String fuelName = KRnD.fuelResources[i];
891-
952+
892953
if (listString != "") listString += ", ";
893954
listString += fuelName;
894955
}
@@ -904,15 +965,15 @@ public void Awake()
904965
for (int i = 0; i < PartLoader.LoadedPartsList.Count; i++)
905966
{
906967
AvailablePart aPart = PartLoader.LoadedPartsList[i];
907-
968+
908969
Part part = aPart.partPrefab;
909970
Boolean skip = false;
910971
string blacklistedModule = "N/A";
911972

912973
for (int i1 = 0; i1 < part.Modules.Count; i1++)
913974
{
914975
PartModule partModule = part.Modules[i1];
915-
976+
916977
if (blacklistedModules.Contains(partModule.moduleName))
917978
{
918979
blacklistedModule = partModule.moduleName;
@@ -965,6 +1026,7 @@ public void Awake()
9651026
// Register event-handlers:
9661027
GameEvents.onVesselChange.Add(this.OnVesselChange);
9671028
GameEvents.onEditorPartEvent.Add(this.EditorPartEvent);
1029+
GameEvents.onVariantApplied.Add(this.OnVariantApplied);
9681030

9691031
KRnD.initialized = true;
9701032
}

Source/KRnDGUI.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,11 @@ private String getPartInfo(Part part, KRnDUpgrade upgradesToApply = null)
398398
ModuleProceduralFairing fairingModule = KRnD.getFairingModule(part);
399399
List<PartResource> fuelResources = KRnD.getFuelResources(part);
400400

401+
float partMass = part.mass + part.partInfo.variant.Mass;
402+
401403
// Basic stats:
402-
info = "<color=#FFFFFF><b>Dry Mass:</b> " + part.mass.ToString("0.#### t") + "\n";
404+
//info = "<color=#FFFFFF><b>Dry Mass:</b> " + part.mass.ToString("0.#### t") + "\n";
405+
info = "<color=#FFFFFF><b>Dry Mass:</b> " + partMass.ToString("0.#### t") + "\n";
403406
info += "<b>Max Temp.:</b> " + part.maxTemp.ToString("0.#") + "/" + part.skinMaxTemp.ToString("0.#") + " °K\n";
404407
if (landingLegModule != null) info += "<b>Crash Tolerance:</b> " + part.crashTolerance.ToString("0.#### m/s") + "\n";
405408
if (electricChargeResource != null) info += "<b>Electric Charge:</b> " + electricChargeResource.maxAmount.ToString() + "\n";
@@ -801,15 +804,15 @@ private void OnWindow(int windowId)
801804
new Exception("unexpected option '" + selectedUpgradeOption + "'");
802805
break;
803806
}
804-
805-
String newInfo = getPartInfo(part, nextUpgrade); // Calculate part-info if the selected stat was upgraded.
807+
#if true
808+
string newInfo = getPartInfo(part, currentUpgrade);
809+
//String newInfo = getPartInfo(part, nextUpgrade); // Calculate part-info if the selected stat was upgraded.
806810
newInfo = highlightChanges(currentInfo, newInfo);
807811

808812
// Current stats:
809813
GUILayout.BeginArea(new Rect(10 + optionsWidth + 10, 30, windowStyle.fixedWidth, 20));
810814
GUILayout.Label("<color=#FFFFFF><b>Current:</b> " + currentUpgradeCount.ToString() + " (" + currentImprovement.ToString("+0.##%;-0.##%;-") + ")</color>", labelStyle);
811815
GUILayout.EndArea();
812-
813816
float areaWidth = (windowStyle.fixedWidth - 20 - optionsWidth) / 2;
814817
float areaHeight = optionsHeight;
815818
GUILayout.BeginArea(new Rect(10 + optionsWidth, 30 + 20, areaWidth, areaHeight));
@@ -852,7 +855,6 @@ private void OnWindow(int windowId)
852855
AvailablePart ap = PartLoader.LoadedPartsList[i];
853856
if (ap.name == part.partInfo.name)
854857
{
855-
Debug.Log("Part found");
856858
foreach (var m in ap.moduleInfos)
857859
{
858860
if (m.moduleName == "R&D")
@@ -869,6 +871,7 @@ private void OnWindow(int windowId)
869871
GUILayout.EndArea();
870872
}
871873
}
874+
#endif
872875

873876
GUILayout.EndVertical();
874877
GUI.DragWindow();

Source/KRnDModule.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ public override void OnStart(PartModule.StartState state)
233233
}
234234
}
235235

236+
public void Start()
237+
{
238+
GameEvents.onVariantApplied.Add(this.OnVariantApplied);
239+
}
236240
// Returns the upgrade-stats which this module represents.
237241
public KRnDUpgrade getCurrentUpgrades()
238242
{
@@ -347,6 +351,25 @@ public override string GetInfo()
347351
{
348352
return GetInfo(this.part);
349353
}
354+
355+
private void OnVariantApplied(Part p, PartVariant pv)
356+
{
357+
if (p == null || p.partInfo.partPrefab == null || p != this.part) return;
358+
359+
String partName = KRnD.sanatizePartName(p.name);
360+
361+
if (KRnD.originalStats.TryGetValue(partName, out PartStats partStats))
362+
{
363+
if (partStats.kRnDVariants != null && partStats.kRnDVariants.TryGetValue(pv.Name, out KRnDVariant kv))
364+
{
365+
partStats.currentVariant = pv.Name;
366+
partStats.currentVariantMass = kv.mass;
367+
this.part.partInfo.variant = pv; // ??? why doesn't KSP do this
368+
}
369+
}
370+
else throw new Exception("no original-stats for part '" + partName + "'");
371+
}
372+
350373
#endif
351374
}
352375
}

Source/PartStats.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,35 @@
1313

1414
namespace KRnD
1515
{
16+
public class KRnDVariant
17+
{
18+
public string name;
19+
public float mass;
20+
public float origMass;
21+
22+
public KRnDVariant(string name, float mass)
23+
{
24+
this.name = name;
25+
this.mass = mass;
26+
origMass = mass;
27+
}
28+
public void UpdateMass(float adjust)
29+
{
30+
this.mass = origMass * adjust;
31+
}
32+
}
33+
1634
// This class is used to store all relevant base-stats of a part used to calculate all other stats with
1735
// incrementel upgrades as well as a backup for resoting the original stats (eg after loading a savegame).
1836
public class PartStats
1937
{
38+
2039
public float mass = 0;
40+
public Dictionary<string, KRnDVariant> kRnDVariants;
41+
public string currentVariant;
42+
public float currentVariantMass = 0;
43+
public float variantBaseMass = 0;
44+
2145
public List<float> maxFuelFlows = null;
2246
public List<FloatCurve> atmosphereCurves = null;
2347
public float torque = 0;
@@ -37,7 +61,20 @@ public class PartStats
3761

3862
public PartStats(Part part)
3963
{
64+
if (part == null || part.partInfo.partPrefab == null)
65+
return;
66+
4067
this.mass = part.mass;
68+
69+
kRnDVariants = KRnD.getVariants(part);
70+
if (part.partInfo.variant != null)
71+
{
72+
currentVariant = part.partInfo.variant.Name;
73+
currentVariantMass = part.partInfo.variant.Mass;
74+
variantBaseMass = part.baseVariant.Mass;
75+
}
76+
else
77+
currentVariantMass = 0;
4178
this.skinMaxTemp = part.skinMaxTemp;
4279
this.intMaxTemp = part.maxTemp;
4380

0 commit comments

Comments
 (0)