C# Inventory System: Modify a targeted character's stats

So I’m pretty new to coding but I’ve been working on a simple inventory and I decided to redo my item classes after some thinking.

One of the classes (which inherits from the item class) is called StatItem. Which is just an item class for items which modify stats on a character.

It only has 2 additional variables, the int BuffAmount and the Attribute TargetAttribute (the attribute class has 3 values: name, basevalue and buffvalue)

public class StatItem : Item {
	public int buffAmount;
	public Attribute targetAttribute;
	
	public StatItem (...(the item class constructors)..., int amountToBuff, Attribute attributeBuffed)
	{
		buffAmount = amountToBuff;
		targetAttribute = attributeBuffed;
	}
	  	
	public static void UseStatItem (StatItem itemUsed){

		itemUsed.targetAttribute._buffValue += itemUsed.buffAmount;
		Debug.Log ("function " + itemUsed.targetAttribute._name + itemUsed.targetAttribute._buffValue);
	}

So with my current method I can define in the ItemDatabase which Attribute is targeted, which for the moment is:

GameObject.FindGameObjectWithTag("Player").GetComponent().playerStats.strength;

.

However!! I’d like to be able to define the target character in the UseStatItem method but still have which attribute on that character (ie strength, agility…) defined on the database.

So my initial plan was on the database to have target.strength as the Attribute (target being a CharacterAttributes variable that I made a class of) and then define the target in the method. However for some reason (and my theory is, is that it’s because the database is created OnStart and then not updated) the target CharacterAttributes is updated but the targetAttribute is not.

I hope I’ve explained okay :s

So basically what catastrophically dumb thing am I doing, is there a way of doing what I want? Am I making it all too complicated?

Am I right to assume:

  • You want StatItem to store what kind of attribute (e.g. Strength, Agility) in general it is targetting
  • You want your StatItem to get a reference to the attribute of matching kind in a given player’s stats and modify it (in UseStatItem(StatItem itemUsed))

Considering the fact that you propably won’t change your list of attributes much (like adding new attributes called “proficience in solving theoretical problems” at runtime) I think creating an enum that holds all of your attribute-types, and then writing a getter-method for attributes should suffice:

public enum EAttributeTypes
{
    Strength,
    Agility,
    ...
}

// StatItem class

public class StatItem : Item {
     public int buffAmount;
     public EAttributeType targetAttribute;
     
     public StatItem (...(the item class constructors)..., int amountToBuff, EAttributeType attributeBuffed)
         : base(...(the item class constructors)...)
     {
         buffAmount = amountToBuff;
         targetAttribute = attributeBuffed;
     }
           
     public static void UseStatItem (StatItem itemUsed, CharacterStats target){
 
         target.GetAttribute(itemUsed.targetAttribute)._buffValue += itemUsed.buffAmount;
     }

And inside your CharacterStats (or wherever you store your character’s attributes) have a method that looks roughly like this:

public Attribute GetAttribute(EAttributeType type)
{
    switch(type)
    {
    case EAttributeType.Strength:
        return strength;
    case EAttributeType.Agility:
        return agility;
    //...
    }
}

You may want to rename your Attribute class. There’s already a class called Attribute in namespace System so if you use this namespace in any class that also has references to one of your attributes your code will produce errors (your compiler does not guess which Attribute it is looking at, therefore you have to tell it explicitly)