2012-03-10 12:43:48 +01:00
|
|
|
#ifndef GAME_MWWORLD_INVENTORYSTORE_H
|
|
|
|
#define GAME_MWWORLD_INVENTORYSTORE_H
|
|
|
|
|
|
|
|
#include "containerstore.hpp"
|
|
|
|
|
2014-02-23 20:11:05 +01:00
|
|
|
namespace ESM
|
|
|
|
{
|
|
|
|
struct MagicEffect;
|
|
|
|
}
|
|
|
|
|
2012-03-31 17:26:15 +02:00
|
|
|
namespace MWMechanics
|
|
|
|
{
|
2012-08-13 13:53:54 -04:00
|
|
|
class NpcStats;
|
2012-03-31 17:26:15 +02:00
|
|
|
}
|
|
|
|
|
2012-03-10 12:43:48 +01:00
|
|
|
namespace MWWorld
|
|
|
|
{
|
2013-11-15 02:08:36 +01:00
|
|
|
class InventoryStoreListener
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Fired when items are equipped or unequipped
|
|
|
|
*/
|
|
|
|
virtual void equipmentChanged() {}
|
|
|
|
|
2020-03-26 12:07:32 +04:00
|
|
|
virtual ~InventoryStoreListener() = default;
|
2013-11-15 02:08:36 +01:00
|
|
|
};
|
|
|
|
|
2012-03-10 12:43:48 +01:00
|
|
|
///< \brief Variant of the ContainerStore for NPCs
|
|
|
|
class InventoryStore : public ContainerStore
|
|
|
|
{
|
2012-03-13 13:31:11 +01:00
|
|
|
public:
|
2021-03-21 13:56:56 +01:00
|
|
|
static constexpr int Slot_Helmet = 0;
|
|
|
|
static constexpr int Slot_Cuirass = 1;
|
|
|
|
static constexpr int Slot_Greaves = 2;
|
|
|
|
static constexpr int Slot_LeftPauldron = 3;
|
|
|
|
static constexpr int Slot_RightPauldron = 4;
|
|
|
|
static constexpr int Slot_LeftGauntlet = 5;
|
|
|
|
static constexpr int Slot_RightGauntlet = 6;
|
|
|
|
static constexpr int Slot_Boots = 7;
|
|
|
|
static constexpr int Slot_Shirt = 8;
|
|
|
|
static constexpr int Slot_Pants = 9;
|
|
|
|
static constexpr int Slot_Skirt = 10;
|
|
|
|
static constexpr int Slot_Robe = 11;
|
|
|
|
static constexpr int Slot_LeftRing = 12;
|
|
|
|
static constexpr int Slot_RightRing = 13;
|
|
|
|
static constexpr int Slot_Amulet = 14;
|
|
|
|
static constexpr int Slot_Belt = 15;
|
|
|
|
static constexpr int Slot_CarriedRight = 16;
|
|
|
|
static constexpr int Slot_CarriedLeft = 17;
|
|
|
|
static constexpr int Slot_Ammunition = 18;
|
2012-03-13 13:31:11 +01:00
|
|
|
|
|
|
|
static constexpr int Slots = 19;
|
|
|
|
|
2018-03-03 14:16:21 +04:00
|
|
|
static constexpr int Slot_NoSlot = -1;
|
2013-11-15 02:08:36 +01:00
|
|
|
|
2013-11-13 18:51:28 +01:00
|
|
|
private:
|
|
|
|
InventoryStoreListener* mInventoryListener;
|
|
|
|
|
2013-11-14 14:41:10 +01:00
|
|
|
// Enables updates of magic effects and actor model whenever items are equipped or unequipped.
|
|
|
|
// This is disabled during autoequip to avoid excessive updates
|
|
|
|
bool mUpdatesEnabled;
|
|
|
|
|
2012-03-31 17:26:15 +02:00
|
|
|
bool mFirstAutoEquip;
|
|
|
|
|
2013-11-13 18:51:28 +01:00
|
|
|
typedef std::vector<ContainerStoreIterator> TSlots;
|
2012-03-13 13:31:11 +01:00
|
|
|
|
2018-03-03 14:16:21 +04:00
|
|
|
TSlots mSlots;
|
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
void autoEquipWeapon(TSlots& slots_);
|
|
|
|
void autoEquipArmor(TSlots& slots_);
|
|
|
|
void autoEquipShield(TSlots& slots_);
|
2012-05-29 12:35:03 +02:00
|
|
|
|
2012-03-13 13:31:11 +01:00
|
|
|
// selected magic item (for using enchantments of type "Cast once" or "Cast when used")
|
|
|
|
ContainerStoreIterator mSelectedEnchantItem;
|
|
|
|
|
2013-11-12 23:23:19 +01:00
|
|
|
void copySlots(const InventoryStore& store);
|
2012-03-31 17:26:15 +02:00
|
|
|
|
2015-04-06 15:13:09 +12:00
|
|
|
void initSlots(TSlots& slots_);
|
2013-11-13 18:51:28 +01:00
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
void fireEquipmentChangedEvent();
|
2014-02-01 17:07:08 +01:00
|
|
|
|
2017-02-28 14:43:20 +00:00
|
|
|
void storeEquipmentState(
|
2020-10-16 22:18:54 +04:00
|
|
|
const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const override;
|
|
|
|
void readEquipmentState(
|
2017-02-28 14:43:20 +00:00
|
|
|
const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory) override;
|
2016-10-18 14:03:11 +02:00
|
|
|
|
2017-02-26 21:24:51 +00:00
|
|
|
ContainerStoreIterator findSlot(int slot) const;
|
2012-03-13 13:31:11 +01:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
public:
|
2012-03-13 13:31:11 +01:00
|
|
|
InventoryStore();
|
|
|
|
|
|
|
|
InventoryStore(const InventoryStore& store);
|
|
|
|
|
|
|
|
InventoryStore& operator=(const InventoryStore& store);
|
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
const MWWorld::Ptr& getActor() const { return mActor; }
|
|
|
|
void setActor(const MWWorld::Ptr& actor) { mActor = actor; }
|
|
|
|
|
2023-01-17 03:04:34 +01:00
|
|
|
std::unique_ptr<ContainerStore> clone() override
|
|
|
|
{
|
|
|
|
auto res = std::make_unique<InventoryStore>(*this);
|
|
|
|
res->clearRefNums();
|
|
|
|
return res;
|
|
|
|
}
|
2014-01-19 11:42:58 +01:00
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
ContainerStoreIterator add(
|
|
|
|
const Ptr& itemPtr, int count, bool allowAutoEquip = true, bool resolve = true) override;
|
2013-08-07 14:45:23 +02:00
|
|
|
///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed)
|
2019-10-28 01:58:23 +03:00
|
|
|
/// Auto-equip items if specific conditions are fulfilled and allowAutoEquip is true (see the implementation).
|
2013-08-07 14:45:23 +02:00
|
|
|
///
|
|
|
|
/// \note The item pointed to is not required to exist beyond this function call.
|
|
|
|
///
|
|
|
|
/// \attention Do not add items to an existing stack by increasing the count instead of
|
|
|
|
/// calling this function!
|
|
|
|
///
|
|
|
|
/// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to
|
|
|
|
/// the newly inserted item.
|
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
void equip(int slot, const ContainerStoreIterator& iterator);
|
2014-08-28 00:41:52 +02:00
|
|
|
///< \warning \a iterator can not be an end()-iterator, use unequip function instead
|
2012-05-29 12:35:03 +02:00
|
|
|
|
2015-12-18 17:06:58 +01:00
|
|
|
bool isEquipped(const MWWorld::ConstPtr& item);
|
2014-12-15 13:47:34 +01:00
|
|
|
///< Utility function, returns true if the given item is equipped in any slot
|
|
|
|
|
2012-05-29 12:35:03 +02:00
|
|
|
void setSelectedEnchantItem(const ContainerStoreIterator& iterator);
|
|
|
|
///< set the selected magic item (for using enchantments of type "Cast once" or "Cast when used")
|
|
|
|
/// \note to unset the selected item, call this method with end() iterator
|
|
|
|
|
|
|
|
ContainerStoreIterator getSelectedEnchantItem();
|
|
|
|
///< @return selected magic item (for using enchantments of type "Cast once" or "Cast when used")
|
|
|
|
/// \note if no item selected, return end() iterator
|
2012-03-13 13:31:11 +01:00
|
|
|
|
|
|
|
ContainerStoreIterator getSlot(int slot);
|
2017-02-26 21:24:51 +00:00
|
|
|
ConstContainerStoreIterator getSlot(int slot) const;
|
2012-03-31 17:26:15 +02:00
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
ContainerStoreIterator getPreferredShield();
|
2020-12-29 01:40:30 +00:00
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
void unequipAll();
|
2013-08-06 11:20:51 +02:00
|
|
|
///< Unequip all currently equipped items.
|
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
void autoEquip();
|
2012-03-31 17:26:15 +02:00
|
|
|
///< Auto equip items according to stats and item value.
|
2012-05-13 14:58:38 +02:00
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
bool stacks(const ConstPtr& ptr1, const ConstPtr& ptr2) const override;
|
2012-05-13 14:58:38 +02:00
|
|
|
///< @return true if the two specified objects can stack with each other
|
|
|
|
|
2020-10-26 20:13:24 +01:00
|
|
|
using ContainerStore::remove;
|
2023-01-16 23:51:04 +01:00
|
|
|
int remove(const Ptr& item, int count, bool equipReplacement = 0, bool resolve = true) override;
|
2013-08-13 01:19:33 +02:00
|
|
|
///< Remove \a count item(s) designated by \a item from this inventory.
|
|
|
|
///
|
|
|
|
/// @return the number of items actually removed
|
2013-11-01 00:54:54 +01:00
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
ContainerStoreIterator unequipSlot(int slot, bool applyUpdates = true);
|
2013-11-01 01:01:55 +01:00
|
|
|
///< Unequip \a slot.
|
|
|
|
///
|
|
|
|
/// @return an iterator to the item that was previously in the slot
|
2013-11-01 00:21:15 +01:00
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
ContainerStoreIterator unequipItem(const Ptr& item);
|
2013-11-01 00:21:15 +01:00
|
|
|
///< Unequip an item identified by its Ptr. An exception is thrown
|
|
|
|
/// if the item is not currently equipped.
|
|
|
|
///
|
|
|
|
/// @return an iterator to the item that was previously in the slot
|
|
|
|
/// (it can be re-stacked so its count may be different than when it
|
|
|
|
/// was equipped).
|
2013-11-15 02:08:36 +01:00
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
ContainerStoreIterator unequipItemQuantity(const Ptr& item, int count);
|
2016-01-18 19:56:35 -06:00
|
|
|
///< Unequip a specific quantity of an item identified by its Ptr.
|
|
|
|
/// An exception is thrown if the item is not currently equipped,
|
|
|
|
/// if count <= 0, or if count > the item stack size.
|
|
|
|
///
|
|
|
|
/// @return an iterator to the unequipped items that were previously
|
|
|
|
/// in the slot (they can be re-stacked so its count may be different
|
|
|
|
/// than the requested count).
|
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
void setInvListener(InventoryStoreListener* listener);
|
2013-11-15 02:08:36 +01:00
|
|
|
///< Set a listener for various events, see \a InventoryStoreListener
|
2013-11-15 20:29:47 +01:00
|
|
|
|
2021-08-27 20:07:50 +02:00
|
|
|
InventoryStoreListener* getInvListener() const;
|
2015-01-05 18:52:37 +01:00
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void clear() override;
|
2014-02-01 17:07:08 +01:00
|
|
|
///< Empty container.
|
2014-12-30 01:36:31 +01:00
|
|
|
|
2021-08-27 20:07:50 +02:00
|
|
|
bool isFirstEquip();
|
2012-03-10 12:43:48 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|