Currency

The currency feature built into the inventory system allows for shops to buy, sell and exchange items from one inventory to another. Each project can have their own take on what a currency is and how it functions. The currency implementation has been abstracted out so that you can implement your unique currencies in case you need to. With that being said, the currency implementation is very generic and should accommodate the majority of use cases.

Currency

Currency is an object that contains data on how it converts to another currency. It is that simple. For example let’s say that you want to implement a classic bronze, silver, and gold currency:

Bronze:

  • Max Value: 99
  • Overflow Currency: Silver

Silver:

  • Base Currency: Bronze
  • Base Exchange Rate: 1 Silver = 100 Bronze
  • Max Value: 99
  • Overflows Currency: Gold
  • Fraction Currency: Bronze

Gold:

  • Base Currency: Silver
  • Base Exchange Rate: 1 Gold = 100 Silver
  • Max Value: 99
  • Fraction Currency: Silver

And just like that we have set up currencies. This data doesn’t do anything by itself but when coupled with a Currency Collection they are used as constraints to know when and how to convert one currency to another.

You can set up as many currencies as necessary. In the example above there is only one root currency and that is Bronze. You can have many roots, but keep in mind that currencies that do not share the same root cannot be converted to one another. The conversion rate is computed by using the root base currency as reference.

//Get the dollar currency from the database.
var dollars = InventorySystemManager.GetCurrency("Dollars");

//create a variable holding 50$.
var fiftyDollars1 = new CurrencyAmount(50, dollars);

//You can use this shortcut if you find it easier to read.
var fiftyDollars2 = (50, dollars);

Currency Collection

A Currency Collection contains the collection of currencies, but it also contains the logic for adding, subtracting and dividing set of currencies. Using the previous example we could do the following:

  • 1 Silver 99 Bronze + 1 Gold 1 Silver 1 Bronze = 1 Gold 2 Silver 0 Bronze
  • 1 Silver – 99 Bronze = 1 Bronze
  • 3 Silver / 40 Bronze = quotient: 7, remainder: 20 Bronze

When dealing with shops its also useful to have price drops or price inflation. Therefore you can also do:

  • 1.5 * ( 2 Silver 1 Bronze) = 3 Silver 1 Bronze
  • 50 * (3 Silver 10 Bronze) = 1 Gold 55 Silver 0 Bronze

Note that the Currency Collection may lose precision in some equations because it always keeps currency amounts to a valid state. Using the same example we cannot have amount lower than 1 Bronze or higher than 99 Gold 99 Silver 99 Bronze (the 99 was defined the currency specification).

var dollars = InventorySystemManager.GetCurrency("Dollar");
var euro = InventorySystemManager.GetCurrency("Euro");

if (dollars.TryGetExchangeRateTo(euro, out var dollarsToEuro)) {
//The conversion is possible.
//Convert fifty dollars in euros.
var fiftyDollarsInEuros = (50*dollarsToEuro,euro);
}

// Debug the amount of currency owned.
Debug.Log(currencyOwner.CurrencyAmount);

// Add 50 Dollars to the Currency Owner.
currencyOwner.CurrencyAmount.AddCurrency(dollars,50);
Debug.Log(currencyOwner.CurrencyAmount); // 50 Dollars

// Check if the currency owner own at least 30 Dollars.
Debug.Log(currencyOwner.CurrencyAmount.HasCurrency(dollars,30));//True

// Check if the currency owner own at least 70 Dollars.
Debug.Log(currencyOwner.CurrencyAmount.HasCurrency(dollars,70));//False

// Remove 20 Dollars.
currencyOwner.CurrencyAmount.RemoveCurrency(dollars,20);
Debug.Log(currencyOwner.CurrencyAmount); // 30 Dollars

// In some cases you might have more than one currency
// Use GetAmountOf to retrieve the amount
var dollarAmount =currencyOwner.CurrencyAmount.GetAmountOf(dollars)

Currency Owner

The Currency Owner is essentially an inventory for your currency. If your character can use currency then the Currency Owner should be added to them. Currency can be anything in an abstract sense. It can be an object, a value, a concept, etc. The currency system does not impose restrictions on the type of currency used. If you’d like to implement your own currency logic you can implement the CurrencyOwner<CurrencyT> class with your own currency type. The Shop also has a Shop<CurrencyType> class that can be implemented.

var inventory = InventorySystemManager.GetInventoryIdentifier(0).Inventory;

// Get the currencyOwner from an Inventory
var currencyOwner = inventory.GetCurrencyComponent<CurrencyCollection>() as CurrencyOwner;
// Or get it directly from the Inventory Identifier.
currencyOwner = InventorySystemManager.GetInventoryIdentifier(0).CurrencyOwner;

// Get the Currency Collection from the owner.
var ownerCurrencyCollection = currencyOwner.CurrencyAmount;

// Get currency from the Inventory System Manager.
var gold = InventorySystemManager.GetCurrency("Gold");
var silver = InventorySystemManager.GetCurrency("Silver");

// Create currency Collections anywhere you need them.
CurrencyCollection otherCurrencyCollection = new CurrencyCollection();
otherCurrencyCollection.AddCurrency(new CurrencyAmount[] {(10, silver), (10, gold)});

// Add Currency.
ownerCurrencyCollection.AddCurrency(gold, 10);
ownerCurrencyCollection.AddCurrency(new CurrencyAmount[] { (10 ,silver), (10 ,gold)});
ownerCurrencyCollection.AddCurrency(otherCurrencyCollection);

// Get Currency.
ownerCurrencyCollection.GetAmountOf(gold); // returns only gold amount
ownerCurrencyCollection.GetAmountOf(silver); // returns only silver amount
// GetFullAmountAsRootCurrency returns the sum of currencies that share the same root
// Example 30 gold, 30 silver, 0 bronze (1 gold == 100 silver, 1 silver == 100 bronze)
// The function will return 30*10000+30*100+0 => 303000 
ownerCurrencyCollection.GetFullAmountAsRootCurrency(gold); 

// Remove Currency
ownerCurrencyCollection.RemoveCurrency(gold, 10);
ownerCurrencyCollection.RemoveCurrency(new CurrencyAmount[] { (10 ,silver), (10 ,gold)});
ownerCurrencyCollection.RemoveCurrency(otherCurrencyCollection);

// Set Currency
ownerCurrencyCollection.SetCurrency(new CurrencyAmount[] { (10 ,silver), (10 ,gold)});
ownerCurrencyCollection.SetCurrency(otherCurrencyCollection);

// Remove All
ownerCurrencyCollection.RemoveAll();

 

Pricing items

Item can be given a price as attributes. It is recommend to use the Currency Amounts attribute type which lets choose an array of amounts of currency. In the shop you are able to set a buy and sell price using an attribute name.