diff --git a/About/About.xml b/About/About.xml
index 015bfc5..946c52f 100644
--- a/About/About.xml
+++ b/About/About.xml
@@ -4,5 +4,5 @@
Pawn Rules
Jaxe
1.0.0
- Mod Version: 1.2.1\n\n\nPawn Rules is a mod that allows custom rules to be assigned individually to your colonists, animals, guests and prisoners.\n\nCurrently the following rules can be applied:\n\n- Disallow certain foods\n- Disallow bonding with certain animals\n- Disallow new romances\n- Disallow constructing items that have a quality level\n\nAny of these rules can be disabled and hidden from the rules window. Rules presets and defaults can be imported and exported between games.
+ Mod Version: 1.2.2\n\n\nPawn Rules is a mod that allows custom rules to be assigned individually to your colonists, animals, guests and prisoners.\n\nCurrently the following rules can be applied:\n\n- Disallow certain foods\n- Disallow bonding with certain animals\n- Disallow new romances\n- Disallow constructing items that have a quality level\n\nAny of these rules can be disabled and hidden from the rules window. Rules presets and defaults can be imported and exported between games.
diff --git a/About/Manifest.xml b/About/Manifest.xml
index 09c91b2..9cac1e5 100644
--- a/About/Manifest.xml
+++ b/About/Manifest.xml
@@ -2,7 +2,7 @@
PawnRules
- 1.2.1
+ 1.2.2
https://raw.githubusercontent.com/Jaxe-Dev/PawnRules/master/About/Manifest.xml
https://github.com/Jaxe-Dev/PawnRules/releases/latest
diff --git a/Languages/English/Keyed/Keys.xml b/Languages/English/Keyed/Keys.xml
index 7a46f03..a58b714 100644
--- a/Languages/English/Keyed/Keys.xml
+++ b/Languages/English/Keyed/Keys.xml
@@ -52,8 +52,8 @@
Unrestricted
Personalized
- Ingestible Policy
- Ingestible Policies
+ Food Policy
+ Food Policies
Ingestibles
Bonding Policy
Bonding Policies
@@ -71,8 +71,8 @@
Persons
Individual
- Ingestible policy: {0}
- Click to choose which ingestibles can be consumed.
+ Food policy: {0}
+ Click to choose which foods, drinks or other ingestibles can be consumed.
Bonding policy: {0}
Click to choose which animals can be bonded with.
Allow Courting
@@ -95,6 +95,7 @@
Global Options
Allow any food when malnourished
Allow any food when training
+ Allow drugs to be restricted
Show {0}
Import/Export Plans
diff --git a/README.md b/README.md
index 472f752..61bfa34 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
# Pawn Rules
-![Mod Version](https://img.shields.io/badge/Mod_Version-1.2.1-blue.svg)
+![Mod Version](https://img.shields.io/badge/Mod_Version-1.2.2-blue.svg)
![RimWorld Version](https://img.shields.io/badge/Built_for_RimWorld-1.0-blue.svg)
![Harmony Version](https://img.shields.io/badge/Powered_by_Harmony-1.2.0.1-blue.svg)\
![Steam Subscribers](https://img.shields.io/badge/dynamic/xml.svg?label=Steam+Subscribers&query=//table/tr[2]/td[1]&colorB=blue&url=https://steamcommunity.com/sharedfiles/filedetails/%3Fid=1499843448&suffix=+total)
diff --git a/Source/Data/Registry.cs b/Source/Data/Registry.cs
index b6e5964..296063e 100644
--- a/Source/Data/Registry.cs
+++ b/Source/Data/Registry.cs
@@ -28,6 +28,7 @@ internal class Registry : WorldObject
public static bool ShowAllowCourting { get => _instance._showAllowCourting; set => _instance._showAllowCourting = value; }
public static bool ShowAllowArtisan { get => _instance._showAllowArtisan; set => _instance._showAllowArtisan = value; }
+ public static bool AllowDrugsRestriction { get => _instance._allowDrugsRestriction; set => _instance._allowDrugsRestriction = value; }
public static bool AllowEmergencyFood { get => _instance._allowEmergencyFood; set => _instance._allowEmergencyFood = value; }
public static bool AllowTrainingFood { get => _instance._allowTrainingFood; set => _instance._allowTrainingFood = value; }
public static Pawn ExemptedTrainer { get => _instance._exemptedTrainer; set => _instance._exemptedTrainer = value; }
@@ -48,6 +49,7 @@ internal class Registry : WorldObject
private bool _showAllowCourting = true;
private bool _showAllowArtisan = true;
+ private bool _allowDrugsRestriction;
private bool _allowEmergencyFood;
private bool _allowTrainingFood;
@@ -324,6 +326,7 @@ public override void ExposeData()
Scribe_Values.Look(ref _showAllowCourting, "showAllowCourting", true);
Scribe_Values.Look(ref _showAllowArtisan, "showAllowArtisan", true);
+ Scribe_Values.Look(ref _allowDrugsRestriction, "allowDrugsRestriction");
Scribe_Values.Look(ref _allowEmergencyFood, "allowEmergencyFood");
Scribe_Values.Look(ref _allowTrainingFood, "allowTrainingFood");
diff --git a/Source/Data/Restriction.cs b/Source/Data/Restriction.cs
index dbb279d..8f8db49 100644
--- a/Source/Data/Restriction.cs
+++ b/Source/Data/Restriction.cs
@@ -36,7 +36,7 @@ public Restriction(XElement xml)
var defs = xml.Element("Defs")?.Elements();
if (defs == null) { return; }
- foreach (var def in defs) { _defs.Add(def.Value); }
+ foreach (var def in defs.Where(def => RestrictionTemplate.IsValidDefName(def.Value, Type))) { _defs.Add(def.Value); }
}
public bool Matches(RestrictionTemplate template) => _defs.SequenceEqual(from category in template.Categories from member in category.Members where !member.Value select member.Def.defName);
@@ -48,7 +48,7 @@ public void Update(RestrictionTemplate template)
}
public bool Allows(Def def) => !_defs.Contains(def.defName);
- public bool AllowsFood(ThingDef def, Pawn pawn) => IsVoid || pawn.InMentalState || !_defs.Contains(def.defName) || (Registry.AllowEmergencyFood && (pawn.health?.hediffSet?.HasHediff(HediffDefOf.Malnutrition) ?? false));
+ public bool AllowsFood(ThingDef def, Pawn pawn) => IsVoid || pawn.InMentalState || (def.IsDrug && !Registry.AllowDrugsRestriction) || !_defs.Contains(def.defName) || (Registry.AllowEmergencyFood && (pawn.health?.hediffSet?.HasHediff(HediffDefOf.Malnutrition) ?? false));
protected override void ExposePresetData()
{
diff --git a/Source/Data/RestrictionTemplate.cs b/Source/Data/RestrictionTemplate.cs
index f17b085..45be0fe 100644
--- a/Source/Data/RestrictionTemplate.cs
+++ b/Source/Data/RestrictionTemplate.cs
@@ -22,6 +22,14 @@ public void ToggleAll(bool value)
}
}
+ public static bool IsValidDefName(string defName, RestrictionType type)
+ {
+ if (type == RestrictionType.Food) { return FoodCache.Any(def => def.defName == defName); }
+ if (type == RestrictionType.Bonding) { return AnimalCache.Any(def => def.defName == defName); }
+
+ throw new Mod.Exception("Invalid restriction type");
+ }
+
private static RestrictionTemplate GetFoodsCategorized(Restriction restriction)
{
var list = new Dictionary { [ThingCategoryDefOf.FoodMeals.LabelCap] = new Category(ThingCategoryDefOf.FoodMeals.LabelCap) };
diff --git a/Source/Interface/Dialog_Alert.cs b/Source/Interface/Dialog_Alert.cs
index 3cd4cb6..70e62a9 100644
--- a/Source/Interface/Dialog_Alert.cs
+++ b/Source/Interface/Dialog_Alert.cs
@@ -40,13 +40,13 @@ public override void DoWindowContents(Rect rect)
var listing = new Listing_Standard();
var vGrid = rect.GetVGrid(4f, -1f, 30f);
- listing.Begin(vGrid[0]);
+ listing.Begin(vGrid[1]);
listing.Label(_message);
listing.End();
- var hGrid = vGrid[1].GetHGrid(4f, 100f, -1f);
+ var hGrid = vGrid[2].GetHGrid(4f, 100f, -1f);
- listing.Begin(_buttons == Buttons.Ok ? vGrid[1] : hGrid[0]);
+ listing.Begin(_buttons == Buttons.Ok ? vGrid[3] : hGrid[1]);
if (listing.ButtonText(_buttons == Buttons.YesNo ? Lang.Get("Button.Yes") : Lang.Get("Button.OK")))
{
@@ -59,7 +59,7 @@ public override void DoWindowContents(Rect rect)
if (_buttons == Buttons.Ok) { return; }
- listing.Begin(hGrid[1]);
+ listing.Begin(hGrid[2]);
if (listing.ButtonText(_buttons == Buttons.YesNo ? Lang.Get("Button.No") : Lang.Get("Button.Cancel"))) { Close(); }
listing.End();
}
diff --git a/Source/Interface/Dialog_Global.cs b/Source/Interface/Dialog_Global.cs
index 9efea8e..72c3fa4 100644
--- a/Source/Interface/Dialog_Global.cs
+++ b/Source/Interface/Dialog_Global.cs
@@ -17,6 +17,7 @@ protected override void DoContent(Rect rect)
var listing = new Listing_StandardPlus();
listing.Begin(rect);
+ Registry.AllowDrugsRestriction = listing.CheckboxLabeled(Lang.Get("Dialog_Global.AllowDrugsRestriction"), Registry.AllowDrugsRestriction);
Registry.AllowEmergencyFood = listing.CheckboxLabeled(Lang.Get("Dialog_Global.AllowEmergencyFood"), Registry.AllowEmergencyFood);
Registry.AllowTrainingFood = listing.CheckboxLabeled(Lang.Get("Dialog_Global.AllowTrainingFood"), Registry.AllowTrainingFood);
diff --git a/Source/Interface/Dialog_Plans.cs b/Source/Interface/Dialog_Plans.cs
index 069e249..e2ba146 100644
--- a/Source/Interface/Dialog_Plans.cs
+++ b/Source/Interface/Dialog_Plans.cs
@@ -57,7 +57,7 @@ protected override void DoContent(Rect rect)
var hasPlans = _plans.Any();
if (hasPlans)
{
- _listing.Begin(vGrid[0], true);
+ _listing.Begin(vGrid[1], true);
foreach (var plan in _plans)
{
if (_listing.RadioButton(plan, _selected == plan)) { _selected = plan; }
@@ -65,17 +65,17 @@ protected override void DoContent(Rect rect)
}
else
{
- _listing.Begin(vGrid[0]);
+ _listing.Begin(vGrid[1]);
_listing.Label(Lang.Get("Dialog_Plans.NoneFound"));
}
_listing.End();
- var tGrid = vGrid[1].GetHGrid(4f, -1f, -1f);
- var bGrid = vGrid[2].GetHGrid(4f, -1f, -1f);
- if (GuiPlus.ButtonText(tGrid[0], Lang.Get("Dialog_Plans.Import"), Lang.Get("Dialog_Plans.ImportDesc"), !_selected.NullOrEmpty())) { LoadPlan(); }
- if (GuiPlus.ButtonText(tGrid[1], Lang.Get("Dialog_Plans.Delete"), Lang.Get("Dialog_Plans.DeleteDesc"), !_selected.NullOrEmpty())) { Dialog_Alert.Open(Lang.Get("Dialog_Plans.ConfirmDelete", _selected), Dialog_Alert.Buttons.YesNo, DeletePlan); }
- if (GuiPlus.ButtonText(bGrid[0], Lang.Get("Dialog_Plans.Export"), Lang.Get("Dialog_Plans.ExportDesc"))) { Dialog_SetName.Open(Lang.Get("Dialog_SetName.PlanTitle"), Lang.Get("Dialog_SetName.PlanLabel"), SavePlan, Persistent.NameIsValid, Persistent.CreateDefaultName()); }
- if (GuiPlus.ButtonText(bGrid[1], "CloseButton".Translate())) { Close(); }
+ var tGrid = vGrid[2].GetHGrid(4f, -1f, -1f);
+ var bGrid = vGrid[3].GetHGrid(4f, -1f, -1f);
+ if (GuiPlus.ButtonText(tGrid[1], Lang.Get("Dialog_Plans.Import"), Lang.Get("Dialog_Plans.ImportDesc"), !_selected.NullOrEmpty())) { LoadPlan(); }
+ if (GuiPlus.ButtonText(tGrid[2], Lang.Get("Dialog_Plans.Delete"), Lang.Get("Dialog_Plans.DeleteDesc"), !_selected.NullOrEmpty())) { Dialog_Alert.Open(Lang.Get("Dialog_Plans.ConfirmDelete", _selected), Dialog_Alert.Buttons.YesNo, DeletePlan); }
+ if (GuiPlus.ButtonText(bGrid[1], Lang.Get("Dialog_Plans.Export"), Lang.Get("Dialog_Plans.ExportDesc"))) { Dialog_SetName.Open(Lang.Get("Dialog_SetName.PlanTitle"), Lang.Get("Dialog_SetName.PlanLabel"), SavePlan, Persistent.NameIsValid, Persistent.CreateDefaultName()); }
+ if (GuiPlus.ButtonText(bGrid[2], "CloseButton".Translate())) { Close(); }
}
}
}
diff --git a/Source/Interface/Dialog_Restrictions.cs b/Source/Interface/Dialog_Restrictions.cs
index dd6de86..8b5a723 100644
--- a/Source/Interface/Dialog_Restrictions.cs
+++ b/Source/Interface/Dialog_Restrictions.cs
@@ -1,4 +1,6 @@
-using PawnRules.Data;
+using System.Collections.Generic;
+using System.Linq;
+using PawnRules.Data;
using PawnRules.Patch;
using UnityEngine;
using Verse;
@@ -55,11 +57,7 @@ void OnAccept()
void OnCancel()
{
- if (_presetList.IsUnsaved)
- {
- //Registry.DeletePreset(_presetList.Selected);
- _presetList.Revert();
- }
+ if (_presetList.IsUnsaved) { _presetList.Revert(); }
base.Close(doCloseSound);
}
@@ -78,96 +76,105 @@ protected override void DoContent(Rect rect)
_color = GUI.color;
var vGrid = rect.GetVGrid(4f, 42f, -1f);
- var hGrid = vGrid[1].GetHGrid(8f, 200f, -1f, -1f);
- DoHeader(vGrid[0]);
+ DoHeader(vGrid[1]);
- _presetList.DoContent(hGrid[0]);
- DoCategories(hGrid[1]);
- DoMembers(hGrid[2]);
+ var hGrid = vGrid[2].GetHGrid(8f, 200f, -1f, -1f);
+ _presetList.DoContent(hGrid[1]);
+ DoCategories(hGrid[2], hGrid[3]);
}
private void DoHeader(Rect rect)
{
var grid = rect.GetHGrid(8f, 200f, -1f, -1f);
- _headerList.Begin(grid[0]);
+ _headerList.Begin(grid[1]);
_headerList.Label(Lang.Get("Preset.Header").Italic().Bold());
_headerList.GapLine();
_headerList.End();
- _headerList.Begin(grid[1]);
+ _headerList.Begin(grid[2]);
_headerList.Label(Lang.Get("Dialog_Restrictions.HeaderCategory").Italic().Bold());
_headerList.GapLine();
_headerList.End();
- _headerList.Begin(grid[2]);
+ _headerList.Begin(grid[3]);
_headerList.Label(_type.Categorization.Italic().Bold());
_headerList.GapLine();
_headerList.End();
}
- private void DoCategories(Rect rect)
+ private void DoCategories(Rect categoriesRect, Rect membersRect)
{
- var vGrid = rect.GetVGrid(4f, -1f, 30f);
- _categoryList.Begin(vGrid[0], true);
+ var vGrid = categoriesRect.GetVGrid(4f, -1f, 30f);
+ _categoryList.Begin(vGrid[1], true);
+
+ var members = new Dictionary();
foreach (var category in _template.Categories)
{
var state = category.GetListState();
+ var showAll = _presetList.EditMode || (_rules.Pawn == null);
+ if (_type == RestrictionType.Food) { members[category.Label] = category.Members.Where(member => member.Def is ThingDef def && (!def.IsDrug || Registry.AllowDrugsRestriction) && (showAll || _rules.Pawn.RaceProps.CanEverEat(def))).ToArray(); }
+ else if (_type == RestrictionType.Bonding) { members[category.Label] = category.Members.ToArray(); }
+ else { throw new Mod.Exception("Unsupported restriction type"); }
+
+ if (members[category.Label].Length == 0) { continue; }
+
if (_presetList.EditMode)
{
_categoryList.CheckboxPartial(category.Label, ref state);
category.UpdateState(state);
- continue;
}
+ else
+ {
+ GUI.color = GuiPlus.ReadOnlyColor;
+ _categoryList.CheckboxPartial(category.Label, ref state);
+ GUI.color = _color;
+ }
+ }
- if ((_type == RestrictionType.Food) && (_rules.Pawn != null) && !category.Members.Any(member => _rules.Pawn.RaceProps.CanEverEat((ThingDef) member.Def))) { continue; }
+ _membersList.Gap();
+ _categoryList.End();
- GUI.color = GuiPlus.ReadOnlyColor;
- _categoryList.CheckboxPartial(category.Label, ref state);
- GUI.color = _color;
+ if (!_presetList.EditMode)
+ {
+ DoMembers(membersRect, members);
+ return;
}
- _categoryList.End();
- if (!_presetList.EditMode) { return; }
+ var hGrid = vGrid[2].GetHGrid(4f, -1f, -1f);
+ var categoryButtons = new Listing_Standard();
+ categoryButtons.Begin(hGrid[1]);
+ if (categoryButtons.ButtonText(Lang.Get("Button.RestrictionsAllowOn"))) { _template.ToggleAll(true); }
+ categoryButtons.End();
+ categoryButtons.Begin(hGrid[2]);
+ if (categoryButtons.ButtonText(Lang.Get("Button.RestrictionsAllowOff"))) { _template.ToggleAll(false); }
+ categoryButtons.End();
- var hGrid = vGrid[1].GetHGrid(4f, -1f, -1f);
- _categoryList.Begin(hGrid[0]);
- if (_categoryList.ButtonText(Lang.Get("Button.RestrictionsAllowOn"))) { _template.ToggleAll(true); }
- _categoryList.End();
- _categoryList.Begin(hGrid[1]);
- if (_categoryList.ButtonText(Lang.Get("Button.RestrictionsAllowOff"))) { _template.ToggleAll(false); }
- _categoryList.End();
+ DoMembers(membersRect, members);
}
- private void DoMembers(Rect rect)
+ private void DoMembers(Rect membersRect, Dictionary categories)
{
- _membersList.Begin(rect, true);
+ _membersList.Begin(membersRect, true);
- foreach (var category in _template.Categories)
+ foreach (var category in categories.Where(category => category.Value.Length > 0))
{
- if ((_type == RestrictionType.Food) && (_rules.Pawn != null) && !category.Members.Any(member => _rules.Pawn.RaceProps.CanEverEat((ThingDef) member.Def))) { continue; }
-
- _membersList.LabelTiny(category.Label.Bold());
+ _membersList.LabelTiny(category.Key.Bold());
- foreach (var member in category.Members)
+ foreach (var member in category.Value)
{
- if (_presetList.EditMode)
+ if (_presetList.EditMode) { _membersList.CheckboxLabeled(member.Def.LabelCap, ref member.Value, member.Def.description); }
+ else
{
- _membersList.CheckboxLabeled(member.Def.LabelCap, ref member.Value, member.Def.description);
- continue;
+ GUI.color = GuiPlus.ReadOnlyColor;
+ _membersList.CheckboxLabeled(member.Def.LabelCap, ref member.Value, member.Def.description, false);
+ GUI.color = _color;
}
-
- if ((_type == RestrictionType.Food) && (_rules.Pawn != null) && !_rules.Pawn.RaceProps.CanEverEat((ThingDef) member.Def)) { continue; }
-
- GUI.color = GuiPlus.ReadOnlyColor;
- _membersList.CheckboxLabeled(member.Def.LabelCap, ref member.Value, member.Def.description, false);
- GUI.color = _color;
}
-
- _membersList.Gap();
}
+ _membersList.Gap();
_membersList.End();
}
}
diff --git a/Source/Interface/Dialog_Rules.cs b/Source/Interface/Dialog_Rules.cs
index e82dae2..6963ef5 100644
--- a/Source/Interface/Dialog_Rules.cs
+++ b/Source/Interface/Dialog_Rules.cs
@@ -202,16 +202,16 @@ protected override void DoContent(Rect rect)
var listing = new Listing_StandardPlus();
var hGrid = rect.GetHGrid(8f, 200f, -1f);
- var lGrid = hGrid[0].GetVGrid(4f, 42f, -1f);
+ var lGrid = hGrid[1].GetVGrid(4f, 42f, -1f);
- listing.Begin(lGrid[0]);
+ listing.Begin(lGrid[1]);
listing.Label(Lang.Get("Preset.Header").Italic().Bold());
listing.GapLine();
listing.End();
- _preset.DoContent(lGrid[1]);
+ _preset.DoContent(lGrid[2]);
- var vGrid = hGrid[1].GetVGrid(4f, 42f, -1f, 62f);
- listing.Begin(vGrid[0]);
+ var vGrid = hGrid[2].GetVGrid(4f, 42f, -1f, 62f);
+ listing.Begin(vGrid[1]);
listing.Label(Lang.Get("Dialog_Rules.Configuration").Italic().Bold());
listing.GapLine();
listing.End();
@@ -221,7 +221,7 @@ protected override void DoContent(Rect rect)
var color = GUI.color;
if (!editMode) { GUI.color = GuiPlus.ReadOnlyColor; }
- listing.Begin(vGrid[1]);
+ listing.Begin(vGrid[2]);
if (Registry.ShowFoodPolicy && listing.ButtonText(Lang.Get("Rules.FoodRestrictions", GetRestrictionDisplayName(_template.GetRestriction(RestrictionType.Food))), Lang.Get("Rules.FoodRestrictionsDesc")) && editMode) { ChangeRestriction(RestrictionType.Food); }
if (_template.Type == PawnType.Colonist)
{
@@ -238,7 +238,7 @@ protected override void DoContent(Rect rect)
if (_template.HasAddons)
{
- var addonsRect = vGrid[1].GetVGrid(4f, listing.CurHeight, -1f)[1];
+ var addonsRect = vGrid[2].GetVGrid(4f, listing.CurHeight, -1f)[2];
_addons.Begin(addonsRect, addonsRect.height <= _template.AddonsRectHeight);
GuiPlus.DoAddonsListing(_addons, _template, editMode);
_addons.End();
@@ -246,12 +246,12 @@ protected override void DoContent(Rect rect)
GUI.color = color;
- var optionGrid = vGrid[2].GetVGrid(2f, -1f, -1f);
- listing.Begin(optionGrid[0]);
+ var optionGrid = vGrid[3].GetVGrid(2f, -1f, -1f);
+ listing.Begin(optionGrid[1]);
if (listing.ButtonText(Lang.Get("Button.AssignTo"), Lang.Get("Button.AssignToDesc"), (_floatMenuAssign.Count > 0) && (!editMode || (_template == _personalized)))) { Find.WindowStack.Add(new FloatMenu(_floatMenuAssign)); }
listing.End();
- listing.Begin(optionGrid[1]);
+ listing.Begin(optionGrid[2]);
if (listing.ButtonText(_type == null ? Lang.Get("Button.ViewType", Lang.Get("PawnType.Individual")) : Lang.Get("Button.ViewTypeDefault", _type.LabelPlural), Lang.Get("Button.ViewTypeDesc"), !editMode || (_template == _personalized))) { Find.WindowStack.Add(new FloatMenu(_floatMenuViews)); }
listing.End();
diff --git a/Source/Interface/Dialog_SetName.cs b/Source/Interface/Dialog_SetName.cs
index 5918d8e..1476f0d 100644
--- a/Source/Interface/Dialog_SetName.cs
+++ b/Source/Interface/Dialog_SetName.cs
@@ -56,11 +56,11 @@ protected override void DoContent(Rect rect)
var grid = rect.AdjustedBy(0f, listing.CurHeight, 0f, -listing.CurHeight).GetHGrid(4f, -1f, -1f);
- listing.Begin(grid[0]);
+ listing.Begin(grid[1]);
if (listing.ButtonText(Lang.Get("Button.OK"), null, NameIsValid())) { CommitName(); }
listing.End();
- listing.Begin(grid[1]);
+ listing.Begin(grid[2]);
if (listing.ButtonText(Lang.Get("Button.Cancel"))) { Close(); }
listing.End();
}
diff --git a/Source/Interface/Listing_Preset.cs b/Source/Interface/Listing_Preset.cs
index 6ff2adb..88f13ea 100644
--- a/Source/Interface/Listing_Preset.cs
+++ b/Source/Interface/Listing_Preset.cs
@@ -59,7 +59,7 @@ public void DoContent(Rect rect)
var presetGrid = rect.GetVGrid(4f, _listing.CurHeight, -1f, 62f);
- _presetListing.Begin(presetGrid[1], true);
+ _presetListing.Begin(presetGrid[2], true);
foreach (var preset in presets)
{
var isSelected = (Selected == preset) || (Selected.Name == preset.Name);
@@ -67,8 +67,8 @@ public void DoContent(Rect rect)
}
_presetListing.End();
- var buttonGrid = presetGrid[2].GetHGrid(4f, -1f, -1f);
- _listing.Begin(buttonGrid[0]);
+ var buttonGrid = presetGrid[3].GetHGrid(4f, -1f, -1f);
+ _listing.Begin(buttonGrid[1]);
if (_listing.ButtonText(Lang.Get("Button.PresetNew"), Lang.Get("Button.PresetNewDesc"), !EditMode)) { Presetable.SetName(Type, CreatePreset); }
@@ -91,7 +91,7 @@ public void DoContent(Rect rect)
}
_listing.End();
- _listing.Begin(buttonGrid[1]);
+ _listing.Begin(buttonGrid[2]);
if (_listing.ButtonText(Lang.Get("Button.PresetDelete"), Lang.Get("Button.PresetDeleteDesc"), !Selected.IsVoid && Selected.IsPreset && !EditMode)) { Dialog_Alert.Open(Lang.Get("Button.PresetDeleteConfirm", Selected.Name), Dialog_Alert.Buttons.YesNo, DeletePreset); }
diff --git a/Source/Mod.cs b/Source/Mod.cs
index 0f547ff..dd96430 100644
--- a/Source/Mod.cs
+++ b/Source/Mod.cs
@@ -13,7 +13,7 @@ internal class Mod : Verse.Mod
{
public const string Id = "PawnRules";
public const string Name = "Pawn Rules";
- public const string Version = "1.2.1";
+ public const string Version = "1.2.2";
public static readonly DirectoryInfo ConfigDirectory = new DirectoryInfo(Path.Combine(GenFilePaths.ConfigFolderPath, Id));
@@ -40,7 +40,7 @@ public Mod(ModContentPack contentPack) : base(contentPack)
public override string SettingsCategory() => Name;
public override void DoSettingsWindowContents(Rect inRect)
{
- var rect = inRect.GetHGrid(1f, -1f, 400f, -1f)[1];
+ var rect = inRect.GetHGrid(1f, -1f, 400f, -1f)[2];
var listing = new Listing_Standard();
listing.Begin(rect);
diff --git a/Source/Patch/Extensions.cs b/Source/Patch/Extensions.cs
index 1ede6ef..6e95ba4 100644
--- a/Source/Patch/Extensions.cs
+++ b/Source/Patch/Extensions.cs
@@ -1,4 +1,5 @@
using System.Collections;
+using System.Collections.Generic;
using PawnRules.Data;
using RimWorld;
using UnityEngine;
@@ -30,13 +31,15 @@ public static PawnType GetTargetType(this Pawn self)
public static string GetDisplayName(this Presetable self) => self == null ? Lang.Get("Preset.None") : self.Name ?? Lang.Get("Preset.Personalized");
public static Rect AdjustedBy(this Rect self, float x, float y, float width, float height) => new Rect(self.x + x, self.y + y, self.width + width, self.height + height);
+ public static Rect Round(this Rect self) => new Rect(Mathf.Round(self.x), Mathf.Round(self.y), Mathf.Round(self.width), Mathf.Round(self.height));
- public static Rect[] GetHGrid(this Rect self, float spacing, params float[] widths)
+ public static Rect[] GetHGrid(this Rect self, float padding, params float[] widths)
{
var unfixedCount = 0;
var currentX = self.x;
var fixedWidths = 0f;
- var rects = new Rect[widths.Length];
+
+ var rects = new List { self };
for (var index = 0; index < widths.Length; index++)
{
@@ -44,37 +47,38 @@ public static Rect[] GetHGrid(this Rect self, float spacing, params float[] widt
if (width >= 0f) { fixedWidths += width; }
else { unfixedCount++; }
- if (index != widths.LastIndex()) { fixedWidths += spacing; }
+ if (index != widths.LastIndex()) { fixedWidths += padding; }
}
- var unfixedWidth = unfixedCount > 0 ? (self.width - fixedWidths) / unfixedCount : 0f;
+ var unfixedWidth = unfixedCount > 0 ? Mathf.Max(0f, (self.width - fixedWidths) / unfixedCount) : 0f;
- for (var index = 0; index < widths.Length; index++)
+ foreach (var width in widths)
{
- var width = widths[index];
float newWidth;
+
if (width >= 0f)
{
newWidth = width;
- rects[index] = new Rect(currentX, self.y, newWidth, self.height);
+ rects.Add(new Rect(currentX, self.y, newWidth, self.height).Round());
}
else
{
newWidth = unfixedWidth;
- rects[index] = new Rect(currentX, self.y, newWidth, self.height);
+ rects.Add(new Rect(currentX, self.y, newWidth, self.height).Round());
}
- currentX += newWidth + spacing;
+
+ currentX = Mathf.Min(self.xMax, currentX + newWidth + (newWidth > 0f ? padding : 0f));
}
- return rects;
+ return rects.ToArray();
}
-
- public static Rect[] GetVGrid(this Rect self, float spacing, params float[] heights)
+ public static Rect[] GetVGrid(this Rect self, float padding, params float[] heights)
{
var unfixedCount = 0;
var currentY = self.y;
var fixedHeights = 0f;
- var rects = new Rect[heights.Length];
+
+ var rects = new List { self };
for (var index = 0; index < heights.Length; index++)
{
@@ -82,29 +86,31 @@ public static Rect[] GetVGrid(this Rect self, float spacing, params float[] heig
if (height >= 0f) { fixedHeights += height; }
else { unfixedCount++; }
- if (index != heights.LastIndex()) { fixedHeights += spacing; }
+ if (index != heights.LastIndex()) { fixedHeights += padding; }
}
- var unfixedWidth = unfixedCount > 0 ? (self.height - fixedHeights) / unfixedCount : 0f;
+ var unfixedHeight = unfixedCount > 0 ? Mathf.Max(0f, (self.height - fixedHeights) / unfixedCount) : 0f;
- for (var index = 0; index < heights.Length; index++)
+ foreach (var height in heights)
{
- var height = heights[index];
float newHeight;
+
if (height >= 0f)
{
newHeight = height;
- rects[index] = new Rect(self.x, currentY, self.width, newHeight);
+ rects.Add(new Rect(self.x, currentY, self.width, newHeight).Round());
}
else
{
- newHeight = unfixedWidth;
- rects[index] = new Rect(self.x, currentY, self.width, newHeight);
+ newHeight = unfixedHeight;
+ rects.Add(new Rect(self.x, currentY, self.width, newHeight).Round());
}
- currentY += newHeight + spacing;
+
+ currentY = Mathf.Min(self.yMax, currentY + newHeight + (newHeight > 0f ? padding : 0f));
}
- return rects;
+ return rects.ToArray();
}
+
}
}