Skip to main content
The project's repository is archived as part of the GitHub Archive Program. RogueLibs' code and the documentation will no longer be updated.

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

UnlockWrapper.cs
// called when the unlock is initialized and integrated into the game
public virtual void SetupUnlock() { }

// called pretty often to determine if it can be unlocked right now
public virtual void UpdateUnlock()
{
if ((Unlock.nowAvailable = !Unlock.unlocked && CanBeUnlocked()) && UnlockCost is 0)
gc.unlocks.DoUnlockForced(Name, Type);
}

// determines whether the unlock can be unlocked right now
public 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 values
public virtual string GetName() => gc.nameDB.GetName(Name, Unlock.unlockNameType);

// gets the unlock's raw description, without any rich text, costs and values
public 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;
Pro-tip

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

DisplayedUnlock

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 info
public abstract void OnPushedButton();

// gets the unlock's "fancy" name, with rich text formatting, costs and point values
public 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 recommendations
public virtual string GetFancyDescription()
{
/* A lot of stuff, see RogueLibs' source code for more information */
}
Pro-tip

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:

PresentUnlock.cs
public class PresentUnlock : ItemUnlock
{
}

Now you can override the DisplayedUnlock's GetImage method:

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:

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
});
}
}

The project's repository is archived as part of the GitHub Archive Program. RogueLibs' code and the documentation will no longer be updated.