Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaxe-Wilde committed Aug 20, 2018
0 parents commit 8295a02
Show file tree
Hide file tree
Showing 56 changed files with 3,584 additions and 0 deletions.
9 changes: 9 additions & 0 deletions About/About.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>

<ModMetaData>
<name>Pawn Rules</name>
<author>Jaxe</author>
<targetVersion>0.19.0</targetVersion>
<description>Pawn 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\n</description>
<url>https://ludeon.com/forums/index.php?topic=43086.0</url>
</ModMetaData>
15 changes: 15 additions & 0 deletions About/ModSync.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>

<ModSyncNinjaData>
<ID>59f538ed-f86d-4506-a4a5-7e9faaa37509</ID>
<ModName>Pawn Rules</ModName>
<Version>v1.0-rw0.19</Version>
<SaveBreaking>False</SaveBreaking>
<Host name="Github">
<Owner>Jaxe-Dev</Owner>
<Project>PawnRules</Project>
<AboutDir>About</AboutDir>
<DownloadFrom>ModSyncReleases</DownloadFrom>
<Branch>master</Branch>
</Host>
</ModSyncNinjaData>
Binary file added 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.
243 changes: 243 additions & 0 deletions Assemblies/PawnRules.xml

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions Defs/WorldObjectDefs/PawnRules.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>

<Defs>

<WorldObjectDef>
<defName>PawnRules_Registry</defName>
<label>Pawn Rules Registry</label>
<worldObjectClass>PawnRules.Data.Registry</worldObjectClass>
</WorldObjectDef>

</Defs>
121 changes: 121 additions & 0 deletions Languages/English/Keyed/PawnRules.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>

<LanguageData>
<PawnRules.Button.OK>OK</PawnRules.Button.OK>
<PawnRules.Button.Cancel>Cancel</PawnRules.Button.Cancel>
<PawnRules.Button.Yes>Yes</PawnRules.Button.Yes>
<PawnRules.Button.No>No</PawnRules.Button.No>

<PawnRules.Button.AssignTo>Assign to ...</PawnRules.Button.AssignTo>
<PawnRules.Button.AssignToDesc>Click to assign this preset to others.</PawnRules.Button.AssignToDesc>

<PawnRules.Button.ViewType>Showing rules for {0}</PawnRules.Button.ViewType>
<PawnRules.Button.ViewTypeDefault>Showing default rules for {0}</PawnRules.Button.ViewTypeDefault>
<PawnRules.Button.ViewTypeDesc>Click to view rules for other types.</PawnRules.Button.ViewTypeDesc>

<PawnRules.Button.GlobalOptions>Options</PawnRules.Button.GlobalOptions>
<PawnRules.Button.GlobalOptionsDesc>Click to open the global options dialog.</PawnRules.Button.GlobalOptionsDesc>

<PawnRules.Button.RemoveMod>Remove Mod</PawnRules.Button.RemoveMod>
<PawnRules.Button.RemoveModDesc>This will remove and all rules from all characters in the current game and deactivate the mod.\n\nThis will avoid any errors being displayed the first time reloading this game without this mod.</PawnRules.Button.RemoveModDesc>
<PawnRules.Button.RemoveModConfirm>This will remove all rules from all characters in the current game and deactivate the mod.\n\nAre you sure you want to do this?</PawnRules.Button.RemoveModConfirm>
<PawnRules.Button.RemoveModComplete>A save was created called '{0}' that contains no traces of this mod.\n\nThe game will now restart.</PawnRules.Button.RemoveModComplete>
<PawnRules.Button.RemoveModAndAddonsComplete>A save was created called '{0}' that contains no traces of this mod or anyone of the following addon mods:\n\n{1}\n\nThe game will now restart.</PawnRules.Button.RemoveModAndAddonsComplete>

<PawnRules.Button.PresetNew>New</PawnRules.Button.PresetNew>
<PawnRules.Button.PresetNewDesc>Create a new preset.</PawnRules.Button.PresetNewDesc>
<PawnRules.Button.PresetEdit>Edit</PawnRules.Button.PresetEdit>
<PawnRules.Button.PresetEditDesc>Modify the currently selected preset.</PawnRules.Button.PresetEditDesc>
<PawnRules.Button.PresetSave>Save</PawnRules.Button.PresetSave>
<PawnRules.Button.PresetSaveDesc>Commit changes to this preset.</PawnRules.Button.PresetSaveDesc>
<PawnRules.Button.PresetSaveAs>Save As</PawnRules.Button.PresetSaveAs>
<PawnRules.Button.PresetSaveAsDesc>Create a preset from the currently displayed rules.</PawnRules.Button.PresetSaveAsDesc>
<PawnRules.Button.PresetClear>Clear</PawnRules.Button.PresetClear>
<PawnRules.Button.PresetClearDesc>Reset these personalized rules to vanilla.</PawnRules.Button.PresetClearDesc>
<PawnRules.Button.PresetRevert>Revert</PawnRules.Button.PresetRevert>
<PawnRules.Button.PresetRevertDesc>Cancel changes to this preset.</PawnRules.Button.PresetRevertDesc>
<PawnRules.Button.PresetRename>Rename</PawnRules.Button.PresetRename>
<PawnRules.Button.PresetRenameDesc>Change the name of this preset.</PawnRules.Button.PresetRenameDesc>
<PawnRules.Button.PresetDelete>Delete</PawnRules.Button.PresetDelete>
<PawnRules.Button.PresetDeleteDesc>Permanently remove this preset.</PawnRules.Button.PresetDeleteDesc>
<PawnRules.Button.PresetDeleteConfirm>Are you sure you want to delete the preset [{0}]?\n\nThis will affect all characters using this preset.</PawnRules.Button.PresetDeleteConfirm>
<PawnRules.Button.PresetSaveConfirm>Save changes to this preset?</PawnRules.Button.PresetSaveConfirm>

<PawnRules.Button.RestrictionsAllowOn>Allow all</PawnRules.Button.RestrictionsAllowOn>
<PawnRules.Button.RestrictionsAllowOff>Disallow all</PawnRules.Button.RestrictionsAllowOff>

<PawnRules.PresetType.Rules>Rules Preset</PawnRules.PresetType.Rules>
<PawnRules.PresetType.Restriction>Restriction Preset</PawnRules.PresetType.Restriction>

<PawnRules.Preset.Header>Presets</PawnRules.Preset.Header>
<PawnRules.Preset.None>None</PawnRules.Preset.None>
<PawnRules.Preset.Personalized>&lt;i&gt;Personalized&lt;/i&gt;</PawnRules.Preset.Personalized>

<PawnRules.RestrictionType.Food>Food Preset</PawnRules.RestrictionType.Food>
<PawnRules.RestrictionType.FoodPlural>Food Presets</PawnRules.RestrictionType.FoodPlural>
<PawnRules.RestrictionType.FoodCategorization>Edibles</PawnRules.RestrictionType.FoodCategorization>
<PawnRules.RestrictionType.Bonding>Bonding Preset</PawnRules.RestrictionType.Bonding>
<PawnRules.RestrictionType.BondingPlural>Bonding Presets</PawnRules.RestrictionType.BondingPlural>
<PawnRules.RestrictionType.BondingCategorization>Animals</PawnRules.RestrictionType.BondingCategorization>

<PawnRules.PawnType.Colonist>Colonist</PawnRules.PawnType.Colonist>
<PawnRules.PawnType.ColonistPlural>Colonists</PawnRules.PawnType.ColonistPlural>
<PawnRules.PawnType.Animal>Animal</PawnRules.PawnType.Animal>
<PawnRules.PawnType.AnimalPlural>Animals</PawnRules.PawnType.AnimalPlural>
<PawnRules.PawnType.Guest>Guest</PawnRules.PawnType.Guest>
<PawnRules.PawnType.GuestPlural>Guests</PawnRules.PawnType.GuestPlural>
<PawnRules.PawnType.Prisoner>Prisoner</PawnRules.PawnType.Prisoner>
<PawnRules.PawnType.PrisonerPlural>Prisoners</PawnRules.PawnType.PrisonerPlural>
<PawnRules.PawnType.Person>Person</PawnRules.PawnType.Person>
<PawnRules.PawnType.PersonPlural>Persons</PawnRules.PawnType.PersonPlural>
<PawnRules.PawnType.Individual>Individual</PawnRules.PawnType.Individual>

<PawnRules.Rules.FoodRestrictions>Food Restrictions: {0}</PawnRules.Rules.FoodRestrictions>
<PawnRules.Rules.FoodRestrictionsDesc>Click to choose foods that can be eaten automatically.</PawnRules.Rules.FoodRestrictionsDesc>
<PawnRules.Rules.BondingRestrictions>Bonding Restrictions: {0}</PawnRules.Rules.BondingRestrictions>
<PawnRules.Rules.BondingRestrictionsDesc>Click to choose animals that can be bonded with.</PawnRules.Rules.BondingRestrictionsDesc>
<PawnRules.Rules.AllowCourting>Allow Courting</PawnRules.Rules.AllowCourting>
<PawnRules.Rules.AllowCourtingDesc>If toggled off will not be allowed to gain a new lover or spouse.</PawnRules.Rules.AllowCourtingDesc>
<PawnRules.Rules.AllowArtisan>Allow Artisan</PawnRules.Rules.AllowArtisan>
<PawnRules.Rules.AllowArtisanDesc>If toggled off will not build any construction that has a quality level.</PawnRules.Rules.AllowArtisanDesc>
<PawnRules.Rules.NotArtisanReason>not allowed artisan builds</PawnRules.Rules.NotArtisanReason>
<PawnRules.Rules.NotArtisanJob>construct {0}</PawnRules.Rules.NotArtisanJob>

<PawnRules.AnimalCategory.Pet>Common Pets</PawnRules.AnimalCategory.Pet>
<PawnRules.AnimalCategory.Farm>Farm Animals</PawnRules.AnimalCategory.Farm>
<PawnRules.AnimalCategory.Herd>Herd Animals</PawnRules.AnimalCategory.Herd>
<PawnRules.AnimalCategory.Predator>Predators</PawnRules.AnimalCategory.Predator>
<PawnRules.AnimalCategory.Insect>Insects</PawnRules.AnimalCategory.Insect>
<PawnRules.AnimalCategory.Other>Other</PawnRules.AnimalCategory.Other>

<PawnRules.Gizmo.EditRulesLabel>Rules</PawnRules.Gizmo.EditRulesLabel>
<PawnRules.Gizmo.EditRulesDesc>Edit the rules for this {0}.</PawnRules.Gizmo.EditRulesDesc>

<PawnRules.Dialog_Global.Title>Global Options</PawnRules.Dialog_Global.Title>

<PawnRules.Dialog_Rules.Title>Rules for {0}, {1}</PawnRules.Dialog_Rules.Title>
<PawnRules.Dialog_Rules.TitleDefault>Default Rules for {0}</PawnRules.Dialog_Rules.TitleDefault>
<PawnRules.Dialog_Rules.HeaderOptions>Options</PawnRules.Dialog_Rules.HeaderOptions>
<PawnRules.Dialog_Rules.Configuration>Configuration</PawnRules.Dialog_Rules.Configuration>
<PawnRules.Dialog_Rules.DefaultType>Default {0}</PawnRules.Dialog_Rules.DefaultType>
<PawnRules.Dialog_Rules.AssignAll>Assign to all {0}</PawnRules.Dialog_Rules.AssignAll>
<PawnRules.Dialog_Rules.AssignAllConfirm>Are you sure you want to {0} {1} other {2}?</PawnRules.Dialog_Rules.AssignAllConfirm>
<PawnRules.Dialog_Rules.AssignDefault>Set as default for new {0}</PawnRules.Dialog_Rules.AssignDefault>
<PawnRules.Dialog_Rules.AssignDefaultConfirm>Are you sure you want to change the default rules for new {0} to the preset {1}?</PawnRules.Dialog_Rules.AssignDefaultConfirm>
<PawnRules.Dialog_Rules.AssignSpecific>Assign to {0}</PawnRules.Dialog_Rules.AssignSpecific>
<PawnRules.Dialog_Rules.AssignSpecificConfirm>Are you sure you want to {0} {1}?</PawnRules.Dialog_Rules.AssignSpecificConfirm>
<PawnRules.Dialog_Rules.AssignPersonalizedName>assign these personalized rules to</PawnRules.Dialog_Rules.AssignPersonalizedName>
<PawnRules.Dialog_Rules.AssignSpecificName>assign the preset {0} to</PawnRules.Dialog_Rules.AssignSpecificName>
<PawnRules.Dialog_Rules.AssignVoidName>clear the rules for</PawnRules.Dialog_Rules.AssignVoidName>
<PawnRules.Dialog_Rules.EditRestriction>Edit restrictions...</PawnRules.Dialog_Rules.EditRestriction>
<PawnRules.Dialog_Rules.ClearRestriction>Allow all {0}</PawnRules.Dialog_Rules.ClearRestriction>
<PawnRules.Dialog_Rules.ChangeRestriction>Set to {0}</PawnRules.Dialog_Rules.ChangeRestriction>

<PawnRules.Dialog_Restrictions.TitlePreset>{0} [{1}]</PawnRules.Dialog_Restrictions.TitlePreset>
<PawnRules.Dialog_Restrictions.TitlePawn>{0} for {1}, {2}</PawnRules.Dialog_Restrictions.TitlePawn>
<PawnRules.Dialog_Restrictions.HeaderCategory>Category</PawnRules.Dialog_Restrictions.HeaderCategory>

<PawnRules.Dialog_PresetName.Title>Preset [{0}]</PawnRules.Dialog_PresetName.Title>
<PawnRules.Dialog_PresetName.TitleNew>Create Preset</PawnRules.Dialog_PresetName.TitleNew>
<PawnRules.Dialog_PresetName.Label>Enter new name:</PawnRules.Dialog_PresetName.Label>
</LanguageData>
56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Pawn Rules
#### Version 1.0
Built for **RimWorld 1.0.x / 0.19.x**\
Supports **ModSync RW**

[Link to Ludeon Forum Post](https://ludeon.com/forums/index.php?topic=43086.0)

------------

Pawn Rules is a mod that allows custom rules to be assigned individually to your colonists, animals, guests and prisoners.

Currently the following rules can be applied:
- Disallow certain foods
- *Ignored if binging on food*
- Disallow bonding with certain animals
- *This has no effect on existing bonds*
- Disallow new romances
- *This has no effect on existing relations and engaged couples can still get married*
- Disallow constructing items that have a quality level
- *Can still haul materials to blueprints*

------------

Supports addons created by other modders by allowing easy creation of new rule options while handling the GUI and world storage saving. For more information check out the [wiki page on Addons](https://github.com/Jaxe-Dev/PawnRules/wiki/Addons).

------------

##### INSTALLATION
- **[Download the latest release](https://github.com/Jaxe-Dev/PawnRules/releases/latest) and unzip it into your *RimWorld/Mods* folder.**

------------

###### TECHINICAL DETAILS
>This mod can be safely removed from a save without breaking the game. To do so go to *Global Options* either from the mod settings menu or the main rules window for a character and select *Remove Mod*.
>
> A save of your world will be made with no traces of this mod and the game will restart. Skipping the *Remove Mod* step will result in errors being displayed the first time a save is loaded although no further problems should occur.
------------

The following original methods are patched using HugsLib.Harmony:
```C#
RimWorld.FoodUtility.BestFoodSourceOnMap : Prefix
RimWorld.FoodUtility.BestFoodInInventory : Prefix
RimWorld.GenConstruct.CanConstruct : Postfix
RimWorld.InteractionWorker_RomanceAttempt.SuccessChance : Prefix
RimWorld.JobGiver_PackFood.IsGoodPackableFoodFor : Postfix
RimWorld.JoyGiver_Ingest.CanIngestForJoy : Prefix
RimWorld.PawnUtility.TrySpawnHatchedOrBornPawn : Postfix
RimWorld.RelationsUtility.TryDevelopBondRelation : Prefix
Verse.Game.FinalizeInit : Postfix
Verse.Pawn.GetGizmos : Postfix
Verse.Pawn.Kill : Postfix
Verse.Pawn.SetFaction : Prefix
Verse.Pawn.SetFactionDirect : Prefix
Verse.Pawn_GuestTracker.SetGuestStatus : Prefix
```
19 changes: 19 additions & 0 deletions Source/Controller.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Reflection;
using Harmony;
using PawnRules.Data;
using Verse;

namespace PawnRules
{
[StaticConstructorOnStartup]
internal static class Controller
{
static Controller() => HarmonyInstance.Create(Mod.Id).PatchAll(Assembly.GetExecutingAssembly());

public static void LoadWorld()
{
AddonManager.AcceptingAddons = false;
Registry.Initialize();
}
}
}
33 changes: 33 additions & 0 deletions Source/Data/AddonManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Verse;

namespace PawnRules.Data
{
internal static class AddonManager
{
private static readonly Regex KeyRegex = new Regex("[a-zA-Z0-9_]+");

private static readonly Dictionary<string, AddonOption> OptionRegistry = new Dictionary<string, AddonOption>();
private static readonly List<ModContentPack> ModRegistry = new List<ModContentPack>();

public static bool AcceptingAddons { get; set; } = true;
public static bool HasAddons { get; private set; }

public static IEnumerable<AddonOption> Options => OptionRegistry.Values;
public static IEnumerable<ModContentPack> Mods => ModRegistry;

public static void Add(AddonOption addon)
{
if (Registry.IsActive || !AcceptingAddons) { throw new Mod.Exception("Options must be added before a world is loaded"); }
if (string.IsNullOrEmpty(addon.Key)) { throw new Mod.Exception("Key is null or empty"); }
if (!KeyRegex.IsMatch(addon.Key)) { throw new Mod.Exception("Key must not contain any non-alphanumeric characters except for an underscore"); }
if (OptionRegistry.ContainsKey(addon.Key)) { throw new Mod.Exception("Key already exists"); }

if (!ModRegistry.Contains(addon.Link.ModContentPack)) { ModRegistry.Add(addon.Link.ModContentPack); }
OptionRegistry.Add(addon.Key, addon);

HasAddons = true;
}
}
}
49 changes: 49 additions & 0 deletions Source/Data/AddonOption.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using PawnRules.Interface;
using PawnRules.SDK;
using Verse;

namespace PawnRules.Data
{
internal class AddonOption
{
public string Key { get; }
public OptionTarget Target { get; }
public OptionWidget Widget { get; }
public string Label { get; set; }
public string Tooltip { get; set; }
public Type Type { get; }

public object DefaultValue { get; }
public bool AllowedInPreset { get; }

public OptionHandle Handle { get; private set; }
public PawnRulesLink Link { get; }
public float WidgetHeight => (Widget == OptionWidget.Button ? 30f : Text.LineHeight) + 2f;

private AddonOption(PawnRulesLink link, string key, OptionTarget target, OptionWidget widget, string label, string tooltip, Type type, object defaultValue, bool allowedInPreset)
{
Link = link;
Key = key;
Target = target;
Widget = widget;
Label = label;
Tooltip = tooltip;
Type = type;
DefaultValue = defaultValue;
AllowedInPreset = allowedInPreset;
}

internal static OptionHandle<T> Add<T>(PawnRulesLink link, string key, OptionTarget target, OptionWidget widget, string label, string tooltip, T defaultValue, bool allowedInPreset = true)
{
var option = new AddonOption(link, link.ModContentPack.Identifier + "_" + key, target, widget, label, tooltip, typeof(T), defaultValue, allowedInPreset);

AddonManager.Add(option);

var handle = new OptionHandle<T>(option);
option.Handle = handle;

return handle;
}
}
}
59 changes: 59 additions & 0 deletions Source/Data/Binding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using PawnRules.Patch;
using Verse;

namespace PawnRules.Data
{
internal class Binding : IExposable
{
public Pawn Pawn;
public PawnType Target;
public Rules Rules;

private Rules _individual;
private Rules _preset;

public Binding()
{ }

public Binding(Pawn pawn, Rules rules) : this()
{
Pawn = pawn;
Rules = rules;
}

public Binding(PawnType target, Rules rules) : this()
{
Target = target;
Rules = rules;
}

public void ExposeData()
{
if ((Scribe.mode != LoadSaveMode.Saving) || (Target == null)) { Scribe_References.Look(ref Pawn, "pawn"); }
if ((Scribe.mode != LoadSaveMode.Saving) || (Target != null)) { Target = PawnType.FromId(ScribePlus.LookValue(Target?.Id, "target")); }


if (Scribe.mode != LoadSaveMode.Saving)
{
Scribe_References.Look(ref _preset, "preset");
if (Target == null)
{
Scribe_Deep.Look(ref _individual, "rules");
_individual?.SetPawn(Pawn);
}
}
else if (Rules != null)
{
if (Rules.IsPreset) { Scribe_References.Look(ref Rules, "preset"); }
else { Scribe_Deep.Look(ref Rules, "rules"); }
}

if (Scribe.mode != LoadSaveMode.PostLoadInit) { return; }

if (_preset != null) { Rules = _preset; }
else if (_individual != null) { Rules = _individual; }
else if (Pawn != null) { Rules = Registry.GetVoidPreset<Rules>(Pawn.GetTargetType()).CloneRulesFor(Pawn); }
else { throw new Mod.Exception("Unable to load rules for binding"); }
}
}
}
9 changes: 9 additions & 0 deletions Source/Data/IPresetableType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace PawnRules.Data
{
internal interface IPresetableType
{
string Id { get; }
string Label { get; }
string LabelPlural { get; }
}
}
Loading

0 comments on commit 8295a02

Please sign in to comment.