diff --git a/1.3/Assemblies/PrisonLabor.dll b/1.3/Assemblies/PrisonLabor.dll
index da7d162f..fa19a5de 100644
Binary files a/1.3/Assemblies/PrisonLabor.dll and b/1.3/Assemblies/PrisonLabor.dll differ
diff --git a/1.3/Defs/MainButton.xml b/1.3/Defs/MainButton.xml
index d41fee49..7c6c41f8 100644
--- a/1.3/Defs/MainButton.xml
+++ b/1.3/Defs/MainButton.xml
@@ -5,6 +5,7 @@
Manage your faction prisoners
PrisonLabor.Core.MainButton_Window.PrisonerButtonWindow
+ PL_TabIcon
35
true
diff --git a/1.3/Defs/PrisonerInteractionModeDef.xml b/1.3/Defs/PrisonerInteractionModeDef.xml
index 1c3052e8..1077ec61 100644
--- a/1.3/Defs/PrisonerInteractionModeDef.xml
+++ b/1.3/Defs/PrisonerInteractionModeDef.xml
@@ -10,9 +10,4 @@
6
-
- PrisonLabor_workAndConvertOption
-
- 7
-
diff --git a/1.3/Defs/WorkGiverDef.xml b/1.3/Defs/WorkGiverDef.xml
index 6c81b193..a70ddb87 100644
--- a/1.3/Defs/WorkGiverDef.xml
+++ b/1.3/Defs/WorkGiverDef.xml
@@ -19,8 +19,8 @@
PrisonLabor.Core.AI.WorkGivers.WorkGiver_HandleChains
PrisonLabor_Jailor
5
- >handle prisoner's chainsr
- >handling prisoner's chains
+ handle prisoner's chains
+ handling prisoner's chains
Manipulation
diff --git a/Ideology/Defs/PrisonersInteractionMode.xml b/Ideology/Defs/PrisonersInteractionMode.xml
new file mode 100644
index 00000000..000391ae
--- /dev/null
+++ b/Ideology/Defs/PrisonersInteractionMode.xml
@@ -0,0 +1,15 @@
+
+
+
+ PrisonLabor_workAndConvertOption
+
+ 7
+
+
+
+ PrisonLabor_workAndEnslaveOption
+
+ 8
+
+
+
\ No newline at end of file
diff --git a/Languages/English/Keyed/Keys.xml b/Languages/English/Keyed/Keys.xml
index 7d779a40..649ee23a 100644
--- a/Languages/English/Keyed/Keys.xml
+++ b/Languages/English/Keyed/Keys.xml
@@ -3,6 +3,7 @@
Force to work
Work and recruit
Work and convert
+ Work and enslave
Your prisoner stopped working!
Warden response threshold
Stopping work threshold
diff --git a/LoadFolders.xml b/LoadFolders.xml
index ceb87a04..c779be13 100644
--- a/LoadFolders.xml
+++ b/LoadFolders.xml
@@ -14,5 +14,6 @@
/
1.3
+ Ideology
\ No newline at end of file
diff --git a/MakeRelease.bat b/MakeRelease.bat
index 8dd804f1..04c1d9ac 100644
--- a/MakeRelease.bat
+++ b/MakeRelease.bat
@@ -39,10 +39,12 @@ xcopy "1.1\*.*" "%target_directory%\1.1" /e
mkdir "%target_directory%\1.2"
xcopy "1.2\*.*" "%target_directory%\1.2" /e
-:: 1.2
+:: 1.3
mkdir "%target_directory%\1.3"
xcopy "1.3\*.*" "%target_directory%\1.3" /e
+mkdir "%target_directory%\Ideology"
+xcopy "Ideology\*.*" "%target_directory%\Ideology" /e
:: LoadFolders.xml
copy "LoadFolders.xml" "%target_directory%\LoadFolders.xml"
diff --git a/Source/Constants/PL_DefOf.cs b/Source/Constants/PL_DefOf.cs
index 7ea0aea9..e52c6b68 100644
--- a/Source/Constants/PL_DefOf.cs
+++ b/Source/Constants/PL_DefOf.cs
@@ -12,8 +12,13 @@ public static class PL_DefOf
{
public static PrisonerInteractionModeDef PrisonLabor_workOption;
public static PrisonerInteractionModeDef PrisonLabor_workAndRecruitOption;
+
+ [MayRequireIdeology]
public static PrisonerInteractionModeDef PrisonLabor_workAndConvertOption;
+ [MayRequireIdeology]
+ public static PrisonerInteractionModeDef PrisonLabor_workAndEnslaveOption;
+
public static WorkTypeDef PrisonLabor_Jailor;
public static NeedDef PrisonLabor_Motivation;
diff --git a/Source/Core/AI/ThinkNodes/ThinkNode_Labor.cs b/Source/Core/AI/ThinkNodes/ThinkNode_Labor.cs
index cada9731..5ca8e83a 100644
--- a/Source/Core/AI/ThinkNodes/ThinkNode_Labor.cs
+++ b/Source/Core/AI/ThinkNodes/ThinkNode_Labor.cs
@@ -1,3 +1,4 @@
+using PrisonLabor.Core.Components;
using PrisonLabor.Core.Needs;
using PrisonLabor.Core.Other;
using PrisonLabor.Core.Trackers;
@@ -32,17 +33,18 @@ protected override bool Satisfied(Pawn pawn)
// Prisoner will escape if get ready to run.
// If he can run he will start ticking impatient, once complete he will get ready.
- var escapeTracker = EscapeTracker.Of(pawn, true);
+
+ var prisonerComp = pawn.TryGetComp();
if (pawn.guest.PrisonerIsSecure && RCellFinder.TryFindBestExitSpot(pawn, out c, TraverseMode.ByPawn))
{
- if (escapeTracker.ReadyToEscape)
+ if (prisonerComp.escapeTracker.ReadyToEscape)
return false;
else
- escapeTracker.CanEscape = true;
+ prisonerComp.escapeTracker.CanEscape = true;
}
else
{
- escapeTracker.CanEscape = false;
+ prisonerComp.escapeTracker.CanEscape = false;
}
diff --git a/Source/Core/AI/WorkGivers/WorkGiver_Supervise.cs b/Source/Core/AI/WorkGivers/WorkGiver_Supervise.cs
index 22ead048..68c8b824 100644
--- a/Source/Core/AI/WorkGivers/WorkGiver_Supervise.cs
+++ b/Source/Core/AI/WorkGivers/WorkGiver_Supervise.cs
@@ -1,3 +1,4 @@
+using PrisonLabor.Core.Components;
using PrisonLabor.Core.Needs;
using PrisonLabor.Core.Trackers;
using RimWorld;
@@ -20,14 +21,17 @@ public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
return null;
if (pawn.IsPrisoner)
return null;
- var escapeTracker = EscapeTracker.Of(prisoner, true);
- if (!PrisonLaborUtility.LaborEnabled(prisoner) && !escapeTracker.CanEscape)
+ var prisonerComp = prisoner.TryGetComp(); ;
+
+ if (!PrisonLaborUtility.LaborEnabled(prisoner) && prisonerComp != null && !prisonerComp.escapeTracker.CanEscape)
return null;
if (PrisonLaborUtility.RecruitInLaborEnabled(prisoner))
return new Job(JobDefOf.PrisonerAttemptRecruit, t);
if (PrisonLaborUtility.ConvertInLaborEnabled(prisoner))
return new Job(JobDefOf.PrisonerConvert, t);
- if ((!PrisonLaborUtility.WorkTime(prisoner) || !need.ShouldBeMotivated) && !escapeTracker.CanEscape)
+ if (PrisonLaborUtility.EnslaveInLaborEnabled(prisoner))
+ return new Job(JobDefOf.PrisonerEnslave, t);
+ if ((!PrisonLaborUtility.WorkTime(prisoner) || !need.ShouldBeMotivated) && prisonerComp != null && !prisonerComp.escapeTracker.CanEscape)
return null;
return new Job(DefDatabase.GetNamed("PrisonLabor_PrisonerSupervise"), prisoner);
diff --git a/Source/Core/Alerts/Alert_EscapingPrisoners.cs b/Source/Core/Alerts/Alert_EscapingPrisoners.cs
index 29df2392..7e5fc9c8 100644
--- a/Source/Core/Alerts/Alert_EscapingPrisoners.cs
+++ b/Source/Core/Alerts/Alert_EscapingPrisoners.cs
@@ -23,10 +23,7 @@ private IEnumerable PotentialEscapingPrisoners
{
get
{
- var maps = Find.Maps;
- for (var i = 0; i < maps.Count; i++)
- foreach (var pawn in maps[i].mapPawns.AllPawns.Where(p=>p.IsPrisoner && EscapeTracker.Of(p, true).CanEscape))
- yield return pawn;
+ return EscapeTracker.PrisonersReadyToEscape;
}
}
diff --git a/Source/Core/BaseClasses/SimpleTimer.cs b/Source/Core/BaseClasses/SimpleTimer.cs
index dadb8fb2..68309719 100644
--- a/Source/Core/BaseClasses/SimpleTimer.cs
+++ b/Source/Core/BaseClasses/SimpleTimer.cs
@@ -32,7 +32,7 @@ public void Tick()
{
if (_IsActive)
{
- Ticks++;
+ Ticks += 250;
}
}
diff --git a/Source/Core/Components/PrisonerComp.cs b/Source/Core/Components/PrisonerComp.cs
index 4470c2f0..ea90ad3a 100644
--- a/Source/Core/Components/PrisonerComp.cs
+++ b/Source/Core/Components/PrisonerComp.cs
@@ -13,8 +13,10 @@
namespace PrisonLabor.Core.Components
{
- public class PrisonerComp : ThingComp
+ public class PrisonerComp : ThingComp
{
+ public EscapeTracker escapeTracker;
+
private bool Active
{
get
@@ -24,6 +26,14 @@ private bool Active
}
}
+ public override void Initialize(CompProperties props)
+ {
+ base.Initialize(props);
+ if (escapeTracker == null)
+ {
+ escapeTracker = new EscapeTracker(this.parent as Pawn);
+ }
+ }
public override void PostDraw()
{
if (Active && PrisonLaborPrefs.EnableMotivationIcons)
@@ -43,10 +53,11 @@ public override void PostDraw()
DrawIcon(TexturePool.lazyTexture);
}
}
-
+
}
+
private void DrawIcon(Material drawIcon)
{
var drawPos = parent.DrawPos;
@@ -62,5 +73,18 @@ private void DrawIcon(Material drawIcon)
var material = FadedMaterialPool.FadedVersionOf(drawIcon, num2);
Graphics.DrawMesh(MeshPool.plane05, drawPos, Quaternion.identity, material, 0);
}
+
+ public override void PostExposeData()
+ {
+ Scribe_Deep.Look(ref escapeTracker, "EscapeTracker", new object[] { this.parent as Pawn });
+ }
+
+ public override void CompTickRare()
+ {
+ if (Active)
+ {
+ escapeTracker?.Tick();
+ }
+ }
}
}
diff --git a/Source/Core/GameSaves/SaveCleaner.cs b/Source/Core/GameSaves/SaveCleaner.cs
index 8f978eca..c87b2efc 100644
--- a/Source/Core/GameSaves/SaveCleaner.cs
+++ b/Source/Core/GameSaves/SaveCleaner.cs
@@ -163,7 +163,7 @@ private static void UpdateData(XmlElement xmlNode)
// TODO bills
// Interaction Mode
- string[] interactions = { PL_DefOf.PrisonLabor_workOption.defName, PL_DefOf.PrisonLabor_workAndRecruitOption.defName, PL_DefOf.PrisonLabor_workAndConvertOption.defName };
+ 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"))
{
diff --git a/Source/Core/MainButton_Window/ColumnWorker_EscapeTracker.cs b/Source/Core/MainButton_Window/ColumnWorker_EscapeTracker.cs
index 0e9e2bec..262bda6c 100644
--- a/Source/Core/MainButton_Window/ColumnWorker_EscapeTracker.cs
+++ b/Source/Core/MainButton_Window/ColumnWorker_EscapeTracker.cs
@@ -1,4 +1,5 @@
-using PrisonLabor.Core.Trackers;
+using PrisonLabor.Core.Components;
+using PrisonLabor.Core.Trackers;
using RimWorld;
using System;
using System.Collections.Generic;
@@ -13,24 +14,23 @@ public class ColumnWorker_EscapeTracker : PawnColumnWorker_Text
{
protected override string GetTextFor(Pawn pawn)
{
-
- var escapeTracker = EscapeTracker.Of(pawn);
- if(escapeTracker != null)
+ var prisonerComp = pawn.TryGetComp();
+ if(prisonerComp != null)
{
- return (escapeTracker.ReadyToEscape ? "ready" : escapeTracker.ReadyToRunPercentage + " %");
+ return (prisonerComp.escapeTracker.ReadyToEscape ? "ready" : prisonerComp.escapeTracker.ReadyToRunPercentage + " %");
}
- return "0 %";
+ return null;
}
protected override string GetTip(Pawn pawn)
{
- var escapeTracker = EscapeTracker.Of(pawn);
- if (escapeTracker != null)
+ var prisonerComp = pawn.TryGetComp();
+ if (prisonerComp != null)
{
- return $"(Cap:{ escapeTracker.EscapeLevel})";
+ return $"(Cap:{ prisonerComp.escapeTracker.EscapeLevel})";
}
- return "";
+ return null;
}
}
}
diff --git a/Source/Core/MainButton_Window/ColumnWorker_HasHandscuffs.cs b/Source/Core/MainButton_Window/ColumnWorker_HasHandscuffs.cs
index 19257991..f166f349 100644
--- a/Source/Core/MainButton_Window/ColumnWorker_HasHandscuffs.cs
+++ b/Source/Core/MainButton_Window/ColumnWorker_HasHandscuffs.cs
@@ -38,5 +38,10 @@ protected override void SetValue(Pawn pawn, bool value, PawnTable table)
}
table.SetDirty();
}
+
+ protected override bool HasCheckbox(Pawn pawn)
+ {
+ return pawn != null && pawn.health != null;
+ }
}
}
diff --git a/Source/Core/MainButton_Window/ColumnWorker_HasLegcuffs.cs b/Source/Core/MainButton_Window/ColumnWorker_HasLegcuffs.cs
index f44162a7..230cf930 100644
--- a/Source/Core/MainButton_Window/ColumnWorker_HasLegcuffs.cs
+++ b/Source/Core/MainButton_Window/ColumnWorker_HasLegcuffs.cs
@@ -38,5 +38,10 @@ protected override void SetValue(Pawn pawn, bool value, PawnTable table)
}
table.SetDirty();
}
+
+ protected override bool HasCheckbox(Pawn pawn)
+ {
+ return pawn != null && pawn.health != null;
+ }
}
}
diff --git a/Source/Core/MainButton_Window/ColumnWorker_Interaction.cs b/Source/Core/MainButton_Window/ColumnWorker_Interaction.cs
index f8469f91..c84ebb93 100644
--- a/Source/Core/MainButton_Window/ColumnWorker_Interaction.cs
+++ b/Source/Core/MainButton_Window/ColumnWorker_Interaction.cs
@@ -1,4 +1,5 @@
-using RimWorld;
+using PrisonLabor.Constants;
+using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -30,6 +31,10 @@ public override void DoCell(Rect rect, Pawn pawn, PawnTable table)
option = new FloatMenuOption(intertaction.LabelCap, delegate
{
pawn.guest.interactionMode = intertaction;
+ if(intertaction == PrisonerInteractionModeDefOf.Convert || intertaction == PL_DefOf.PrisonLabor_workAndConvertOption)
+ {
+ pawn.guest.ideoForConversion = Faction.OfPlayer.ideos.PrimaryIdeo;
+ }
}),
payload = intertaction
};
diff --git a/Source/Core/MainButton_Window/CustomTabWindow.cs b/Source/Core/MainButton_Window/CustomTabWindow.cs
index c686770e..b4d25d6a 100644
--- a/Source/Core/MainButton_Window/CustomTabWindow.cs
+++ b/Source/Core/MainButton_Window/CustomTabWindow.cs
@@ -54,7 +54,7 @@ public override Vector2 InitialSize
return requestedTabSize;
}
}
- protected virtual IEnumerable Pawns => Find.CurrentMap.mapPawns.FreeColonists_NoHusks;
+ protected virtual IEnumerable Pawns => Find.CurrentMap.mapPawns.FreeColonists;
public override void PostOpen()
{
diff --git a/Source/Core/MainButton_Window/PrisonerButtonWindow.cs b/Source/Core/MainButton_Window/PrisonerButtonWindow.cs
index d55facf0..7dddc2aa 100644
--- a/Source/Core/MainButton_Window/PrisonerButtonWindow.cs
+++ b/Source/Core/MainButton_Window/PrisonerButtonWindow.cs
@@ -84,6 +84,7 @@ public PrisonerButtonWindow() : base()
{
foreach(var def in DefDatabase.AllDefs)
{
+ Log.Message($"Def: {def.defName}, def.dev: {def.dev}, dev: {Prefs.DevMode}");
if(def.dev == false)
{
tabsView.Add(def, CreateWindow(def));
@@ -94,9 +95,9 @@ public PrisonerButtonWindow() : base()
}
}
- DebugLogger.debug("Prisoners main windows constructed");
-
+ DebugLogger.debug("Prisoners main windows constructed");
}
+
public override void DoWindowContents(Rect inRect)
{
@@ -113,15 +114,16 @@ public override void PostOpen()
{
base.PostOpen();
tabs.Clear();
- foreach (PrisonersTabDef tabDef in DefDatabase.AllDefs.OrderBy(def => def.order))
+ foreach (PrisonersTabDef tabDef in DefDatabase.AllDefs.Where(def => !def.dev || def.dev == Prefs.DevMode).OrderBy(def => def.order))
{
tabs.Add(new PrisonerWindowTab(tabDef, tabDef.LabelCap, delegate
{
CurTab = tabDef;
}, () => CurTab == tabDef));
GetTable(tabDef);
+
}
- CurTab = tabs[0].def;
+ CurTab = tabs[1].def;
foreach(var tab in tabsView.Values)
{
tab.PostOpen();
diff --git a/Source/Core/Needs/Need_Treatment.cs b/Source/Core/Needs/Need_Treatment.cs
index 0b791145..017c523b 100644
--- a/Source/Core/Needs/Need_Treatment.cs
+++ b/Source/Core/Needs/Need_Treatment.cs
@@ -106,6 +106,7 @@ public override void NeedInterval()
var motivation = pawn.needs.TryGetNeed();
if (motivation != null && motivation.IsPrisonerWorking)
CurLevel += BGP.LaborRate;
+
}
public override string GetTipString()
diff --git a/Source/Core/PrisonLaborUtility.cs b/Source/Core/PrisonLaborUtility.cs
index 4948f1af..cb52ffa4 100644
--- a/Source/Core/PrisonLaborUtility.cs
+++ b/Source/Core/PrisonLaborUtility.cs
@@ -14,8 +14,11 @@ internal static class PrisonLaborUtility
public static bool LaborEnabled(this Pawn pawn)
{
if (pawn.IsPrisoner)
- if (pawn.guest.interactionMode == PL_DefOf.PrisonLabor_workOption || pawn.guest.interactionMode == PL_DefOf.PrisonLabor_workAndRecruitOption || pawn.guest.interactionMode == PL_DefOf.PrisonLabor_workAndConvertOption)
+ if (pawn.guest.interactionMode == PL_DefOf.PrisonLabor_workOption || pawn.guest.interactionMode == PL_DefOf.PrisonLabor_workAndRecruitOption
+ || pawn.guest.interactionMode == PL_DefOf.PrisonLabor_workAndConvertOption || pawn.guest.interactionMode == PL_DefOf.PrisonLabor_workAndEnslaveOption)
+ {
return true;
+ }
return false;
}
@@ -36,10 +39,15 @@ public static bool ConvertInLaborEnabled(Pawn pawn)
return false;
}
+ public static bool EnslaveInLaborEnabled(Pawn pawn)
+ {
+ if (pawn.guest.interactionMode == PL_DefOf.PrisonLabor_workAndEnslaveOption && pawn.guest.ScheduledForInteraction && pawn.health.capacities.CapableOf(PawnCapacityDefOf.Talking))
+ return true;
+
+ return false;
+ }
public static bool WorkTime(Pawn pawn)
{
-/* if (pawn.needs == null || pawn.needs.food == null || pawn.needs.rest == null)
- return false;*/
if (pawn.timetable == null)
return true;
if (pawn.timetable.CurrentAssignment == TimeAssignmentDefOf.Work)
diff --git a/Source/Core/Trackers/EscapeTracker.cs b/Source/Core/Trackers/EscapeTracker.cs
index 1b66928d..ca1e7f32 100644
--- a/Source/Core/Trackers/EscapeTracker.cs
+++ b/Source/Core/Trackers/EscapeTracker.cs
@@ -17,31 +17,32 @@ public class EscapeTracker : IExposable
* This region is for ensuring that for every pawn there will be only one escape tracker.
* It is constructed in this way to prevent heavy modification of Pawn class (on external library).
*/
- private static Dictionary escapeTimers = new Dictionary();
+ private static HashSet prisonersReadyToEscape = new HashSet();
- ///
- /// Access EscapeTracker of Pawn
- ///
- public static EscapeTracker Of(Pawn pawn, bool forced = false)
+ public static HashSet PrisonersReadyToEscape
{
- if(!pawn.IsPrisoner && !forced)
- {
- return null;
- }
- if (!escapeTimers.ContainsKey(pawn))
+ get
{
- escapeTimers.Add(pawn, new EscapeTracker(pawn));
+ return prisonersReadyToEscape;
}
- return escapeTimers[pawn];
}
- public static void Save(Pawn pawn, EscapeTracker tracker)
+ private static void Register(Pawn pawn)
{
- if(pawn != null && tracker != null)
+ if (pawn.IsPrisoner)
{
- escapeTimers[pawn] = tracker;
+ prisonersReadyToEscape.Add(pawn);
}
}
+
+ private static void DeRegister(Pawn pawn)
+ {
+ prisonersReadyToEscape.Remove(pawn);
+ }
+
+ ///
+ /// Access EscapeTracker of Pawn
+ ///
#endregion
private SimpleTimer timer = new SimpleTimer();
@@ -120,12 +121,14 @@ public void Tick()
{
timer.ResetAndStop();
ReadyToEscape = false;
+ DeRegister(Pawn);
}
}
// Check if timer should trigger escape
else if (timer.Ticks >= EscapeLevel)
{
ReadyToEscape = true;
+ Register(Pawn);
}
// Tick timer
diff --git a/Source/Core/Trackers/InspirationTracker.cs b/Source/Core/Trackers/InspirationTracker.cs
index 3670e1ea..27090b92 100644
--- a/Source/Core/Trackers/InspirationTracker.cs
+++ b/Source/Core/Trackers/InspirationTracker.cs
@@ -53,7 +53,7 @@ public static void Calculate(Map map)
{
if (InspirationTracker.tickCounter >= InspirationTracker.updateInterval)
{
- if (map.mapPawns.PrisonersOfColonyCount == 0)
+ if (map.mapPawns.PrisonersOfColonySpawnedCount == 0)
{
return;
}
@@ -64,10 +64,10 @@ public static void Calculate(Map map)
{
var wardens = new List();
- wardens.AddRange(map.mapPawns.FreeColonists);
+ wardens.AddRange(map.mapPawns.FreeColonistsSpawned);
var prisoners = new List();
- prisoners.AddRange(map.mapPawns.PrisonersOfColony);
+ prisoners.AddRange(map.mapPawns.PrisonersOfColonySpawned);
if (wardens.Count == 0 || prisoners.Count == 0)
{
diff --git a/Source/HarmonyPatches/DevTools.cs b/Source/HarmonyPatches/DevTools.cs
index a3d1cb94..46b5a6f8 100644
--- a/Source/HarmonyPatches/DevTools.cs
+++ b/Source/HarmonyPatches/DevTools.cs
@@ -56,14 +56,20 @@ public static void TreatmentDown(Pawn p)
[DebugAction("Prison Labor Tools", "Turn into prisoner", actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.PlayingOnMap)]
public static void MakePrisoner(Pawn p)
{
- p.guest.SetGuestStatus(Faction.OfPlayer, GuestStatus.Prisoner);
+ if (p.RaceProps.Humanlike)
+ {
+ p.guest.SetGuestStatus(Faction.OfPlayer, GuestStatus.Prisoner);
+ }
}
[DebugAction("Prison Labor Tools", "Set free", actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.PlayingOnMap)]
public static void SetFree(Pawn p)
{
- p.guest.SetGuestStatus(null, GuestStatus.Guest);
+ if (p.RaceProps.Humanlike)
+ {
+ p.guest.SetGuestStatus(null, GuestStatus.Guest);
+ }
}
diff --git a/Source/HarmonyPatches/HPatcher.cs b/Source/HarmonyPatches/HPatcher.cs
index 43af874f..9fb68688 100644
--- a/Source/HarmonyPatches/HPatcher.cs
+++ b/Source/HarmonyPatches/HPatcher.cs
@@ -166,7 +166,7 @@ public static IEnumerable ReplaceFragment(OpCode[] opCodes, Str
}
// Jump back to begining of fragment
- index -= operands.Length;
+ index -= operands.Length - 1;
// If no fragment is found throw exception (or somehow begining of fragment is lower than 0)
if (index < 0)
@@ -178,7 +178,7 @@ public static IEnumerable ReplaceFragment(OpCode[] opCodes, Str
instructions.RemoveRange(index, operands.Length);
// Add fragment
- instructions.InsertRange(index + 1, newFragment);
+ instructions.InsertRange(index, newFragment);
return instructions;
}
diff --git a/Source/HarmonyPatches/Patches_BillAssignation/Patch_Bill_ProductionWithUft.cs b/Source/HarmonyPatches/Patches_BillAssignation/Patch_Bill_ProductionWithUft.cs
index 8f1440db..084f4f66 100644
--- a/Source/HarmonyPatches/Patches_BillAssignation/Patch_Bill_ProductionWithUft.cs
+++ b/Source/HarmonyPatches/Patches_BillAssignation/Patch_Bill_ProductionWithUft.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using Verse;
@@ -13,57 +14,28 @@ namespace PrisonLabor.HarmonyPatches.Patches_BillAssignation
[HarmonyPatch(typeof(Bill_ProductionWithUft), "get_BoundWorker")]
class Patch_Bill_ProductionWithUft
{
-
- static void Prefix(Bill_ProductionWithUft __instance, out UnfinishedThing __state)
+ private static IEnumerable Transpiler(ILGenerator gen, IEnumerable instr)
{
- UnfinishedThing unfinishedThing = Traverse.Create(__instance).Field("boundUftInt").GetValue();
-
- if(unfinishedThing != null && unfinishedThing.Creator != null && unfinishedThing.Creator.IsPrisonerOfColony)
+ OpCode[] opCodesToFind =
{
- DebugLogger.debug($"[PL] Saving unfinished thing to state pawn: {unfinishedThing.Creator.LabelShort}, bill: {unfinishedThing.LabelShort}");
- __state = unfinishedThing;
- }
- else
+ OpCodes.Ldloc_0,
+ OpCodes.Callvirt,
+ OpCodes.Brtrue_S
+ };
+ string[] operandsToFind =
{
- __state = null;
- }
-
- }
-
- static Pawn Postfix(Pawn __result, Bill_ProductionWithUft __instance, UnfinishedThing __state)
- {
-
- if (__result == null && __state != null)
+ "",
+ "RimWorld.Faction get_HostFaction()",
+ "System.Reflection.Emit.Label"
+ };
+ Label label = (Label)HPatcher.FindOperandAfter(opCodesToFind, operandsToFind, instr);
+ CodeInstruction[] replacemnt =
{
- Pawn creator = __state.Creator;
- if (creator == null || creator.Downed || creator.Destroyed || !creator.Spawned)
- {
- return __result;
- }
- Thing thing = __instance.billStack.billGiver as Thing;
- if (thing != null)
- {
- WorkTypeDef workTypeDef = null;
- List allDefsListForReading = DefDatabase.AllDefsListForReading;
- for (int i = 0; i < allDefsListForReading.Count; i++)
- {
- if (allDefsListForReading[i].fixedBillGiverDefs != null && allDefsListForReading[i].fixedBillGiverDefs.Contains(thing.def))
- {
- workTypeDef = allDefsListForReading[i].workType;
- break;
- }
- }
- if (workTypeDef != null && !creator.workSettings.WorkIsActive(workTypeDef))
- {
- return __result;
- }
- }
- Traverse.Create(__instance).Field("boundUftInt").SetValue(__state);
- DebugLogger.debug($"Returning creator {creator.LabelShort}, value override");
- return creator;
- }
-
- return __result;
+ new CodeInstruction(OpCodes.Nop),
+ new CodeInstruction(OpCodes.Nop),
+ new CodeInstruction(OpCodes.Nop, label),
+ };
+ return HPatcher.ReplaceFragment(opCodesToFind, operandsToFind, instr, replacemnt, "Patch_Bill_ProductionWithUft");
}
}
}
diff --git a/Source/HarmonyPatches/Patches_Escaping/Patch_EscapeTracker.cs b/Source/HarmonyPatches/Patches_Escaping/Patch_EscapeTracker.cs
deleted file mode 100644
index 6e19c42c..00000000
--- a/Source/HarmonyPatches/Patches_Escaping/Patch_EscapeTracker.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using HarmonyLib;
-using PrisonLabor.Core.Trackers;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Verse;
-
-namespace PrisonLabor.HarmonyPatches.Patches_Escaping
-{
- static class Patch_EscapeTracker
- {
- [HarmonyPatch(typeof(Pawn))]
- [HarmonyPatch(nameof(Pawn.ExposeData))]
- static class Patch_ExposeData
- {
- static void Postfix(Pawn __instance)
- {
- var escapeTracker = EscapeTracker.Of(__instance);
- Scribe_Deep.Look(ref escapeTracker, "EscapeTracker", new object[] { __instance});
- EscapeTracker.Save(__instance, escapeTracker);
- }
- }
-
- [HarmonyPatch(typeof(Pawn))]
- [HarmonyPatch(nameof(Pawn.Tick))]
- static class Patch_Tick
- {
- static void Postfix(Pawn __instance)
- {
- if (!__instance.Dead)
- {
- EscapeTracker.Of(__instance)?.Tick();
- }
- }
- }
- }
-}
diff --git a/Source/HarmonyPatches/Patches_Escaping/Patch_EscapingPrisoner.cs b/Source/HarmonyPatches/Patches_Escaping/Patch_EscapingPrisoner.cs
index be6ff011..525598b6 100644
--- a/Source/HarmonyPatches/Patches_Escaping/Patch_EscapingPrisoner.cs
+++ b/Source/HarmonyPatches/Patches_Escaping/Patch_EscapingPrisoner.cs
@@ -7,6 +7,7 @@
using System;
using System.IO;
using PrisonLabor.Core.Trackers;
+using PrisonLabor.Core.Components;
namespace PrisonLabor.HarmonyPatches.Patches_Escaping
{
@@ -39,8 +40,9 @@ private static IEnumerable Transpiler(ILGenerator gen, MethodBa
public static bool IsReadyToEscape(Pawn pawn)
{
- var escapeTracker = EscapeTracker.Of(pawn, true);
- if (escapeTracker.ReadyToEscape)
+
+ var prisonerComp = pawn.TryGetComp();
+ if (prisonerComp != null && prisonerComp.escapeTracker.ReadyToEscape)
return true;
else
return false;
diff --git a/Source/HarmonyPatches/Patches_GUI/GUI_PrisonerTab/Patch_AddScrollToPrisonerTab.cs b/Source/HarmonyPatches/Patches_GUI/GUI_PrisonerTab/Patch_AddScrollToPrisonerTab.cs
index cc303421..19084942 100644
--- a/Source/HarmonyPatches/Patches_GUI/GUI_PrisonerTab/Patch_AddScrollToPrisonerTab.cs
+++ b/Source/HarmonyPatches/Patches_GUI/GUI_PrisonerTab/Patch_AddScrollToPrisonerTab.cs
@@ -1,4 +1,5 @@
using HarmonyLib;
+using PrisonLabor.Constants;
using RimWorld;
using System;
using System.Collections.Generic;
@@ -20,7 +21,7 @@ internal class Patch_AddScrollToPrisonerTab
{
private static IEnumerable Transpiler(ILGenerator gen, IEnumerable instr)
{
- #region fragment>>GUI.BeginGroup(position);
+ #region fragment>>GUI.BeginGroup(position);
OpCode[] opCodes1 =
{
OpCodes.Call,
@@ -76,6 +77,7 @@ private static IEnumerable Transpiler(ILGenerator gen, IEnumera
#endregion
foreach (var ci in instr)
{
+
// end scroll
if (HPatcher.IsFragment(opCodes2, operands2, ci, ref step2, "AddScrollToPrisonerTab2"))
{
diff --git a/Source/HarmonyPatches/Patches_InteractionMode/Patch_VisitorTab_TabDraw.cs b/Source/HarmonyPatches/Patches_InteractionMode/Patch_VisitorTab_TabDraw.cs
new file mode 100644
index 00000000..81d8c32f
--- /dev/null
+++ b/Source/HarmonyPatches/Patches_InteractionMode/Patch_VisitorTab_TabDraw.cs
@@ -0,0 +1,70 @@
+using HarmonyLib;
+using PrisonLabor.Constants;
+using RimWorld;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Text;
+using System.Threading.Tasks;
+using Verse;
+
+namespace PrisonLabor.HarmonyPatches.Patches_InteractionMode
+{
+ [HarmonyPatch(typeof(ITab_Pawn_Visitor), "FillTab")]
+ class Patch_VisitorTab_TabDraw
+ {
+ static IEnumerable Transpiler(ILGenerator gen, MethodBase mBase, IEnumerable instructions)
+ {
+ OpCode[] opCodesToFind =
+ {
+ OpCodes.Call,
+ OpCodes.Ldfld,
+ OpCodes.Ldfld,
+ OpCodes.Ldsfld,
+ OpCodes.Bne_Un
+ };
+ string[] operandsToFind =
+ {
+ "Verse.Pawn get_SelPawn()",
+ "RimWorld.Pawn_GuestTracker guest",
+ "RimWorld.PrisonerInteractionModeDef interactionMode",
+ "RimWorld.PrisonerInteractionModeDef Convert",
+ "System.Reflection.Emit.Label"
+ };
+
+ OpCode[] opCodesToReplace =
+ {
+ OpCodes.Call,
+ OpCodes.Ldfld,
+ OpCodes.Ldfld,
+ OpCodes.Ldsfld,
+ OpCodes.Bne_Un
+ };
+ string[] operandsToReplace =
+ {
+ "Verse.Pawn get_SelPawn()",
+ "RimWorld.Pawn_GuestTracker guest",
+ "RimWorld.PrisonerInteractionModeDef interactionMode",
+ "RimWorld.PrisonerInteractionModeDef Convert",
+ "System.Reflection.Emit.Label"
+ };
+
+ var label = (Label)HPatcher.FindOperandAfter(opCodesToFind, operandsToFind, instructions);
+ CodeInstruction[] replacment =
+ {
+ new CodeInstruction(OpCodes.Call, typeof(Patch_VisitorTab_TabDraw).GetMethod(nameof(ShouldDisplayConvertIco))),
+ new CodeInstruction(OpCodes.Brfalse, label)
+ };
+
+ return HPatcher.ReplaceFragment(opCodesToReplace, operandsToReplace, instructions, replacment, nameof(ITab_Pawn_Visitor) + ": patch display ideo ico");
+ }
+
+ public static bool ShouldDisplayConvertIco(ITab_Pawn_Visitor tab)
+ {
+ Pawn p = Traverse.Create(tab).Property("SelPawn").GetValue();
+ return p.guest.interactionMode == PrisonerInteractionModeDefOf.Convert || p.guest.interactionMode == PL_DefOf.PrisonLabor_workAndConvertOption;
+ }
+ }
+}
diff --git a/Source/HarmonyPatches/Patches_Work/Patch_WorkGiver_TakeToPen.cs b/Source/HarmonyPatches/Patches_Work/Patch_WorkGiver_TakeToPen.cs
new file mode 100644
index 00000000..974dc37b
--- /dev/null
+++ b/Source/HarmonyPatches/Patches_Work/Patch_WorkGiver_TakeToPen.cs
@@ -0,0 +1,26 @@
+using HarmonyLib;
+using RimWorld;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Verse;
+
+namespace PrisonLabor.HarmonyPatches.Patches_Work
+{
+ [HarmonyPatch(typeof(WorkGiver_TakeToPen), "PotentialWorkThingsGlobal")]
+ class Patch_WorkGiver_TakeToPen
+ {
+ static bool Prefix(ref IEnumerable __result, Pawn pawn)
+ {
+ if (pawn != null && pawn.IsPrisonerOfColony)
+ {
+ __result = pawn.Map.mapPawns.SpawnedPawnsInFaction(Faction.OfPlayer);
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/Source/PrisonLabor.csproj b/Source/PrisonLabor.csproj
index da6d00f2..22bd05bc 100644
--- a/Source/PrisonLabor.csproj
+++ b/Source/PrisonLabor.csproj
@@ -133,7 +133,6 @@
-
@@ -144,6 +143,7 @@
+
@@ -183,6 +183,7 @@
+
@@ -272,6 +273,9 @@
Organizer\changelog.txt
+
+ Ideology\Defs\PrisonersInteractionMode.xml
+
Language\Keys.xml
Designer
@@ -293,6 +297,9 @@
Organizer\credits.md
+
+ MakeRelease.bat
+
Organizer\README.md
diff --git a/Textures/PL_TabIcon.png b/Textures/PL_TabIcon.png
new file mode 100644
index 00000000..649cc155
Binary files /dev/null and b/Textures/PL_TabIcon.png differ
diff --git a/changelog.txt b/changelog.txt
index 7d188c6e..9517e71f 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,4 +1,15 @@
Changelog:
+1.3.1
+- Added NPR checks for new table workers
+- Added Work and Convert option (https://github.com/samdeane)
+- Added Work and enslave option
+- Work and Convert/Enslave should load only for DLC owners
+- Setting convert interaction option from Overview should select default ideology
+- Dev tab should only show in dev mode
+- Escape tracker is now checked after rare tick (~4s) refactored how alert is notified.
+- Added icon for new main table. Create by me, so it's not fancy.
+- Updated Chinese translation (https://github.com/Juijote)
+
1.3.0
- Update to Rimworld 1.3
- Created menu for prisoners