Skip to content
Jaxe edited this page Sep 8, 2018 · 6 revisions

Writing addons for Pawn Rules

Summary

Other mods can utilize the rules dialog by adding new options. The saving of the variables for the individual pawns is handled by Pawn Rules.

Currently the following options can be added:

  • Toggle a checkbox widget holding a bool
  • Entry a textentry widget holding either a string, int or float
  • Button a button widget that can hold a bool, string, int or float. The input of this data must be handled by a delegate. For example it could open a custom dialog or float menu.

Basic Example

This assumes you have a decent understand of C# and RimWorld modding. To begin with we will need to add the PawnRules.dll as a reference to the project but make sure the dll itself is not included in the mod. We'll start by creating a link to Pawn Rules in the constructor (it can be created at a later time although must be before a world has loaded):

using PawnRules.API;

namespace PawnRulesAddonExample
{
  [StaticConstructorOnStartup]
  public static class AddonExample
  {
    static AddonExample()
    {
      var pawnRules = new PawnRulesLink();
      // We'll be adding options here
    }
  }
}

The link must be made before the world is loaded so in the constructor or DefsLoaded would be a good spot. Now to add an option, let's go with a simple toggle which has the following arguments:

AddToggle(string key, OptionTarget target, string label, string tooltip, bool defaultValue, bool allowedInPreset = true)

key: The name used in the savegame xml. Will automatically be prefixed with your mod identifier.
target: The type of pawn this rule applies to. Can be set to multiple targets.
label: Shown on the widget in the rules dialog.
tooltip: Shown when hovering over the widget.
defaultValue: If the value is this it will not be recorded in the save file. This also serves as the default value if allowedInPreset is false or no default rules exist when a pawn is first given rules.
allowedInPreset: If set to false it cannot be used in a preset.

It will then return an OptionHandle which we can use to edit the option later in the code if we want.

So using this we'll add a simple toggle:

var toggle = pawnRules.AddToggle("exampleToggle", OptionTarget.Colonist, "Example Toggle", "This is just an example", true);

Now that is enough for Pawn Rules to add it to the rules dialog of any colonist you control. It does nothing so far but the toggle state will be saved to an individual colonist and a state could also be set as a default for any new colonists who join.

But really we would want this toggle to do something later so we'll save the handle as a public property. The value of a toggle is a bool so we'll be using the OptionHandle class.

public static OptionHandle<bool> ExampleToggle { get; private set; }

static AddonExample()
{
  // Preparing Harmony for the next part of this tutorial
  HarmonyInstance.Create("com.example.addon").PatchAll();

  // PawnRules link and adding our options
  var pawnRules = new PawnRulesLink();
  var toggle = pawnRules.AddToggle("exampleToggle", OptionTarget.Colonist, "Example Toggle", "This is just an example", false);
  if (toggle != null) // We don't really need to check if it's null as we set it up properly but it doesn't hurt
  {
    ExampleToggle = toggle;
  }
}

So now we have a handle we can use it to check the value while we're patching some method. Here we will patch the DrawSocialCard method so that it will show a little box blue box with the words "Hello World" when we click on a pawn's social tab who has our toggle set to true.

[HarmonyPatch(typeof(SocialCardUtility), "DrawSocialCard")]
public static class ExamplePatch
{
  public static void Postfix(Pawn pawn)
  {
    if (!AddonExample.ExampleToggle.IsUsedBy(pawn)) // We can use IsUsedBy(Pawn) to check if a given pawn has the option
    {
      return;
    }

    var value = AddonExample.ExampleToggle.GetValue(pawn); // Gets the value of this option for the pawn
    if (!value) { return; } // Ignore the next part if the toggle is set to false

    var rect = new Rect(100f, 100f, 100f, 30f);
    Widgets.DrawBoxSolid(rect, Color.blue);
    Widgets.Label(rect, "Hello World!");
  }
}

A rather simple example but an example nonetheless of being able to access our option for a given pawn. Pawn Rules will handle all the saving of the variable for the pawn and frees up modders to work on implementing interesting options.

The next tutorial covers Advanced Addons.

Clone this wiki locally