Question on Item buffs

Say I have a serialized item class. how would i go about augmenting an item? can it be done without changing all items called?

what i’m getting at is, how do I create an instance of an item that I can modify from the ItemDatabase?
or am I doing it wrong?
honest criticism encouraged.

here is the item class:

using UnityEngine;
using System.Collections;

[System.Serializable]
public class Item {

    public string itemName;
    public int itemID;
    public string itemDesc;
    public Texture2D itemIcon;
    public int itemPower;
    public int itemSpeed;
    public ItemType itemType;
    public Element itemElement;
    public int itemElementProc;
    public Sharpness itemSharpness;
    public bool itemCanBeMade;
    public int idOfFirstMat;
    public int idOfSecondMat;
    public bool isArmor;
    public int itemEffect1;
    public int itemEffect2;
    public Rarity itemRarity;
    public bool itemIsStackable;
    public int maxStackCount;
    public int warChestMax;

    public enum ItemType{
        HeavyWeapon,
        MediumWeapon,
        LightWeapon,
        Consumable,
        Helmet,
        Shoulders,
        Chest,
        Belt,
        Gloves,
        Pantaloons,
        Shoes,
        Ring,
        Food,
        Vegetable,
        Energy,
        QuestItem,
        Ingredient,
        Jewel
    }
    public enum Rarity{
        Common,
        Uncommon,
        Rare,
        Rarer,
        SaughtAfter,
        Legend
    }
    public enum Element{
        None,
        Cold,
        Fiery,
        Corrosive,
        Accurate,
        Explosive,
        Lightning
        }
    public enum Sharpness{
        None,
        Dull,
        Sharp,
        Blunt
        }
    public Item(string name, int id, string desc, int power, int speed, ItemType type, Element element, int proc, Sharpness sharpness, bool canBeMade, int firstMat, int secondMat, bool armor, int effect1, int effect2, Rarity rarity, bool stackable, int maxStack, int warChestMaxStack){
        itemName = name;
        itemID = id;
        itemDesc = desc;
        itemIcon = Resources.Load<Texture2D>("Item Icons/" + name);
        itemPower = power;
        itemSpeed = speed;
        itemType = type;
        itemElement = element;
        itemElementProc = proc;
        itemSharpness = sharpness;
        itemCanBeMade = canBeMade;
        idOfFirstMat = firstMat;
        idOfSecondMat = secondMat;
        isArmor = armor;
        itemEffect1 = effect1;
        itemEffect2 = effect2;
        itemRarity = rarity;
        itemIsStackable = stackable;
        maxStackCount = maxStack;
        warChestMax = warChestMaxStack;
    }
    public Item(){
        itemID = -1;
    }
}

And here is the item database:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class ItemDatabase : MonoBehaviour {

    public List<Item> items = new List<Item>();

    void Start(){
        items.Add (new Item("Green Potion", 1, "Heals Lex for 50 HP.", 0, 0, Item.ItemType.Consumable,Item.Element.None, 0,Item.Sharpness.None, true, 5, 16, false, 50, 0, Item.Rarity.Common, true, 10, 200));
        items.Add (new Item("Meat",2,"A trading Resource.",0,0,Item.ItemType.Food,Item.Element.None, 0,Item.Sharpness.None, false, 0, 0, false, 0, 0, Item.Rarity.Rare, true, 20, 999));
        items.Add (new Item("Plastic Shank",3,"Quick stabbing weapon.",0,0,Item.ItemType.LightWeapon,Item.Element.None, 0,Item.Sharpness.Sharp, false,0,0, true, 0, 0, Item.Rarity.Common, false, 1, 1));
        items.Add (new Item("Nunchaku",4,"A fast blunt weapon.",0,0,Item.ItemType.MediumWeapon,Item.Element.None, 0,Item.Sharpness.Blunt, false,0,0, true, 0, 0, Item.Rarity.Uncommon, false, 1, 1));
        items.Add (new Item("Blackberry",5,"Material for potions.",0,0,Item.ItemType.Ingredient,Item.Element.None, 0,Item.Sharpness.None, false,0,0, false, 0, 0, Item.Rarity.Common, true, 10, 200));
        items.Add (new Item("Blueberry",6,"Material for potion, it looks sad.",0,0,Item.ItemType.Ingredient,Item.Element.None, 0,Item.Sharpness.None, false, 0,0,false, 0, 0, Item.Rarity.Common, true, 10, 200));
        items.Add (new Item("Boysenberry",7,"Material for potions.",0,0,Item.ItemType.Ingredient,Item.Element.None, 0,Item.Sharpness.None, false,0,0, false, 0, 0, Item.Rarity.Common, true, 10, 200));
        items.Add (new Item("Currant Berry",8,"Material for potions.",0,0,Item.ItemType.Ingredient,Item.Element.None, 0,Item.Sharpness.None, false,0,0, false, 0, 0, Item.Rarity.Rarer, true, 10, 200));
        items.Add (new Item("Elderberry",9,"Material for potions.",0,0,Item.ItemType.Ingredient,Item.Element.None, 0,Item.Sharpness.None, false,0,0, false, 0, 0, Item.Rarity.Common, true, 10, 200));
        items.Add (new Item("Salmonberry",10,"Material for potions.",0,0,Item.ItemType.Ingredient,Item.Element.None, 0,Item.Sharpness.None, false,0,0, false, 0, 0, Item.Rarity.Common, true, 10, 200));
        items.Add (new Item("Sea-Buckthorn Berry",11,"Material for potions.",0,0,Item.ItemType.Ingredient,Item.Element.None, 0,Item.Sharpness.None,false,0,0, false, 0, 0, Item.Rarity.Common, true, 10, 200));
        items.Add (new Item("Dave, the great and powerful",12,"Bestows deminion over the dead, and is a great apple slicer!",0,0,Item.ItemType.HeavyWeapon,Item.Element.None, 0,Item.Sharpness.None,false,0,0, true, 0, 0, Item.Rarity.Legend, false, 1, 1));
        items.Add (new Item("Natural Diamond",13, "Used as a material for item upgrades", 0, 0, Item.ItemType.Ingredient,Item.Element.None, 0,Item.Sharpness.None,false,0,0, false, 0, 0, Item.Rarity.SaughtAfter, true, 10, 200));
        items.Add (new Item("European Cut Diamond", 14, "Increases Intellect by 4", 0, 0, Item.ItemType.Jewel,Item.Element.None, 0,Item.Sharpness.None, true,13,17, true, 8, 0, Item.Rarity.Rare, true, 10, 200));
        items.Add (new Item("Point Cut Diamond", 15, "Intellect +4\nEnergy regeneration +4", 0, 0, Item.ItemType.Jewel,Item.Element.None, 0,Item.Sharpness.None, true,13,17, false, 4, 4, Item.Rarity.Rare, true, 10, 200));
        items.Add (new Item("Tea",16,"Delicious tea? or deadly poison..",0,0,Item.ItemType.Ingredient,Item.Element.None, 0,Item.Sharpness.None, false,0,0, false, 0, 0, Item.Rarity.Common, true, 10, 200));
        items.Add (new Item("Iron Ore",17,"Rock with iron bits in it.",0,0,Item.ItemType.Ingredient,Item.Element.None, 0,Item.Sharpness.None, false, 0,0, false, 0, 0, Item.Rarity.Uncommon, true, 10, 200));
        items.Add (new Item("Venom", 19, "Slightly increase attack power for one mission", 0, 0, Item.ItemType.Consumable,Item.Element.None, 0,Item.Sharpness.None, true, 6, 8, false, 5, 0, Item.Rarity.Rarer, true, 10, 200));
        items.Add (new Item("Stone soup", 20, "Slightly increase attack power for one mission", 0, 0, Item.ItemType.Consumable,Item.Element.None, 0,Item.Sharpness.None, true, 5, 8, false, 5, 0, Item.Rarity.Common, true, 10, 200));
        items.Add (new Item("Hot soup", 21, "Fire negate", 0, 0, Item.ItemType.Consumable,Item.Element.None, 0,Item.Sharpness.None, true, 11, 16, false, 5, 23, Item.Rarity.Common, true, 10, 200));
        items.Add (new Item("Freezy", 22, "Fire protection for short period", 0, 0, Item.ItemType.Consumable,Item.Element.None, 0,Item.Sharpness.None, true, 10, 23, false, 5, 0, Item.Rarity.Rare, true, 10, 200));
        items.Add (new Item("Ginseng", 23, "Herb", 0, 0, Item.ItemType.Ingredient,Item.Element.None, 0,Item.Sharpness.None, false, 0, 0, false, 0, 0, Item.Rarity.Common, true, 10, 200));
    }
    public Item GetItem(string name, int id){
        for (int i=0; i < items.Count; i++) {
            if(items[i].itemName == name){
                return items[i];
            }
            if(items[i].itemID == id){
                return items[i];
            }
        }
        return null;
    }
}

-Lamont

If you want to modify the numbers on items you’ll need to create more Item objects. For example, if you wanted to make a Green Potion that healed more you would need to create a new item with the improved values. If you modify the one in that list then all Green Potions will heal more forever.

That type of item list could be very useful for creating a catalog of the base items but if you want the player to be able to augment them you will need to create separate items. However, you can do things like create copies of the base items and then modify the values of the copies.

This is where inheritance would shine.

e.g. With SevenHams Green poition example.

You have a base class Item, Green Potion inherits from that, then Super Green Potion inherits from Green Potion. Every child class could then modify the common values of items to produce many different effects.

http://unity3d.com/learn/tutorials/modules/intermediate/scripting/inheritance

http://www.dotnetperls.com/inheritance

“The base items” is conceptually wrong to what I’m referring to with Inheritance. I suggest reading/learning those links I gave you.

Create a constructor that takes another item as the only argument then have the new constructor go through the old item and just copy the values into the new one. It’s called a copy constructor and they are very very useful.

alright so if i wanted to “modify” a green potion that is in the inventory list Inventory[1]
i would have to say something like

void Item(Item toBeCopied){
Item thisItem = toBeCopied;
thisItem.someVariable = newVariable;
Inventory[1] = thisItem;
}

right?
or would that modify the item in the database?
I’m still trying to wrap my head around it.

Item (Item toBeCopied)
{

variable1 = toBeCopied.variable1;
variable2 = toBeCopied.variable2;

variable1 = new value;

Inventory.Add(this);

}

If you did Inventory[1] = this you would overrite the original. What you want to do is create a totally new item and store it somewhere while leaving the original untouched. A copy constructor allows you to create a perfect copy of the original. Then you can mess with it either within the constructor or elsewhere. It would be better to add other functions to Item that allowed the player to modify stuff and then alter it later, without the variable1 = new value.

This is also a case where Inheritance is useful. You could make this type of Item a BaseItem and then have Item inherit from it. You could prevent BaseItems from being modified but allow modifications to Item. In this case you could have an Item constructor that takes a BaseItem as an argument and then get the values from there.

edit: Now that I think about it Inventory.Add(this) is probably not the best way to do it.

Inventory.Add(new Item(…)) would probably work better

so store the variables, there by separating them from the original and making a new item with those variables as the new items’.
like, say i wanted to use an item in my inventory as a material for “making a new item”

Item(Item materialItem){
Item newitem = new Item();
variable1 = materialItem.variable1;
variable2 = materialItem.variable2;
newitem.variable1 = variable1;
newitem.variable2 = variable2;
inventory.add(newitem);
}

That would end up creating two Items rather than one. Use this instead.

Inventory.Add(new Item(materialItem)

That would be the code you want to use to create a new item. Then for the constructor.

Item(Item materialItem)
{
variable1 = materialItem.variable1;
variable2 = materialItem.variable2;
}

If you are adding the item to the Inventory you don’t need to actually create a new variable for a new item. How you do this really depends on how you want the code to function. You can automatically have items add themselves to the inventory or do it manually. It can be useful to create the new items directly into the Inventory, however, and Inventory.Add(new Item()) basically tells the program to create a new item and add it to the end of the inventory list.

The constructor is basically just a list of instructions for what to do whenever a new item is created. From an organizational standpoint it is best to tell the item where to go elsewhere.

what im building is a blacksmith, i want to be able to use what is in my inventory as materials or ingredients for the blacksmith to make a modification of the original item, like say a Broadsword+ by using an Iron Ore and a Broadsword.
i would need to copy the Broadsword and add a +1 to one of the variables while deleting the original Broadsword and replacing it with the Broadsword+.

so what ive got so far is i need a function that passes in the items

void Blacksmith(Item broadsword, Item ironore){
bool haveIngredient1 = false;
bool haveingredient2 = false;
for(int i = 0; i < inventory.count; i++){
if(inventory.itemName == broadsword.itemName ){
haveIngredient1 = true;
}
if(inventory.itemName == ironore.itemName){
haveingredient2 = true;
}
}
if(haveIngredient1 && haveingredient2){
ironore.ammount -= 1;
broadsword.variable = newvariable;
broadsword.itemName = "Broadsword+";
inventory.functionthataddsitem(broadsword);
}
}

and this wouldnt screw with my item database?

Actually in that case you wouldn’t need to delete the original broadsword. You could just rename the original to Broadsword+ and then add one to whatever variable you wanted to modify. The best option there would be to alter whatever item was handed to the broadsword and remove the ore. It would, however, be useful to have an unmodified broadsword stored somewhere in case you wanted to add an unmodified broadsword at some point.

right, i have it stored in the ItemDatabase.
but since the inventory is an entirely new list that was “copied” from item database… does it matter?
when I made the inventory I tried to make it so it could receive unique items.

public void AddItem(Item item, int ammount){
        int overflow = 0;

        for(int j =0; j < inventory.Count; j++){
            if(inventory[j].itemIsStackable == true && stackCount[j] < inventory[j].maxStackCount){
                if(inventory[j].itemID == item.itemID){
                    stackCount[j] += ammount;
                    if(stackCount[j] > inventory[j].maxStackCount){
                        overflow = stackCount[j] - inventory[j].maxStackCount;
                        stackCount[j] = inventory[j].maxStackCount;
                        InventoryStackOverflow (item, overflow);
                    }
                break;
                }
            }
            if(inventory[j].itemID <= 0){
                stackCount[j] += ammount + 1;
                inventory[j] = item;
                if(stackCount[j] > inventory[j].maxStackCount){
                    overflow = stackCount[j] - inventory[j].maxStackCount;
                    stackCount[j] = inventory[j].maxStackCount;
                    InventoryStackOverflow (item, overflow);
                }
            break;
            }
        }
    }
    void InventoryStackOverflow(Item item, int overflowAdd){
        int overflow = 0;
        for (int i =0; i < inventory.Count; i++) {
            if(inventory[i].itemID <= 0){
                inventory[i] = item;
                stackCount[i] += overflowAdd + 1;
                if(stackCount[i] > inventory[i].maxStackCount){
                    overflow = stackCount[i] - inventory[i].maxStackCount;
                    stackCount[i] = inventory[i].maxStackCount;
                    AddItem (item, overflow);
                    break;
                }
                break;
            }
            if(i == inventory.Count && inventory[i].itemID > 0){
                Debug.Log ("Inventory is full!");
                break;
            }
        }
    }

the only time my loot system looks at the item database is when it drops loot.
so if i modify things in the inventory im safe correct?

Yes. Any time you are not modifying the original it will not modify the original. If you modify the stats on an object you are only modifying that specific object so if you create a copy and then modify the copy the original will never change. So if the only thing you ever do to the originals is copy them then they will never change.

There are actually ways to prevent yourself from accidentally modifying the originals. Look at properties, getters, setters, and constants.

thank you for taking the time to help me understand. you’re a lifesaver.