diff --git a/Assemblies/PrisonLabor.dll b/Assemblies/PrisonLabor.dll
index f7ca037b..326b727f 100644
Binary files a/Assemblies/PrisonLabor.dll and b/Assemblies/PrisonLabor.dll differ
diff --git a/README.md b/README.md
index 03bf2202..4ecbb669 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
-
+
@@ -24,22 +24,13 @@ This is early alpha version! Some features can be changed, and there are many th
## Compatibility
* Works with mods that add Jobs of type cook/mine/craft/haul/clean like Quarry, or Haulers Can Haul To Blueprints
-Works with saves.
-* You can enable, re-enable, disable this mod to all saves. (However disabling mod can throw errors, but they just saying they can't find tutorials, no harm)
-* No collisions with other mods detected yet. Only mods that changes thinking of humanlike should be considered (Humanlike_PostDuty handle).
+* Works with old saves.
+* Disabling this mod to saves causes prisoners to disappear. In 0.7 I've planned tool to safely disable this mod.
+* Now works with WorkTab (by Fluffy)
+* There are some collisions that causes prisoners to fail to reserve target of their jobs. They will work on same thing or stealing resources from benches. If you experiencing this issue please le me know what mods are you using. I need to identify which mod causes that.
## [To-do list](https://github.com/Aviuz/PrisonLabor/projects/1)
-## Currently to make prisoners work you must meet these conditions
-* Prisoner is safe, and don't need medical assistance.
-* Prisoner don't need to recover from injury/sickness in bed.
-* Prisoner can't escape.
-* Prisoner can reach work (best way to do that is leaving open doors to work area).
-* Prisoner is fed, and rested.
-* Prisoner interaction is set to "Force to work" (no "Chat and Recruit", or "Friendly Chat").
-* Laziness bar in "Needs" tab is below 80%.
-* Work type is enabled in "Work" tab.
-
## Translations
Please contact me if you want help me writing translations. It will take you a few minutes to translate few sentences, and you will help making the mod even better. Thank you in advance!
Also I would gladly hear about misspellings or grammar mistakes in English version.
diff --git a/Source/Alert_LazyPrisoners.cs b/Source/Alert_LazyPrisoners.cs
index 47871894..0aaeb055 100644
--- a/Source/Alert_LazyPrisoners.cs
+++ b/Source/Alert_LazyPrisoners.cs
@@ -43,7 +43,14 @@ public override string GetExplanation()
public override AlertReport GetReport()
{
- return AlertReport.CulpritIs(LazyPrisoners.FirstOrDefault());
+ if (PrisonLaborPrefs.EnableMotivationMechanics)
+ {
+ return AlertReport.CulpritIs(LazyPrisoners.FirstOrDefault());
+ }
+ else
+ {
+ return false;
+ }
}
}
diff --git a/Source/Alert_StarvingPrisoners.cs b/Source/Alert_StarvingPrisoners.cs
index 12a8deaa..503ee30a 100644
--- a/Source/Alert_StarvingPrisoners.cs
+++ b/Source/Alert_StarvingPrisoners.cs
@@ -24,7 +24,7 @@ private IEnumerable StarvingPrisoners
{
foreach (Pawn pawn in maps[i].mapPawns.AllPawns)
{
- if (PrisonLaborUtility.LaborEnabled(pawn) && PrisonLaborUtility.WorkTime(pawn) && !pawn.needs.TryGetNeed().IsLazy && pawn.timetable != null && pawn.timetable.CurrentAssignment == TimeAssignmentDefOf.Anything && pawn.needs.food.Starving)
+ if (PrisonLaborUtility.LaborEnabled(pawn) && PrisonLaborUtility.WorkTime(pawn) && (!PrisonLaborPrefs.EnableMotivationMechanics || !pawn.needs.TryGetNeed().IsLazy) && pawn.timetable != null && pawn.timetable.CurrentAssignment == TimeAssignmentDefOf.Anything && pawn.needs.food.Starving)
yield return pawn;
}
}
@@ -43,7 +43,14 @@ public override string GetExplanation()
public override AlertReport GetReport()
{
- return AlertReport.CulpritIs(StarvingPrisoners.FirstOrDefault());
+ if (!PrisonLaborPrefs.DisableMod)
+ {
+ return AlertReport.CulpritIs(StarvingPrisoners.FirstOrDefault());
+ }
+ else
+ {
+ return false;
+ }
}
}
}
diff --git a/Source/HarmonyPatches.cs b/Source/HarmonyPatches.cs
index 106423b2..a192b84b 100644
--- a/Source/HarmonyPatches.cs
+++ b/Source/HarmonyPatches.cs
@@ -120,7 +120,7 @@ public static bool ShouldHaveNeedPrisoner(NeedDef nd, Pawn pawn)
//delete later
if (nd.defName == "PrisonLabor_Laziness" || nd is Need_Laziness)
return false;
- if (nd.defName == "PrisonLabor_Motivation" && !pawn.IsPrisoner)
+ if (nd.defName == "PrisonLabor_Motivation" && !(pawn.IsPrisoner && PrisonLaborPrefs.EnableMotivationMechanics))
{
return false;
}
@@ -330,4 +330,34 @@ public static bool isPrisoner(Pawn pawn)
return false;
}
}
+
+ [HarmonyPatch(typeof(ForbidUtility))]
+ [HarmonyPatch("IsForbidden")]
+ [HarmonyPatch(new Type[] { typeof(Thing), typeof(Pawn) })]
+ class FoodReservingPatch
+ {
+ private static IEnumerable Transpiler(ILGenerator gen, MethodBase mBase, IEnumerable instr)
+ {
+ Label jumpTo = gen.DefineLabel();
+ yield return new CodeInstruction(OpCodes.Ldarg_0);
+ yield return new CodeInstruction(OpCodes.Call, typeof(PrisonerFoodReservation).GetMethod("isReserved"));
+ yield return new CodeInstruction(OpCodes.Brfalse, jumpTo);
+ yield return new CodeInstruction(OpCodes.Ldarg_1);
+ yield return new CodeInstruction(OpCodes.Call, typeof(Pawn).GetMethod("get_IsPrisoner"));
+ yield return new CodeInstruction(OpCodes.Brtrue, jumpTo);
+ yield return new CodeInstruction(OpCodes.Ldc_I4_1);
+ 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;
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/Source/Initialization.cs b/Source/Initialization.cs
index e4958e9a..8cc7f074 100644
--- a/Source/Initialization.cs
+++ b/Source/Initialization.cs
@@ -14,7 +14,7 @@ namespace PrisonLabor
[StaticConstructorOnStartup]
class Initialization
{
- public static int version = 6;
+ public static int version = PrisonLaborMod.versionNumber;
static Initialization()
{
@@ -47,12 +47,17 @@ private static void checkVersion()
if (PrisonLaborPrefs.LastVersion < 5)
{
Log.Message("Detected older version of PrisonLabor than 0.5");
- Tutorials.msgShowVersion0_5 = true;
+ NewsDialog.news_0_5 = true;
}
if (PrisonLaborPrefs.LastVersion < 6)
{
Log.Message("Detected older version of PrisonLabor than 0.6");
- Tutorials.msgShowVersion0_6 = true;
+ NewsDialog.news_0_6 = true;
+ }
+ if (PrisonLaborPrefs.LastVersion < 7)
+ {
+ Log.Message("Detected older version of PrisonLabor than 0.7");
+ NewsDialog.news_0_7 = true;
}
Log.Message("Loaded PrisonLabor v" + PrisonLaborPrefs.Version);
diff --git a/Source/JobGiver_Diet.cs b/Source/JobGiver_Diet.cs
index 04d85417..eda7d936 100644
--- a/Source/JobGiver_Diet.cs
+++ b/Source/JobGiver_Diet.cs
@@ -53,7 +53,8 @@ protected override Job TryGiveJob(Pawn pawn)
{
return null;
}
- pawn.needs.TryGetNeed().Enabled = false;
+ if(pawn.needs.TryGetNeed() != null)
+ pawn.needs.TryGetNeed().Enabled = false;
bool flag;
if (pawn.RaceProps.Animal)
{
diff --git a/Source/JobGiver_Labor.cs b/Source/JobGiver_Labor.cs
index 5ceb2b75..fb6afad0 100644
--- a/Source/JobGiver_Labor.cs
+++ b/Source/JobGiver_Labor.cs
@@ -29,22 +29,23 @@ public override float GetPriority(Pawn pawn)
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
{
- if(pawn.timetable == null)
+ if (pawn.timetable == null)
{
PrisonLaborUtility.InitWorkSettings(pawn);
}
- if(HealthAIUtility.ShouldHaveSurgeryDoneNow(pawn))
+ if (HealthAIUtility.ShouldHaveSurgeryDoneNow(pawn))
{
return ThinkResult.NoJob;
}
//Check medical assistance, fed, and rest if not override
- if(!PrisonLaborUtility.WorkTime(pawn))
+ if (!PrisonLaborUtility.WorkTime(pawn))
{
- pawn.needs.TryGetNeed().Enabled = false;
+ if (pawn.needs.TryGetNeed() != null)
+ pawn.needs.TryGetNeed().Enabled = false;
return ThinkResult.NoJob;
}
//Check laziness
- if (pawn.needs.TryGetNeed().IsLazy)
+ if (PrisonLaborPrefs.EnableMotivationMechanics && pawn.needs.TryGetNeed().IsLazy)
{
return ThinkResult.NoJob;
}
@@ -52,7 +53,8 @@ public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobPara
PrisonLaborUtility.InitWorkSettings(pawn);
List workList = pawn.workSettings.WorkGiversInOrderNormal;
workList.RemoveAll(workGiver => workGiver.def.defName == "GrowerSow");
- pawn.needs.TryGetNeed().Enabled = false;
+ if (pawn.needs.TryGetNeed() != null)
+ pawn.needs.TryGetNeed().Enabled = false;
int num = -999;
TargetInfo targetInfo = TargetInfo.Invalid;
@@ -71,7 +73,8 @@ public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobPara
Job job2 = workGiver.NonScanJob(pawn);
if (job2 != null)
{
- pawn.needs.TryGetNeed().Enabled = true;
+ if (pawn.needs.TryGetNeed() != null)
+ pawn.needs.TryGetNeed().Enabled = true;
return new ThinkResult(job2, this, new JobTag?(workList[j].def.tagToGive));
}
WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner;
@@ -168,7 +171,8 @@ public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobPara
}
if (job3 != null)
{
- pawn.needs.TryGetNeed().Enabled = true;
+ if (pawn.needs.TryGetNeed() != null)
+ pawn.needs.TryGetNeed().Enabled = true;
return new ThinkResult(job3, this, new JobTag?(workList[j].def.tagToGive));
}
Log.ErrorOnce(string.Concat(new object[]
diff --git a/Source/NewsDialog.cs b/Source/NewsDialog.cs
new file mode 100644
index 00000000..e965f910
--- /dev/null
+++ b/Source/NewsDialog.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UnityEngine;
+using Verse;
+
+namespace PrisonLabor
+{
+ class NewsDialog : Window
+ {
+ private static bool autoShow = true;
+
+ public static bool showAll = false;
+
+ public static bool news_0_5 = false;
+ public static bool news_0_6 = false;
+ public static bool news_0_7 = false;
+
+ private Vector2 position;
+ private Rect cRect;
+
+ public NewsDialog()
+ {
+ this.doCloseButton = true;
+ this.doCloseX = true;
+ }
+
+ public static void TryShow()
+ {
+ if (autoShow && PrisonLaborPrefs.ShowNews)
+ {
+ Find.WindowStack.Add(new NewsDialog());
+ PrisonLaborPrefs.LastVersion = PrisonLaborPrefs.Version;
+ PrisonLaborPrefs.Save();
+ autoShow = false;
+ }
+ }
+
+ public static void ForceShow()
+ {
+ Find.WindowStack.Add(new NewsDialog());
+ PrisonLaborPrefs.LastVersion = PrisonLaborPrefs.Version;
+ PrisonLaborPrefs.Save();
+ autoShow = false;
+ }
+
+ public override void DoWindowContents(Rect inRect)
+ {
+ if(cRect == null)
+ cRect = inRect;
+
+ Rect viewRect = new Rect(inRect.x, inRect.y, inRect.width, inRect.height - 50);
+
+ Widgets.BeginScrollView(viewRect, ref this.position, cRect, true);
+
+ float CurHeight = 0;
+
+ Listing_Standard ls_title = new Listing_Standard(GameFont.Medium);
+ Listing_Standard ls_desc = new Listing_Standard(GameFont.Small);
+ if(news_0_7 || showAll)
+ {
+ ls_title.Begin(new Rect(cRect.x, cRect.y + CurHeight, cRect.width, cRect.height - CurHeight));
+ ls_title.Label("Prison Labor Alpha v0.7");
+ ls_title.GapLine();
+ ls_title.End();
+ CurHeight += ls_title.CurHeight;
+ ls_desc.Begin(new Rect(cRect.x, cRect.y + CurHeight, cRect.width, cRect.height - CurHeight));
+ ls_desc.Label(" - Added settings! You can now change almost any aspect of this mod, including:\n * work types\n * motivation mechanics\n * prevention of planting advanced plants.");
+ ls_desc.Label(" - Added \"uninstaller\" (\"disable\" option in settings), which will allow to disable this mod from existing saves.");
+ ls_desc.Label(" - \"No more beeping!\". Changed way of informing player what's going on with prisoners. It should be less annoying and more insightful.");
+ ls_desc.Label(" - Fixed bugs, including bug that prevents prisoners from cleaning and bug that causes warden to stuck in loop of delivering food to prisoner.");
+ ls_desc.Label(" - \"No more watching while prisoner is sleeping.\"Wardens will no longer watch over not working prisoners.");
+ ls_desc.Label(" - Prisoners will now stay in bed while waiting for operation");
+ ls_desc.Label(" - Prisoners will now stop work when starving for default (\"Anything\" time), instead of hungry. They will still get minor debuff.");
+ ls_desc.Gap();
+ ls_desc.End();
+ CurHeight += ls_desc.CurHeight;
+ }
+ if(news_0_6 || showAll)
+ {
+ ls_title.Begin(new Rect(cRect.x, cRect.y + CurHeight, cRect.width, cRect.height - CurHeight));
+ ls_title.Label("Prison Labor Alpha v0.6");
+ ls_title.GapLine();
+ ls_title.End();
+ CurHeight += ls_title.CurHeight;
+ ls_desc.Begin(new Rect(cRect.x, cRect.y + CurHeight, cRect.width, cRect.height - CurHeight));
+ ls_desc.Label("Changes in PrisonLabor v0.6:\n\n 1. Time restrictions - now you can manage your prisoners time for sleep, work and joy. You can now even force them to work when they're hungry!\n 2. Getting food by prisoners - Now prisoners will look for food in much better way, and now (when they desperate enough) they will eat corpses!\n 3. \"Laziness\" changed to \"Motivation\" and inverted.\n\n ATTENTION: After PrisonLabor reaches beta all saves with PrisonLabor v0.5a or lower will be corrupted and unplayable. This version (0.6) is safe and converts all older saves.");
+ ls_desc.Gap();
+ ls_desc.End();
+ CurHeight += ls_desc.CurHeight;
+ }
+ if(news_0_5 || showAll)
+ {
+ ls_title.Begin(new Rect(cRect.x, cRect.y + CurHeight, cRect.width, cRect.height - CurHeight));
+ ls_title.Label("Prison Labor Alpha v0.5");
+ ls_title.GapLine();
+ ls_title.End();
+ CurHeight += ls_title.CurHeight;
+ ls_desc.Begin(new Rect(cRect.x, cRect.y + CurHeight, cRect.width, cRect.height - CurHeight));
+ ls_desc.Label("Major changes to PrisonLabor:\n\n 1. Prisoners can now grow, but only plants that not require any skills.\n 2. You can now manage prisoners work types. Just check \"Work\" tab!\n 3. Laziness now appear on \"Needs\" tab. Above 50% wardens will watch prisoners. Above 80% prisoners won't work unless supervised.\n 4. Wardens will now bring food to prisoners that went too far from his bed.\n 5. Prisoners won't gain laziness when not working anymore.\n 6. Fixed many bugs");
+ ls_desc.Gap();
+ ls_desc.End();
+ CurHeight += ls_desc.CurHeight;
+ }
+
+ Widgets.EndScrollView();
+
+ cRect = new Rect(inRect.x, inRect.y, inRect.width - 50f, CurHeight + 50f);
+ }
+ }
+}
diff --git a/Source/Prefs.cs b/Source/Prefs.cs
index 2596ae1e..f5ff0c4e 100644
--- a/Source/Prefs.cs
+++ b/Source/Prefs.cs
@@ -10,7 +10,9 @@ namespace PrisonLabor
public static class PrisonLaborPrefs
{
private static PrisonLaborPrefsData data;
- private static string prefsFilePath = Path.Combine(GenFilePaths.ConfigFolderPath, "PrisonData_Prefs.xml");
+ //OLD DELETE WHEN BETA
+ private static string oldFilePath = Path.Combine(GenFilePaths.ConfigFolderPath, "PrisonData_Prefs.xml");
+ private static string prefsFilePath = Path.Combine(GenFilePaths.ConfigFolderPath, "PrisonLabor_Prefs.xml");
public static int Version
{
@@ -51,7 +53,7 @@ public static bool ShowNews
}
}
- public static bool AllowAllWorktypes
+ public static bool AllowAllWorkTypes
{
get
{
@@ -68,6 +70,8 @@ public static bool EnableMotivationMechanics
{
get
{
+ if (data.disable_mod)
+ return false;
return PrisonLaborPrefs.data.enable_motivation_mechanics;
}
set
@@ -90,15 +94,43 @@ public static bool DisableMod
}
}
+ public static bool AdvancedGrowing
+ {
+ get
+ {
+ return data.advanced_growing;
+ }
+ set
+ {
+ data.advanced_growing = value;
+ Apply();
+ }
+ }
+
+ public static string AllowedWorkTypes
+ {
+ get
+ {
+ return PrisonLaborPrefs.data.allowed_works;
+ }
+ set
+ {
+ PrisonLaborPrefs.data.allowed_works = value;
+ PrisonLaborPrefs.Apply();
+ }
+ }
+
public static void Init()
{
+ //delete after beta
+ if (new FileInfo(oldFilePath).Exists)
+ {
+ System.IO.File.Move(oldFilePath, prefsFilePath);
+ }
bool flag = !new FileInfo(prefsFilePath).Exists;
PrisonLaborPrefs.data = new PrisonLaborPrefsData();
PrisonLaborPrefs.data = DirectXmlLoader.ItemFromXmlFile(prefsFilePath, true);
- if (flag)
- {
- ;
- }
+ Apply();
}
public static void Save()
@@ -123,7 +155,18 @@ public static void Save()
public static void Apply()
{
- PrisonLaborPrefs.data.Apply();
+ data.Apply();
+ PrisonLaborUtility.AllowedWorkTypesData = AllowedWorkTypes;
+ }
+
+ public static void RestoreToDefault()
+ {
+ int version = data.version;
+ int last_version = data.last_version;
+ data = new PrisonLaborPrefsData();
+ data.version = version;
+ data.last_version = last_version;
+ Apply();
}
}
}
\ No newline at end of file
diff --git a/Source/PrefsData.cs b/Source/PrefsData.cs
index 3abe3e78..1da7ebcb 100644
--- a/Source/PrefsData.cs
+++ b/Source/PrefsData.cs
@@ -12,10 +12,13 @@ public class PrisonLaborPrefsData
public bool allow_all_worktypes = false;
public bool enable_motivation_mechanics = true;
public bool disable_mod = false;
+ public bool advanced_growing = false;
+
+ public string allowed_works = "";
public PrisonLaborPrefsData()
{
-
+
}
public void Apply()
diff --git a/Source/PrisonLabor.csproj b/Source/PrisonLabor.csproj
index 68d70dc9..f1a3e301 100644
--- a/Source/PrisonLabor.csproj
+++ b/Source/PrisonLabor.csproj
@@ -62,6 +62,8 @@
+
+
diff --git a/Source/PrisonLaborMod.cs b/Source/PrisonLaborMod.cs
index c755dfec..5265e4a8 100644
--- a/Source/PrisonLaborMod.cs
+++ b/Source/PrisonLaborMod.cs
@@ -10,9 +10,15 @@ namespace PrisonLabor
[StaticConstructorOnStartup]
class PrisonLaborMod : Mod
{
+ public const int versionNumber = 7;
+ public const string versionString = "0.7";
+
+ private static string difficulty = "";
+
private static bool showNews;
private static bool allowAllWorktypes;
private static bool enableMotivationMechanics;
+ private static bool advanceGrowing;
private static bool disableMod;
public PrisonLaborMod(ModContentPack content) : base(content)
@@ -22,46 +28,100 @@ public PrisonLaborMod(ModContentPack content) : base(content)
public static void Init()
{
showNews = PrisonLaborPrefs.ShowNews;
- allowAllWorktypes = PrisonLaborPrefs.AllowAllWorktypes;
+ allowAllWorktypes = PrisonLaborPrefs.AllowAllWorkTypes;
enableMotivationMechanics = PrisonLaborPrefs.EnableMotivationMechanics;
disableMod = PrisonLaborPrefs.DisableMod;
}
public override void DoSettingsWindowContents(Rect inRect)
{
- Listing_Standard listing_Standard = new Listing_Standard();
+ Rect leftRect = new Rect(inRect.x, inRect.y, inRect.width * 0.75f, inRect.height);
+ Rect rightRect = new Rect(inRect.x + inRect.width * 0.75f + 30f, inRect.y, inRect.width * 0.25f - 30f, inRect.height);
- listing_Standard.Begin(inRect);
- listing_Standard.Label("Version: " + PrisonLaborPrefs.Version, -1f);
+ Listing_Standard listing_options = new Listing_Standard();
- listing_Standard.GapLine();
+ listing_options.Begin(leftRect);
- listing_Standard.CheckboxLabeled("Show news", ref showNews, "Show news");
+ listing_options.CheckboxLabeled("Show news", ref showNews, "Showing news about changes in mod when prisoners detected.");
- listing_Standard.GapLine();
+ listing_options.GapLine();
- listing_Standard.Label("Allowed work types:", -1f);
- listing_Standard.CheckboxLabeled(" allow all", ref allowAllWorktypes, "allow all");
- if (!allowAllWorktypes)
+ if (!disableMod)
{
- if (listing_Standard.ButtonTextLabeled(" enabled:", "select"))
- ;//add dialog
+ listing_options.Label("Allowed work types:", -1f);
+ listing_options.CheckboxLabeled(" allow all", ref allowAllWorktypes, "allow all work types");
+ if (!allowAllWorktypes)
+ {
+ if (listing_options.ButtonTextLabeled(" allowed work types:", "browse"))
+ Find.WindowStack.Add(new SelectWorkTypesDialog());
+ }
+ else
+ {
+ listing_options.Gap();
+ }
+
+ listing_options.GapLine();
+
+ listing_options.CheckboxLabeled("Motivation mechanics (!)", ref enableMotivationMechanics, "When checked prisoners need to be motivated.\n\nWARINING: Needs reloading save.");
+
+ listing_options.GapLine();
+
+ listing_options.CheckboxLabeled("Prisoners can grow advanced plants", ref advanceGrowing, "When disabled prisoners can only grow plants that not require any skills.");
+
}
else
{
- listing_Standard.Gap();
+ listing_options.Gap();
+ listing_options.Gap();
+ listing_options.Label("Restart then re-save your game.", -1f);
+ listing_options.Label("After this steps you can safely disable this mod.", -1f);
+ listing_options.Gap();
+ listing_options.Gap();
+ listing_options.Gap();
}
- listing_Standard.GapLine();
+ listing_options.Gap();
+ listing_options.Gap();
+ listing_options.Gap();
+
+ listing_options.CheckboxLabeled("Disable mod", ref disableMod, "When enabled, worlds that are saved are transferred to 'safe mode', and can be played without mod.");
+
+ listing_options.End();
- listing_Standard.CheckboxLabeled("Motivation mechanics", ref enableMotivationMechanics, "When checked prisoners need to be motivated.");
+ Listing_Standard listing_panel = new Listing_Standard();
- listing_Standard.GapLine();
+ listing_panel.Begin(rightRect);
- listing_Standard.CheckboxLabeled("Disable", ref disableMod, "When enabled, worlds that are saved are transferred to 'safe mode', and can be played without mod.");
+ listing_panel.Label("Prison Labor Alpha", -1f);
+ listing_panel.Label("Version: " + versionString, -1f);
+
+ listing_panel.GapLine();
+
+ listing_panel.Label("Difficulty: " + difficulty, -1f);
+
+ listing_panel.GapLine();
+
+ Listing_Standard listing_buttons = new Listing_Standard();
+
+ listing_buttons.Begin(new Rect(rightRect.width * 0.25f, listing_panel.CurHeight, rightRect.width * 0.5f, rightRect.height - listing_panel.CurHeight));
+
+ if (listing_buttons.ButtonText("Defaults"))
+ {
+ PrisonLaborPrefs.RestoreToDefault();
+ Init();
+ }
- listing_Standard.End();
- Save();
+ if (listing_buttons.ButtonText("ShowNews"))
+ {
+ NewsDialog.showAll = true;
+ NewsDialog.ForceShow();
+ }
+
+ listing_buttons.End();
+
+ listing_panel.End();
+
+ Apply();
}
public override string SettingsCategory()
@@ -69,21 +129,54 @@ public override string SettingsCategory()
return "Prison Labor";
}
- public void Save()
+ public override void WriteSettings()
{
- if (
- PrisonLaborPrefs.ShowNews != showNews &&
- PrisonLaborPrefs.AllowAllWorktypes != allowAllWorktypes &&
- PrisonLaborPrefs.EnableMotivationMechanics != enableMotivationMechanics &&
- PrisonLaborPrefs.DisableMod != disableMod
- )
- {
- PrisonLaborPrefs.ShowNews = showNews;
- PrisonLaborPrefs.AllowAllWorktypes = allowAllWorktypes;
+ Log.Message("saved");
+ PrisonLaborPrefs.ShowNews = showNews;
+ PrisonLaborPrefs.AllowAllWorkTypes = allowAllWorktypes;
+ if(!disableMod)
PrisonLaborPrefs.EnableMotivationMechanics = enableMotivationMechanics;
- PrisonLaborPrefs.DisableMod = disableMod;
- PrisonLaborPrefs.Save();
+ PrisonLaborPrefs.AdvancedGrowing = advanceGrowing;
+ PrisonLaborPrefs.DisableMod = disableMod;
+ PrisonLaborPrefs.Save();
+ }
+
+ private static void Apply()
+ {
+ PrisonLaborPrefs.Apply();
+ CalculateDifficulty();
+ }
+
+ private static void CalculateDifficulty()
+ {
+ int value = 1000;
+ if (!enableMotivationMechanics)
+ value -= 300;
+ if (advanceGrowing)
+ value -= 50;
+ value -= 500;
+ if(!allowAllWorktypes)
+ {
+ int delta = 500 + 7 * 50 + (DefDatabase.DefCount - 20) * 25;
+ foreach (WorkTypeDef wtd in DefDatabase.AllDefs)
+ {
+ if (!PrisonLaborUtility.WorkDisabled(wtd))
+ delta -= 50;
+ }
+ if (delta > 0)
+ value += delta;
}
+
+ if (value >= 1000)
+ difficulty = (int)(value / 10) + " (Normal)";
+ else if (value >= 800)
+ difficulty = (int)(value / 10) + " (Casual)";
+ else if (value >= 500)
+ difficulty = (int)(value / 10) + " (Easy)";
+ else if (value >= 300)
+ difficulty = (int)(value / 10) + " (Peaceful)";
+ else
+ difficulty = (int)(value / 10) + " (A joke)";
}
}
}
diff --git a/Source/PrisonLaborUtility.cs b/Source/PrisonLaborUtility.cs
index 0dbc58b0..0bc88b9d 100644
--- a/Source/PrisonLaborUtility.cs
+++ b/Source/PrisonLaborUtility.cs
@@ -12,51 +12,84 @@ class PrisonLaborUtility
private static PrisonerInteractionModeDef pimDef;
- private static List enabledWorks;
- private static List disabledWorks;
+ private static List defaultWorkTypes;
+ private static List allowedWorkTypes;
- public static List DisabledWorks
+ private static List DefaultWorkTypes
{
get
{
- if(enabledWorks == null)
+ if(defaultWorkTypes == null)
{
- enabledWorks = new List();
- enabledWorks.Add(WorkTypeDefOf.Growing);
- enabledWorks.Add(WorkTypeDefOf.Mining);
- enabledWorks.Add(WorkTypeDefOf.Hauling);
- enabledWorks.Add(DefDatabase.GetNamed("Cooking"));
- enabledWorks.Add(DefDatabase.GetNamed("PlantCutting"));
- enabledWorks.Add(DefDatabase.GetNamed("Crafting"));
- enabledWorks.Add(DefDatabase.GetNamed("Cleaning"));
-
- enabledWorks.Add(DefDatabase.GetNamed("HaulingUrgent", false));
+ defaultWorkTypes = new List();
+ defaultWorkTypes.Add(WorkTypeDefOf.Growing);
+ defaultWorkTypes.Add(WorkTypeDefOf.Mining);
+ defaultWorkTypes.Add(WorkTypeDefOf.Hauling);
+ defaultWorkTypes.Add(DefDatabase.GetNamed("Cooking"));
+ defaultWorkTypes.Add(DefDatabase.GetNamed("PlantCutting"));
+ defaultWorkTypes.Add(DefDatabase.GetNamed("Crafting"));
+ defaultWorkTypes.Add(DefDatabase.GetNamed("Cleaning"));
+
+ defaultWorkTypes.Add(DefDatabase.GetNamed("HaulingUrgent", false));
+ }
+ return defaultWorkTypes;
+ }
+ }
+
+ private static List AllowedWorkTypes
+ {
+ get
+ {
+ if (allowedWorkTypes == null)
+ {
+ return DefaultWorkTypes;
+ }
+ else
+ {
+ return allowedWorkTypes;
+ }
+ }
+ }
+
+ public static string AllowedWorkTypesData
+ {
+ get
+ {
+ if (allowedWorkTypes == null)
+ {
+ return "";
}
- if(disabledWorks == null)
+ else
{
- disabledWorks = new List();
- disabledWorks.Add(WorkTypeDefOf.Construction);
- disabledWorks.Add(WorkTypeDefOf.Doctor);
- disabledWorks.Add(WorkTypeDefOf.Firefighter);
- disabledWorks.Add(WorkTypeDefOf.Handling);
- disabledWorks.Add(WorkTypeDefOf.Hunting);
- disabledWorks.Add(WorkTypeDefOf.Warden);
- disabledWorks.Add(DefDatabase.GetNamed("Art"));
- disabledWorks.Add(DefDatabase.GetNamed("PatientEmergency"));
- disabledWorks.Add(DefDatabase.GetNamed("PatientBedRest"));
- disabledWorks.Add(DefDatabase.GetNamed("Flicker"));
- disabledWorks.Add(DefDatabase.GetNamed("Research"));
- disabledWorks.Add(DefDatabase.GetNamed("Smithing"));
- disabledWorks.Add(DefDatabase.GetNamed("Tailoring"));
+ string data = "";
+ foreach(WorkTypeDef workDef in allowedWorkTypes)
+ {
+ data += workDef.defName + ";";
+ }
+ return data;
+ }
+ }
+
+ set
+ {
+ if(value.NullOrEmpty())
+ {
+ allowedWorkTypes = null;
+ }
+ else
+ {
+ allowedWorkTypes = new List();
+ string[] subs = value.Split(';');
+ foreach (string s in subs)
+ allowedWorkTypes.Add(DefDatabase.GetNamed(s, false));
}
- return disabledWorks;
}
}
public static bool WorkDisabled(WorkTypeDef wt)
{
- if (wt != null)
- return DisabledWorks.Contains(wt);
+ if (wt != null && !PrisonLaborPrefs.AllowAllWorkTypes)
+ return !AllowedWorkTypes.Contains(wt);
else
return false;
}
@@ -69,13 +102,23 @@ public static bool WorkDisabled(Pawn p, WorkTypeDef wt)
return false;
}
+ public static void SetAllowedWorkTypes(IEnumerable newList)
+ {
+ allowedWorkTypes = new List();
+ foreach(WorkTypeDef workDef in newList)
+ {
+ allowedWorkTypes.Add(workDef);
+ }
+ }
+
public static void InitWorkSettings(Pawn pawn)
{
//Work Types
if (!pawn.workSettings.EverWork)
pawn.workSettings.EnableAndInitialize();
- foreach (WorkTypeDef def in PrisonLaborUtility.DisabledWorks)
- pawn.workSettings.Disable(def);
+ foreach (WorkTypeDef def in DefDatabase.AllDefs)
+ if(WorkDisabled(def))
+ pawn.workSettings.Disable(def);
//Timetables
if(pawn.timetable == null)
@@ -89,7 +132,7 @@ public static bool LaborEnabled(Pawn pawn)
{
if (pimDef == null)
pimDef = DefDatabase.GetNamed("PrisonLabor_workOption");
- if (pawn.IsPrisoner && pawn.guest.interactionMode == pimDef)
+ if (pawn.IsPrisoner && pawn.guest.interactionMode == pimDef && !PrisonLaborPrefs.DisableMod)
return true;
else
return false;
diff --git a/Source/PrisonerFoodReservation.cs b/Source/PrisonerFoodReservation.cs
index 6c355d66..86fd9840 100644
--- a/Source/PrisonerFoodReservation.cs
+++ b/Source/PrisonerFoodReservation.cs
@@ -1,4 +1,5 @@
-using System;
+using RimWorld;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -8,19 +9,41 @@ namespace PrisonLabor
{
class PrisonerFoodReservation
{
- private static List reservation = new List();
+ private static Dictionary reservation = new Dictionary();
public static bool isReserved(Thing t)
{
- if (reservation.Contains(t))
+ Pawn p;
+ reservation.TryGetValue(t, out p);
+ if (p != null && p.GetRoom() == t.GetRoom() && p.needs.food.CurCategory != HungerCategory.Fed)
return true;
else
return false;
}
- public static void reserve(Thing t)
+ public static void reserve(Thing t, Pawn p)
{
- reservation.Add(t);
+ if (!reservation.ContainsKey(t))
+ reservation.Add(t, p);
+ else
+ reservation[t] = p;
+
+ if (reservation.Count > 50)
+ clearEatenFood();
+ }
+
+ private static void clearEatenFood()
+ {
+ List removeList = new List();
+ foreach(Thing t in reservation.Keys)
+ {
+ if (t == null || t.GetRoom() == null || !isReserved(t))
+ removeList.Add(t);
+ }
+ foreach(Thing t in removeList)
+ {
+ reservation.Remove(t);
+ }
}
}
}
diff --git a/Source/Properties/AssemblyInfo.cs b/Source/Properties/AssemblyInfo.cs
index aa3447f8..b6a6810d 100644
--- a/Source/Properties/AssemblyInfo.cs
+++ b/Source/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@
// 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("0.6.0.0")]
-[assembly: AssemblyFileVersion("0.6.0.0")]
+[assembly: AssemblyVersion("0.7.0.0")]
+[assembly: AssemblyFileVersion("0.7.0.0")]
diff --git a/Source/SelectWorkTypesDialog.cs b/Source/SelectWorkTypesDialog.cs
new file mode 100644
index 00000000..f143e360
--- /dev/null
+++ b/Source/SelectWorkTypesDialog.cs
@@ -0,0 +1,118 @@
+using RimWorld;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UnityEngine;
+using Verse;
+using Verse.Sound;
+
+namespace PrisonLabor
+{
+ class SelectWorkTypesDialog : Window
+ {
+ Dictionary workTypes;
+
+ float maxH;
+ Vector2 position;
+ bool temp;
+
+ public SelectWorkTypesDialog()
+ {
+ this.absorbInputAroundWindow = true;
+ this.closeOnEscapeKey = true;
+ this.doCloseX = true;
+ this.doCloseButton = true;
+
+ workTypes = new Dictionary();
+
+ foreach (WorkTypeDef workType in DefDatabase.AllDefs)
+ if (!PrisonLaborUtility.WorkDisabled(workType))
+ workTypes.Add(workType, true);
+ else
+ workTypes.Add(workType, false);
+ }
+
+ public override void DoWindowContents(Rect inRect)
+ {
+
+ Rect listRect = new Rect(inRect.x, inRect.y + 10f, inRect.width, inRect.height - 50f);
+ Rect contentRect = new Rect(0f, 0f, inRect.width - 20f, 24f * workTypes.Count());
+ Widgets.BeginScrollView(listRect, ref this.position, contentRect, true);
+ Listing_Standard listing_Standard = new Listing_Standard();
+ listing_Standard.Begin(contentRect);
+
+ WorkTypeDef workTypeClicked = null;
+ foreach (WorkTypeDef workDef in workTypes.Keys)
+ {
+ String label = workDef.labelShort, tooltip = workDef.description;
+ float lineHeight = Text.LineHeight;
+ bool checkOn = workTypes[workDef];
+ //workTypes.TryGetValue(workDef, out checkOn);
+ Rect rect = listing_Standard.GetRect(lineHeight);
+ if (!tooltip.NullOrEmpty())
+ {
+ if (Mouse.IsOver(rect))
+ {
+ Widgets.DrawHighlight(rect);
+ }
+ TooltipHandler.TipRegion(rect, tooltip);
+ }
+ TextAnchor anchor = Text.Anchor;
+ Text.Anchor = TextAnchor.MiddleLeft;
+ Widgets.Label(rect, label);
+ if (Widgets.ButtonInvisible(rect, false))
+ {
+ workTypeClicked = workDef;
+ if (checkOn)
+ {
+ SoundDefOf.CheckboxTurnedOn.PlayOneShotOnCamera(null);
+ }
+ else
+ {
+ SoundDefOf.CheckboxTurnedOff.PlayOneShotOnCamera(null);
+ }
+ }
+ Color color = GUI.color;
+ Texture2D image;
+ if (checkOn)
+ {
+ image = Widgets.CheckboxOnTex;
+ }
+ else
+ {
+ image = Widgets.CheckboxOffTex;
+ }
+ Rect position = new Rect(rect.x + rect.width - 24f, rect.y, 24f, 24f);
+ GUI.DrawTexture(position, image);
+ Text.Anchor = anchor;
+ listing_Standard.Gap(listing_Standard.verticalSpacing);
+ }
+
+ if (workTypeClicked != null)
+ {
+ workTypes[workTypeClicked] = !workTypes[workTypeClicked];
+ Apply(workTypes);
+ }
+
+ maxH = listing_Standard.CurHeight;
+
+ listing_Standard.End();
+ Widgets.EndScrollView();
+ }
+
+ private static void Apply(Dictionary workTypes)
+ {
+ List list = new List();
+ foreach (WorkTypeDef workDef in workTypes.Keys)
+ {
+ if(workTypes[workDef] == true)
+ {
+ list.Add(workDef);
+ }
+ }
+ PrisonLaborUtility.SetAllowedWorkTypes(list);
+ PrisonLaborPrefs.AllowedWorkTypes = PrisonLaborUtility.AllowedWorkTypesData;
+ }
+ }
+}
diff --git a/Source/ThinkNode_IfLaborEnabled.cs b/Source/ThinkNode_IfLaborEnabled.cs
index e56d8005..741c3cf7 100644
--- a/Source/ThinkNode_IfLaborEnabled.cs
+++ b/Source/ThinkNode_IfLaborEnabled.cs
@@ -23,7 +23,8 @@ protected override bool Satisfied(Pawn pawn)
{
return true;
}
- pawn.needs.TryGetNeed().Enabled = false;
+ if(pawn.needs.TryGetNeed() != null)
+ pawn.needs.TryGetNeed().Enabled = false;
}
}
return false;
diff --git a/Source/Tutorials.cs b/Source/Tutorials.cs
index 5dd9f903..d4c4d5ce 100644
--- a/Source/Tutorials.cs
+++ b/Source/Tutorials.cs
@@ -15,16 +15,12 @@ class Tutorials
private static ConceptDef managementDef = DefDatabase.GetNamed("PrisonLabor_Management", true);
private static ConceptDef timetableDef = DefDatabase.GetNamed("PrisonLabor_Timetable", true);
- public static bool showNews = true;
- public static bool msgShowVersion0_5 = false;
- public static bool msgShowVersion0_6 = false;
-
public static void Introduction()
{
if (!PlayerKnowledgeDatabase.IsComplete(introductionDef))
Verse.Find.Tutor.learningReadout.TryActivateConcept(introductionDef);
//Move it to point after map genration
- News();
+ NewsDialog.TryShow();
}
public static void Motivation()
@@ -51,23 +47,5 @@ public static void Growing()
Verse.Find.Tutor.learningReadout.TryActivateConcept(growingDef);
}
- public static void News()
- {
- if (showNews)
- {
- if (msgShowVersion0_6)
- {
- Find.WindowStack.Add(new Dialog_MessageBox("Changes in PrisonLabor v0.6:\n\n 1. Time restrictions - now you can manage your prisoners time for sleep, work and joy. You can now even force them to work when they're hungry!\n 2. Getting food by prisoners - Now prisoners will look for food in much better way, and now (when they desperate enough) they will eat corpses!\n 3. \"Laziness\" changed to \"Motivation\" and inverted.\n\n ATTENTION: After PrisonLabor reaches beta all saves with PrisonLabor v0.5a or lower will be corrupted and unplayable. This version (0.6) is safe and converts all older saves.", "Ok", null, null, null, "PrisonLabor - Patch 0.6", false));
- }
- if (msgShowVersion0_5)
- {
- Find.WindowStack.Add(new Dialog_MessageBox("Major changes to PrisonLabor:\n\n 1. Prisoners can now grow, but only plants that not require any skills.\n 2. You can now manage prisoners work types. Just check \"Work\" tab!\n 3. Laziness now appear on \"Needs\" tab. Above 50% wardens will watch prisoners. Above 80% prisoners won't work unless supervised.\n 4. Wardens will now bring food to prisoners that went too far from his bed.\n 5. Prisoners won't gain laziness when not working anymore.\n 6. Fixed many bugs", "Ok", null, null, null, "PrisonLabor - Update", false));
- }
- PrisonLaborPrefs.LastVersion = PrisonLaborPrefs.Version;
- PrisonLaborPrefs.Save();
- showNews = false;
- }
- }
-
}
}
diff --git a/Source/Tweaks/FoodUtility_Tweak.cs b/Source/Tweaks/FoodUtility_Tweak.cs
index 88c9af2a..cafa7816 100644
--- a/Source/Tweaks/FoodUtility_Tweak.cs
+++ b/Source/Tweaks/FoodUtility_Tweak.cs
@@ -160,6 +160,7 @@ public static Thing BestFoodInInventory(Pawn holder, Pawn eater = null, FoodPref
return thing;
}
}
+
}
return null;
}
@@ -195,7 +196,7 @@ public static Thing BestFoodSourceOnMap(Pawn getter, Pawn eater, bool desperate,
}
Predicate foodValidator = delegate (Thing t)
{
- if (PrisonerFoodReservation.isReserved(t) && !eater.IsPrisoner && !desperate)
+ if (PrisonerFoodReservation.isReserved(t) && (eater != getter || !eater.IsPrisoner) && !desperate)
{
return false;
}
diff --git a/Source/Tweaks/JobDriver_FoodDeliver_Tweak.cs b/Source/Tweaks/JobDriver_FoodDeliver_Tweak.cs
index 3c97d486..e08589a3 100644
--- a/Source/Tweaks/JobDriver_FoodDeliver_Tweak.cs
+++ b/Source/Tweaks/JobDriver_FoodDeliver_Tweak.cs
@@ -51,6 +51,7 @@ public override void Notify_Starting()
[DebuggerHidden]
protected override IEnumerable MakeNewToils()
{
+ this.FailOn(() => PrisonerFoodReservation.isReserved(TargetA.Thing));
yield return Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null);
if (this.eatingFromInventory)
{
@@ -88,7 +89,7 @@ protected override IEnumerable MakeNewToils()
{
Thing thing;
pawn.carryTracker.TryDropCarriedThing(toil.actor.jobs.curJob.targetC.Cell, ThingPlaceMode.Direct, out thing, null);
- PrisonerFoodReservation.reserve(thing);
+ PrisonerFoodReservation.reserve(thing, (Pawn)toil.actor.jobs.curJob.targetB.Thing);
},
defaultCompleteMode = ToilCompleteMode.Instant
};
diff --git a/Source/Tweaks/WorkGiver_GrowerSow_Tweak.cs b/Source/Tweaks/WorkGiver_GrowerSow_Tweak.cs
index 42e38033..527a4d88 100644
--- a/Source/Tweaks/WorkGiver_GrowerSow_Tweak.cs
+++ b/Source/Tweaks/WorkGiver_GrowerSow_Tweak.cs
@@ -100,7 +100,7 @@ public override Job JobOnCell(Pawn pawn, IntVec3 c)
}
return null;
}
- if (WorkGiver_Grower.wantedPlantDef.plant.sowMinSkill > 0)
+ if (WorkGiver_Grower.wantedPlantDef.plant.sowMinSkill > 0 && !PrisonLaborPrefs.AdvancedGrowing)
{
return null;
}
diff --git a/changelog.txt b/changelog.txt
index a7862156..d9daa9e2 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,12 +1,13 @@
Changelog:
0.7
+- fixed "failing to reserve food" bug (that one with circling warden around food)
- prisoners now stop working (while "anything" time) while starving instead of hungry. They will still get minor debuff
- wardens will no longer watch over not working prisoners
- prisoners will no longer work if waiting for operation
- fixed bug preventing prisoners from cleaning
- added "starving prisoners" alert
- added settings
-- changed "Your prisoner stopped working" message to "Your prisoners are not working" alert
+- changed "Your prisoner stopped working" message to "Prisoners aren't working" alert
0.6a
- fixed some bugs
0.6