So, initially I was planning to create a base class, and some inherited classes like weapon/armour/etc, and each class will have an enum that specifies its type, and everything was going ok until I hit "usable items".
I ended up with creating UsableItem class, and tons of inherited classes, like Drink/Apple/SuperApple/MagickPotato/Potion/Landmine/(whatever that player can use) each with unique behaviour. I planned to store items in the SQLite database, but I discovered that there are not many ways of creating variables(pointers) with type determined at runtime (that preferably get their stats/model/icon/etc from DB). So, I think that I need to use some variation of the Factory pattern, but I have no idea how I should implement it for this particular case (giant switch/case ? ).
It would be really nice if you guys can give me some advice on how I should manage this kind of problem or maybe how I should redesign the inventory.
Inventory storage is an array of pointers. I'm working with CryEngine V, so RTTI can't be used.
Example code:
namespace Inventory
{
enum ItemType
{
Static,
Building,
Usable,
Weapon,
Armour
};
class InventoryItem
{
public:
virtual ~InventoryItem() = default;
virtual ItemType GetType() = 0;
virtual string GetName() = 0;
virtual string GetIcon() = 0;
virtual void Destroy()
{
//TODO: Notify inventory storage
delete this;
}
};
class UsableItem : public InventoryItem
{
public:
struct Usage
{
int Index;
string Use_Name;
};
virtual CryMT::vector<Usage> GetUsages() = 0;
virtual void UseItem(int usage) = 0;
};
class TestItem : public UsableItem
{
int Counter =0;
ItemType GetType() override
{
return ItemType::Usable;
}
string GetName() override
{
return "TestItem";
}
string GetIcon() override
{
return "NULL";
}
CryMT::vector<Usage> GetUsages() override
{
CryMT::vector<Usage> Usages;
Usages.push_back(Usage{1, "Dec"});
Usages.push_back(Usage{2,"Inc"});
Usages.push_back(Usage{3,"Show"});
return Usages;
}
void UseItem(int usage) override
{
CryMT::vector<Usage> uses = GetUsages();
switch (usage)
{
case 0:
for (int i =0; i<uses.size(); i++)
{
CryLog(uses[i].Use_Name);
}
break;
case 1:
Counter--;
CryLog("Dec");
CryLog("%d", Counter);
break;
case 2:
Counter++;
CryLog("Inc");
CryLog("%d", Counter);
break;
case 3:
CryLog("%d", Counter);
break;
default:
CryLog("WRONG INDEX");
break;
}
}
};
}