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.

Combinable Items

Custom items can be made combinable with other items by implementing the IItemCombinable interface. You can define what kind of items your item is combinable with, what happens when you combine these items, and what tooltips to display in the combinable item's cell, and when hovering over it.

Making items combinable

Just implement the IItemCombinable interface in your item's class:

MyCombinableItem.cs
public class MyCombinableItem : CustomItem, IItemCombinable
{
public bool CombineFilter(InvItem other) { /* ... */ }
public bool CombineItems(InvItem other) { /* ... */ }
public CustomTooltip CombineTooltip(InvItem other) { /* ... */ }
public CustomTooltip CombineCursorText(InvItem other) { /* ... */ }
}

Plus, your item's type must be "Combine":

    public override void SetupDetails()
{
Item.itemType = ItemTypes.Combine;
/* ... */
}

CombineFilter determines what items will be highlighted, when combining the current item.

CombineItems combines the current item with the other one. The return value indicates whether it was a success or not. Usually you'd just play a "CantDo" sound, if the items cannot be combined. Returning true will also play an animation.

CombineTooltip determines the tooltip in the upper-left corner of the inventory slot. Text set to null will default to an empty string, and Color set to null will default to

#FFED00
. See the tool below.

CombineCursorText determines the cursor text when hovering over the item. Text set to null will default to "Combine", and Color set to null will default to

#FFFFFF
.

Inventory Slot Preview

Wanna see how your CombineTooltip will look in the game? Check out this small tool:

$123

Examples

A pretty complicated example with a lot of math.

using UnityEngine;

namespace RogueLibsCore.Test
{
[ItemCategories(RogueCategories.Technology, RogueCategories.GunAccessory, RogueCategories.Guns)]
public class AmmoBox : CustomItem, IItemCombinable
{
[RLSetup]
public static void Setup()
{
RogueLibs.CreateCustomItem<AmmoBox>()
.WithName(new CustomNameInfo("Ammo Box"))
.WithDescription(new CustomNameInfo("Combine with any refillable weapon to refill it. Limited ammo."))
.WithSprite(Properties.Resources.AmmoBox)
.WithUnlock(new ItemUnlock
{
UnlockCost = 10,
LoadoutCost = 5,
CharacterCreationCost = 3,
Prerequisites = { VanillaItems.KillAmmunizer },
});
}

public override void SetupDetails()
{
Item.itemType = ItemTypes.Combine;
Item.itemValue = 4;
Item.initCount = 100;
Item.rewardCount = 200;
Item.hasCharges = true;
Item.stackable = true;
}
public bool CombineFilter(InvItem other) => other.itemType == ItemTypes.WeaponProjectile && !other.noRefills;
public bool CombineItems(InvItem other)
{
if (!CombineFilter(other))
{
gc.audioHandler.Play(Owner, VanillaAudio.CantDo);
return false;
}
if (other.invItemCount >= other.maxAmmo)
{
Owner!.SayDialogue("AmmoDispenserFull");
gc.audioHandler.Play(Owner, VanillaAudio.CantDo);
return false;
}

int amountToRefill = other.maxAmmo - other.invItemCount;
float singleCost = (float)other.itemValue / other.maxAmmo;
if (Owner!.oma.superSpecialAbility && Owner.agentName is VanillaAgents.Soldier or VanillaAgents.Doctor)
singleCost = 0f;

int affordableAmount = (int)Mathf.Ceil(Count / singleCost);
int willBeBought = Mathf.Min(affordableAmount, amountToRefill);
int willBeReduced = (int)Mathf.Min(Count, willBeBought * singleCost);

Count -= willBeReduced;
other.invItemCount += willBeBought;
Owner.SayDialogue("AmmoDispenserFilled");
gc.audioHandler.Play(Owner, VanillaAudio.BuyItem);
return true;
}

public CustomTooltip CombineTooltip(InvItem other)
{
if (!CombineFilter(other)) return default;

int amountToRefill = other.maxAmmo - other.invItemCount;
if (amountToRefill == 0) return default;

float singleCost = (float)other.itemValue / other.maxAmmo;
if (Owner!.oma.superSpecialAbility && Owner.agentName is VanillaAgents.Soldier or VanillaAgents.Doctor)
singleCost = 0f;
int cost = (int)Mathf.Floor(amountToRefill * singleCost);
int canAfford = (int)Mathf.Ceil(Count / singleCost);

return "+" + Mathf.Min(amountToRefill, canAfford) + " (" + Mathf.Min(cost, Count) + ")";
}

public CustomTooltip CombineCursorText(InvItem other) => gc.nameDB.GetName("RefillGun", NameTypes.Interface);
// it's one of the vanilla dialogues, so there's no need to define it in the mod
}
}

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