Skip to content

Commit

Permalink
v1.1.4
Browse files Browse the repository at this point in the history
- Better optimization of data
- Re-fixed "Could not find player faction bug"
- Added support for upcoming version of RimHUD
  • Loading branch information
Jaxe-Dev committed Sep 21, 2018
1 parent 2b95ab3 commit 819e0d2
Show file tree
Hide file tree
Showing 25 changed files with 110 additions and 105 deletions.
2 changes: 1 addition & 1 deletion About/About.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
<name>Pawn Rules</name>
<author>Jaxe</author>
<targetVersion>0.19.0</targetVersion>
<description>Mod Version: 1.1.3\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.</description>
<description>Mod Version: 1.1.4\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.</description>
<url>https://github.com/Jaxe-Dev/PawnRules</url>
</ModMetaData>
2 changes: 1 addition & 1 deletion About/ModSync.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<ModSyncNinjaData>
<ID>59f538ed-f86d-4506-a4a5-7e9faaa37508</ID>
<ModName>Pawn Rules</ModName>
<Version>v1.1.3</Version>
<Version>v1.1.4</Version>
<SaveBreaking>False</SaveBreaking>
<Host name="Github">
<Owner>Jaxe-Dev</Owner>
Expand Down
Binary file modified About/Preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Languages/English/Keyed/Keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,5 @@
<PawnRules.Dialog_SetName.PlanLabel>Choose a name for this plan:</PawnRules.Dialog_SetName.PlanLabel>

<PawnRules.Settings.NoGame>There are no settings for this mod outside of a game.</PawnRules.Settings.NoGame>

</LanguageData>
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Pawn Rules
![](https://img.shields.io/badge/Mod_Version-1.1.3-blue.svg)
![](https://img.shields.io/badge/Mod_Version-1.1.4-blue.svg)
![](https://img.shields.io/badge/Built_for_RimWorld-B19-blue.svg)
![](https://img.shields.io/badge/Powered_by_Harmony-1.2.0.1-blue.svg)

Expand Down Expand Up @@ -62,10 +62,9 @@ Prefix : RimWorld.RelationsUtility.TryDevelopBondRelation
Prefix : RimWorld.WorkGiver_InteractAnimal.HasFoodToInteractAnimal
Prefix : RimWorld.WorkGiver_InteractAnimal.TakeFoodForAnimalInteractJob
Postfix : Verse.Game.FinalizeInit
Prefix : Verse.Game.InitNewGame
Prefix : Verse.Game.LoadGame
Postfix : Verse.Pawn.GetGizmos
Postfix : Verse.Pawn.Kill
Prefix : Verse.Pawn.SetFaction
Postfix : Verse.PawnGenerator.GeneratePawn
Prefix : Verse.Profile.MemoryUtility.ClearAllMapsAndWorld
```
4 changes: 2 additions & 2 deletions Source/API/OptionHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ public bool IsUsedBy(Pawn pawn)

internal void ChangeValue<T>(Pawn pawn, T newValue)
{
var handle = this as OptionHandle<T>;
if (!(this is OptionHandle<T> handle)) { throw new Mod.Exception($"Invalid OptionHandle for type {typeof(T).Name}"); }
handle.SetValue(pawn, handle.OnChangeForPawnForPawn == null ? newValue : handle.OnChangeForPawnForPawn(pawn, handle.GetValue(pawn), newValue));
}

internal void ChangePresetValue<T>(Rules rules, T newValue)
{
var handle = this as OptionHandle<T>;
if (!(this is OptionHandle<T> handle)) { throw new Mod.Exception($"Invalid OptionHandle for type {typeof(T).Name}"); }
rules.SetAddonValueDirect(handle.Addon, handle.OnChangeForForPreset == null ? newValue : handle.OnChangeForForPreset(rules.Type.AsTarget, rules.GetAddonValue(handle.Addon, (T) handle.Addon.DefaultValue), newValue));
}

Expand Down
11 changes: 6 additions & 5 deletions Source/Data/Registry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,20 @@ internal class Registry : WorldObject
private const string WorldObjectDefName = "PawnRules_Registry";
private const string CurrentVersion = "v" + Mod.Version;

public static bool IsActive => !_isDeactivating && (_instance != null) && (Current.Game != null);
public static bool IsActive => !_isDeactivating && (_instance != null) && (Find.GameInitData.playerFaction != null);

private static Registry _instance;

private static bool _isDeactivating;


public static bool ShowFoodPolicy { get => _instance._showFoodPolicy; set => _instance._showFoodPolicy = value; }
public static bool ShowBondingPolicy { get => _instance._showBondingPolicy; set => _instance._showBondingPolicy = value; }
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 AllowEmergencyFood { get => _instance._allowEmergencyFood; set => _instance._allowEmergencyFood = value; }
public static bool AllowTrainingFood { get => _instance._allowTrainingFood; set => _instance._allowTrainingFood = value; }
public static Pawn ExemptedTrainer { get; set; }
public static Pawn ExemptedTrainer { get => _instance._exemptedTrainer; set => _instance._exemptedTrainer = value; }

private string _loadedVersion;

Expand All @@ -52,6 +51,8 @@ internal class Registry : WorldObject
private bool _allowEmergencyFood;
private bool _allowTrainingFood;

private Pawn _exemptedTrainer;

public static void Initialize()
{
var worldObjects = Current.Game.World.worldObjects;
Expand All @@ -67,7 +68,7 @@ public static void Initialize()
worldObjects.Add(instance);
}

public static void Reset() => _instance = null;
public static void Clear() => _instance = null;

public static T GetVoidPreset<T>(IPresetableType type) where T : Presetable => (T) _instance._voidPresets[typeof(T)][type];

Expand Down Expand Up @@ -372,7 +373,7 @@ public static void FromXml(XElement xml)
var version = xml.Attribute("Version")?.Value;
if (version != CurrentVersion) { Mod.Warning($"Loaded xml from a different mod version ({version ?? "vNULL"} loaded, current is {CurrentVersion})"); }

var presets = xml.Element("Presets")?.Elements();
var presets = xml.Element("Presets")?.Elements().ToArray();
if (presets == null) { return; }

foreach (var restriction in presets.Where(preset => preset.Name == "Restriction").Select(preset => new Restriction(preset))) { AddPreset(restriction); }
Expand Down
2 changes: 1 addition & 1 deletion Source/Data/Restriction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public Restriction(XElement xml)
return;
}

Type = RestrictionType.FromId(xml.Attribute("Type").Value);
Type = RestrictionType.FromId(xml.Attribute("Type")?.Value);
if (Type == null)
{
Mod.Warning("Skipping invalid restriction type");
Expand Down
2 changes: 1 addition & 1 deletion Source/Data/RestrictionTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal class RestrictionTemplate
private static readonly ThingDef[] FoodCache = DefDatabase<ThingDef>.AllDefs.Where(food => food.IsNutritionGivingIngestible).ToList().OrderBy(food => food.category).ThenBy(food => food.FirstThingCategory?.index).ThenBy(food => food.label).ToArray();
public readonly IEnumerable<Category> Categories;

public RestrictionTemplate(IEnumerable<Category> list) => Categories = list;
private RestrictionTemplate(IEnumerable<Category> list) => Categories = list;

public void ToggleAll(bool value)
{
Expand Down
4 changes: 2 additions & 2 deletions Source/Data/Rules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public Rules(XElement xml)
return;
}

Type = PawnType.FromId(xml.Attribute("Type").Value);
Type = PawnType.FromId(xml.Attribute("Type")?.Value);
if (Type == null)
{
Mod.Warning("Skipping invalid rules preset type");
Expand All @@ -53,7 +53,7 @@ public Rules(XElement xml)
{
foreach (var restriction in restrictions)
{
var type = RestrictionType.FromId(restriction.Attribute("Type").Value);
var type = RestrictionType.FromId(restriction.Attribute("Type")?.Value);
if (type == null)
{
Mod.Warning("Skipping invalid restriction type in rules preset");
Expand Down
19 changes: 19 additions & 0 deletions Source/Integration/HugsLib.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Linq;
using System.Reflection;
using Harmony;

namespace PawnRules.Integration
{
internal static class HugsLib
{
public static void RegisterUpdateFeature()
{
var hugsLib = (from assembly in AppDomain.CurrentDomain.GetAssemblies() from type in assembly.GetTypes() where type.Name == "HugsLibController" select type).FirstOrDefault();
if (hugsLib == null) { return; }

var version = Assembly.GetExecutingAssembly().GetName().Version;
Traverse.Create(hugsLib).Field("instance")?.Property("UpdateFeatures")?.Method("InspectActiveMod", Mod.Id, version)?.GetValue();
}
}
}
21 changes: 21 additions & 0 deletions Source/Integration/RimHUD.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using PawnRules.Data;
using Verse;

namespace PawnRules.Integration
{
internal static class RimHUD
{
public static bool HideGizmo { get; set; } = false;

public static string GetRulesInfo(Pawn pawn)
{
if (!Registry.IsActive) { return null; }

var rules = Registry.GetRules(pawn);
if (rules == null) { return null; }

var name = rules.IsPreset ? rules.Name : Lang.Get("Preset.Personalized");
return name;
}
}
}
4 changes: 2 additions & 2 deletions Source/Interface/Dialog_Rules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private void ChangeRestriction(RestrictionType type)
{
var list = new List<FloatMenuOption>();

var presets = Registry.GetPresets<Restriction>(type).Where(preset => preset != _template.GetRestriction(type));
var presets = Registry.GetPresets<Restriction>(type).Where(preset => preset != _template.GetRestriction(type)).ToArray();

if (!presets.Any() && _template.GetRestriction(type).IsVoid)
{
Expand Down Expand Up @@ -146,7 +146,7 @@ private List<FloatMenuOption> GetAssignmentOptions()

private void AssignAll(bool byKind)
{
var pawns = GetOtherPawnsOfType(byKind);
var pawns = GetOtherPawnsOfType(byKind).ToArray();

void OnAccept()
{
Expand Down
2 changes: 1 addition & 1 deletion Source/Interface/Listing_Preset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ private void ChangeSelected(T selected)
public void DoContent(Rect rect)
{
var selectedIsIgnored = Selected.IsIgnored();
var presets = Registry.GetPresets<T>(Type);
var presets = Registry.GetPresets<T>(Type).ToArray();

_listing.Begin(rect);
foreach (var preset in FixedPresets)
Expand Down
22 changes: 4 additions & 18 deletions Source/Mod.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using Harmony;
using System.IO;
using PawnRules.Data;
using PawnRules.Integration;
using PawnRules.Interface;
using PawnRules.Patch;
using RimWorld;
Expand All @@ -16,7 +13,7 @@ internal class Mod : Verse.Mod
{
public const string Id = "PawnRules";
public const string Name = "Pawn Rules";
public const string Version = "1.1.3";
public const string Version = "1.1.4";

public static readonly DirectoryInfo ConfigDirectory = new DirectoryInfo(Path.Combine(GenFilePaths.ConfigFolderPath, Id));

Expand All @@ -31,18 +28,7 @@ public Mod(ModContentPack contentPack) : base(contentPack)
FirstTimeUser = !ConfigDirectory.Exists;
ConfigDirectory.Create();

if (!FirstTimeUser) { TryRegisterHugsLibUpdateFeature(); }
}

private static void TryRegisterHugsLibUpdateFeature()
{
var hugsLib = (from assembly in AppDomain.CurrentDomain.GetAssemblies() from type in assembly.GetTypes() where type.Name == "HugsLibController" select type).FirstOrDefault();
if (hugsLib == null) { return; }

var updateFeatures = Traverse.Create(hugsLib)?.Field("instance")?.Property("UpdateFeatures")?.GetValue();
if (updateFeatures == null) { return; }

AccessTools.Method(updateFeatures.GetType(), "InspectActiveMod")?.Invoke(updateFeatures, new object[] { Id, Assembly.GetExecutingAssembly().GetName().Version });
if (!FirstTimeUser) { HugsLib.RegisterUpdateFeature(); }
}

public static void Log(string message) => Verse.Log.Message(PrefixMessage(message));
Expand Down
33 changes: 10 additions & 23 deletions Source/Patch/RimWorld_FoodUtility_BestFoodSourceOnMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,16 @@ private static bool Prefix(ref Thing __result, Pawn getter, Pawn eater, bool des
return restriction.AllowsFood(thing.def, eater);
});

var req = ((eater.RaceProps.foodType & (FoodTypeFlags.Plant | FoodTypeFlags.Tree)) == FoodTypeFlags.None) || !allowPlant ? ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree) : ThingRequest.ForGroup(ThingRequestGroup.FoodSource);
var request = ((eater.RaceProps.foodType & (FoodTypeFlags.Plant | FoodTypeFlags.Tree)) == FoodTypeFlags.None) || !allowPlant ? ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree) : ThingRequest.ForGroup(ThingRequestGroup.FoodSource);
Thing bestThing;
if (getter.RaceProps.Humanlike)
{
bestThing = Access.Method_RimWorld_FoodUtility_SpawnedFoodSearchInnerScan_Call(eater, getter.Position, getter.Map.listerThings.ThingsMatching(req), PathEndMode.ClosestTouch, TraverseParms.For(getter), 9999f, foodValidator);
bestThing = Access.Method_RimWorld_FoodUtility_SpawnedFoodSearchInnerScan_Call(eater, getter.Position, getter.Map.listerThings.ThingsMatching(request), PathEndMode.ClosestTouch, TraverseParms.For(getter), 9999f, foodValidator);

if (allowHarvest && getterCanManipulate)
{
var searchRegionsMax = !forceScanWholeMap || (bestThing != null) ? 30 : -1;
var firstBestThing = bestThing;

bool Validator(Thing thing)
{
Expand All @@ -62,7 +64,7 @@ bool Validator(Thing thing)
var harvestedThingDef = plant.def.plant.harvestedThingDef;

// Pawn Rules - Food check below
return harvestedThingDef.IsNutritionGivingIngestible && eater.RaceProps.CanEverEat(harvestedThingDef) && getter.CanReserve(plant) && (allowForbidden || !plant.IsForbidden(getter)) && ((bestThing == null) || (FoodUtility.GetFinalIngestibleDef(bestThing).ingestible.preferability < harvestedThingDef.ingestible.preferability)) && restriction.AllowsFood(plant.def, eater);
return harvestedThingDef.IsNutritionGivingIngestible && eater.RaceProps.CanEverEat(harvestedThingDef) && getter.CanReserve(plant) && (allowForbidden || !plant.IsForbidden(getter)) && ((firstBestThing == null) || (FoodUtility.GetFinalIngestibleDef(firstBestThing).ingestible.preferability < harvestedThingDef.ingestible.preferability)) && restriction.AllowsFood(plant.def, eater);
}

var foodSource = GenClosest.ClosestThingReachable(getter.Position, getter.Map, ThingRequest.ForGroup(ThingRequestGroup.HarvestablePlant), PathEndMode.Touch, TraverseParms.For(getter), 9999f, Validator, null, 0, searchRegionsMax);
Expand All @@ -88,28 +90,13 @@ bool Validator(Thing thing)

var ignoreEntirelyForbiddenRegions = !allowForbidden && ForbidUtility.CaresAboutForbidden(getter, true) && (getter.playerSettings?.EffectiveAreaRestrictionInPawnCurrentMap != null);
var predicate = (Predicate<Thing>) (thing => foodValidator(thing) && !filtered.Contains(thing) && (thing is Building_NutrientPasteDispenser || (thing.def.ingestible.preferability > FoodPreferability.DesperateOnly)) && !thing.IsNotFresh());
var position1 = getter.Position;
var map1 = getter.Map;
var thingReq1 = req;
var traverseParams1 = TraverseParms.For(getter);
var validator1 = predicate;
var ignoreEntirelyForbiddenRegions1 = ignoreEntirelyForbiddenRegions;

bestThing = GenClosest.ClosestThingReachable(position1, map1, thingReq1, PathEndMode.ClosestTouch, traverseParams1, 9999f, validator1, null, 0, maxRegionsToScan, false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions1);
filtered.Clear();
var traverseParams = TraverseParms.For(getter);
var validator = predicate;

if (bestThing == null)
{
desperate = true;
var position2 = getter.Position;
var map2 = getter.Map;
var thingReq2 = req;
var traverseParams2 = TraverseParms.For(getter);
var validator2 = foodValidator;
var ignoreEntirelyForbiddenRegions2 = ignoreEntirelyForbiddenRegions;
bestThing = GenClosest.ClosestThingReachable(position2, map2, thingReq2, PathEndMode.ClosestTouch, traverseParams2, 9999f, validator2, null, 0, maxRegionsToScan, false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions2);
}
bestThing = GenClosest.ClosestThingReachable(getter.Position, getter.Map, request, PathEndMode.ClosestTouch, traverseParams, 9999f, validator, null, 0, maxRegionsToScan, false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions);
filtered.Clear();

if (bestThing == null) { bestThing = GenClosest.ClosestThingReachable(getter.Position, getter.Map, request, PathEndMode.ClosestTouch, traverseParams, 9999f, foodValidator, null, 0, maxRegionsToScan, false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions); }
if (bestThing != null) { foodDef = FoodUtility.GetFinalIngestibleDef(bestThing); }
}

Expand Down
4 changes: 1 addition & 3 deletions Source/Patch/RimWorld_GenConstruct_CanConstruct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ internal static class RimWorld_GenConstruct_CanConstruct
{
private static void Postfix(ref bool __result, Thing t, Pawn p, bool checkConstructionSkill = true, bool forced = false)
{
if (!Registry.IsActive) { return; }

if (__result == false) { return; }
if (!Registry.IsActive || (__result == false)) { return; }

var rules = Registry.GetRules(p);
if ((rules == null) || rules.AllowArtisan || !checkConstructionSkill || !((ThingDef) t.def.entityDefToBuild).HasComp(typeof(CompQuality))) { return; }
Expand Down
Loading

0 comments on commit 819e0d2

Please sign in to comment.