[C#] Help with accessing classes by unique identifier

I am working on creating a system for creating items based on base classes.

For some of the attributes it makes sense, but I’m looking for a little help
Currently I have the weapon damage based off the ammo type loaded, but I don’t know how to have it look up the class that has .ID that matches the ammo id

public class BaseWeapon
{
public BaseWeapon()
{
private string _name;
private string _description;
private int _id;
private ItemTypes _itemtype;
private WeaponTypes _weapontype;
private BaseDamage _damage;
private int _reqammo;
private int _ammoloaded;

public enum ItemTypes{WEAPON, ARMOR}
public enum WeaponTypes{PISTOL, RIFLE, N/A}

public string ItemName{get { return _name; } set { _name = value; }
public string ItemDescription{get { return _description; } set { _description = value; }
public int ItemID{get { return _id; } set { _id = value; }
public ItemTypes ItemType{get { return _itemtype; } set { _itemtype = value; }
public WeaponTypes WeaponType{get { return _itemtype; } set { _itemtype = value; }
public BaseDamage Damage{ return _damage; } set { _damage = value; }
public int ReqAmmo{ return _reqammo; } set { _reqammo = value; }
public int AmmoLoaded{ return _ammoloaded; } set { _ammoloaded = value; }
}
}
public class BaseWeapon1: BaseWeapon
{
public BaseWeapon1()
{
ItemName = "BaseWeapon1 " + Random.Range(0,100);
ItemDescription = “This is the Description”;
ItemID = 1;
ItemType = ItemTypes.WEAPON;
WeaponType = WeaponTypes.PISTOL;
Damage.StatBaseValue = 5
Damage.StatModValue = Damage.StatBaseValue + AmmoLoaded.Damage
ReqAmmo = 1 || 2;
AmmoLoaded = 1;
}
}

public class BaseAmmo
{
public BaseAmmo()
{
private string _description;
private int _damage;
private int _id;
}
}
public class BaseAmmo
{
public BaseAmmo()
{
private string _description;
private int _damage;
private int _id;
}
}
public class 9mmAmmo : BaseAmmo
{
public BaseAmmo()
{
_description = 9mm rounds;
_damage = 10;
_id = 1;
}
}
public class 9mmAPAmmo : BaseAmmo
{
public BaseAmmo()
{
Description = 9mm Armor Peircing rounds;
Damage = 10 + Random.Range(0,10);
ID = 2;
}
}

Only thing I have come up with is making a switch statement;
Case AmmoLoaded = 1
AmmoLoaded.Damage = 9mmAmmo.Damage
Case AmmoLoaded = 2
AmmoLoaded.Damage = 9mmAPAmmo.Damage

but I feel that is messy, and there has to be a better way

I personally dont think a switch would be that bad in your case, because at some point in your code you most likely have to write down the ID’s. Another kind of similar option would be a dictionary<id, yourthing>, that’s atleast what i used for my game.
Edit: from the looks of it, it seems to me, that you dont need a subclass for every item, you could just construct the baseX with the specific values and inject behaviour if needed, to make them distinct, but that’s just a random thought.

First off, please use code tags.

You have inherited classes, but you’re not using them. Instead of having an ammo type integer variable in BaseWeapon, just have a BaseAmmo property in which you assign one of your classes - i.e. 9mmAmmo or 9mmAPAmmo. Then you just get the .Damage from that property.

Judging from “Damage.StatModValue = Damage.StatBaseValue + AmmoLoaded.Damage” in BaseWeapon1, this was the case in that bit of code, however AmmoLoaded is now an int instead of BaseAmmo. Did you copy this code from somewhere and change it partially without understanding it fully?

As a side note, the constructors in the 9mmAmmo and 9mmAPAmmo should have the same name as those class names, instead of BaseAmmo.

And lastly, just as a general C# tip: properties in which you don’t do anything custom in the get and set can be written a lot more compact:

public int Property {get; set;}

is the same as

private int _property;

public int Property{ get {return _property; } set { _property = value; }}

ValooFX - I will have to do a little learning on dictionaries. I agree with you, in the example code there would not be a reason to make a separate subclass for each weapon. In order to help with randomness of items / item drops I planning on making a few more fields that would diversify the item more.

ThomasCreate - Nice Catch on the constructor - bunch of copy pasting going on.
If I had separate ammo classes wouldn’t I have to write separate get/set functions for each? Whereas if I inherit from BaseAmmo all sub-classes use the same get/set functions?

I’m not sure how I would handle changing the AmmoLoaded if I was to assigned a subclass directly.

public 9mmAmmo AmmoLoaded

This would set AmmoLoaded.Damage to whatevever was defined in the class, however once the player changed the ammo how would I go about changing the class of AmmoLoaded without changing all the other properties?
Something like this?

Public Weapon1() Gun1
Gun1.AmmoLoaded = public 9mmAP()

I was playing around with how to code it. Originally I was going to have 3 ammo types for all weapons, in which case AmmoLoaded was going to be an int.

Damage.StatBaseValue = 10
Damage.StatModValue = Damage.StatBaseValue + Switch(AmmoLoaded)
{
case 1: 10
break;
case 2: 15
break;
case 3: 20
break;
}

However I am now planning on a more in depth version where each weapon will have specific ammunition allowed and more stats being based off the ammunition rather than the weapon.

I think you misread. It’s a good thing that you’re inheriting from BaseAmmo, keep it that way.

You’re on entirely the wrong track here, maybe I should clarify a bit more:

public class BaseWeapon
{
    public BaseAmmo LoadedAmmo { get; set; }
    public string ItemName { get; set; }
    public string ItemDescription { get; set; }
    public int ItemID { get; set; }
    //other properties...

    public abstract void Shoot();
}

public class BaseWeapon1 : BaseWeapon
{
    public BaseWeapon1()
    {
        ItemName = "BaseWeapon1 " + Random.Range(0, 100);
        ItemDescription = "This is the Description";
        ItemID = 1;
    }

    public override void Shoot()
    {
        if (LoadedAmmo == null)
            return;

        //Shoot with LoadedAmmo.Damage;
        //This will use the Damage value defined in whatever sub class that was assigned to the LoadedAmmo property.
    }
}

public class BaseAmmo
{
    public string Description { get; set; }
    public int Damage { get; set; }
    public int AmmoID { get; set; }
}

public class NineMMAmmo : BaseAmmo
{
    public NineMMAmmo()
    {
        Description = "9mm rounds";
        Damage = 10;
        AmmoID = 1;
    }
}

public class NineMMAPAmmo : BaseAmmo
{
    public NineMMAPAmmo()
    {
        Description = "9mm Armor Piercing rounds";
        Damage = 10 + Random.Range(0, 10);
        AmmoID = 2;
    }
}