Skip to content

Commit

Permalink
Merge 1.4 fixes (#1)
Browse files Browse the repository at this point in the history
* Update FavouriteManager.cs

Fluffy.WorkTab.NoStoredFavourites was not translated

* Default priority (+ tip) setting now transletable

Update Keyed-English.xml

* Fix horizontal scroll area

fixes fluffy-mods#157, fluffy-mods#159 and fluffy-mods#164

The scroll area was using cachedSize for its output rectangle capping it at the screen width. As the "Work"-tab window is not as wide as the screen, ouput rectangle was too wide when there were many work types.

To fix this the PawnTable was extended with the property methods void set_OutRect(this PawnTable, Rect) and Rect get_OutRect() 'fake adding' a new property that can be used to set and get the "Work"-tab window dimension instead of relying on the screen size.

MainTabWindow_WorkTab.DoWindowContents calls set_OutRect with the window dimension PawnTable_PawnTableOnGUI.PawnTableOnGUI calls get_OutRect to clamp the output rectangle properly

I think ideally PawnTable.PawnTableOnGUI's parameter would be Rect window instead of Vector2 position in the future.

* Respect "Disable Scrollwheel" on Checkbox WorkTypes

* Replace Job Icon Column with Job Text Column

* Make Mod Setting for Job Text Column (Icon vs Text)

* Localize Mod Setting for Job Text Column

* Add Option to Highlight Current Active Work Cell

* Fix: Priorities reset after save-load.

PriorityManager class was relying on Scribe methods in ExposeData() for clearing out old priorities data.
But ExposeData() is not called when a new game is started or a game is loaded which was saved without the mod active.
So, new data was added to the old one.
If a non-modded save was loaded twice, pawn priorities lists were doubled, with the latest list being active.
When the game was subsequently saved and loaded, all data was saved, but only the oldest copy of priorities was restored.
Other copies yielded an error:
Exception in LookDictionary(label=Priorities): System.InvalidOperationException: Tried to add different values for the same key.
Attempts to load priorities data of non-existent pawns, inherited from other games, resulted in a probably harmless error:
Could not resolve reference to object with loadID Thing_Human#

Now, all static members of PriorityManager are initialized by constructor.

* Removed unused project DynamicPawnTable.

* Fix warning: DrawUtilities probably needs a StaticConstructorOnStartup attribute

Fix warning in the game's log:
Type DrawUtilities probably needs a StaticConstructorOnStartup attribute, because it has a field activeHighlightBox of type Texture2D. All assets must be loaded in the main thread.

* Fix: Naming rule violation.

* Fix: active job frame is too bright.

* Fix wording in tooltips: increase/increment/decrease/decrement priorities => raise/lower

* Enable HighlightCurrentJobCell by default.

Also, change names and labels for being consistent: ActiveWorkCells => CurrentJobCell.
Minor clean-up.

* Fix: Numeric settings are reset after restarting the game.

* Fix the last fix: Numeric settings are hard to edit.

---------

Co-authored-by: angelolocritani <67960642+angelolocritani@users.noreply.github.com>
Co-authored-by: Sineme <sineme@users.noreply.github.com>
Co-authored-by: maarxx <chris.lewark@gmail.com>
Co-authored-by: Doomster14 <146005125+Doomster14@users.noreply.github.com>
  • Loading branch information
5 people authored Apr 15, 2024
1 parent 80a0feb commit 0e2955a
Show file tree
Hide file tree
Showing 16 changed files with 171 additions and 30 deletions.
8 changes: 8 additions & 0 deletions Defs/PawnColumnDefs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
<headerIconSize>(16,16)</headerIconSize>
</PawnColumnDef>

<PawnColumnDef>
<defName>JobText</defName>
<workerClass>WorkTab.PawnColumnWorker_JobText</workerClass>
<sortable>true</sortable>
<label>Current job</label>
<headerTip>Current job</headerTip>
</PawnColumnDef>

<PawnColumnDef>
<defName>CopyPasteDetailedWorkPriorities</defName>
<workerClass>WorkTab.PawnColumnWorker_CopyPasteDetailedWorkPriorities</workerClass>
Expand Down
12 changes: 9 additions & 3 deletions Languages/English/Keyed/Keyed-English.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<WorkTab.CollapseAll>Click to collapse all priorities\nCtrl-click headers to toggle expanding individual priorities</WorkTab.CollapseAll>

<!-- column header tooltips -->
<WorkTab.DetailedColumnTip>Shift + left-click or scroll up to increase priorities\nShift + right click or scroll down to decrease priorities</WorkTab.DetailedColumnTip>
<WorkTab.DetailedColumnTip>Shift + left-click or scroll up to raise priorities\nShift + right click or scroll down to lower priorities</WorkTab.DetailedColumnTip>
<WorkTab.ToggleColumnTip>Shift + left-click or scroll up to toggle priorities on\nShift + right click or scroll down to toggle priorities off</WorkTab.ToggleColumnTip>
<WorkTab.ExpandWorkgiversColumnTip>Ctrl + click to expand list of detailed priorities</WorkTab.ExpandWorkgiversColumnTip>
<WorkTab.CollapseWorkgiversColumnTip>Ctrl + click to collapse list of detailed priorities</WorkTab.CollapseWorkgiversColumnTip>
Expand All @@ -21,12 +21,18 @@
<WorkTab.24HourModeTip>Should times be shown in 12h (e.g. noon, 9p.m.) or 24h (e.g. 12:00, 21:00) mode?</WorkTab.24HourModeTip>
<WorkTab.MaxPriority>Levels of priority</WorkTab.MaxPriority>
<WorkTab.MaxPriorityTip>How many levels of priority should we use? (Limited to between 4 and 9)</WorkTab.MaxPriorityTip>
<WorkTab.DefaultPriority>Default priority</WorkTab.DefaultPriority>
<WorkTab.DefaultPriorityTip>Which level of priority is assigned by default?</WorkTab.DefaultPriorityTip>
<WorkTab.PlaySounds>Sounds</WorkTab.PlaySounds>
<WorkTab.PlaySoundsTip>Play sounds when a priority is changed?</WorkTab.PlaySoundsTip>
<WorkTab.PlayCrunch>Crunchy sounds</WorkTab.PlayCrunch>
<WorkTab.PlayCrunchTip>Play a crunchy sound when a pawn is assigned to a job they are not skilled at?</WorkTab.PlayCrunchTip>
<WorkTab.DisableScrollwheel>Disable Scrollwheel</WorkTab.DisableScrollwheel>
<WorkTab.DisableScrollwheelTip>Disable the scrollwheel functions (when hovering over skills)</WorkTab.DisableScrollwheelTip>
<WorkTab.JobTextMode>Current job column as text (requires restart)</WorkTab.JobTextMode>
<WorkTab.JobTextModeTip>Render the current job column as a text description of current activity.\nWhen disabled, an icon is displayed.\n\n(Due to a technical limitation, you must restart the game after changing this option.)</WorkTab.JobTextModeTip>
<WorkTab.HighlightCurrentJobCell>Highlight current job cell</WorkTab.HighlightCurrentJobCell>
<WorkTab.HighlightCurrentJobCellTip>Highlight the grid square in the work tab when the pawn is actually working that job right now.</WorkTab.HighlightCurrentJobCellTip>
<WorkTab.VerticalLabels>Vertical labels</WorkTab.VerticalLabels>
<WorkTab.VerticalLabelsTip>Display work labels vertically</WorkTab.VerticalLabelsTip>
<WorkTab.FontFix>Fix vertical fonts</WorkTab.FontFix>
Expand All @@ -48,7 +54,7 @@
<WorkTab.XIsAssignedToY>{0} is assigned to {1}</WorkTab.XIsAssignedToY>

<!-- pawn label tooltip -->
<WorkTab.LabelCellTip>Click to jump to\nShift-left-click or scroll up to increment priorities\nShift-right-click or scroll down to decrement priorities</WorkTab.LabelCellTip>
<WorkTab.LabelCellTip>Click to jump to\nShift-left-click or scroll up to raise priorities\nShift-right-click or scroll down to lower priorities</WorkTab.LabelCellTip>

<!-- Favourites -->
<Fluffy.WorkTab.CreateFavourite>Create new favourite</Fluffy.WorkTab.CreateFavourite>
Expand Down Expand Up @@ -77,4 +83,4 @@
<Fluffy.WorkTab.Priority.VeryLow>Very low priority</Fluffy.WorkTab.Priority.VeryLow>
<Fluffy.WorkTab.Priority.Lowest>Lowest priority</Fluffy.WorkTab.Priority.Lowest>

</LanguageData>
</LanguageData>
1 change: 1 addition & 0 deletions Source/Core/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public static class Constants {
public const float MinTimeBarLabelSpacing = 50f;
public const int TimeBarHeight = 40;
public const int VerticalHeaderHeight = 100;
public const int JobTextWidth = 150;
public const int WorkGiverBoxSize = 20;
public const int WorkGiverWidth = 25;
public const int WorkTypeBoxSize = 25;
Expand Down
40 changes: 24 additions & 16 deletions Source/Core/Settings.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
// Settings.cs
// Settings.cs
// Copyright Karel Kroeze, 2020-2020

using UnityEngine;
using Verse;

namespace WorkTab {
public class Settings: ModSettings {
public static int defaultPriority = 3;
public static bool disableScrollwheel;
public static int maxPriority = 9;
public static bool playCrunch = true;
public static bool playSounds = true;
public static bool TwentyFourHourMode = true;
public static bool verticalLabels = true;
private static string _defaultPriorityBuffer = defaultPriority.ToString();

// public static bool sharedFavourites = true;
public static int maxPriority = 9;
public static int defaultPriority = 3;
public static bool TwentyFourHourMode = true;
public static bool playSounds = true;
public static bool playCrunch = true;
public static bool disableScrollwheel = false;
public static bool jobTextMode = false;
public static bool highlightCurrentJobCell = true;
public static bool verticalLabels = true;
private static bool _fontFix = true;
// public static bool sharedFavourites = true;

// buffers
private static string _maxPriorityBuffer = maxPriority.ToString();
// Buffers will be initialized with current settings as soon as
// DoWindowContents() → Listing_Standard.TextFieldNumericLabeled() → Widgets.TextFieldNumeric() will be called.
private static string maxPriorityBuffer = null;
private static string defaultPriorityBuffer = null;

public Settings() {
ApplyFontFix(_fontFix);
Expand All @@ -37,10 +39,10 @@ public static void ApplyFontFix(bool state) {
public static void DoWindowContents(Rect rect) {
Listing_Standard options = new Listing_Standard();
options.Begin(rect);
options.TextFieldNumericLabeled("WorkTab.MaxPriority".Translate(), ref maxPriority, ref _maxPriorityBuffer,
options.TextFieldNumericLabeled("WorkTab.MaxPriority".Translate(), ref maxPriority, ref maxPriorityBuffer,
4, 9, "WorkTab.MaxPriorityTip".Translate(), 1 / 8f);
options.TextFieldNumericLabeled("WorkTab.DefaultPriority".Translate(), ref defaultPriority,
ref _defaultPriorityBuffer, 1, 9, "WorkTab.DefaultPriorityTip".Translate(),
ref defaultPriorityBuffer, 1, 9, "WorkTab.DefaultPriorityTip".Translate(),
1 / 8f);
options.CheckboxLabeled("WorkTab.24HourMode".Translate(), ref TwentyFourHourMode,
"WorkTab.24HourModeTip".Translate());
Expand All @@ -51,6 +53,10 @@ public static void DoWindowContents(Rect rect) {
"WorkTab.PlayCrunchTip".Translate());
options.CheckboxLabeled("WorkTab.DisableScrollwheel".Translate(), ref disableScrollwheel,
"WorkTab.DisableScrollwheelTip".Translate());
options.CheckboxLabeled("WorkTab.JobTextMode".Translate(), ref jobTextMode,
"WorkTab.JobTextModeTip".Translate());
options.CheckboxLabeled("WorkTab.HighlightCurrentJobCell".Translate(), ref highlightCurrentJobCell,
"WorkTab.HighlightCurrentJobCellTip".Translate());
bool verticalLabelsBuffer = verticalLabels;
options.CheckboxLabeled("WorkTab.VerticalLabels".Translate(), ref verticalLabelsBuffer,
"WorkTab.VerticalLabelsTip".Translate());
Expand All @@ -64,7 +70,7 @@ public static void DoWindowContents(Rect rect) {
options.CheckboxLabeled("WorkTab.FontFix".Translate(), ref _fontFixBuffer,
"WorkTab.FontFixTip".Translate());
_fontFixBuffer =
verticalLabels && _fontFixBuffer; // disabling vertical labels makes the font fix unnecesary.
verticalLabels && _fontFixBuffer; // disabling vertical labels makes the font fix unnecessary.

// apply any changes.
if (_fontFixBuffer != _fontFix) {
Expand All @@ -86,7 +92,9 @@ public override void ExposeData() {
Scribe_Values.Look(ref playSounds, "PlaySounds", true);
Scribe_Values.Look(ref playCrunch, "PlayCrunch", true);
Scribe_Values.Look(ref disableScrollwheel, "DisableScrollwheel");
Scribe_Values.Look(ref jobTextMode, "JobTextMode");
Scribe_Values.Look(ref verticalLabels, "VerticalLabels", true);
Scribe_Values.Look(ref highlightCurrentJobCell, "HighlightCurrentJobCell", true);
Scribe_Values.Look(ref _fontFix, "FontFix", true);

// apply font-fix on load
Expand Down
35 changes: 35 additions & 0 deletions Source/Extensions/PawnTable_Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using RimWorld;
using RimWorld.BaseGen;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace WorkTab.Extensions {
internal static class PawnTable_Extensions {
private static ConditionalWeakTable<PawnTable, StrongBox<Rect>> outRectDictionary=new ConditionalWeakTable<PawnTable, StrongBox<Rect>>();
/// <summary>
/// Sets the rectangle the <see cref="PawnTable"/> is drawn in.
/// </summary>
/// <param name="pawnTable">The <see cref="PawnTable"/> being extended.</param>
/// <param name="outRect">The rectangle the <see cref="PawnTable"/> will be drawn in.</param>
internal static void set_OutRect(this PawnTable pawnTable, Rect outRect) {
var value = outRectDictionary.GetValue(
pawnTable,
a => new StrongBox<Rect>(outRect)
);
value.Value = outRect;
}
/// <summary>
/// Gets the rectangle the <see cref="PawnTable"/> will be drawn in.
/// </summary>
/// <param name="pawnTable">The <see cref="PawnTable"/> being extended.</param>
/// <returns>The rectangle the <see cref="PawnTable"/> will be drawn in.</returns>
internal static Rect get_OutRect(this PawnTable pawnTable) {
return outRectDictionary.GetOrCreateValue(pawnTable).Value;
}
}
}
2 changes: 1 addition & 1 deletion Source/Favourites/FavouriteManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ private static void LoadFavouriteFloatMenu(Pawn pawn) {
() => LoadFavourite(f.path, pawn)))
.ToList();
if (options.Count == 0) {
options.Add(new FloatMenuOption("Fluffy.WorkTab.NoStoredFavourites", null));
options.Add(new FloatMenuOption("Fluffy.WorkTab.NoStoredFavourites".Translate(), null));
}
Find.WindowStack.Add(new FloatMenu(options));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ private static void Postfix() {
// insert mood and job columns before first work column name
int firstWorkindex =
workTable.columns.FindIndex(d => d.workerClass == typeof(PawnColumnWorker_WorkPriority));
workTable.columns.Insert(firstWorkindex, PawnColumnDefOf.Job);
if (Settings.jobTextMode) {
workTable.columns.Insert(firstWorkindex, PawnColumnDefOf.JobText);
} else {
workTable.columns.Insert(firstWorkindex, PawnColumnDefOf.Job);
}
workTable.columns.Insert(firstWorkindex + 1, PawnColumnDefOf.Mood);

// go over PawnColumnDefs and replace all PawnColumnWorker_WorkPriority
Expand Down
7 changes: 6 additions & 1 deletion Source/HarmonyPatches/PawnTable/PawnTable_PawnTableOnGUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using RimWorld;
using UnityEngine;
using Verse;
using WorkTab.Extensions;

namespace WorkTab {
[HarmonyPatch(typeof(PawnTable), nameof(PawnTable.PawnTableOnGUI))]
Expand Down Expand Up @@ -79,7 +80,11 @@ public static bool Prefix(PawnTable __instance,
// Instead, we want to limit outRect to the available view area, so a horizontal scrollbar can appear.
float labelWidth = cachedColumnWidths[0];
var labelCol = columns[0];
float outWidth = Mathf.Min( cachedSize.x - labelWidth, UI.screenWidth - (standardWindowMargin * 2f) );
// ideally this method would be called with a Rect outRect
// indicating the window it is being drawn in instead
// of a Vector2 position
var outRect = __instance.get_OutRect();
float outWidth = outRect.width - labelWidth;
float viewWidth = cachedSize.x - labelWidth - 16f;

Rect labelHeaderRect = new Rect(
Expand Down
33 changes: 33 additions & 0 deletions Source/PawnColumns/PawnColumnWorker_JobText.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright Karel Kroeze, 2020-2021.
// WorkTab/WorkTab/PawnColumnWorker_WorkTabLabel.cs

using RimWorld;
using Verse;
using static WorkTab.Constants;

namespace WorkTab {
public class PawnColumnWorker_JobText : PawnColumnWorker_Text {
public override int GetMinWidth(PawnTable table)
{
return JobTextWidth;
}
private string GetJobString(Pawn pawn)
{
return pawn.jobs?.curDriver?.GetReport() ?? "";
}
protected override string GetTextFor(Pawn pawn) {
return GetJobString(pawn);
}
protected override string GetTip(Pawn pawn) {
return GetJobString(pawn);
}
public string GetValueToCompare(Pawn pawn)
{
return GetJobString(pawn);
}
public override int Compare(Pawn a, Pawn b)
{
return GetValueToCompare(a).CompareTo(GetValueToCompare(b));
}
}
}
10 changes: 10 additions & 0 deletions Source/PawnColumns/PawnColumnWorker_WorkGiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ public override void DoCell(Rect rect, Pawn pawn, PawnTable table) {

WorkGiverDef workgiver = WorkGiver;

if (Settings.highlightCurrentJobCell)
{
bool doingNow = (pawn.CurJob?.workGiverDef?.defName == workgiver?.defName);
if (doingNow)
{
GUI.color = Color.white;
GUI.DrawTexture(rect.ContractedBy(-2f), DrawUtilities.GetCurrentJobHighlightBox());
}
}

// create rect in centre of cell, slightly offsetting left to give the appearance of aligning to worktype.
Vector2 pos = rect.center - (new Vector2( WorkGiverBoxSize, WorkGiverBoxSize ) / 2f);
Rect box = new Rect( pos.x - 2f, pos.y, WorkGiverBoxSize, WorkGiverBoxSize );
Expand Down
12 changes: 11 additions & 1 deletion Source/PawnColumns/PawnColumnWorker_WorkType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ public override void DoCell(Rect rect, Pawn pawn, PawnTable table) {
bool incapable = IncapableOfWholeWorkType( pawn );
WorkTypeDef worktype = def.workType;

if (Settings.highlightCurrentJobCell)
{
bool doingNow = (pawn.CurJob?.workGiverDef?.workType?.defName == worktype?.defName);
if (doingNow)
{
GUI.color = Color.white;
GUI.DrawTexture(rect.ContractedBy(-2f), DrawUtilities.GetCurrentJobHighlightBox());
}
}

// create rect in centre of cell
Vector2 pos = rect.center - (new Vector2( WorkTypeBoxSize, WorkTypeBoxSize ) / 2f);
Rect box = new Rect( pos.x, pos.y, WorkTypeBoxSize, WorkTypeBoxSize );
Expand Down Expand Up @@ -381,7 +391,7 @@ private void HandleInteractionsDetailed(Rect rect, Pawn pawn) {
}

private void HandleInteractionsToggle(Rect rect, Pawn pawn) {
if ((Event.current.type == EventType.MouseDown || Event.current.type == EventType.ScrollWheel)
if ((Event.current.type == EventType.MouseDown || (Event.current.type == EventType.ScrollWheel && !Settings.disableScrollwheel))
&& Mouse.IsOver(rect)) {
// track priority so we can play appropriate sounds
bool active = pawn.GetPriority( def.workType, VisibleHour ) > 0;
Expand Down
2 changes: 2 additions & 0 deletions Source/PawnTable/MainTabWindow_WorkTab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using RimWorld.Planet;
using UnityEngine;
using Verse;
using WorkTab.Extensions;
using static WorkTab.Constants;
using static WorkTab.InteractionUtilities;
using static WorkTab.Resources;
Expand Down Expand Up @@ -122,6 +123,7 @@ public static void SelectWholeDay() {
}

public override void DoWindowContents(Rect rect) {
Instance.Table.set_OutRect(rect);
if (_columnsChanged) {
RebuildTable();
}
Expand Down
6 changes: 5 additions & 1 deletion Source/Priorities/PriorityManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ public class PriorityManager: GameComponent {
private List<PawnPriorityTracker> pawnPriorityTrackersScribe;
private List<Pawn> pawnsScribe;

[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "RimWorld requires a constructor with parameter")]
public PriorityManager(Game game) : this() {
}

public PriorityManager() {
_instance = this;
_nextId = 0;
_showScheduler = false;
priorities = new Dictionary<Pawn, PawnPriorityTracker>();
}

public static PriorityManager Get {
Expand Down Expand Up @@ -90,7 +94,7 @@ public override void ExposeData() {
List<Pawn> pawns = priorities.Keys.ToList();
foreach (Pawn pawn in pawns) {
if (pawn?.Destroyed ?? true) // null or destroyed
{
{
priorities.Remove(pawn);
}
}
Expand Down
1 change: 1 addition & 0 deletions Source/Utilities/DefOf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public static class PawnColumnDefOf {
[MayRequireIdeology] public static PawnColumnDef Guest;
[MayRequireIdeology] public static PawnColumnDef Ideo;
public static PawnColumnDef Job;
public static PawnColumnDef JobText;
public static PawnColumnDef LabelShortWithIcon;
public static PawnColumnDef Mood;
public static PawnColumnDef WorkTabLabel;
Expand Down
Loading

0 comments on commit 0e2955a

Please sign in to comment.