Edit:
Some of the assumptions made by Yuushi are correct and I wish to state them here:
EntityDatabase is the base class for all Databases such as ItemDatabase. It contains raw pointers to objects created after reading the appropriate Json-File.
template <typename DataType>
class EntityDatabase
{
public:
typedef std::map<EntityId, DataType*> Container;
Loading happens in the derived Databases, for example the loading of Items including Armor, Weapons, Consumables:
class ItemDatabase : public EntityDatabase<Item>
{
public:
static void load();
template <typename ItemType>
static void load(std::string const& filename)
{
PropertyTree propertyTree;
boost::property_tree::read_json(filename, propertyTree);
for (auto& jsonItem : propertyTree)
{
Item *item = new ItemType();
item->fromJson(jsonItem);
database_[item->id()] = item;
}
}
Further, Weapon, Armor, Consumable are all of type Item
:
class Item
{
Item();
virtual ~Item();
//....
}
class Weapon : public Item
{
//...
}
class Armor : public Item
{
//...
}
ItemDatabase::find() returns a unique_ptr<Item>
, a deep copy of the pointer object to be owned by only one person:
static std::unique_ptr<Item> find(EntityId const& id)
{
auto item = database_.find(id);
if (item != std::end(database_))
return std::unique_ptr<Item>(new Item(**item));
else
return nullptr;
}
The Inventory class I showed whose weapon_
and armor_
fields must be set looks like this:
class Inventory : public JsonObject
{
public:
Inventory();
~Inventory();
virtual void fromJson(PropertyTree::value_type const& properties) override;
virtual void toJson(PropertyTree& propertyTree);
void equipWeapon(Weapon *weapon);
void removeWeapon();
std::shared_ptr<Weapon> weapon() const;
void equipArmor(Armor *armor);
void removeArmor();
std::shared_ptr<Armor> armor() const;
void pickUpItem(Item *item);
std::shared_ptr<Item> dropItem(Item *item);
void destroyItem(Item *item);
std::shared_ptr<Item> getItem(Item *item);
std::shared_ptr<Item> findItem(std::string const& name);
bool hasItem(Item *item);
void earnMoney(Money amount);
void spendMoney(Money amount);
Money money() const;
size_t size() const;
friend std::ostream& operator<<(std::ostream& os, Inventory const& inventory);
private:
bool isBeingUsedAsAWeapon(Item *item) const;
bool isBeingUsedAsArmor(Item *item) const;
private:
std::shared_ptr<Weapon> weapon_;
std::shared_ptr<Armor> armor_;
std::vector<std::shared_ptr<Item>> inventory_;
Money money_;
};
Wherein an Item only of type Weapon can be equipped as a weapon, but both Weapon and Armor must be displayed and kept in the inventory.