Skip to content

Commit

Permalink
Version 0.5
Browse files Browse the repository at this point in the history
- added growing to available jobs
- added prisoner work priorities to "Work" tab
- food is no longer reserved in prison cell unless is brought by warden
- food is now delivered by Wardens even if prisoner get out of his prison cell
- disabled passive "Laziness" when prisoner have no work to do
  • Loading branch information
Aviuz committed Jul 16, 2017
1 parent e81c2fb commit 759fd1d
Show file tree
Hide file tree
Showing 18 changed files with 567 additions and 57 deletions.
4 changes: 2 additions & 2 deletions About/About.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
<name>Prison Labor (Alpha)</name>
<author>Avius</author>
<targetVersion>0.17.0</targetVersion>
<description>Version 0.4
<description>Version 0.5

This mod force prisoners to work if Prisoner Interaction is set to "Force to work".
Prisoner must be fed, and rested, or he(she) will refuse to work. Currently prisoners can only cook, mine, cut plants, craft, haul, and clean.
Prisoner must be fed, and rested, or he(she) will refuse to work. Currently prisoners can only cook, mine, cut plants, craft, haul, clean and grow low-skilled plants.
Attention! He can run away if he mine a way out.

Prisoners need to be watched by wardens, or they will get lazy.
Expand Down
Binary file modified Assemblies/PrisonLabor.dll
Binary file not shown.
5 changes: 5 additions & 0 deletions Defs/JobDef.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
<reportString>watching prisoner TargetA.</reportString>
<alwaysShowWeapon>true</alwaysShowWeapon>
</JobDef>
<JobDef>
<defName>PrisonLabor_DeliverFood_Tweak</defName>
<driverClass>PrisonLabor.JobDriver_FoodDeliver_Tweak</driverClass>
<reportString>feeding TargetA to TargetB.</reportString>
</JobDef>
<JobDef>
<defName>PrisonLabor_Mine_Tweak</defName>
<driverClass>PrisonLabor.JobDriver_Mine_Tweak</driverClass>
Expand Down
22 changes: 18 additions & 4 deletions Defs/WorkGiverDef.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@
<li>Talking</li>
</requiredCapacities>
</WorkGiverDef>
<!--WorkGiverDef>
<defName>DeliverFoodToPrisonerTweak</defName>
<WorkGiverDef>
<defName>PrisonLabor_DeliverFoodToPrisoner_Tweak</defName>
<label>deliver food to prisoners</label>
<giverClass>PrisonLabor.WorkGiver_Warden_DeliverFood_Tweak</giverClass>
<workType>Warden</workType>
<verb>deliver food for</verb>
<gerund>delivering food for</gerund>
<priorityInType>69</priorityInType>
<priorityInType>71</priorityInType>
<requiredCapacities>
<li>Manipulation</li>
</requiredCapacities>
</WorkGiverDef-->
</WorkGiverDef>
<WorkGiverDef>
<defName>PrisonLabor_Mine_Tweak</defName>
<label>mine</label>
Expand Down Expand Up @@ -63,4 +63,18 @@
<li>Manipulation</li>
</requiredCapacities>
</WorkGiverDef>
<WorkGiverDef>
<defName>PrisonLabor_GrowerSow_Tweak</defName>
<label>sow crops</label>
<giverClass>PrisonLabor.WorkGiver_GrowerSow_Tweak</giverClass>
<workType>Growing</workType>
<priorityInType>49</priorityInType>
<verb>sow</verb>
<gerund>sowing</gerund>
<scanThings>false</scanThings>
<scanCells>true</scanCells>
<requiredCapacities>
<li>Manipulation</li>
</requiredCapacities>
</WorkGiverDef>
</WorkGivers>
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# PrisonLabor
Prison Labor mod for "RimWorld" game

## Version 0.4
## Version 0.5

## Description
This mod force prisoners to work if Prisoner Interaction is set to "Work".
Expand Down
143 changes: 143 additions & 0 deletions Source/HarmonyPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Reflection.Emit;
using System.Text;
using Verse;
using Verse.AI;

namespace PrisonLabor
{
Expand Down Expand Up @@ -136,4 +137,146 @@ public static void Postfix2(Pawn_CarryTracker __instance, int count, IntVec3 dro
Postfix(__instance, dropLoc, mode, resultingThing, placedAction);
}
}

[HarmonyPatch(typeof(Verse.AI.HaulAIUtility))]
[HarmonyPatch("PawnCanAutomaticallyHaulBasicChecks")]
[HarmonyPatch(new Type[] { typeof(Pawn), typeof(Thing), typeof(bool) })]
class ReservedByPrisonerPatch
{
static IEnumerable<CodeInstruction> Transpiler(ILGenerator gen, MethodBase mBase, IEnumerable<CodeInstruction> instr)
{
//Load arguments onto stack
yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Ldarg_1);
yield return new CodeInstruction(OpCodes.Ldarg_2);
//Call function
yield return new CodeInstruction(OpCodes.Call, typeof(ReservedByPrisonerPatch).GetMethod("CanHaulAndInPrisonCell"));
//Return
yield return new CodeInstruction(OpCodes.Ret);
}


public static bool CanHaulAndInPrisonCell(Pawn p, Thing t, bool forced)
{
UnfinishedThing unfinishedThing = t as UnfinishedThing;
if (unfinishedThing != null && unfinishedThing.BoundBill != null)
{
return false;
}
if (!p.CanReach(t, PathEndMode.ClosestTouch, p.NormalMaxDanger(), false, TraverseMode.ByPawn))
{
return false;
}
if (!p.CanReserve(t, 1, -1, null, forced))
{
return false;
}
if (t.def.IsNutritionGivingIngestible && t.def.ingestible.HumanEdible && !t.IsSociallyProper(p, false, true))
{
if (PrisonerFoodReservation.isReserved(t))
{
JobFailReason.Is("ReservedForPrisoners".Translate());
return false;
}
}
if (t.IsBurning())
{
JobFailReason.Is("BurningLower".Translate());
return false;
}
return true;
}
}

[HarmonyPatch(typeof(MainTabWindow_Work))]
[HarmonyPatch("get_Pawns")]
class WorkAssigmentsPatch
{
static IEnumerable<CodeInstruction> Transpiler(ILGenerator gen, MethodBase mBase, IEnumerable<CodeInstruction> instr)
{
yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Call, typeof(WorkAssigmentsPatch).GetMethod("Pawns"));
yield return new CodeInstruction(OpCodes.Ret);
}

public static IEnumerable<Pawn> Pawns(MainTabWindow mainTabWindow)
{
foreach (Pawn p in Find.VisibleMap.mapPawns.FreeColonists)
yield return p;
if (mainTabWindow is MainTabWindow_Work)
{
foreach (Pawn pawn in Find.VisibleMap.mapPawns.PrisonersOfColony)
if (pawn.guest.interactionMode == DefDatabase<PrisonerInteractionModeDef>.GetNamed("PrisonLabor_workOption"))
{
if (!pawn.workSettings.EverWork)
pawn.workSettings.EnableAndInitialize();
foreach(WorkTypeDef def in PrisonerWorkDisabledUtility.DisabledWorks)
pawn.workSettings.Disable(def);
yield return pawn;
}
}
}
}

[HarmonyPatch(typeof(WidgetsWork))]
[HarmonyPatch("DrawWorkBoxFor")]
[HarmonyPatch(new Type[] { typeof(float), typeof(float), typeof(Pawn), typeof(WorkTypeDef), typeof(bool) })]
class WorkDisablePatch
{
static IEnumerable<CodeInstruction> Transpiler(ILGenerator gen, MethodBase mBase, IEnumerable<CodeInstruction> instr)
{
// Define label to the begining of the original code
Label jumpTo = gen.DefineLabel();
yield return new CodeInstruction(OpCodes.Ldarg_2);
yield return new CodeInstruction(OpCodes.Ldarg_3);
yield return new CodeInstruction(OpCodes.Call, typeof(PrisonerWorkDisabledUtility).GetMethod("Disabled", new Type[] { typeof(Pawn), typeof(WorkTypeDef) }));
//If false continue
yield return new CodeInstruction(OpCodes.Brfalse, jumpTo);
//Return
yield return new CodeInstruction(OpCodes.Ret);

bool first = true;
foreach (CodeInstruction ci in instr)
{
if (first)
{
first = false;
ci.labels.Add(jumpTo);
}
yield return ci;
}
}
}

[HarmonyPatch(typeof(WidgetsWork))]
[HarmonyPatch("TipForPawnWorker")]
[HarmonyPatch(new Type[] { typeof(Pawn), typeof(WorkTypeDef), typeof(bool) })]
class WorkDisablePatch2
{
static IEnumerable<CodeInstruction> Transpiler(ILGenerator gen, MethodBase mBase, IEnumerable<CodeInstruction> instr)
{
// Define label to the begining of the original code
Label jumpTo = gen.DefineLabel();
yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Ldarg_1);
yield return new CodeInstruction(OpCodes.Call, typeof(PrisonerWorkDisabledUtility).GetMethod("Disabled", new Type[] { typeof(Pawn), typeof(WorkTypeDef) }));
//If false continue
yield return new CodeInstruction(OpCodes.Brfalse, jumpTo);
//Load string TODO translate
yield return new CodeInstruction(OpCodes.Ldstr, "Work type disabled by prisoners");
//Return
yield return new CodeInstruction(OpCodes.Ret);

bool first = true;
foreach (CodeInstruction ci in instr)
{
if (first)
{
first = false;
ci.labels.Add(jumpTo);
}
yield return ci;
}
}
}
}
14 changes: 8 additions & 6 deletions Source/Initialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ namespace PrisonLabor
[StaticConstructorOnStartup]
class Initialization
{
public static int version = 4;
public static bool oldPlayerNotification = false;
public static int version = 5;

static Initialization()
{
Expand All @@ -32,14 +31,17 @@ private static void checkVersion()
if (PlayerKnowledgeDatabase.IsComplete(DefDatabase<ConceptDef>.GetNamed("PrisonLabor")))
{
Log.Message("Detected older version of PrisonLabor");
oldPlayerNotification = true;
Tutorials.msgShowVersion0_3 = true;
}
}
else
if(PrisonLaborPrefs.Version < 5)
{
Log.Message("Detected PrisonLabor v" + PrisonLaborPrefs.Version);
Log.Message("Detected older version of PrisonLabor");
Tutorials.msgShowVersion0_5 = true;
}
//PrisonLaborPrefs.Version = version;

Log.Message("Loaded PrisonLabor v" + PrisonLaborPrefs.Version);
PrisonLaborPrefs.Version = version;
PrisonLaborPrefs.Save();
}
}
Expand Down
24 changes: 5 additions & 19 deletions Source/JobGiver_Labor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,25 +68,9 @@ public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobPara
pawn.mindState.priorityWork.Clear();
}
//Work prisoners will do
List<String> typeNameList = new List<String> { "Cooking", "Mining", "PlantCutting", "Crafting", "Hauling", "Cleaning" };
List<WorkTypeDef> typeList = new List<WorkTypeDef>();
List<WorkGiver> workList = new List<WorkGiver>();
foreach (String workTypeName in typeNameList)
typeList.Add(DefDatabase<WorkTypeDef>.GetNamed(workTypeName, true));
foreach (WorkTypeDef workType in typeList.OrderBy(type => -pawn.skills.AverageOfRelevantSkillsFor(type)))
{
if (!pawn.story.WorkTypeIsDisabled(workType))
{
for (int m = 0; m < workType.workGiversByPriority.Count; m++)
{
WorkGiver worker = workType.workGiversByPriority[m].Worker;
if (!worker.def.emergency)
{
workList.Add(worker);
}
}
}
}
List<WorkGiver> workList = pawn.workSettings.WorkGiversInOrderNormal;
workList.RemoveAll(workGiver => workGiver.def.defName == "GrowerSow");
pawn.needs.TryGetNeed<Need_Laziness>().Enabled = false;

int num = -999;
TargetInfo targetInfo = TargetInfo.Invalid;
Expand All @@ -105,6 +89,7 @@ public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobPara
Job job2 = workGiver.NonScanJob(pawn);
if (job2 != null)
{
pawn.needs.TryGetNeed<Need_Laziness>().Enabled = true;
return new ThinkResult(job2, this, new JobTag?(workList[j].def.tagToGive));
}
WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner;
Expand Down Expand Up @@ -201,6 +186,7 @@ public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobPara
}
if (job3 != null)
{
pawn.needs.TryGetNeed<Need_Laziness>().Enabled = true;
return new ThinkResult(job3, this, new JobTag?(workList[j].def.tagToGive));
}
Log.ErrorOnce(string.Concat(new object[]
Expand Down
36 changes: 30 additions & 6 deletions Source/Need_Laziness.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,26 @@ public class Need_Laziness : Need
private static PrisonerInteractionModeDef pimDef;
private static NeedDef def;

private bool enabled;
private bool needToBeInspired;
private bool isLazy;
private int wardensCount;
private int prisonersCount;

private int slowDown;

public bool Enabled
{
get
{
return enabled;
}
set
{
enabled = value;
}
}

public bool NeedToBeInspired
{
get
Expand Down Expand Up @@ -69,12 +82,22 @@ public override int GUIChangeArrow
{
get
{
if (wardensCount * WardenCapacity < prisonersCount)
return 1;
else if (wardensCount * WardenCapacity > prisonersCount)
return -1;
if (enabled && pawn.guest.interactionMode == PimDef)
{
if (wardensCount * WardenCapacity < prisonersCount)
return 1;
else if (wardensCount * WardenCapacity > prisonersCount)
return -1;
else
return 0;
}
else
return 0;
{
if (wardensCount > 0)
return -1;
else
return 0;
}
}
}

Expand Down Expand Up @@ -126,7 +149,7 @@ private float LazinessRate
prisonersCount++;
}

if (pawn.guest.interactionMode == PimDef)
if (pawn.guest.interactionMode == PimDef && enabled)
return LazyRate - wardensCount * InspireRate / prisonersCount;
else
return -wardensCount * InspireRate / (prisonersCount + 1);
Expand Down Expand Up @@ -186,6 +209,7 @@ public override void NeedInterval()
public override void SetInitialLevel()
{
CurLevel = 0.0f;
enabled = false;
}

public override string GetTipString()
Expand Down
4 changes: 4 additions & 0 deletions Source/PrisonLabor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
<Compile Include="HarmonyPatches.cs" />
<Compile Include="InfoDialog.cs" />
<Compile Include="Need_Laziness.cs" />
<Compile Include="PrisonerFoodReservation.cs" />
<Compile Include="PrisonerWorkDisabledUtility.cs" />
<Compile Include="Tweaks\JobDriver_FoodDeliver_Tweak.cs" />
<Compile Include="Tweaks\JobDriver_Mine_Tweak.cs" />
<Compile Include="JobDriver_Supervise.cs" />
<Compile Include="Prefs.cs" />
Expand All @@ -68,6 +71,7 @@
<Compile Include="Tweaks\JobDriver_PlantHarvest_Tweak.cs" />
<Compile Include="Tweaks\JobDriver_PlantWork_Tweak.cs" />
<Compile Include="Tweaks\WorkGiver_GrowerHarvest_Tweak.cs" />
<Compile Include="Tweaks\WorkGiver_GrowerSow_Tweak.cs" />
<Compile Include="Tweaks\WorkGiver_Miner_Tweak.cs" />
<Compile Include="Tweaks\WorkGiver_PlantsCut_Tweak.cs" />
<Compile Include="WorkGiver_Supervise.cs" />
Expand Down
Loading

0 comments on commit 759fd1d

Please sign in to comment.