#pragma once #include #include #include #include #include #include #include "Area.h" class ItemFilter; class Inventory; class NetworkMessage; class Entity; class ItemSlot; class Item; class ItemStack; class InventoryInteraction { private: Inventory* current; Inventory* other; Direction dir; void lock(); void unlock(); void transaction(Inventory* zSource, Inventory* zTarget, ItemFilter* zFilter, Direction sourceView, Direction targetView, int count); public: InventoryInteraction(Inventory* zCurrent, Inventory* zOther, Direction dir); InventoryInteraction(const InventoryInteraction& interaction); ~InventoryInteraction(); InventoryInteraction& operator=(const InventoryInteraction& data); void endInteraction(); void pullItems(int count, ItemFilter* zFilter); void pushItems(int count, ItemFilter* zFilter); }; class MultipleInventoryLock { private: Inventory** inventories; int count; bool locked; public: MultipleInventoryLock(Inventory** inventories, int count); ~MultipleInventoryLock(); void unlock(); void lock(); }; class Inventory : public virtual Framework::ReferenceCounter { private: Framework::Array> observers; Framework::RCArray* pullSlotsOrder; Framework::RCArray* pushSlotsOrder; Framework::HashMap*>* itemCache; Framework::Critical cs; Framework::Array> afterPullStackCalls; Framework::Array> afterPushStackCalls; Framework::Array> observerAddedCalls; int nextSlotId; void updateCache(ItemSlot* zSlot, int beforeKey); protected: int dimensionId; Framework::Vec3 location; virtual bool allowPullStack(ItemSlot* zSlot, Direction dir) const; virtual bool allowPushStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int& count) const; virtual void afterPullStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int count); virtual void afterPushStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int count); virtual void updateSlot(ItemSlot* zSlot); virtual void loadInventory(Framework::StreamReader* zReader); virtual void saveInventory(Framework::StreamWriter* zWriter); void removeObserver(Entity* zSource, Framework::Text id); void addObserver(Entity* zSource, Framework::Text id); virtual void addItems( ItemStack* zItems, Direction dir, ItemFilter* zFilter); void lock(); void unlock(); public: Inventory(const Framework::Vec3 location, int dimensionId, bool hasInventory); virtual ~Inventory(); void notifyObservers(NetworkMessage* msg); const ItemSlot* zSlot(int id) const; void addSlot(ItemSlot* slot); void localTransaction(Framework::Array* zSourceSlots, Framework::Array* zTargetSlots, ItemFilter* zFilter, int count, Direction outDir, Direction inDir); ItemStack* takeItemsOut(ItemSlot* zSlot, int count, Direction dir); virtual void addItems(ItemSlot* zSlot, ItemStack* zItems, Direction dir); InventoryInteraction interactWith(Inventory* zInventory, Direction dir); void unsaveAddItem(ItemStack* zStack, Direction dir, ItemFilter* zFilter); int numberOfAddableItems(const ItemStack* zStack, Direction dir) const; Framework::ArrayIterator begin(); Framework::ArrayIterator end(); void inventoryApi(Framework::StreamReader* zRequest, NetworkMessage* zResponse, Entity* zSource); void registerAfterPullStackCall(std::function call); void registerAfterPushStackCall(std::function call); void registerObserverAddedCall( std::function call); int getDimensionId() const; Framework::Vec3 getLocation() const; friend InventoryInteraction; friend MultipleInventoryLock; private: static bool unsafeMove(Inventory* zSource, Inventory* zTarget, Framework::ArrayIterator& sourceSlot, Framework::ArrayIterator& targetSlot, Direction outDir, Direction inDir, int& count); };