diff --git a/EdBPrepareCarefully.csproj b/EdBPrepareCarefully.csproj
index ab9ccd0..9bbc1c9 100644
--- a/EdBPrepareCarefully.csproj
+++ b/EdBPrepareCarefully.csproj
@@ -64,6 +64,7 @@
+
@@ -145,6 +146,7 @@
+
diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
index bc6abb2..d9cae45 100644
--- a/Properties/AssemblyInfo.cs
+++ b/Properties/AssemblyInfo.cs
@@ -14,4 +14,4 @@
[assembly: AssemblyVersion("1.1.1")]
// Increment for each new release
-[assembly: AssemblyFileVersion("1.5.11")]
+[assembly: AssemblyFileVersion("1.5.12")]
diff --git a/Resources/About/About.xml b/Resources/About/About.xml
index b55159a..9c6a9f6 100644
--- a/Resources/About/About.xml
+++ b/Resources/About/About.xml
@@ -25,7 +25,7 @@
If you get a set of starting colonists that you like, save them as a preset so that you can start your game the same way next time.
-[Version 1.5.11]
+[Version 1.5.12]
net.pardeike.rimworld.mod.harmony
diff --git a/Resources/About/Manifest.xml b/Resources/About/Manifest.xml
index 1e2058f..5d75442 100644
--- a/Resources/About/Manifest.xml
+++ b/Resources/About/Manifest.xml
@@ -1,7 +1,7 @@
EdB.PrepareCarefully
- 1.5.11
+ 1.5.12
false
https://github.com/edbmods/EdBPrepareCarefully/raw/master/Resources/About/Manifest.xml
https://github.com/edbmods/EdBPrepareCarefully/releases/latest
diff --git a/Resources/CHANGELOG.txt b/Resources/CHANGELOG.txt
index eb37680..0710a67 100644
--- a/Resources/CHANGELOG.txt
+++ b/Resources/CHANGELOG.txt
@@ -1,3 +1,12 @@
+ _____________________________________________________________________________
+
+ 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
+
_____________________________________________________________________________
Version 1.5.11
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/ExtensionsPawnRelationDef.cs b/Source/ExtensionsPawnRelationDef.cs
new file mode 100644
index 0000000..1a9e76d
--- /dev/null
+++ b/Source/ExtensionsPawnRelationDef.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using RimWorld;
+using Verse;
+
+namespace EdB.PrepareCarefully {
+ public static class ExtensionsPawnRelationDef {
+
+ public static string GetGenderSpecificLabelCap(this PawnRelationDef relationDef, CustomizedPawn customizedPawn) {
+ Pawn pawn = customizedPawn?.Pawn;
+ if (pawn != null) {
+ return relationDef.GetGenderSpecificLabelCap(pawn);
+ }
+ else if (customizedPawn.TemporaryPawn != null && customizedPawn.TemporaryPawn.Gender == Gender.Female && !relationDef.labelFemale.NullOrEmpty()) {
+ return relationDef.labelFemale.CapitalizeFirst();
+ }
+ else {
+ return relationDef.label.CapitalizeFirst();
+ }
+ }
+ }
+}
diff --git a/Source/ManagerRelationships.cs b/Source/ManagerRelationships.cs
index 0a74dd9..d599a80 100644
--- a/Source/ManagerRelationships.cs
+++ b/Source/ManagerRelationships.cs
@@ -51,13 +51,13 @@ public void InitializeWithPawns(IEnumerable customPawns) {
InitializeHiddenPawns(customPawns);
State.Customizations.ParentChildGroups = InitializeParentChildGroupsForStartingPawns(customPawns);
InitializeRelationshipsForStartingPawns(customPawns);
- // Add a male and a female pawn to the new hidden pawn list.
- temporaryPawns.Add(CreateNewTemporaryPawn(Gender.Female));
- temporaryPawns.Add(CreateNewTemporaryPawn(Gender.Male));
// Assign indices to hidden pawns (indices are used to name pawns, i.e. "Unknown 1" and "Unknown 2").
// We do this here (and not when we initially created the hidden pawns) so that the initial indices will
// start at 1 and count up from there as they are displayed from left to right in the UI.
ReassignHiddenPawnIndices();
+ // Add a male and a female pawn to the new temporary pawn list.
+ temporaryPawns.Add(CreateNewTemporaryPawn(Gender.Female));
+ temporaryPawns.Add(CreateNewTemporaryPawn(Gender.Male));
}
// If there are any world pawns that our starting pawns have a relationship with, then store
@@ -261,8 +261,33 @@ private List SortAndDedupeParentChildGroups(IEnumerable {
- return def.GetGenderSpecificLabelCap(sourceParentChildPawn.Pawn);
+ return def.GetGenderSpecificLabelCap(sourceParentChildPawn);
},
SelectedFunc = (PawnRelationDef def) => {
return def == selectedRelationship;
@@ -373,7 +373,7 @@ protected void ShowAddRelationshipDialogs() {
return def;
}).ToList();
relationDefs.Sort((PawnRelationDef a, PawnRelationDef b) => {
- return a.GetGenderSpecificLabelCap(sourceParentChildPawn.Pawn).CompareTo(b.GetGenderSpecificLabelCap(sourceParentChildPawn.Pawn));
+ return a.GetGenderSpecificLabelCap(sourceParentChildPawn).CompareTo(b.GetGenderSpecificLabelCap(sourceParentChildPawn));
});
relationshipDialog.Options = relationDefs;
Find.WindowStack.Add(relationshipDialog);
diff --git a/Source/PanelRelationshipsParentChild.cs b/Source/PanelRelationshipsParentChild.cs
index a6a27c5..9ddf31f 100644
--- a/Source/PanelRelationshipsParentChild.cs
+++ b/Source/PanelRelationshipsParentChild.cs
@@ -307,7 +307,6 @@ protected string GetPawnShortName(CustomizedPawn customizedPawn) {
}
return pawn.LabelShortCap;
}
-
}
protected string GetTooltipText(CustomizedPawn pawn) {
@@ -352,7 +351,7 @@ protected void ShowParentDialogForGroup(ParentChildGroup group, CustomizedPawn s
}
});
rowGroups.Add(new WidgetTable.RowGroup("" + "EdB.PC.AddParentChild.Header.SelectWorldPawn".Translate() + "",
- RelationshipManager.AvailableWorldPawns));
+ RelationshipManager.AvailableWorldPawns.Concat(sortedHiddenPawns)));
WidgetTable.RowGroup newPawnGroup = new WidgetTable.RowGroup("" + "EdB.PC.AddParentChild.Header.CreateTemporaryPawn".Translate() + "", RelationshipManager.TemporaryPawns);
rowGroups.Add(newPawnGroup);
var pawnDialog = new DialogSelectParentChildPawn() {
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);
}
}
}