diff --git a/EdBPrepareCarefully.csproj b/EdBPrepareCarefully.csproj
index e2d1ca8..9bbc1c9 100644
--- a/EdBPrepareCarefully.csproj
+++ b/EdBPrepareCarefully.csproj
@@ -146,6 +146,7 @@
+
diff --git a/Resources/CHANGELOG.txt b/Resources/CHANGELOG.txt
index 6761b4e..0710a67 100644
--- a/Resources/CHANGELOG.txt
+++ b/Resources/CHANGELOG.txt
@@ -3,6 +3,7 @@
Version 1.5.12
_____________________________________________________________________________
+ - Added support for the additional passions in Vanilla Skills Expanded
- Bug fixes:
- Fixed problems with temporary pawns in the Relationships tab
diff --git a/Source/ControllerTabViewPawns.cs b/Source/ControllerTabViewPawns.cs
index ee4a0ee..09849e8 100644
--- a/Source/ControllerTabViewPawns.cs
+++ b/Source/ControllerTabViewPawns.cs
@@ -15,6 +15,7 @@ public class ControllerTabViewPawns {
public PawnCustomizer Customizer { get; set; }
public ManagerPawns PawnManager { get; set; }
public ManagerRelationships RelationshipManager { get; set; }
+ public ProviderPassions ProviderPassions { get; set; }
protected Dictionary PawnLayerOptionUpdateHandlers { get; set; } = new Dictionary();
protected Dictionary PawnLayerColorUpdateHandlers { get; set; } = new Dictionary();
@@ -251,14 +252,11 @@ public void AdjustSkillPassion(SkillDef skill, int direction) {
}
Passion currentPassion = record.passion;
Passion nextPassion = currentPassion;
- if (currentPassion == Passion.None) {
- nextPassion = direction > 0 ? Passion.Minor : Passion.Major;
+ if (direction > 0) {
+ nextPassion = ProviderPassions.NextPassionValue(currentPassion);
}
- else if (currentPassion == Passion.Minor) {
- nextPassion = direction > 0 ? Passion.Major : Passion.None;
- }
- else if (currentPassion == Passion.Major) {
- nextPassion = direction > 0 ? Passion.None : Passion.Minor;
+ else {
+ nextPassion = ProviderPassions.PreviousPassionValue(currentPassion);
}
PawnManager.UpdatePawnSkillPassion(customizedPawn, skill, nextPassion);
}
diff --git a/Source/Mod.cs b/Source/Mod.cs
index 399891c..b108a11 100644
--- a/Source/Mod.cs
+++ b/Source/Mod.cs
@@ -79,6 +79,8 @@ public void Start(Page_ConfigureStartingPawns configureStartingPawnsPage) {
};
providerEquipmentTypes.PostConstruction();
var providerPawnKinds = new ProviderPawnKinds();
+ var providerPassions = new ProviderPassions();
+ providerPassions.PostConstruct();
var ageModifier = new AgeModifier();
@@ -94,7 +96,8 @@ public void Start(Page_ConfigureStartingPawns configureStartingPawnsPage) {
ProviderHealthOptions = providerHealthOptions,
};
var pawnLoaderV5 = new PawnLoaderV5() {
- ProviderHealthOptions = providerHealthOptions
+ ProviderHealthOptions = providerHealthOptions,
+ ProviderPassions = providerPassions,
};
var pawnLoader = new PawnLoader() {
PawnLoaderV3 = pawnLoaderV3,
@@ -121,7 +124,8 @@ public void Start(Page_ConfigureStartingPawns configureStartingPawnsPage) {
PresetLoaderV5 = presetLoaderV5,
};
var pawnSaver = new PawnSaver() {
- ProviderHealthOptions = providerHealthOptions
+ ProviderHealthOptions = providerHealthOptions,
+ ProviderPassions = providerPassions,
};
var presetSaver = new PresetSaver() {
PawnSaver = pawnSaver
@@ -164,6 +168,7 @@ public void Start(Page_ConfigureStartingPawns configureStartingPawnsPage) {
Customizer = pawnCustomizer,
PawnManager = pawnManager,
RelationshipManager = relationshipManager,
+ ProviderPassions = providerPassions,
};
var controllerRelationships = new ControllerTabViewRelationships() {
State = state,
@@ -277,7 +282,8 @@ public void Start(Page_ConfigureStartingPawns configureStartingPawnsPage) {
};
var skillsPanel = new PanelSkills() {
State = state,
- ViewState = viewState
+ ViewState = viewState,
+ ProviderPassions = providerPassions,
};
var incapableOfPanel = new PanelIncapableOf() {
State = state,
diff --git a/Source/PanelSkills.cs b/Source/PanelSkills.cs
index 6bc82ca..ec145a9 100644
--- a/Source/PanelSkills.cs
+++ b/Source/PanelSkills.cs
@@ -26,6 +26,7 @@ public class PanelSkills : PanelBase {
protected WidgetScrollViewVertical scrollView = new WidgetScrollViewVertical();
public ModState State { get; set; }
public ViewState ViewState { get; set; }
+ public ProviderPassions ProviderPassions { get; set; }
public PanelSkills() {
}
@@ -219,19 +220,7 @@ public Texture2D GetPassionTextureForSkill(SkillRecord skillRecord) {
if (skillRecord == null) {
return null;
}
- Passion passion = skillRecord.passion;
- if (passion == Passion.Minor) {
- return Textures.TexturePassionMinor;
- }
- else if (passion == Passion.Major) {
- return Textures.TexturePassionMajor;
- }
- else if (passion == Passion.None) {
- return Textures.TexturePassionNone;
- }
- else {
- return null;
- }
+ return ProviderPassions.TextureForPassion(skillRecord.passion);
}
public static void FillableBar(Rect rect, float fillPercent, Texture2D fillTex) {
diff --git a/Source/PawnLoaderV5.cs b/Source/PawnLoaderV5.cs
index 85ccd3a..557c87b 100644
--- a/Source/PawnLoaderV5.cs
+++ b/Source/PawnLoaderV5.cs
@@ -11,6 +11,7 @@
namespace EdB.PrepareCarefully {
public class PawnLoaderV5 {
public ProviderHealthOptions ProviderHealthOptions { get; set; }
+ public ProviderPassions ProviderPassions { get; set; }
// Maintain lists of definitions that were replaced in newer versions of the game.
public Dictionary thingDefReplacements = new Dictionary();
@@ -534,12 +535,13 @@ public PawnLoaderResult ConvertSaveRecordToCustomizedPawn(SaveRecordPawnV5 recor
result.AddWarning("Could not load skill definition \"" + skill.name + "\" from saved preset");
continue;
}
+ Passion passion = ProviderPassions.MapFromString(skill.passion);
customizations.Skills.Add(new CustomizationsSkill() {
SkillDef = def,
Level = skill.value,
OriginalLevel = skill.value,
- Passion = skill.passion,
- OriginalPassion = skill.passion,
+ Passion = passion,
+ OriginalPassion = passion,
}
);
}
diff --git a/Source/PawnSaver.cs b/Source/PawnSaver.cs
index 66ec09e..f780ffb 100644
--- a/Source/PawnSaver.cs
+++ b/Source/PawnSaver.cs
@@ -8,6 +8,7 @@
namespace EdB.PrepareCarefully {
public class PawnSaver {
public ProviderHealthOptions ProviderHealthOptions { get; set; }
+ public ProviderPassions ProviderPassions { get; set; }
public void SaveToFile(CustomizedPawn customizedPawn, string colonistName) {
if (customizedPawn?.Customizations == null) {
@@ -233,7 +234,7 @@ public void ConvertSkills(SaveRecordPawnV5 result, CustomizationsPawn customizat
result.skills.Add(new SaveRecordSkillV4() {
name = skill.SkillDef?.defName,
value = skill.Level,
- passion = skill.Passion
+ passion = ProviderPassions.MapToString(skill.Passion),
});
}
}
diff --git a/Source/ProviderPassions.cs b/Source/ProviderPassions.cs
new file mode 100644
index 0000000..8a26308
--- /dev/null
+++ b/Source/ProviderPassions.cs
@@ -0,0 +1,166 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using RimWorld;
+using UnityEngine;
+using Verse;
+
+namespace EdB.PrepareCarefully {
+ public class ProviderPassions {
+ public Type PassionManagerType { get; set; }
+ public List Icons { get; set; } = new List();
+ public List PassionDefs { get; set; } = new List();
+ public List NextValues { get; set; } = new List() { 1, 2, 0 };
+ public List PreviousValues { get; set; } = new List() { 2, 0, 1 };
+ public int PassionCount { get; set; } = 3;
+ public void PostConstruct() {
+ InitializeExtendedPassions();
+ }
+ public bool UsingExtendedPassions {
+ get {
+ return PassionManagerType != null;
+ }
+ }
+ public void InitializeExtendedPassions() {
+ //Logger.Debug("InitializeExtendedPassions()");
+ PassionManagerType = ReflectionUtil.TypeByName("VSE.Passions.PassionManager");
+ if (PassionManagerType == null) {
+ //Logger.Debug(" Didn't find VSE.Passions.PassionManager class");
+ return;
+ }
+ //Logger.Debug(" Found VFE PassionManager class");
+ Array passionDefArray = ReflectionUtil.GetStaticFieldValue(PassionManagerType, "Passions");
+ if (passionDefArray == null) {
+ Logger.Debug(" Didn't find PassionManager.Passions array");
+ return;
+ }
+ //Logger.Debug(" Found VFE PassionManager.Passions array with " + passionDefArray.Length + " items");
+ PassionCount = passionDefArray.Length;
+ for (int i = 0; i < PassionCount; i++) {
+ Texture2D icon = Textures.TexturePassionNone;
+ Def passionDef = passionDefArray.GetValue(i) as Def;
+ if (passionDef != null) {
+ if (passionDef.defName == "None") {
+ icon = Textures.TexturePassionNone;
+ }
+ else {
+ icon = ReflectionUtil.GetPropertyValue(passionDef, "Icon");
+ }
+ if (icon != null) {
+ //Logger.Debug(" Found icon for passion " + i + ", " + passionDef.defName + ": " + (icon?.name ?? "no name"));
+ }
+ else {
+ //Logger.Debug(" Did not find icon for passion " + i + ", " + passionDef.defName);
+ }
+ }
+ else {
+ //Logger.Debug(" Did not find passion def for index " + i);
+ }
+ PassionDefs.Add(passionDef);
+ Icons.Add(icon);
+ }
+
+ if (PassionCount == 6
+ && PassionDefs[0]?.defName == "None"
+ && PassionDefs[1]?.defName == "Minor"
+ && PassionDefs[2]?.defName == "Major"
+ && PassionDefs[3]?.defName == "VSE_Apathy"
+ && PassionDefs[4]?.defName == "VSE_Natural"
+ && PassionDefs[5]?.defName == "VSE_Critical") {
+ NextValues = new List {
+ 1, 2, 5, 0, 3, 4
+ };
+ PreviousValues = new List {
+ 3, 0, 1, 4, 5, 2
+ };
+ }
+ else {
+ NextValues.Clear();
+ for (int i=0; i= 0 && value < Icons.Count) {
+ return Icons[value];
+ }
+ }
+ return Textures.TexturePassionNone;
+ }
+
+ public Passion NextPassionValue(Passion passion) {
+ int value = (int)passion;
+ if (value < 0 || value >= NextValues.Count) {
+ return Passion.None;
+ }
+ return (Passion)NextValues[value];
+ }
+
+ public Passion PreviousPassionValue(Passion passion) {
+ int value = (int)passion;
+ if (value < 0 || value >= PreviousValues.Count) {
+ return Passion.None;
+ }
+ return (Passion)PreviousValues[value];
+ }
+
+ public Passion MapFromString(string value) {
+ if (UsingExtendedPassions && PassionDefs.CountAllowNull() > 0) {
+ int index = PassionDefs.FindIndex(d => d.defName == value);
+ if (index != -1) {
+ return (Passion)index;
+ }
+ else {
+ return Passion.None;
+ }
+ }
+ else {
+ Passion? passion = null;
+ try {
+ passion = (Passion)Enum.Parse(typeof(Passion), value);
+ }
+ catch (Exception) { }
+ if (passion.HasValue) {
+ return passion.Value;
+ }
+ if (value == "VSE_Critical" || value == "VSE_Natural") {
+ return Passion.Major;
+ }
+ return Passion.None;
+ }
+ }
+
+ public string MapToString(Passion passion) {
+ int index = (int)passion;
+ if (UsingExtendedPassions && PassionDefs.CountAllowNull() > index) {
+ return PassionDefs[index].defName;
+ }
+ else {
+ return passion.ToString();
+ }
+ }
+ }
+}
diff --git a/Source/ReflectionUtil.cs b/Source/ReflectionUtil.cs
index 9c73b13..a982b8a 100644
--- a/Source/ReflectionUtil.cs
+++ b/Source/ReflectionUtil.cs
@@ -190,6 +190,29 @@ public static T GetFieldValue(object target, string name) {
return default(T);
}
+ public static T GetStaticFieldValue(Type target, string name) {
+ if (target == null) {
+ Logger.Warning("Could not get value from static field {" + name + "} using reflection because the target type was null");
+ return default(T);
+ }
+ FieldInfo field = Field(target, name);
+ if (field == null) {
+ Logger.Warning("Could not get value from static field {" + name + "} using reflection because we could not find the field on the target type");
+ return default(T);
+ }
+ object o = field.GetValue(null);
+ if (o == null) {
+ return default(T);
+ }
+ if (typeof(T).IsAssignableFrom(o.GetType())) {
+ return (T)field.GetValue(target);
+ }
+ else {
+ Logger.Warning("Could not cast the value from static field {" + name + "} whose type is {" + o.GetType().FullName + "} to the specified type {" + typeof(T).FullName + "}");
+ }
+ return default(T);
+ }
+
public static T GetPropertyValue(object target, string name) {
if (target == null) {
Logger.Warning("Could not get value from property {" + name + "} using reflection because the target was null");
diff --git a/Source/Version4/SaveRecordSkillV4.cs b/Source/Version4/SaveRecordSkillV4.cs
index af5189f..7e74d52 100644
--- a/Source/Version4/SaveRecordSkillV4.cs
+++ b/Source/Version4/SaveRecordSkillV4.cs
@@ -1,4 +1,4 @@
-using RimWorld;
+using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -9,12 +9,12 @@ namespace EdB.PrepareCarefully {
public class SaveRecordSkillV4 : IExposable {
public string name;
public int value;
- public Passion passion;
+ public string passion;
public void ExposeData() {
Scribe_Values.Look(ref this.name, "name", null, true);
Scribe_Values.Look(ref this.value, "value", 0, true);
- Scribe_Values.Look(ref this.passion, "passion", Passion.None, true);
+ Scribe_Values.Look(ref this.passion, "passion", "None", true);
}
}
}