diff --git a/1.4/Assemblies/PrisonLabor.dll b/1.4/Assemblies/PrisonLabor.dll
index 8b11ebc..78c4b92 100644
Binary files a/1.4/Assemblies/PrisonLabor.dll and b/1.4/Assemblies/PrisonLabor.dll differ
diff --git a/PL_Biotech_PrisonersInteractionMode.xml b/1.4/Biotech/Languages/ChineseTraditional/DefInjected/PrisonerInteractionModeDef/PL_Biotech_PrisonersInteractionMode.xml
similarity index 99%
rename from PL_Biotech_PrisonersInteractionMode.xml
rename to 1.4/Biotech/Languages/ChineseTraditional/DefInjected/PrisonerInteractionModeDef/PL_Biotech_PrisonersInteractionMode.xml
index b586484..1e1e57c 100644
--- a/PL_Biotech_PrisonersInteractionMode.xml
+++ b/1.4/Biotech/Languages/ChineseTraditional/DefInjected/PrisonerInteractionModeDef/PL_Biotech_PrisonersInteractionMode.xml
@@ -1,7 +1,7 @@
-
-
- 工作與供血 強迫囚犯工作,血原需求者可無視囚犯心情直接對其進食。
-
- 工作和血包 強迫囚犯工作,以不造成死亡為原則,抽取血液。
-
+
+
+ 工作與供血 強迫囚犯工作,血原需求者可無視囚犯心情直接對其進食。
+
+ 工作和血包 強迫囚犯工作,以不造成死亡為原則,抽取血液。
+
\ No newline at end of file
diff --git a/1.4/CashRegistry/Assemblies/PrisonLaborCashRegistryCompatibility.dll b/1.4/CashRegistry/Assemblies/PrisonLaborCashRegistryCompatibility.dll
index dbc7128..8a9dbc6 100644
Binary files a/1.4/CashRegistry/Assemblies/PrisonLaborCashRegistryCompatibility.dll and b/1.4/CashRegistry/Assemblies/PrisonLaborCashRegistryCompatibility.dll differ
diff --git a/1.4/CleaningArea/Assemblies/PrisonLaborCleaningAreaCompatibility.dll b/1.4/CleaningArea/Assemblies/PrisonLaborCleaningAreaCompatibility.dll
index 80a7df4..48b71f9 100644
Binary files a/1.4/CleaningArea/Assemblies/PrisonLaborCleaningAreaCompatibility.dll and b/1.4/CleaningArea/Assemblies/PrisonLaborCleaningAreaCompatibility.dll differ
diff --git a/1.4/ColonyGroups/Assemblies/PrisonLaborColonyGroupsCompatibility.dll b/1.4/ColonyGroups/Assemblies/PrisonLaborColonyGroupsCompatibility.dll
new file mode 100644
index 0000000..d789ec7
Binary files /dev/null and b/1.4/ColonyGroups/Assemblies/PrisonLaborColonyGroupsCompatibility.dll differ
diff --git a/1.4/Hospitality/Assemblies/PrisonLaborHospitalityCompatibility.dll b/1.4/Hospitality/Assemblies/PrisonLaborHospitalityCompatibility.dll
index 46e3899..8fb3d32 100644
Binary files a/1.4/Hospitality/Assemblies/PrisonLaborHospitalityCompatibility.dll and b/1.4/Hospitality/Assemblies/PrisonLaborHospitalityCompatibility.dll differ
diff --git a/1.4/Kijin/Assemblies/PrisonLaborKijinCompatibility.dll b/1.4/Kijin/Assemblies/PrisonLaborKijinCompatibility.dll
index 96a9f16..5e8a32c 100644
Binary files a/1.4/Kijin/Assemblies/PrisonLaborKijinCompatibility.dll and b/1.4/Kijin/Assemblies/PrisonLaborKijinCompatibility.dll differ
diff --git a/1.4/Quarry/Assemblies/PrisonLaborQuarryCompatibility.dll b/1.4/Quarry/Assemblies/PrisonLaborQuarryCompatibility.dll
index 66720e8..13be35a 100644
Binary files a/1.4/Quarry/Assemblies/PrisonLaborQuarryCompatibility.dll and b/1.4/Quarry/Assemblies/PrisonLaborQuarryCompatibility.dll differ
diff --git a/1.4/Therapy/Assemblies/PrisonLaborTherapyCompatibility.dll b/1.4/Therapy/Assemblies/PrisonLaborTherapyCompatibility.dll
index e9f4b4f..3075d0f 100644
Binary files a/1.4/Therapy/Assemblies/PrisonLaborTherapyCompatibility.dll and b/1.4/Therapy/Assemblies/PrisonLaborTherapyCompatibility.dll differ
diff --git a/About/About.xml b/About/About.xml
index 14b4e17..0284a2e 100644
--- a/About/About.xml
+++ b/About/About.xml
@@ -35,7 +35,7 @@
- Version 1.4.5
+ Version 1.4.6
This mod force prisoners to work. To enable this feature prisoners must have "Force to work" option checked ("Prisoner" tab). Prison labor needs management that consist:
- Motivation - prisoners need to be motivated by presence of colonists. Wardens have new job - supervising prisoners. Low motivation can lead to revolts.
diff --git a/Languages/ChineseTraditional/DefInjected/PrisonerInteractionModeDef/PrisonerInteractionModeDef.xml b/Languages/ChineseTraditional/DefInjected/PrisonerInteractionModeDef/PrisonerInteractionModeDef.xml
index c2eb755..2d6b02a 100644
--- a/Languages/ChineseTraditional/DefInjected/PrisonerInteractionModeDef/PrisonerInteractionModeDef.xml
+++ b/Languages/ChineseTraditional/DefInjected/PrisonerInteractionModeDef/PrisonerInteractionModeDef.xml
@@ -3,12 +3,4 @@
強迫工作
工作與招募
-
- 工作與供血
- 強迫囚犯工作,血原需求者可無視囚犯心情直接對其進食。
-
- 工作和血包
- 強迫囚犯工作,以不造成死亡為原則,抽取血液。
-
-
diff --git a/LoadFolders.xml b/LoadFolders.xml
index 0391afd..d52b0e8 100644
--- a/LoadFolders.xml
+++ b/LoadFolders.xml
@@ -29,5 +29,6 @@
1.4/Kijin2
1.4/Kijin
1.4/Quarry
+ 1.4/ColonyGroups
\ No newline at end of file
diff --git a/README.md b/README.md
index aceed2d..c2111af 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
-
+
diff --git a/Source/CompatibilityProjects/ColonyGroupsCompatibility/ColonyGroupsCompatibility.csproj b/Source/CompatibilityProjects/ColonyGroupsCompatibility/ColonyGroupsCompatibility.csproj
new file mode 100644
index 0000000..5154ce6
--- /dev/null
+++ b/Source/CompatibilityProjects/ColonyGroupsCompatibility/ColonyGroupsCompatibility.csproj
@@ -0,0 +1,76 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {A77AE1EB-BA5D-4B3A-9D9B-A9580850FAAD}
+ Library
+ Properties
+ ColonyGroupsCompatibility
+ PrisonLaborColonyGroupsCompatibility
+ v4.8
+ 512
+ true
+
+
+
+ true
+ full
+ false
+ ..\..\..\1.4\ColonyGroups\Assemblies\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\..\packages\Lib.Harmony.2.2.2\lib\net472\0Harmony.dll
+ False
+
+
+ ..\..\..\..\..\Gry\Steam\steamapps\common\RimWorld\RimWorldWin64_Data\Managed\Assembly-CSharp.dll
+ False
+
+
+ ..\..\..\..\..\Gry\Steam\steamapps\workshop\content\294100\2345493945\1.4\Assemblies\CompatUtils.dll
+ False
+
+
+
+
+
+
+
+
+
+
+ ..\..\..\..\..\Gry\Steam\steamapps\workshop\content\294100\2345493945\1.4\Assemblies\TacticalGroups.dll
+ False
+
+
+
+
+
+
+
+
+
+ {97750974-4cb6-4d31-84a1-a3aa77b1e2ee}
+ PrisonLabor
+ False
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/CompatibilityProjects/ColonyGroupsCompatibility/HarmonyInit.cs b/Source/CompatibilityProjects/ColonyGroupsCompatibility/HarmonyInit.cs
new file mode 100644
index 0000000..5962469
--- /dev/null
+++ b/Source/CompatibilityProjects/ColonyGroupsCompatibility/HarmonyInit.cs
@@ -0,0 +1,29 @@
+using HarmonyLib;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Verse;
+
+namespace ColonyGroupsCompatibility
+{
+ [StaticConstructorOnStartup]
+ public class HarmonyInit
+ {
+ static HarmonyInit()
+ {
+ var harmony = new Harmony("Harmony_PrisonLabor_ColonyGroups");
+ try
+ {
+ harmony.PatchAll(Assembly.GetExecutingAssembly());
+ Log.Message("[PL] ColonyGroups patched");
+ }
+ catch (Exception e)
+ {
+ Log.Error($"[PL] Patches for ColonyGroups failed: {e}");
+ }
+ }
+ }
+}
diff --git a/Source/CompatibilityProjects/ColonyGroupsCompatibility/HarmonyPatches/MarkGroupAssigment_Patch.cs b/Source/CompatibilityProjects/ColonyGroupsCompatibility/HarmonyPatches/MarkGroupAssigment_Patch.cs
new file mode 100644
index 0000000..b8185c9
--- /dev/null
+++ b/Source/CompatibilityProjects/ColonyGroupsCompatibility/HarmonyPatches/MarkGroupAssigment_Patch.cs
@@ -0,0 +1,89 @@
+using HarmonyLib;
+using RimWorld;
+using PrisonLabor.Core.BillAssignation;
+using PrisonLabor.HarmonyPatches.Patches_GUI.GUI_Bill;
+using TacticalGroups;
+using System.Collections.Generic;
+using Verse;
+using PrisonLabor.Core.Other;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Linq;
+using static Verse.Widgets;
+using System;
+
+namespace ColonyGroupsCompatibility.HarmonyPatches
+{
+ [HarmonyPatch(typeof(Patch_RestrictBillToPrisoner))]
+ public class ReturnLabel_Patch
+ {
+ [HarmonyPostfix]
+ [HarmonyPatch("GetDropLabel")]
+ public static string PostfixGetDropLabel(string __result, Dialog_BillConfig dialog)
+ {
+ Bill_Production bill = Traverse.Create(dialog).Field("bill").GetValue();
+ if (BillAssignationUtility.IsFor(bill) == GroupMode.ColonyGroups)
+ {
+ if (HarmonyPatches_GroupBills.BillsSelectedGroup.TryGetValue(bill, out PawnGroup group))
+ {
+ string label = "TG.AnyPawnOfGroup".Translate(group.curGroupName);
+ return label;
+ }
+ }
+ return __result;
+ }
+
+ }
+ [HarmonyPatch]
+ public class MarkGroupAssigment_Patch
+ {
+ static MethodBase TargetMethod()
+ {
+ return AccessTools.Method("TacticalGroups.HarmonyPatches_GroupBills:GeneratePawnRestrictionOptions");
+ }
+ public static IEnumerable Transpiler(ILGenerator gen, MethodBase mBase, IEnumerable inst)
+ {
+ int bill = -1;
+ var codes = new List(inst);
+ for (int i = 0; i < codes.Count(); i++)
+ {
+ yield return codes[i];
+ if (ShouldCopy(codes[i]))
+ {
+ bill = i;
+ }
+ if (ShouldPatch(codes[i]) && bill > -1)
+ {
+ DebugLogger.debug($"Changing delegate: {mBase.ReflectedType.Assembly.GetName().Name}.{mBase.ReflectedType.Name}.{mBase.Name}");
+ yield return new CodeInstruction(OpCodes.Ldloc_3, null);
+ //ldfld | TacticalGroups.HarmonyPatches_GroupBills+<>c__DisplayClass6_0 CS$<>8__locals1 | no labels
+ yield return codes[bill - 1];
+ //ldfld | RimWorld.Bill_Production ___bill | no labels
+ yield return codes[bill];
+ //ldloc.s | Verse.Widgets+DropdownMenuElement`1[Verse.Pawn] (8) | no labels
+ yield return codes[i - 1];
+ yield return new CodeInstruction(OpCodes.Call, typeof(MarkGroupAssigment_Patch).GetMethod(nameof(MarkGroupAssigment_Patch.UpdateAction)));
+ }
+ }
+ }
+
+ private static bool ShouldPatch(CodeInstruction actual)
+ {
+ return actual.opcode == OpCodes.Callvirt && actual.operand != null && actual.operand.ToString().Contains("Void Insert(Int32, DropdownMenuElement`1)");
+ }
+
+ private static bool ShouldCopy(CodeInstruction actual)
+ {
+ return actual.opcode == OpCodes.Ldfld && actual.operand != null && actual.operand.ToString().Contains("RimWorld.Bill_Production ___bill");
+ }
+ public static void UpdateAction(Bill_Production bill, DropdownMenuElement element)
+ {
+ Action notify = delegate
+ {
+ BillAssignationUtility.SetFor(bill, GroupMode.ColonyGroups);
+ DebugLogger.debug($"For {bill.Label} set {GroupMode.ColonyGroups}");
+ };
+ element.option.action += notify;
+ }
+ }
+}
diff --git a/Source/CompatibilityProjects/ColonyGroupsCompatibility/Properties/AssemblyInfo.cs b/Source/CompatibilityProjects/ColonyGroupsCompatibility/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..40ae7d8
--- /dev/null
+++ b/Source/CompatibilityProjects/ColonyGroupsCompatibility/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ColonyGroupsCompatibility")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ColonyGroupsCompatibility")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a77ae1eb-ba5d-4b3a-9d9b-a9580850faad")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Source/CompatibilityProjects/ColonyGroupsCompatibility/packages.config b/Source/CompatibilityProjects/ColonyGroupsCompatibility/packages.config
new file mode 100644
index 0000000..6bf55ad
--- /dev/null
+++ b/Source/CompatibilityProjects/ColonyGroupsCompatibility/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/Source/Core/BillAssignation/BillAssignationUtility.cs b/Source/Core/BillAssignation/BillAssignationUtility.cs
index 84d72b7..bc9ae2c 100644
--- a/Source/Core/BillAssignation/BillAssignationUtility.cs
+++ b/Source/Core/BillAssignation/BillAssignationUtility.cs
@@ -3,34 +3,48 @@
namespace PrisonLabor.Core.BillAssignation
{
- public class BillAssignationUtility
+ public class BillAssignationUtility
+ {
+ private static readonly Dictionary Map = new Dictionary();
+
+ public static GroupMode IsFor(Bill key)
{
- private static readonly Dictionary Map = new Dictionary();
+ if (!Map.ContainsKey(key))
+ {
+ Map[key] = new BillGroupData();
+ SetMechanitorIfNeeded(key);
+ }
+ return Map[key].Mode;
+ }
- public static GroupMode IsFor(Bill key)
- {
- if (!Map.ContainsKey(key))
- Map[key] = new BillGroupData();
- return Map[key].Mode;
- }
+ public static void SetFor(Bill key, GroupMode value)
+ {
+ if (!Map.ContainsKey(key))
+ Map[key] = new BillGroupData();
+ Map[key].Mode = value;
+ }
- public static void SetFor(Bill key, GroupMode value)
- {
- if (!Map.ContainsKey(key))
- Map[key] = new BillGroupData();
- Map[key].Mode = value;
- }
+ public static BillGroupData GetData(Bill key)
+ {
+ if (!Map.ContainsKey(key))
+ {
+ Map[key] = new BillGroupData();
+ SetMechanitorIfNeeded(key);
+ }
+ return Map[key];
+ }
- public static BillGroupData GetData(Bill key)
- {
- if (!Map.ContainsKey(key))
- Map[key] = new BillGroupData();
- return Map[key];
- }
+ private static void SetMechanitorIfNeeded(Bill key)
+ {
+ if (key.recipe.mechanitorOnlyRecipe)
+ {
+ Map[key].Mode = GroupMode.MechanitorOnly;
+ }
+ }
- public static void Remove(Bill bill)
- {
- Map.Remove(bill);
- }
+ public static void Remove(Bill bill)
+ {
+ Map.Remove(bill);
}
+ }
}
\ No newline at end of file
diff --git a/Source/Core/BillAssignation/BillGroupData.cs b/Source/Core/BillAssignation/BillGroupData.cs
index d9d35ae..c37ee45 100644
--- a/Source/Core/BillAssignation/BillGroupData.cs
+++ b/Source/Core/BillAssignation/BillGroupData.cs
@@ -8,7 +8,11 @@ public enum GroupMode
PrisonersOnly,
ColonistsOnly,
SlavesOnly,
- CaptiveOnly
+ HumansOnly,
+ MechsOnly,
+ MechanitorOnly,
+ CaptiveOnly,
+ ColonyGroups
}
public class BillGroupData : IExposable
diff --git a/Source/Core/GameSaves/SaveCleaner.cs b/Source/Core/GameSaves/SaveCleaner.cs
index 9936063..0fd3d30 100644
--- a/Source/Core/GameSaves/SaveCleaner.cs
+++ b/Source/Core/GameSaves/SaveCleaner.cs
@@ -11,263 +11,259 @@
namespace PrisonLabor.Core.GameSaves
{
- public static class SaveCleaner
+ public static class SaveCleaner
+ {
+ public static void BackupSavegame(string fileName)
{
- public static void BackupSavegame(string fileName)
- {
- string savegamePath = GenFilePaths.FilePathForSavedGame(fileName);
- string backupPath = GetFilePathForBackup(savegamePath);
-
- File.Copy(savegamePath, backupPath, false);
- Log.Message($"Save copied to \"{backupPath}\"");
- }
+ string savegamePath = GenFilePaths.FilePathForSavedGame(fileName);
+ string backupPath = GetFilePathForBackup(fileName);
- public static void RemoveFromSave(string fileName)
- {
- LongEventHandler.QueueLongEvent(
- () => UpdateFile(fileName),
- "Removing",
- false,
- (e) => OnError(e)
- );
- }
+ File.Copy(savegamePath, backupPath, false);
+ Log.Message($"Save copied to \"{backupPath}\"");
+ }
- private static void UpdateFile(string fileName)
- {
- string filePath = GenFilePaths.FilePathForSavedGame(fileName);
+ public static void RemoveFromSave(string fileName)
+ {
+ LongEventHandler.QueueLongEvent(
+ () => UpdateFile(fileName),
+ "Removing",
+ false,
+ (e) => OnError(e)
+ );
+ }
- XmlElement xmlNode;
- using (StreamReader streamReader = new StreamReader(filePath))
- {
- using (XmlTextReader xmlTextReader = new XmlTextReader(streamReader))
- {
- var XmlDocument = new XmlDocument();
- XmlDocument.Load(xmlTextReader);
- xmlNode = XmlDocument.DocumentElement;
- }
- }
+ private static void UpdateFile(string fileName)
+ {
+ string filePath = GenFilePaths.FilePathForSavedGame(fileName);
- UpdateData(xmlNode);
+ XmlElement xmlNode;
+ using (StreamReader streamReader = new StreamReader(filePath))
+ {
+ using (XmlTextReader xmlTextReader = new XmlTextReader(streamReader))
+ {
+ var XmlDocument = new XmlDocument();
+ XmlDocument.Load(xmlTextReader);
+ xmlNode = XmlDocument.DocumentElement;
+ }
+ }
- using (FileStream saveStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
- {
- var xmlWriterSettings = new XmlWriterSettings();
- xmlWriterSettings.Indent = true;
- xmlWriterSettings.IndentChars = "\t";
- using (XmlWriter writer = XmlWriter.Create(saveStream, xmlWriterSettings))
- {
- writer.WriteStartDocument();
- writer.WriteNode(xmlNode.CreateNavigator(), false);
- }
- }
+ UpdateData(xmlNode);
- Log.Message($"Save'{fileName}' converted successfuly");
+ using (FileStream saveStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
+ {
+ var xmlWriterSettings = new XmlWriterSettings();
+ xmlWriterSettings.Indent = true;
+ xmlWriterSettings.IndentChars = "\t";
+ using (XmlWriter writer = XmlWriter.Create(saveStream, xmlWriterSettings))
+ {
+ writer.WriteStartDocument();
+ writer.WriteNode(xmlNode.CreateNavigator(), false);
}
+ }
- private static void UpdateData(XmlElement xmlNode)
- {
- List removalBuffer = new List();
- XmlNode curNode = xmlNode;
+ Log.Message($"Save'{fileName}' converted successfuly");
+ }
- #region Meta
- var metaNode = xmlNode["meta"];
+ private static void UpdateData(XmlElement xmlNode)
+ {
+ List removalBuffer = new List();
+ XmlNode curNode = xmlNode;
- // Meta.ModIds & Meta.ModNames
- XmlNode modIdsNode = metaNode["modIds"], modNamesNode = metaNode["modNames"];
- for (int i = 0; i < modIdsNode.ChildNodes.Count; i++)
- {
- var modNode = modIdsNode.ChildNodes[i];
-
- if (modNode.InnerText == "972057888" || modNode.InnerText == "PrisonLabor")
- {
- modIdsNode.RemoveChild(modIdsNode.ChildNodes[i]);
- modNamesNode.RemoveChild(modNamesNode.ChildNodes[i]);
- break;
- }
- }
+ #region Meta
+ var metaNode = xmlNode["meta"];
- // Remove version of PL
- var plVersionInfo = metaNode["PrisonLaborVersion"];
- if (plVersionInfo != null)
- metaNode.RemoveChild(plVersionInfo);
- #endregion
+ // Meta.ModIds & Meta.ModNames
+ XmlNode modIdsNode = metaNode["modIds"], modNamesNode = metaNode["modNames"];
+ for (int i = 0; i < modIdsNode.ChildNodes.Count; i++)
+ {
+ var modNode = modIdsNode.ChildNodes[i];
- #region Game
- var gameNode = xmlNode["game"];
+ if (modNode.InnerText == "972057888" || modNode.InnerText == "PrisonLabor")
+ {
+ modIdsNode.RemoveChild(modIdsNode.ChildNodes[i]);
+ modNamesNode.RemoveChild(modNamesNode.ChildNodes[i]);
+ break;
+ }
+ }
+
+ // Remove version of PL
+ var plVersionInfo = metaNode["PrisonLaborVersion"];
+ if (plVersionInfo != null)
+ metaNode.RemoveChild(plVersionInfo);
+ #endregion
+
+ #region Game
+ var gameNode = xmlNode["game"];
+
+ // Game.Tutor
+ string[] conceptDefs = { "PrisonLabor_Indroduction", "PrisonLabor_Motivation", "PrisonLabor_Growing", "PrisonLabor_Management", "PrisonLabor_Timetable" };
+
+ var tutorNode = gameNode["tutor"];
+ //var activeLessonsNode = tutorNode["activeLesson"];
+ var learningReadoutNode = tutorNode["learningReadout"];
+ if (learningReadoutNode["activeConcepts"].HasChildNodes)
+ {
+ removalBuffer.Clear();
+ foreach (XmlNode concept in learningReadoutNode["activeConcepts"].ChildNodes)
+ {
+ foreach (string conceptDef in conceptDefs)
+ {
+ if (concept.InnerText == conceptDef)
+ removalBuffer.Add(concept);
+ }
+ }
+ foreach (var concept in removalBuffer)
+ learningReadoutNode["activeConcepts"].RemoveChild(concept);
+ }
+ if (learningReadoutNode["selectedConcept"] != null)
+ {
+ removalBuffer.Clear();
+ foreach (string conceptDef in conceptDefs)
+ {
+ if (learningReadoutNode["selectedConcept"].InnerText == conceptDef)
+ learningReadoutNode.RemoveChild(learningReadoutNode["selectedConcept"]);
+ }
+ }
+ //var tutorialStateNode = tutorNode["tutorialState"];
- // Game.Tutor
- string[] conceptDefs = { "PrisonLabor_Indroduction", "PrisonLabor_Motivation", "PrisonLabor_Growing", "PrisonLabor_Management", "PrisonLabor_Timetable" };
+ // Game.Maps
+ foreach (XmlNode mapNode in gameNode["maps"].ChildNodes)
+ {
+ // Game.Maps.AreaManager
+ var areaManagerNode = mapNode["areaManager"];
- var tutorNode = gameNode["tutor"];
- //var activeLessonsNode = tutorNode["activeLesson"];
- var learningReadoutNode = tutorNode["learningReadout"];
- if (learningReadoutNode["activeConcepts"].HasChildNodes)
- {
- removalBuffer.Clear();
- foreach (XmlNode concept in learningReadoutNode["activeConcepts"].ChildNodes)
- {
- foreach (string conceptDef in conceptDefs)
- {
- if (concept.InnerText == conceptDef)
- removalBuffer.Add(concept);
- }
- }
- foreach (var concept in removalBuffer)
- learningReadoutNode["activeConcepts"].RemoveChild(concept);
- }
- if (learningReadoutNode["selectedConcept"] != null)
+ if (areaManagerNode["areas"] != null && areaManagerNode["areas"].HasChildNodes)
+ {
+ removalBuffer.Clear();
+ foreach (XmlNode areaNode in areaManagerNode["areas"].ChildNodes)
+ {
+ if (areaNode.Attributes["Class"].Value == typeof(Area_Labor).FullName)
{
- removalBuffer.Clear();
- foreach (string conceptDef in conceptDefs)
- {
- if (learningReadoutNode["selectedConcept"].InnerText == conceptDef)
- learningReadoutNode.RemoveChild(learningReadoutNode["selectedConcept"]);
- }
+ removalBuffer.Add(areaNode);
}
- //var tutorialStateNode = tutorNode["tutorialState"];
+ }
+ foreach (var node in removalBuffer)
+ areaManagerNode["areas"].RemoveChild(node);
+ }
- // Game.Maps
- foreach (XmlNode mapNode in gameNode["maps"].ChildNodes)
- {
- // Game.Maps.AreaManager
- var areaManagerNode = mapNode["areaManager"];
-
- if (areaManagerNode["areas"] != null && areaManagerNode["areas"].HasChildNodes)
- {
- removalBuffer.Clear();
- foreach (XmlNode areaNode in areaManagerNode["areas"].ChildNodes)
- {
- if (areaNode.Attributes["Class"].Value == typeof(Area_Labor).FullName)
- {
- removalBuffer.Add(areaNode);
- }
- }
- foreach (var node in removalBuffer)
- areaManagerNode["areas"].RemoveChild(node);
- }
-
- //Game.Maps.Components
- var components = mapNode["components"];
- removalBuffer.Clear();
- foreach (XmlNode component in components)
- {
- if (component.Attributes["Class"].Value == "PrisonLabor.Core.GUI_Components.PawnIcons")
- {
- removalBuffer.Add(component);
- }
-
- if (component.Attributes["Class"].Value == "PrisonLabor.Core.Trackers.CuffsTracker")
- {
- removalBuffer.Add(component);
- }
- }
- foreach (var item in removalBuffer)
- components.RemoveChild(item);
- }
+ //Game.Maps.Components
+ var components = mapNode["components"];
+ removalBuffer.Clear();
+ foreach (XmlNode component in components)
+ {
+ if (component.Attributes["Class"].Value == "PrisonLabor.Core.GUI_Components.PawnIcons")
+ {
+ removalBuffer.Add(component);
+ }
+
+ if (component.Attributes["Class"].Value == "PrisonLabor.Core.Trackers.CuffsTracker")
+ {
+ removalBuffer.Add(component);
+ }
+ }
+ foreach (var item in removalBuffer)
+ components.RemoveChild(item);
+ }
- // TODO bills
+ // TODO bills
- // Interaction Mode
- string[] interactions = { PL_DefOf.PrisonLabor_workOption.defName, PL_DefOf.PrisonLabor_workAndRecruitOption.defName, PL_DefOf.PrisonLabor_workAndConvertOption.defName, PL_DefOf.PrisonLabor_workAndEnslaveOption.defName };
+ // Interaction Mode
+ string[] interactions = { PL_DefOf.PrisonLabor_workOption.defName, PL_DefOf.PrisonLabor_workAndRecruitOption.defName, PL_DefOf.PrisonLabor_workAndConvertOption.defName, PL_DefOf.PrisonLabor_workAndEnslaveOption.defName };
- foreach (var guestTracker in gameNode.GetEveryNode("guest"))
- {
- var interactionMode = guestTracker["interactionMode"];
- if (interactionMode != null)
- {
- foreach (string interaction in interactions)
- {
- if (interactionMode.InnerText == interaction)
- interactionMode.InnerText = PrisonerInteractionModeDefOf.NoInteraction.defName;
- }
- }
- }
+ foreach (var guestTracker in gameNode.GetEveryNode("guest"))
+ {
+ var interactionMode = guestTracker["interactionMode"];
+ if (interactionMode != null)
+ {
+ foreach (string interaction in interactions)
+ {
+ if (interactionMode.InnerText == interaction)
+ interactionMode.InnerText = PrisonerInteractionModeDefOf.NoInteraction.defName;
+ }
+ }
+ }
- // Remove Heddifs
- foreach (var needTracker in gameNode.GetEveryNode("needs"))
- {
- var needs = needTracker["needs"];
- if (needs != null)
- {
-
- if (needs != null && needs.HasChildNodes)
- {
- removalBuffer.Clear();
- foreach (XmlNode need in needs.ChildNodes)
- {
- if (need.Attributes["Class"].Value == typeof(Need_Motivation).FullName)
- removalBuffer.Add(need);
- else if (need.Attributes["Class"].Value == typeof(Need_Treatment).FullName)
- removalBuffer.Add(need);
- }
- foreach (var node in removalBuffer)
- needs.RemoveChild(node);
- }
- }
- }
+ // Remove Heddifs
+ foreach (var needTracker in gameNode.GetEveryNode("needs"))
+ {
+ var needs = needTracker["needs"];
+ if (needs != null)
+ {
- // Remove Heddifs
- foreach (var hediffSet in gameNode.GetEveryNode("hediffSet"))
+ if (needs != null && needs.HasChildNodes)
+ {
+ removalBuffer.Clear();
+ foreach (XmlNode need in needs.ChildNodes)
{
- var hediffs = hediffSet["hediffs"];
-
- if (hediffs != null && hediffs.HasChildNodes)
- {
- removalBuffer.Clear();
- foreach (XmlNode hediff in hediffs.ChildNodes)
- {
- if (hediff["def"].InnerText == "PrisonLabor_PrisonerChains")
- {
- removalBuffer.Add(hediff);
- }
- }
- foreach (var node in removalBuffer)
- hediffs.RemoveChild(node);
- }
+ if (need.Attributes["Class"].Value == typeof(Need_Motivation).FullName)
+ removalBuffer.Add(need);
+ else if (need.Attributes["Class"].Value == typeof(Need_Treatment).FullName)
+ removalBuffer.Add(need);
}
- #endregion
+ foreach (var node in removalBuffer)
+ needs.RemoveChild(node);
+ }
}
+ }
+
+ // Remove Heddifs
+ foreach (var hediffSet in gameNode.GetEveryNode("hediffSet"))
+ {
+ var hediffs = hediffSet["hediffs"];
- private static IEnumerable GetEveryNode(this XmlNode rootElement, string nodeName)
+ if (hediffs != null && hediffs.HasChildNodes)
{
- foreach (XmlNode node in rootElement.ChildNodes)
+ removalBuffer.Clear();
+ foreach (XmlNode hediff in hediffs.ChildNodes)
+ {
+ if (hediff["def"].InnerText == "PrisonLabor_PrisonerChains")
{
- if (node.Name.Equals(nodeName))
- yield return node;
- if (node.HasChildNodes)
- {
- foreach (XmlNode childNode in node.GetEveryNode(nodeName))
- yield return childNode;
- }
+ removalBuffer.Add(hediff);
}
+ }
+ foreach (var node in removalBuffer)
+ hediffs.RemoveChild(node);
}
+ }
+ #endregion
+ }
- private static void OnError(Exception e)
+ private static IEnumerable GetEveryNode(this XmlNode rootElement, string nodeName)
+ {
+ foreach (XmlNode node in rootElement.ChildNodes)
+ {
+ if (node.Name.Equals(nodeName))
+ yield return node;
+ if (node.HasChildNodes)
{
- Log.Error(e.ToString());
+ foreach (XmlNode childNode in node.GetEveryNode(nodeName))
+ yield return childNode;
}
+ }
+ }
- private static string GetFilePathForBackup(string filePath)
- {
- string originFilePathWithoutExtension = Path.GetDirectoryName(filePath) + @"\" + Path.GetFileNameWithoutExtension(filePath);
-
- string backupFileCoreString = originFilePathWithoutExtension + "_Backup";
+ private static void OnError(Exception e)
+ {
+ Log.Error(e.ToString());
+ }
- string backupFilePathFinal = backupFileCoreString + ".rws";
+ private static string GetFilePathForBackup(string fileName)
+ {
+ string backupFile = GenFilePaths.FilePathForSavedGame(fileName + "_Backup");
- if (!File.Exists(backupFilePathFinal))
- return backupFilePathFinal;
+ if (!File.Exists(backupFile))
+ return backupFile;
- for (int i = 1; i < int.MaxValue; i++)
- {
- backupFilePathFinal = backupFileCoreString + i.ToString() + ".rws";
+ for (int i = 1; i < int.MaxValue; i++)
+ {
+ backupFile = GenFilePaths.FilePathForSavedGame(fileName + "_Backup" + i);
- if (!File.Exists(backupFilePathFinal))
- return backupFilePathFinal;
- }
+ if (!File.Exists(backupFile))
+ return backupFile;
+ }
- throw new IndexOutOfRangeException();
- }
+ throw new IndexOutOfRangeException();
}
+ }
}
diff --git a/Source/Core/Meta/Version.cs b/Source/Core/Meta/Version.cs
index 6a5f75f..ac4e8b1 100644
--- a/Source/Core/Meta/Version.cs
+++ b/Source/Core/Meta/Version.cs
@@ -85,6 +85,7 @@ public enum Version
v1_4_2,
v1_4_3,
v1_4_4,
- v1_4_5
+ v1_4_5,
+ v1_4_6
}
}
diff --git a/Source/Core/Meta/VersionUtility.cs b/Source/Core/Meta/VersionUtility.cs
index 69f0247..b5cda28 100644
--- a/Source/Core/Meta/VersionUtility.cs
+++ b/Source/Core/Meta/VersionUtility.cs
@@ -5,8 +5,8 @@ namespace PrisonLabor.Core.Meta
{
public class VersionUtility
{
- public const Version versionNumber = Version.v1_4_5;
- public const string versionString = "1.4.5";
+ public const Version versionNumber = Version.v1_4_6;
+ public const string versionString = "1.4.6";
public static Version VersionOfSaveFile { get; set; }
diff --git a/Source/Core/Other/CustomForbidenUtil.cs b/Source/Core/Other/CustomForbidenUtil.cs
index dc17053..a0e55e5 100644
--- a/Source/Core/Other/CustomForbidenUtil.cs
+++ b/Source/Core/Other/CustomForbidenUtil.cs
@@ -10,74 +10,80 @@
namespace PrisonLabor.Core.Other
{
- public static class CustomForbidenUtil
+ public static class CustomForbidenUtil
+ {
+ public static bool PrisonerCaresAboutForbidden(Pawn pawn, bool cellTarget)
{
- public static bool PrisonerCaresAboutForbidden(Pawn pawn, bool cellTarget)
- {
- if (!pawn.Spawned || !pawn.IsPrisonerOfColony && pawn.timetable.CurrentAssignment != TimeAssignmentDefOf.Work)
- {
- return false;
- }
- if (pawn.InMentalState)
- {
- return false;
- }
- if (cellTarget && ThinkNode_ConditionalShouldFollowMaster.ShouldFollowMaster(pawn))
- {
- return false;
- }
- return true;
- }
+ if (!pawn.Spawned || !pawn.IsPrisonerOfColony && pawn.timetable.CurrentAssignment != TimeAssignmentDefOf.Work)
+ {
+ return false;
+ }
+ if (pawn.InMentalState)
+ {
+ return false;
+ }
+ if (cellTarget && ThinkNode_ConditionalShouldFollowMaster.ShouldFollowMaster(pawn))
+ {
+ return false;
+ }
+ return true;
+ }
- public static bool IsFoodForbiden(this Thing t, Pawn pawn)
- {
- if (pawn.IsPrisonerOfColony)
- {
- DebugLogger.debug($"[PL] Pawn {pawn.LabelShort} checking null object");
- }
- return t != null && PrisonerFoodReservation.IsReserved(t) && !pawn.IsPrisoner;
- }
+ public static bool IsFoodForbiden(this Thing t, Pawn pawn)
+ {
+ if (pawn.IsPrisonerOfColony)
+ {
+ DebugLogger.debug($"[PL] Pawn {pawn.LabelShort} checking null object");
+ }
+ return t != null && PrisonerFoodReservation.IsReserved(t) && !pawn.IsPrisoner;
+ }
- public static bool IsForbiddenForPrisoner(this Thing t, Pawn pawn)
- {
+ public static bool IsForbiddenForPrisoner(this Thing t, Pawn pawn)
+ {
+ if ((t is Frame || t is Blueprint) && ForbidUtility.IsForbidden(t, Faction.OfPlayer))
+ {
+ //Should prevent delivering resources for frames by prisoners when forbidden.
+ //Simpified solution, not worth to overthing about that.
+ return true;
+ }
- if (pawn.IsWatched() && ForbidUtility.IsForbidden(t, Faction.OfPlayer))
- {
- return true;
- }
- if (!PrisonerCaresAboutForbidden(pawn, cellTarget: false))
- {
- return false;
- }
- if (t != null && t.Spawned && t.Position.IsForbiddenForPrisoner(pawn))
- {
- return true;
- }
- Lord lord = pawn.GetLord();
- if (lord != null && lord.extraForbiddenThings.Contains(t))
- {
- return true;
- }
- return false;
- }
+ if (pawn.IsWatched() && ForbidUtility.IsForbidden(t, Faction.OfPlayer))
+ {
+ return true;
+ }
+ if (!PrisonerCaresAboutForbidden(pawn, cellTarget: false))
+ {
+ return false;
+ }
+ if (t != null && t.Spawned && t.Position.IsForbiddenForPrisoner(pawn))
+ {
+ return true;
+ }
+ Lord lord = pawn.GetLord();
+ if (lord != null && lord.extraForbiddenThings.Contains(t))
+ {
+ return true;
+ }
+ return false;
+ }
- public static bool IsForbiddenForPrisoner(this IntVec3 c, Pawn pawn)
- {
- if (!PrisonerCaresAboutForbidden(pawn, cellTarget: true))
- {
- return false;
- }
- if (!c.InAllowedArea(pawn))
- {
- return true;
- }
- if (pawn.mindState.maxDistToSquadFlag > 0f && !c.InHorDistOf(pawn.DutyLocation(), pawn.mindState.maxDistToSquadFlag))
- {
- return true;
- }
- return false;
- }
+ public static bool IsForbiddenForPrisoner(this IntVec3 c, Pawn pawn)
+ {
+ if (!PrisonerCaresAboutForbidden(pawn, cellTarget: true))
+ {
+ return false;
+ }
+ if (!c.InAllowedArea(pawn))
+ {
+ return true;
+ }
+ if (pawn.mindState.maxDistToSquadFlag > 0f && !c.InHorDistOf(pawn.DutyLocation(), pawn.mindState.maxDistToSquadFlag))
+ {
+ return true;
+ }
+ return false;
}
+ }
}
diff --git a/Source/HarmonyPatches/Patches_BillAssignation/Bill_StartAnew_Patch.cs b/Source/HarmonyPatches/Patches_BillAssignation/Bill_StartAnew_Patch.cs
index ea31509..0b5b215 100644
--- a/Source/HarmonyPatches/Patches_BillAssignation/Bill_StartAnew_Patch.cs
+++ b/Source/HarmonyPatches/Patches_BillAssignation/Bill_StartAnew_Patch.cs
@@ -1,5 +1,6 @@
using HarmonyLib;
using PrisonLabor.Core.BillAssignation;
+using PrisonLabor.Core.Other;
using RimWorld;
using System;
using System.Collections.Generic;
@@ -11,56 +12,61 @@
namespace PrisonLabor.HarmonyPatches.Patches_BillAssignation
{
- [HarmonyPatch(typeof(Bill))]
- [HarmonyPatch("PawnAllowedToStartAnew")]
- public class Bill_StartAnew_Patch
+ [HarmonyPatch(typeof(Bill))]
+ [HarmonyPatch("PawnAllowedToStartAnew")]
+ public class Bill_StartAnew_Patch
+ {
+ static bool Postfix(bool __result, Bill __instance, Pawn p)
{
- static bool Postfix(bool __result, Bill __instance, Pawn p)
- {
- if (__result == false && __instance.PawnRestriction == null)
- {
- GroupMode group = BillAssignationUtility.IsFor(__instance);
+ if (__result == false && __instance.PawnRestriction == null)
+ {
+ GroupMode group = BillAssignationUtility.IsFor(__instance);
- if (group == GroupMode.ColonyOnly && __instance.SlavesOnly && p.IsSlave)
- {
- return true;
- }
- if (group == GroupMode.SlavesOnly && __instance.SlavesOnly && p.IsSlave)
- {
- return true;
- }
+ if (group == GroupMode.ColonyGroups)
+ {
+ DebugLogger.debug($"Skiping checking for {__instance.Label}. Pawn: {p.NameShortColored}");
+ return __result;
+ }
- if (group == GroupMode.CaptiveOnly && __instance.SlavesOnly && p.IsSlave)
- {
- return true;
- }
- if (__instance.recipe.workSkill != null && (p.skills != null || p.IsColonyMech))
- {
- int level = (p.skills != null) ? p.skills.GetSkill(__instance.recipe.workSkill).Level : p.RaceProps.mechFixedSkillLevel;
- if (level < __instance.allowedSkillRange.min)
- {
- JobFailReason.Is("UnderAllowedSkill".Translate(__instance.allowedSkillRange.min), __instance.Label);
- return false;
- }
- if (level > __instance.allowedSkillRange.max)
- {
- JobFailReason.Is("AboveAllowedSkill".Translate(__instance.allowedSkillRange.max), __instance.Label);
- return false;
- }
+ if (group == GroupMode.ColonyOnly && __instance.SlavesOnly && p.IsSlave)
+ {
+ return true;
+ }
+ if (group == GroupMode.SlavesOnly && __instance.SlavesOnly && p.IsSlave)
+ {
+ return true;
+ }
- }
- if (ModsConfig.BiotechActive && __instance.recipe.mechanitorOnlyRecipe && !MechanitorUtility.IsMechanitor(p))
- {
- JobFailReason.Is("NotAMechanitor".Translate());
- return false;
- }
- if (group == GroupMode.ColonyOnly || (group == GroupMode.CaptiveOnly && p.IsPrisoner))
- {
- return true;
- }
+ if (group == GroupMode.CaptiveOnly && __instance.SlavesOnly && p.IsSlave)
+ {
+ return true;
+ }
+ if (__instance.recipe.workSkill != null && (p.skills != null || p.IsColonyMech))
+ {
+ int level = (p.skills != null) ? p.skills.GetSkill(__instance.recipe.workSkill).Level : p.RaceProps.mechFixedSkillLevel;
+ if (level < __instance.allowedSkillRange.min)
+ {
+ JobFailReason.Is("UnderAllowedSkill".Translate(__instance.allowedSkillRange.min), __instance.Label);
+ return false;
+ }
+ if (level > __instance.allowedSkillRange.max)
+ {
+ JobFailReason.Is("AboveAllowedSkill".Translate(__instance.allowedSkillRange.max), __instance.Label);
+ return false;
+ }
- }
- return __result;
}
+ if (group == GroupMode.MechanitorOnly)
+ {
+ return MechanitorUtility.IsMechanitor(p);
+ }
+ if (group == GroupMode.ColonyOnly || (group == GroupMode.CaptiveOnly && p.IsPrisoner))
+ {
+ return true;
+ }
+
+ }
+ return __result;
}
+ }
}
diff --git a/Source/HarmonyPatches/Patches_BillAssignation/Patch_BillPrevention.cs b/Source/HarmonyPatches/Patches_BillAssignation/Patch_BillPrevention.cs
index bff73f4..42372a0 100644
--- a/Source/HarmonyPatches/Patches_BillAssignation/Patch_BillPrevention.cs
+++ b/Source/HarmonyPatches/Patches_BillAssignation/Patch_BillPrevention.cs
@@ -7,33 +7,34 @@
using System;
using System.IO;
using PrisonLabor.Core.BillAssignation;
+using Verse.AI;
namespace PrisonLabor.HarmonyPatches.Patches_BillAssignation
{
- [HarmonyPatch(typeof(WorkGiver_DoBill))]
- [HarmonyPatch("StartOrResumeBillJob")]
- [HarmonyPatch(new[] { typeof(Pawn), typeof(IBillGiver) })]
- internal class Patch_BillPrevention
+ [HarmonyPatch(typeof(WorkGiver_DoBill))]
+ [HarmonyPatch("StartOrResumeBillJob")]
+ [HarmonyPatch(new[] { typeof(Pawn), typeof(IBillGiver) })]
+ internal class Patch_BillPrevention
+ {
+ private static IEnumerable Transpiler(ILGenerator gen, MethodBase mBase,
+ IEnumerable instr)
{
- private static IEnumerable Transpiler(ILGenerator gen, MethodBase mBase,
- IEnumerable instr)
- {
- OpCode[] opCodes =
- {
+ OpCode[] opCodes =
+ {
OpCodes.Ldfld,
OpCodes.Ldfld,
OpCodes.Bne_Un
};
- String[] operands =
- {
+ String[] operands =
+ {
"RimWorld.WorkGiverDef def",
"Verse.WorkTypeDef workType",
"System.Reflection.Emit.Label"
};
- var label = (Label)HPatcher.FindOperandAfter(opCodes, operands, instr);
+ var label = (Label)HPatcher.FindOperandAfter(opCodes, operands, instr);
- OpCode[] opCodes2 =
- {
+ OpCode[] opCodes2 =
+ {
OpCodes.Ldc_I4_0,
OpCodes.Stloc_1,
OpCodes.Br,
@@ -43,8 +44,8 @@ private static IEnumerable Transpiler(ILGenerator gen, MethodBa
OpCodes.Callvirt,
OpCodes.Stloc_2,
};
- String[] operands2 =
- {
+ String[] operands2 =
+ {
"",
"",
"System.Reflection.Emit.Label",
@@ -54,45 +55,62 @@ private static IEnumerable Transpiler(ILGenerator gen, MethodBa
"RimWorld.Bill get_Item(Int32)",
"",
};
- var step = 0;
- foreach (var ci in instr)
- {
- yield return ci;
- if (HPatcher.IsFragment(opCodes2, operands2, ci, ref step, "Patch_BillPrevention"))
- {
- yield return new CodeInstruction(OpCodes.Ldarg_1);
- yield return new CodeInstruction(OpCodes.Ldloc_2);
- yield return new CodeInstruction(OpCodes.Call, typeof(Patch_BillPrevention).GetMethod(nameof(IsForCertainGroup)));
- yield return new CodeInstruction(OpCodes.Brfalse, label);
- }
- }
+ var step = 0;
+ foreach (var ci in instr)
+ {
+ yield return ci;
+ if (HPatcher.IsFragment(opCodes2, operands2, ci, ref step, "Patch_BillPrevention"))
+ {
+ yield return new CodeInstruction(OpCodes.Ldarg_1);
+ yield return new CodeInstruction(OpCodes.Ldloc_2);
+ yield return new CodeInstruction(OpCodes.Call, typeof(Patch_BillPrevention).GetMethod(nameof(IsForCertainGroup)));
+ yield return new CodeInstruction(OpCodes.Brfalse, label);
}
+ }
+ }
- public static bool IsForCertainGroup(Pawn pawn, Bill bill)
- {
- var group = BillAssignationUtility.IsFor(bill);
- if (group == GroupMode.ColonyOnly)
- {
- return true;
- }
- if (group == GroupMode.ColonistsOnly && !pawn.IsPrisoner && !pawn.IsSlave)
- {
- return true;
- }
- if (group == GroupMode.PrisonersOnly && pawn.IsPrisoner)
- {
- return true;
- }
- if(group == GroupMode.SlavesOnly && bill.SlavesOnly && pawn.IsSlave)
- {
- return true;
- }
+ public static bool IsForCertainGroup(Pawn pawn, Bill bill)
+ {
+ var group = BillAssignationUtility.IsFor(bill);
- if(group == GroupMode.CaptiveOnly && (pawn.IsPrisoner || (bill.SlavesOnly && pawn.IsSlave)))
- {
- return true;
- }
- return false;
- }
+ if (group == GroupMode.ColonyOnly)
+ {
+ return true;
+ }
+ if (group == GroupMode.ColonistsOnly && !pawn.IsPrisoner && !pawn.IsSlave)
+ {
+ return true;
+ }
+ if (group == GroupMode.PrisonersOnly && pawn.IsPrisoner)
+ {
+ return true;
+ }
+ if (group == GroupMode.SlavesOnly && bill.SlavesOnly && pawn.IsSlave)
+ {
+ return true;
+ }
+
+ if (group == GroupMode.CaptiveOnly && (pawn.IsPrisoner || (bill.SlavesOnly && pawn.IsSlave)))
+ {
+ return true;
+ }
+ if (group == GroupMode.ColonyGroups)
+ {
+ return true;
+ }
+ if (group == GroupMode.MechanitorOnly && MechanitorUtility.IsMechanitor(pawn))
+ {
+ return true;
+ }
+ if (group == GroupMode.MechsOnly && pawn.IsColonyMechPlayerControlled)
+ {
+ return true;
+ }
+ if (group == GroupMode.HumansOnly && !pawn.IsColonyMech)
+ {
+ return true;
+ }
+ return false;
}
+ }
}
\ No newline at end of file
diff --git a/Source/HarmonyPatches/Patches_GUI/GUI_Bill/Patch_Bill_Assigment.cs b/Source/HarmonyPatches/Patches_GUI/GUI_Bill/Patch_Bill_Assigment.cs
index 2e9c03f..6067cf8 100644
--- a/Source/HarmonyPatches/Patches_GUI/GUI_Bill/Patch_Bill_Assigment.cs
+++ b/Source/HarmonyPatches/Patches_GUI/GUI_Bill/Patch_Bill_Assigment.cs
@@ -9,21 +9,43 @@
namespace PrisonLabor.HarmonyPatches.Patches_GUI.GUI_Bill
{
- [HarmonyPatch(typeof(Bill))]
- public class Patch_Bill_Assigment
+ [HarmonyPatch(typeof(Bill))]
+ public class Patch_Bill_Assigment
+ {
+ [HarmonyPostfix]
+ [HarmonyPatch("SetAnyPawnRestriction")]
+ static void ColonistPostFix(Bill __instance)
{
- [HarmonyPostfix]
- [HarmonyPatch("SetAnyPawnRestriction")]
- static void ColonistPostFix(Bill __instance)
- {
- BillAssignationUtility.SetFor(__instance, GroupMode.ColonistsOnly);
- }
+ if (__instance.recipe.mechanitorOnlyRecipe)
+ {
+ BillAssignationUtility.SetFor(__instance, GroupMode.MechanitorOnly);
+ }
+ else
+ {
+ BillAssignationUtility.SetFor(__instance, GroupMode.ColonistsOnly);
+ }
+ }
+
+ [HarmonyPostfix]
+ [HarmonyPatch("SetAnyMechRestriction")]
+ static void MechPostFix(Bill __instance)
+ {
+ BillAssignationUtility.SetFor(__instance, GroupMode.MechsOnly);
+ }
+
- [HarmonyPostfix]
- [HarmonyPatch("SetAnySlaveRestriction")]
- static void SlavePostFix(Bill __instance)
- {
- BillAssignationUtility.SetFor(__instance, GroupMode.SlavesOnly);
- }
+ [HarmonyPostfix]
+ [HarmonyPatch("SetAnyNonMechRestriction")]
+ static void OnlyHumanPostFix(Bill __instance)
+ {
+ BillAssignationUtility.SetFor(__instance, GroupMode.HumansOnly);
+ }
+
+ [HarmonyPostfix]
+ [HarmonyPatch("SetAnySlaveRestriction")]
+ static void SlavePostFix(Bill __instance)
+ {
+ BillAssignationUtility.SetFor(__instance, GroupMode.SlavesOnly);
}
+ }
}
diff --git a/Source/HarmonyPatches/Patches_GUI/GUI_Bill/Patch_RestrictBillToPrisoner.cs b/Source/HarmonyPatches/Patches_GUI/GUI_Bill/Patch_RestrictBillToPrisoner.cs
index 414951c..eb99dd7 100644
--- a/Source/HarmonyPatches/Patches_GUI/GUI_Bill/Patch_RestrictBillToPrisoner.cs
+++ b/Source/HarmonyPatches/Patches_GUI/GUI_Bill/Patch_RestrictBillToPrisoner.cs
@@ -13,232 +13,252 @@
namespace PrisonLabor.HarmonyPatches.Patches_GUI.GUI_Bill
{
- [HarmonyPatch(typeof(Dialog_BillConfig))]
- class Patch_RestrictBillToPrisoner
- {
+ [HarmonyPatch(typeof(Dialog_BillConfig))]
+ public class Patch_RestrictBillToPrisoner
+ {
- ///
- /// Replace button label to allow select more element
- /// Oryginal:
- /// Widgets.Dropdown(buttonLabel: (bill.PawnRestriction != null) ? bill.PawnRestriction.LabelShortCap : ((!ModsConfig.IdeologyActive || !bill.SlavesOnly) ? ((string)"AnyWorker".Translate()) : ((string)"AnySlave".Translate()))
- ///
- ///
- ///
- [HarmonyTranspiler]
- [HarmonyPatch("DoWindowContents")]
- [HarmonyPatch(new[] { typeof(Rect) })]
- static IEnumerable Transpiler_DoWindowContent(IEnumerable instructions)
- {
- /*
- call | Boolean get_IdeologyActive() | Label 39
- brfalse.s | Label 41 | no labels
- ldarg.0 | | no labels
- ldfld | RimWorld.Bill_Production bill | no labels
- callvirt | Boolean get_SlavesOnly() | no labels
- brfalse.s | Label 42 | no labels
- ldstr | AnySlave | no labels
- call | Verse.TaggedString Translate(System.String) | no labels
- call | System.String op_Implicit(Verse.TaggedString) | no labels
- stloc.s | System.String (25) | no labels
- br.s | Label 43 | no labels
- ldstr | AnyWorker | Label 41Label 42
- call | Verse.TaggedString Translate(System.String) | no labels
- call | System.String op_Implicit(Verse.TaggedString) | no labels
- stloc.s | System.String (25) | no labels
- */
- CodeInstruction[] replacement =
- {
+ ///
+ /// Replace button label to allow select more element
+ /// Oryginal:
+ /// Widgets.Dropdown(buttonLabel: (bill.PawnRestriction != null) ? bill.PawnRestriction.LabelShortCap : ((!ModsConfig.IdeologyActive || !bill.SlavesOnly) ? ((string)"AnyWorker".Translate()) : ((string)"AnySlave".Translate()))
+ ///
+ ///
+ ///
+ [HarmonyTranspiler]
+ [HarmonyPatch("DoWindowContents")]
+ [HarmonyPatch(new[] { typeof(Rect) })]
+ static IEnumerable Transpiler_DoWindowContent(IEnumerable instructions)
+ {
+ /*
+ call | Boolean get_IdeologyActive() | Label 39
+ brfalse.s | Label 41 | no labels
+ ldarg.0 | | no labels
+ ldfld | RimWorld.Bill_Production bill | no labels
+ callvirt | Boolean get_SlavesOnly() | no labels
+ brfalse.s | Label 42 | no labels
+ ldstr | AnySlave | no labels
+ call | Verse.TaggedString Translate(System.String) | no labels
+ call | System.String op_Implicit(Verse.TaggedString) | no labels
+ stloc.s | System.String (25) | no labels
+ br.s | Label 43 | no labels
+ ldstr | AnyWorker | Label 41Label 42
+ call | Verse.TaggedString Translate(System.String) | no labels
+ call | System.String op_Implicit(Verse.TaggedString) | no labels
+ stloc.s | System.String (25) | no labels
+ */
+ CodeInstruction[] replacement =
+ {
new CodeInstruction(OpCodes.Ldarg_0),
new CodeInstruction(OpCodes.Call, typeof(Patch_RestrictBillToPrisoner).GetMethod(nameof(GetLabel))),
new CodeInstruction(OpCodes.Stloc_S, 25)
};
- // return HPatcher.ReplaceFragment(opCodes, operands, instructions, replacement, "Patch_RestrictBillToPrisoner patch for DoWindowContents", false);
+ // return HPatcher.ReplaceFragment(opCodes, operands, instructions, replacement, "Patch_RestrictBillToPrisoner patch for DoWindowContents", false);
- List instr = instructions.ToList();
- int start = 0;
- int end = 0;
- for (int i = 0; i < instr.Count(); i++)
- {
- if (instr[i].IsLdarg(0) && instr[i - 1].opcode == OpCodes.Stloc_S)
- {
- if (instr[i - 1].operand is LocalBuilder lb1 && lb1.LocalIndex == 24)
- {
- start = i;
-
- }
- }
+ List instr = instructions.ToList();
+ int start = 0;
+ int end = 0;
+ for (int i = 0; i < instr.Count(); i++)
+ {
+ if (instr[i].IsLdarg(0) && instr[i - 1].opcode == OpCodes.Stloc_S)
+ {
+ if (instr[i - 1].operand is LocalBuilder lb1 && lb1.LocalIndex == 24)
+ {
+ start = i;
- if (instr[i].IsStloc() && instr[i].operand is LocalBuilder lb && lb.LocalIndex == 25 && instr[i + 1].opcode == OpCodes.Ldloc_S)
- {
- end = i;
- }
- }
- instr.RemoveRange(start, end - start + 1);
- instr.InsertRange(start, replacement);
-
- return instr.AsEnumerable();
+ }
}
- public static string GetLabel(Dialog_BillConfig dialog)
+
+ if (instr[i].IsStloc() && instr[i].operand is LocalBuilder lb && lb.LocalIndex == 25 && instr[i + 1].opcode == OpCodes.Ldloc_S)
{
+ end = i;
+ }
+ }
+ instr.RemoveRange(start, end - start + 1);
+ instr.InsertRange(start, replacement);
- Bill_Production bill = Traverse.Create(dialog).Field("bill").GetValue();
- if(bill.PawnRestriction != null)
- {
- return bill.PawnRestriction.LabelShortCap;
- }
- return GetDropLabel(dialog);
+ return instr.AsEnumerable();
+ }
+ public static string GetLabel(Dialog_BillConfig dialog)
+ {
+
+ Bill_Production bill = Traverse.Create(dialog).Field("bill").GetValue();
+ if (bill.PawnRestriction != null)
+ {
+ return bill.PawnRestriction.LabelShortCap;
+ }
+ return GetDropLabel(dialog);
+
+ }
+ public static string GetDropLabel(Dialog_BillConfig dialog)
+ {
+ Bill_Production bill = Traverse.Create(dialog).Field("bill").GetValue();
+ GroupMode groupMode = ExtractGroupMode(bill);
+ switch (groupMode)
+ {
+ case GroupMode.ColonyOnly:
+ return "PrisonLabor_ColonyOnly".Translate();
+ case GroupMode.PrisonersOnly:
+ return "PrisonLabor_PrisonersOnly".Translate();
+ case GroupMode.ColonistsOnly:
+ return "AnyWorker".Translate();
+ case GroupMode.SlavesOnly:
+ return "AnySlave".Translate();
+ case GroupMode.CaptiveOnly:
+ return "PrisonLabor_PrisonersAndSlaveOnly".Translate();
+ case GroupMode.MechanitorOnly:
+ return "AnyMechanitor".Translate();
+ case GroupMode.MechsOnly:
+ return "AnyMech".Translate();
+ case GroupMode.HumansOnly:
+ return "AnyNonMech".Translate();
+ default:
+ return (!ModsConfig.IdeologyActive || !bill.SlavesOnly) ? ("AnyWorker".Translate()) : ("AnySlave".Translate());
+ }
+ }
+ public static GroupMode ExtractGroupMode(Bill_Production bill)
+ {
+ return BillAssignationUtility.IsFor(bill);
+ }
+
+ [HarmonyPostfix]
+ [HarmonyPatch("GeneratePawnRestrictionOptions")]
+ static IEnumerable> Postfix_GenerateFields(IEnumerable> values, Dialog_BillConfig __instance)
+ {
+ int check = ModsConfig.IdeologyActive ? 1 : 0;
+ int i = 0;
+ Bill_Production bill = Traverse.Create(__instance).Field("bill").GetValue();
+
+ if (bill.recipe.mechanitorOnlyRecipe)
+ {
+ foreach (Widgets.DropdownMenuElement value in values)
+ {
+ yield return value;
}
- public static string GetDropLabel(Dialog_BillConfig dialog)
+ yield break;
+ }
+ Widgets.DropdownMenuElement anyone = new Widgets.DropdownMenuElement
+ {
+ option = new FloatMenuOption("PrisonLabor_ColonyOnly".Translate(), delegate
+ {
+ Traverse.Create(bill).Field("slavesOnly").SetValue(true);
+ Traverse.Create(bill).Field("pawnRestriction").SetValue(null);
+ BillAssignationUtility.SetFor(bill, GroupMode.ColonyOnly);
+ }),
+ payload = null
+ };
+ yield return anyone;
+ foreach (Widgets.DropdownMenuElement value in values)
+ {
+ yield return value;
+ if (check == i)
{
- Bill_Production bill = Traverse.Create(dialog).Field("bill").GetValue();
- GroupMode groupMode = BillAssignationUtility.IsFor(bill);
- switch (groupMode)
+ Widgets.DropdownMenuElement prisonerMenu = new Widgets.DropdownMenuElement
+ {
+ option = new FloatMenuOption("PrisonLabor_PrisonersOnly".Translate(), delegate
+ {
+ bill.SetAnyPawnRestriction();
+ BillAssignationUtility.SetFor(bill, GroupMode.PrisonersOnly);
+ }),
+ payload = null
+ };
+ yield return prisonerMenu;
+
+ Widgets.DropdownMenuElement anyCaptive = new Widgets.DropdownMenuElement
+ {
+ option = new FloatMenuOption("PrisonLabor_PrisonersAndSlaveOnly".Translate(), delegate
{
- case GroupMode.ColonyOnly:
- return "PrisonLabor_ColonyOnly".Translate();
- case GroupMode.PrisonersOnly:
- return "PrisonLabor_PrisonersOnly".Translate();
- case GroupMode.ColonistsOnly:
- return "AnyWorker".Translate();
- case GroupMode.SlavesOnly:
- return "AnySlave".Translate();
- case GroupMode.CaptiveOnly:
- return "PrisonLabor_PrisonersAndSlaveOnly".Translate();
- default:
- return (!ModsConfig.IdeologyActive || !bill.SlavesOnly) ? ("AnyWorker".Translate()) : ("AnySlave".Translate());
- }
+ bill.SetAnySlaveRestriction();
+ BillAssignationUtility.SetFor(bill, GroupMode.CaptiveOnly);
+ }),
+ payload = null
+ };
+ yield return anyCaptive;
}
+ i++;
+ }
+ WorkGiverDef workGiver = bill.billStack.billGiver.GetWorkgiver();
+ SkillDef workSkill = bill.recipe.workSkill;
+ IEnumerable allPrisonersOfColony = PawnsFinder.AllMaps_PrisonersOfColony;
- [HarmonyPostfix]
- [HarmonyPatch("GeneratePawnRestrictionOptions")]
- static IEnumerable> Postfix_GenerateFields(IEnumerable> values, Dialog_BillConfig __instance)
+ allPrisonersOfColony = allPrisonersOfColony.OrderBy((Pawn pawn) => pawn.LabelShortCap);
+ if (workSkill != null)
+ {
+ allPrisonersOfColony = allPrisonersOfColony.OrderByDescending((Pawn pawn) => pawn.skills.GetSkill(bill.recipe.workSkill).Level);
+ }
+ if (workGiver == null)
+ {
+ Log.ErrorOnce("Generating pawn restrictions for a BillGiver without a Workgiver", 96455148);
+ yield break;
+ }
+ allPrisonersOfColony = allPrisonersOfColony.OrderByDescending((Pawn pawn) => pawn.workSettings.WorkIsActive(workGiver.workType));
+ allPrisonersOfColony = allPrisonersOfColony.OrderBy((Pawn pawn) => pawn.WorkTypeIsDisabled(workGiver.workType));
+
+ Widgets.DropdownMenuElement dropdownMenuElement;
+ foreach (Pawn pawn in allPrisonersOfColony)
+ {
+ if (PrisonLaborUtility.LaborEnabled(pawn))
{
- int check = ModsConfig.IdeologyActive ? 1 : 0;
- int i = 0;
- Bill_Production bill = Traverse.Create(__instance).Field("bill").GetValue();
- Widgets.DropdownMenuElement anyone = new Widgets.DropdownMenuElement
+ if (pawn.WorkTypeIsDisabled(workGiver.workType))
+ {
+ dropdownMenuElement = new Widgets.DropdownMenuElement
{
- option = new FloatMenuOption("PrisonLabor_ColonyOnly".Translate(), delegate
- {
- Traverse.Create(bill).Field("slavesOnly").SetValue(true);
- Traverse.Create(bill).Field("pawnRestriction").SetValue(null);
- BillAssignationUtility.SetFor(bill, GroupMode.ColonyOnly);
- }),
- payload = null
+ option = new FloatMenuOption(string.Format("P: {0} ({1})", pawn.LabelShortCap, "WillNever".Translate(workGiver.verb)), null),
+ payload = pawn
};
- yield return anyone;
- foreach (Widgets.DropdownMenuElement value in values)
+ yield return dropdownMenuElement;
+ }
+ else if (bill.recipe.workSkill != null && !pawn.workSettings.WorkIsActive(workGiver.workType))
+ {
+ dropdownMenuElement = new Widgets.DropdownMenuElement
{
- yield return value;
- if (check == i)
- {
- Widgets.DropdownMenuElement prisonerMenu = new Widgets.DropdownMenuElement
- {
- option = new FloatMenuOption("PrisonLabor_PrisonersOnly".Translate(), delegate
- {
- bill.SetAnyPawnRestriction();
- BillAssignationUtility.SetFor(bill, GroupMode.PrisonersOnly);
- }),
- payload = null
- };
- yield return prisonerMenu;
-
- Widgets.DropdownMenuElement anyCaptive = new Widgets.DropdownMenuElement
- {
- option = new FloatMenuOption("PrisonLabor_PrisonersAndSlaveOnly".Translate(), delegate
- {
- bill.SetAnySlaveRestriction();
- BillAssignationUtility.SetFor(bill, GroupMode.CaptiveOnly);
- }),
- payload = null
- };
- yield return anyCaptive;
- }
- i++;
- }
- WorkGiverDef workGiver = bill.billStack.billGiver.GetWorkgiver();
- SkillDef workSkill = bill.recipe.workSkill;
- IEnumerable allPrisonersOfColony = PawnsFinder.AllMaps_PrisonersOfColony;
-
- allPrisonersOfColony = allPrisonersOfColony.OrderBy((Pawn pawn) => pawn.LabelShortCap);
- if (workSkill != null)
+ option = new FloatMenuOption(string.Format("P: {0} ({1} {2}, {3})", pawn.LabelShortCap, pawn.skills.GetSkill(bill.recipe.workSkill).Level, bill.recipe.workSkill.label, "NotAssigned".Translate()), delegate
+ {
+ bill.SetPawnRestriction(pawn);
+ }),
+ payload = pawn
+ };
+ yield return dropdownMenuElement;
+ }
+ else if (!pawn.workSettings.WorkIsActive(workGiver.workType))
+ {
+ dropdownMenuElement = new Widgets.DropdownMenuElement
{
- allPrisonersOfColony = allPrisonersOfColony.OrderByDescending((Pawn pawn) => pawn.skills.GetSkill(bill.recipe.workSkill).Level);
- }
- if (workGiver == null)
+ option = new FloatMenuOption(string.Format("P: {0} ({1})", pawn.LabelShortCap, "NotAssigned".Translate()), delegate
+ {
+ bill.SetPawnRestriction(pawn);
+ }),
+ payload = pawn
+ };
+ yield return dropdownMenuElement;
+ }
+ else if (bill.recipe.workSkill != null)
+ {
+ dropdownMenuElement = new Widgets.DropdownMenuElement
{
- Log.ErrorOnce("Generating pawn restrictions for a BillGiver without a Workgiver", 96455148);
- yield break;
- }
- allPrisonersOfColony = allPrisonersOfColony.OrderByDescending((Pawn pawn) => pawn.workSettings.WorkIsActive(workGiver.workType));
- allPrisonersOfColony = allPrisonersOfColony.OrderBy((Pawn pawn) => pawn.WorkTypeIsDisabled(workGiver.workType));
-
- Widgets.DropdownMenuElement dropdownMenuElement;
- foreach (Pawn pawn in allPrisonersOfColony)
+ option = new FloatMenuOption($"P: {pawn.LabelShortCap} ({pawn.skills.GetSkill(bill.recipe.workSkill).Level} {bill.recipe.workSkill.label})", delegate
+ {
+ bill.SetPawnRestriction(pawn);
+ }),
+ payload = pawn
+ };
+ yield return dropdownMenuElement;
+ }
+ else
+ {
+ dropdownMenuElement = new Widgets.DropdownMenuElement
{
- if (PrisonLaborUtility.LaborEnabled(pawn))
- {
- if (pawn.WorkTypeIsDisabled(workGiver.workType))
- {
- dropdownMenuElement = new Widgets.DropdownMenuElement
- {
- option = new FloatMenuOption(string.Format("P: {0} ({1})", pawn.LabelShortCap, "WillNever".Translate(workGiver.verb)), null),
- payload = pawn
- };
- yield return dropdownMenuElement;
- }
- else if (bill.recipe.workSkill != null && !pawn.workSettings.WorkIsActive(workGiver.workType))
- {
- dropdownMenuElement = new Widgets.DropdownMenuElement
- {
- option = new FloatMenuOption(string.Format("P: {0} ({1} {2}, {3})", pawn.LabelShortCap, pawn.skills.GetSkill(bill.recipe.workSkill).Level, bill.recipe.workSkill.label, "NotAssigned".Translate()), delegate
- {
- bill.SetPawnRestriction(pawn);
- }),
- payload = pawn
- };
- yield return dropdownMenuElement;
- }
- else if (!pawn.workSettings.WorkIsActive(workGiver.workType))
- {
- dropdownMenuElement = new Widgets.DropdownMenuElement
- {
- option = new FloatMenuOption(string.Format("P: {0} ({1})", pawn.LabelShortCap, "NotAssigned".Translate()), delegate
- {
- bill.SetPawnRestriction(pawn);
- }),
- payload = pawn
- };
- yield return dropdownMenuElement;
- }
- else if (bill.recipe.workSkill != null)
- {
- dropdownMenuElement = new Widgets.DropdownMenuElement
- {
- option = new FloatMenuOption($"P: {pawn.LabelShortCap} ({pawn.skills.GetSkill(bill.recipe.workSkill).Level} {bill.recipe.workSkill.label})", delegate
- {
- bill.SetPawnRestriction(pawn);
- }),
- payload = pawn
- };
- yield return dropdownMenuElement;
- }
- else
- {
- dropdownMenuElement = new Widgets.DropdownMenuElement
- {
- option = new FloatMenuOption($"P: {pawn.LabelShortCap}", delegate
- {
- bill.SetPawnRestriction(pawn);
- }),
- payload = pawn
- };
- yield return dropdownMenuElement;
- }
- }
- }
+ option = new FloatMenuOption($"P: {pawn.LabelShortCap}", delegate
+ {
+ bill.SetPawnRestriction(pawn);
+ }),
+ payload = pawn
+ };
+ yield return dropdownMenuElement;
+ }
}
+ }
}
+ }
}
diff --git a/Source/Organizer/NewsFeed.xml b/Source/Organizer/NewsFeed.xml
index 6a5af86..efcc06f 100644
--- a/Source/Organizer/NewsFeed.xml
+++ b/Source/Organizer/NewsFeed.xml
@@ -4,6 +4,7 @@
+
diff --git a/Source/PrisonLabor.sln b/Source/PrisonLabor.sln
index 6eea459..5160984 100644
--- a/Source/PrisonLabor.sln
+++ b/Source/PrisonLabor.sln
@@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KijinCompatibility", "Compa
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CleaningAreaCompatibility", "CompatibilityProjects\CleaningAreaCompatibility\CleaningAreaCompatibility.csproj", "{B904E495-7C04-412A-AF45-B02EE0150087}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColonyGroupsCompatibility", "CompatibilityProjects\ColonyGroupsCompatibility\ColonyGroupsCompatibility.csproj", "{A77AE1EB-BA5D-4B3A-9D9B-A9580850FAAD}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -57,6 +59,10 @@ Global
{B904E495-7C04-412A-AF45-B02EE0150087}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B904E495-7C04-412A-AF45-B02EE0150087}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B904E495-7C04-412A-AF45-B02EE0150087}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A77AE1EB-BA5D-4B3A-9D9B-A9580850FAAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A77AE1EB-BA5D-4B3A-9D9B-A9580850FAAD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A77AE1EB-BA5D-4B3A-9D9B-A9580850FAAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A77AE1EB-BA5D-4B3A-9D9B-A9580850FAAD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/changelog.txt b/changelog.txt
index 613411a..7bdb02b 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,4 +1,9 @@
Changelog:
+1.4.6
+- Chinese translation update (https://github.com/shiuanyue)
+- Mechanitor and Mechs should be assignable from bills menu
+- Prisoners should not deliver resources to forbidden frames and blueprints
+- Compatibility patches for [LTO] Colony Groups
1.4.5
- Fix: need assigments for prisoners only
1.4.4