0
\$\begingroup\$

I have a non-MonoBehaviour script called Item which contains two classes.

public class Item
{
    public string itemName;
    //public string itemRarity;

    public Item(string newItemName)
    {
        itemName = newItemName;
    }
}

and

public class ItemRandomizer
{
    List<Item> itemContainer = new List<Item>();

    public void AddItem(Item item, int amount)
    {
        for (int i = 0; i < amount; i++)
        {
            itemContainer.Add(item);
        }
    }

    public Item GetRandomItem()
    {
        int index = Random.Range(0, itemContainer.Count);

        // want to return item combined with rarity
        return itemContainer[index];
    }

I want GetRandomItem to not only return a random item "type", e.g., gloves, contained in the itemContainer list, but also combine it with a rarity (common, rare, legendary) and return that if possible.

How can I code this functionality in a flexible way so that two base items with the same drop chance can have varying drop chances when it comes to their rare versions? Swords and axes have the same drop chance, but a rare sword might be rarer than a rare axe. I'd like to maintain that kind of flexibility.

Also, if I make public string itemRarity a property of the Item class, but I want to set the rarity tier in GetRandomItem() in the ItemRandomizer class, how should I do that? Thus far, I've almost exclusively used MonoBehaviour classes so any pointers are appreciated.

\$\endgroup\$
1
  • \$\begingroup\$ By rarity, I mean tiers of rarity that are typical in ARPG games. Normal or common, magic or uncommon, rare, legendary, etc. I don't mean the actual chance of getting the item, which is 1/N. \$\endgroup\$ – embracethefuture Jul 6 '17 at 4:12
0
\$\begingroup\$
public class Item
{
    public string name, rarity;
    public Item(string name, string rarity)
    {
        this.name = name;
        this.rarity = rarity;
    }
}

Now, I would not add the same item repeatedly to the list. You can do this in a much easier way with a Dictionary:

public class ItemRandomizer
{
    Dictionary<Item, int> itemContainer;
    public ItemRandomizer() //Constructor. The "start" method of regular C# classes.
    {
        itemContainer = new Dictionary<Item, int>();
    }

    public void AddItem(Item item, int amount)
    {
        if(itemContainer.ContainsKey(item)
        {
            int items = itemContainer[item] + amount;
            itemContainer [item] = items;
        }
        else
        {
            itemContainer.Add(item, amount);
        }
    }
}

I'm not entirely sure what you want, so if I am misinterpreting you, correct me. You want to spawn an item based on its "rarity". Now, for that, you can do the following:

public Item GetRandomItem()
{
    Item returnval = null;
    bool foundItem = false;
    for(int i = Random.Range(0, itemContainer.Keys.Count); !foundItem; i = random.Range(0, itemContainer. Keys.Count))
    {
        returnval = itemContainer.Keys[i];
        string rarity = returnval.rarity;
        switch(rarity)
        {
            case "legendary":
                if(Random.Range(0, 101) <= 10) //10% chance of dropping.
                    foundItem = true;
            break;
            case "average":
                if(Random.Range(0, 101) <= 50) //50% chance of spawning
                    foundItem = true;
            break;
            //etc...
            default: break;
        }
    }
    return returnval;
}

There might be a few typos in the code, let me know if so - I'm typing this from my phone.

\$\endgroup\$
2

Not the answer you're looking for? Browse other questions tagged or ask your own question.