diff --git a/Languages/English/Keyed/Manager_Keyed.xml b/Languages/English/Keyed/Manager_Keyed.xml
index 8e8cb447..e7e9c63f 100644
--- a/Languages/English/Keyed/Manager_Keyed.xml
+++ b/Languages/English/Keyed/Manager_Keyed.xml
@@ -167,6 +167,10 @@
Training
Restrict animals to area?
Restrict animals to a specific area, optionally separated by gender and lifestage
+ Restrict hungry animals
+ Restrict hungry animals to a specific area, optionally separated by gender and lifestage, as long as they are not restricted animals marked for slaughter.
+ Animal Food Need
+ An animal whose food need is below or equal to this value will be restricted to this area.
Butcher excess livestock
Should excess livestock be butchered for meat?
Trained
diff --git a/Source/Helpers/Utilities.cs b/Source/Helpers/Utilities.cs
index ff57f044..23a4bbc6 100644
--- a/Source/Helpers/Utilities.cs
+++ b/Source/Helpers/Utilities.cs
@@ -327,6 +327,22 @@ public static void DrawToggle( Rect rect, string label, string tooltip, bool che
DrawToggle( rect, label, tooltip, checkOn, !checkOn, on, off, expensive, size, margin, wrap );
}
+ public static void DrawSlider(Rect rect, string label, string tooltip, ref float value, float size = 5*SmallIconSize,
+ float margin = Margin, bool wrap = true)
+ {
+ // set up rects
+ var labelRect = rect;
+ var sliderRect = new Rect(rect.xMax - size - margin, 0f, size, labelRect.height/2f);
+ labelRect.xMax = sliderRect.xMin - Margin / 2f;
+ // finetune rects
+ sliderRect = sliderRect.CenteredOnYIn(labelRect);
+ // draw label
+ Label(rect, label, TextAnchor.MiddleLeft, GameFont.Small, margin: margin, wrap: wrap);
+ // tooltip
+ if (!tooltip.NullOrEmpty()) TooltipHandler.TipRegion(rect, tooltip );
+ // draw slider
+ value = Widgets.HorizontalSlider(sliderRect, value, 0f, 1f, true, String.Format("{0:P0}", value)); // GUI.HorizontalSlider(sliderRect, value, 0f, 1f);
+ }
public static void DrawToggle( Rect rect, string label, string tooltip, bool checkOn, bool checkOff, Action on,
Action off, bool expensive = false, float size = SmallIconSize,
diff --git a/Source/ManagerJobs/ManagerJob_Livestock.cs b/Source/ManagerJobs/ManagerJob_Livestock.cs
index 1443bc21..35f1e0b1 100644
--- a/Source/ManagerJobs/ManagerJob_Livestock.cs
+++ b/Source/ManagerJobs/ManagerJob_Livestock.cs
@@ -31,6 +31,9 @@ public class ManagerJob_Livestock : ManagerJob
public bool RespectBonds = true;
public List RestrictArea;
public bool RestrictToArea;
+ public List RestrictHungryArea;
+ public bool RestrictToHungryArea;
+ public float SendToHungryAreaMaximumFoodNeed;
public bool SendToSlaughterArea;
public bool SendToTrainingArea;
public bool SetFollow;
@@ -72,6 +75,11 @@ public ManagerJob_Livestock( Manager manager ) : base( manager )
RestrictToArea = false;
RestrictArea = Utilities_Livestock.AgeSexArray.Select( k => (Area) null ).ToList();
+ // set hungry animals areas for restriction
+ RestrictToHungryArea = false;
+ SendToHungryAreaMaximumFoodNeed = 0.01f;
+ RestrictHungryArea = Utilities_Livestock.AgeSexArray.Select(k => (Area)null).ToList();
+
// set up sending animals designated for slaughter to an area (freezer)
SendToSlaughterArea = false;
SlaughterArea = null;
@@ -141,6 +149,7 @@ public override void ExposeData()
Scribe_References.Look( ref Master, "Master" );
Scribe_References.Look( ref Trainer, "Trainer" );
Scribe_Collections.Look( ref RestrictArea, "AreaRestrictions", LookMode.Reference );
+ Scribe_Collections.Look(ref RestrictHungryArea, "HungryAreaRestrictions", LookMode.Reference);
Scribe_Deep.Look( ref Trigger, "trigger", manager );
Scribe_Deep.Look( ref Training, "Training" );
Scribe_Deep.Look( ref _history, "History" );
@@ -149,6 +158,8 @@ public override void ExposeData()
Scribe_Values.Look( ref ButcherPregnant, "ButcherPregnant" );
Scribe_Values.Look( ref ButcherBonded, "ButcherBonded" );
Scribe_Values.Look( ref RestrictToArea, "RestrictToArea" );
+ Scribe_Values.Look( ref RestrictToHungryArea, "RestrictToHungryArea", false);
+ Scribe_Values.Look( ref SendToHungryAreaMaximumFoodNeed, "SendToHungryAreaMaximumFoodNeed", 0.01f);
Scribe_Values.Look( ref SendToSlaughterArea, "SendToSlaughterArea" );
Scribe_Values.Look( ref SendToTrainingArea, "SendToTrainingArea" );
Scribe_Values.Look( ref TryTameMore, "TryTameMore" );
@@ -221,6 +232,12 @@ private void DoAreaRestrictions( ref bool actionTaken )
p.playerSettings.AreaRestriction = SlaughterArea;
}
+ // hungry
+ else if (RestrictToHungryArea && p.needs.food.CurLevelPercentage <= SendToHungryAreaMaximumFoodNeed)
+ {
+ actionTaken = true;
+ p.playerSettings.AreaRestriction = RestrictHungryArea[i];
+ }
// training
else if ( SendToTrainingArea && p.training.NextTrainableToTrain() != null )
{
diff --git a/Source/ManagerTabs/ManagerTab_Livestock.cs b/Source/ManagerTabs/ManagerTab_Livestock.cs
index b3a4d262..8f9024d1 100644
--- a/Source/ManagerTabs/ManagerTab_Livestock.cs
+++ b/Source/ManagerTabs/ManagerTab_Livestock.cs
@@ -361,44 +361,8 @@ private float DrawAreaRestrictionsSection( Vector2 pos, float width )
if ( _selectedCurrent.RestrictToArea )
{
- // area selectors table
- // set up a 3x3 table of rects
- var cols = 3;
- var fifth = width / 5;
- float[] widths = {fifth, fifth * 2, fifth * 2};
- float[] heights = {ListEntryHeight * 2 / 3, ListEntryHeight, ListEntryHeight};
-
- var areaRects = new Rect[cols, cols];
- for ( var x = 0; x < cols; x++ )
- for ( var y = 0; y < cols; y++ )
- areaRects[x, y] = new Rect(
- widths.Take( x ).Sum(),
- pos.y + heights.Take( y ).Sum(),
- widths[x],
- heights[y] );
-
- // headers
- Label( areaRects[1, 0], Gender.Female.ToString(), TextAnchor.LowerCenter, GameFont.Tiny );
- Label( areaRects[2, 0], Gender.Male.ToString(), TextAnchor.LowerCenter, GameFont.Tiny );
- Label( areaRects[0, 1], "FML.Adult".Translate(), TextAnchor.MiddleRight, GameFont.Tiny );
- Label( areaRects[0, 2], "FML.Juvenile".Translate(), TextAnchor.MiddleRight, GameFont.Tiny );
-
- // do the selectors
- _selectedCurrent.RestrictArea[0] = AreaAllowedGUI.DoAllowedAreaSelectors( areaRects[1, 1],
- _selectedCurrent.RestrictArea[
- 0], manager, Margin );
- _selectedCurrent.RestrictArea[1] = AreaAllowedGUI.DoAllowedAreaSelectors( areaRects[2, 1],
- _selectedCurrent.RestrictArea[
- 1], manager, Margin );
- _selectedCurrent.RestrictArea[2] = AreaAllowedGUI.DoAllowedAreaSelectors( areaRects[1, 2],
- _selectedCurrent.RestrictArea[
- 2], manager, Margin );
- _selectedCurrent.RestrictArea[3] = AreaAllowedGUI.DoAllowedAreaSelectors( areaRects[2, 2],
- _selectedCurrent.RestrictArea[
- 3], manager, Margin );
-
- Text.Anchor = TextAnchor.UpperLeft; // DoAllowedAreaMode leaves the anchor in an incorrect state.
- pos.y += 3 * ListEntryHeight;
+ DrawAreaSelectorPerGenderAndAge(pos, width, ref _selectedCurrent.RestrictArea);
+ pos.y += 3 * ListEntryHeight;
}
var sendToSlaughterAreaRect = new Rect( pos.x, pos.y, width, ListEntryHeight );
@@ -426,6 +390,29 @@ private float DrawAreaRestrictionsSection( Vector2 pos, float width )
color: Color.grey );
}
+ // restrict to hungry area
+ var RestrictHungryAreaRect = new Rect(pos.x, pos.y, width, ListEntryHeight);
+
+ DrawToggle(RestrictHungryAreaRect,
+ "FML.RestrictToHungryArea".Translate(),
+ "FML.RestrictToHungryArea.Tip".Translate(),
+ ref _selectedCurrent.RestrictToHungryArea);
+ pos.y += ListEntryHeight;
+ if (_selectedCurrent.RestrictToHungryArea)
+ {
+ if (_selectedCurrent.RestrictHungryArea.Count != _selectedCurrent.RestrictArea.Count)
+ {
+ _selectedCurrent.RestrictHungryArea = Utilities_Livestock.AgeSexArray.Select(k => (Area)null).ToList();
+ }
+ DrawAreaSelectorPerGenderAndAge(pos, width, ref _selectedCurrent.RestrictHungryArea);
+ pos.y += 3 * ListEntryHeight;
+ var HungryAreaFoodFullness = new Rect(pos.x, pos.y, width, ListEntryHeight);
+ HungryAreaFoodFullness.xMin += 3 * Margin;
+ DrawSlider(HungryAreaFoodFullness, "FML.SendToHungryAreaMaximumFoodNeed.Label".Translate(), "FML.SendToHungryAreaMaximumFoodNeed.Tip".Translate(),
+ ref _selectedCurrent.SendToHungryAreaMaximumFoodNeed);
+ pos.y += ListEntryHeight;
+ }
+
var sendToTrainingAreaRect = new Rect( pos.x, pos.y, width, ListEntryHeight );
pos.y += ListEntryHeight;
if ( _selectedCurrent.Training.Any )
@@ -454,6 +441,41 @@ private float DrawAreaRestrictionsSection( Vector2 pos, float width )
return pos.y - start.y;
}
+
+
+ private void DrawAreaSelectorPerGenderAndAge(Vector2 pos, float width, ref List restrictArea)
+ {
+ // area selectors table
+ // set up a 3x3 table of rects
+ var cols = 3;
+ var fifth = width / 5;
+ float[] widths = { fifth, fifth * 2, fifth * 2 };
+ float[] heights = { ListEntryHeight * 2 / 3, ListEntryHeight, ListEntryHeight };
+
+ var areaRects = new Rect[cols, cols];
+ for (var x = 0; x < cols; x++)
+ for (var y = 0; y < cols; y++)
+ areaRects[x, y] = new Rect(
+ widths.Take(x).Sum(),
+ pos.y + heights.Take(y).Sum(),
+ widths[x],
+ heights[y]);
+
+ // headers
+ Label(areaRects[1, 0], Gender.Female.ToString(), TextAnchor.LowerCenter, GameFont.Tiny);
+ Label(areaRects[2, 0], Gender.Male.ToString(), TextAnchor.LowerCenter, GameFont.Tiny);
+ Label(areaRects[0, 1], "FML.Adult".Translate(), TextAnchor.MiddleRight, GameFont.Tiny);
+ Label(areaRects[0, 2], "FML.Juvenile".Translate(), TextAnchor.MiddleRight, GameFont.Tiny);
+
+ // do the selectors
+ restrictArea[0] = AreaAllowedGUI.DoAllowedAreaSelectors(areaRects[1, 1], restrictArea[0], manager, Margin);
+ restrictArea[1] = AreaAllowedGUI.DoAllowedAreaSelectors(areaRects[2, 1], restrictArea[1], manager, Margin);
+ restrictArea[2] = AreaAllowedGUI.DoAllowedAreaSelectors(areaRects[1, 2], restrictArea[2], manager, Margin);
+ restrictArea[3] = AreaAllowedGUI.DoAllowedAreaSelectors(areaRects[2, 2], restrictArea[3], manager, Margin);
+
+ Text.Anchor = TextAnchor.UpperLeft; // DoAllowedAreaMode leaves the anchor in an incorrect state.
+ }
+
private float DrawTrainingSection( Vector2 pos, float width )
{
var trainingRect = new Rect( pos.x, pos.y, width, ListEntryHeight );