I'm making a game in Unity and I need to have a inventory/item system, I decided to store my items in simple XML document which I later read from. I'm planning to have different varieties of items and they will all have distinct classes which extend they're base interface. Here's how my hierarchy looks like for now :
IBaseItem
public interface IBaseItem
{
int ItemID { get; }
string ItemName { get; }
string Description { get; }
}
A really simple interface which contains all the common properties between all the items.
EquipementItem : IBaseItem
[System.Serializable]
public abstract class EquipementItem : IBaseItem
{
public enum ItemTypes
{
None,
Armor,
Weapon
}
public enum SlotTypes
{
Head,
Shoulders,
Chest,
Bracers,
Gloves,
Waist,
Legs,
Boots,
Weapon
}
private readonly int itemID;
public int ID
{
get { return itemID; }
}
private readonly string itemName;
public string Name
{
get { return itemName; }
}
private readonly string description;
public string Description
{
get { return description; }
}
private readonly ItemTypes itemType;
public ItemTypes ItemType
{
get { return itemType; }
}
private readonly SlotTypes slotType;
public SlotTypes SlotType
{
get { return slotType; }
}
protected EquipementItem(int itemID, string itemName, ItemTypes itemType, SlotTypes slotType, string description)
{
this.itemID = itemID;
this.itemName = itemName;
this.itemType = itemType;
this.slotType = slotType;
this.description = description;
}
}
This is the class for all the equippable items, and since the items are constant throughout the entire game I made the object immutable. However this might cause me some trouble since the constructor apparently needs too much parameters (there will be more) and I wont be able implement the Builder Pattern because of the readonly
fields. I also wonder if I need this class to be made abstract and then inherited by other classes such as Weapon & Armor for example, but I don't see any different in the implementation of those 2 so for now I have it just as a normal class.
ItemDatabase.xml
<EquipementItem>
<ID>1</ID>
<Name>Basic Sword</Name>
<ItemType>Weapon</ItemType>
<SlotType>Weapon</SlotType>
<Description>A basic sword</Description>
</EquipementItem>
<EquipementItem>
<ID>2</ID>
<Name>Advanced Sword</Name>
<ItemType>Weapon</ItemType>
<SlotType>Weapon</SlotType>
<Description>Not a basic sword</Description>
</EquipementItem>
</EquipementItems>
That's pretty much how the db will look like with a few additional tags
DatabaseBuilderEQItems : MonoBehaviour
public class DatabaseBuilderEQItems : MonoBehaviour
{
public TextAsset DatabaseFile;
public static List<EquipementItem> EquipementItems;
private void Awake()
{
if(EquipementItems == null)
{
EquipementItems = new List<EquipementItem>();
}
LoadEquipementItemsFromDB();
}
private void LoadEquipementItemsFromDB()
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(DatabaseFile.text);
XmlNodeList equipementItemList = xmlDocument.GetElementsByTagName("EquipementItem");
foreach (XmlNode equipementItem in equipementItemList)
{
XmlNodeList itemInfo = equipementItem.ChildNodes;
EquipementItem item = new EquipementItemParser(
itemInfo.Cast<XmlNode>()
.ToDictionary(itemContent => itemContent.Name, itemContent => itemContent.InnerText));
EquipementItems.Add(item);
}
}
}
This is where I read and save the items from the database.
EquipementItemParser : EquipementItem
public class EquipementItemParser : EquipementItem
{
public EquipementItemParser(IDictionary<string, string> databaseItemInfo)
: base(
int.Parse(databaseItemInfo["ID"]), databaseItemInfo["Name"],
(ItemTypes) Enum.Parse(typeof(ItemTypes), databaseItemInfo["ItemType"]),
(SlotTypes) Enum.Parse(typeof(SlotTypes), databaseItemInfo["SlotType"]),
databaseItemInfo["Description"])
{
}
}
What bothers me the most is that with my current setup where I read from the xml document if I create a new type of items I will pretty much need to rewritte a new script with almost the exact same code with the small difference of few types namely EquipementItem
& EquipementItemParser
can anything be done about that ?
Are there any flaws in my design ?
How extendable is this design ?
And overall what can be improved ?