RogueLibs' logo

Configuring Unlocks

Custom unlocks' displayed names, descriptions, images, buttons and their order in the list can be configured. You can even determine your own unlock conditions, change the displayed text and sprites conditionally and stuff like that.

Sorting

Unlocks are first sorted by their SortingOrder, then by their state (unlocked, purchasable, available and locked), and then by their SortingIndex. You can ignore the sorting by the state by setting IgnoreStateSorting to true.

Here's an example of how this sorting would work:

  • SortingOrder = -400:
    • Unlocked:
      • SortingIndex = -3;
      • SortingIndex = 1;
      • SortingIndex = 2;
    • Purchasable:
      • ...
    • Available:
      • ...
    • Locked:
      • ...
  • SortingOrder = -3:
    • ...
  • SortingOrder = 0 (vanilla unlocks go here, with sorting index of 0):
    • ...
  • SortingOrder = 1:
    • ...
  • SortingOrder = 500:
    • ...
caution

The menu might get weird or even crash if not all unlocks on the current SortingOrder have IgnoreStateSorting set to the same value. So make sure that all other unlocks have IgnoreStateSorting set to true too.

Overrideable methods

UnlockWrapper

/RogueLibsCore/Hooks/Unlocks/UnlockWrapper.cs
// called when the unlock is initialized and integrated into the gamepublic virtual void SetupUnlock() { }// called pretty often to determine if it can be unlocked right nowpublic virtual void UpdateUnlock(){    if ((Unlock.nowAvailable = !Unlock.unlocked && CanBeUnlocked()) && UnlockCost == 0)        gc.unlocks.DoUnlockForced(Name, Type);}// determines whether the unlock can be unlocked right nowpublic virtual bool CanBeUnlocked()    => UnlockCost > -1 && Unlock.prerequisites.TrueForAll(        c => gc.sessionDataBig.unlocks.Exists(u => u.unlockName == c && u.unlocked)    );// gets the unlock's raw name, without any rich text, costs and valuespublic virtual string GetName()    => gc.nameDB.GetName(Name, Unlock.unlockNameType);// gets the unlock's raw description, without any rich text, costs and valuespublic virtual string GetDescription()    => gc.nameDB.GetName(Name, Unlock.unlockDescriptionType);// gets the unlock's image (displayed in the menus)public virtual Sprite GetImage()    => RogueFramework.ExtraSprites.TryGetValue(Name, out Sprite image) ? image;
note

You can see for yourself how these methods are implemented in RogueLibs' source code.

DisplayedUnlock

/RogueLibsCore/Hooks/Unlocks/DisplayedUnlock.cs
// called when the button is updated. `UpdateUnlock` is called right before this.public virtual void UpdateButton()    => UpdateButton(IsEnabled, UnlockButtonState.Selected, UnlockButtonState.Normal);protected void UpdateButton(bool isEnabledOrSelected, UnlockButtonState selected, UnlockButtonState normal){    Text = GetFancyName();    State = IsUnlocked ? isEnabledOrSelected ? selected : normal        : Unlock.nowAvailable && UnlockCost > -1 ? UnlockButtonState.Purchasable        : UnlockButtonState.Locked;}// called when the button is pressed. See other unlocks' implementations for more infopublic abstract void OnPushedButton();// gets the unlock's "fancy" name, with rich text formatting, costs and point valuespublic virtual string GetFancyName(){    /* A lot of stuff, see RogueLibs' source code for more information */}// gets the unlock's "fancy" description, with rich text formatting, cancellations, prerequisites and recommendationspublic virtual string GetFancyDescription(){    /* A lot of stuff, see RogueLibs' source code for more information */}
note

You can see for yourself how these methods are implemented in RogueLibs' source code.

Examples

Let's say, you want to make an item called Present, and it has 3 different sprites.

First of all, you'll need to create an unlock class deriving from ItemUnlock:

/MyAwesomeProject/PresentUnlock.cs
public class PresentUnlock : ItemUnlock{}

Now you can override the DisplayedUnlock's GetImage method:

/MyAwesomeProject/PresentUnlock.cs
public class PresentUnlock : ItemUnlock{    public override Sprite GetImage()    {        int rnd = new System.Random().Next(3) + 1;        return gc.gameResources.itemDic[$"Present{rnd}"];    }}

Then just use your custom unlock in the custom item's initialization:

/MyAwesomeProject/Present.cs
public class Present : CustomItem, IItemUsable{    [RLSetup]    public static void Setup()    {        RogueLibs.CreateCustomItem<Present>()            .WithName(new CustomNameInfo("Present"))            .WithDescription(new CustomNameInfo("Open it!"))            .WithSprite(Properties.Resources.Present)            .WithUnlock(new PresentUnlock            {                UnlockCost = 5,                CharacterCreationCost = 3,                LoadoutCost = 3            });    }}