1
0
cuberite-2a/source/ItemGrid.h
madmaxoft@gmail.com cf87169737 Refactored cInventory to use cItemGrid for the actual Storage
This makes the API more orthogonal and is easier to use in the plugins. Also changes in the inventory are now propagated to the needed places (armor updates to BroadcastEntityEquipment etc.) even when the inventory is changed by a plugin.

git-svn-id: http://mc-server.googlecode.com/svn/trunk@1503 0a769ca7-a7f5-676a-18bf-c427514a06d6
2013-05-24 07:30:39 +00:00

147 lines
5.3 KiB
C++

// ItemGrid.h
// Declares the cItemGrid class representing a storage for items in a XY grid (chests, dispensers, inventory etc.)
#pragma once
#include "Item.h"
// tolua_begin
class cItemGrid
{
public:
// tolua_end
/// This class is used as a callback for when a slot changes
class cListener
{
public:
/// Called whenever a slot changes
virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) = 0;
} ;
typedef std::vector<cListener *> cListeners;
cItemGrid(int a_Width, int a_Height);
~cItemGrid();
// tolua_begin
int GetWidth (void) const { return m_Width; }
int GetHeight (void) const { return m_Height; }
int GetNumSlots(void) const { return m_NumSlots; }
/// Converts XY coords into slot number; returns -1 on invalid coords
int GetSlotNum(int a_X, int a_Y) const;
// tolua_end
/// Converts slot number into XY coords; sets coords to -1 on invalid slot number. Exported in ManualBindings.cpp
void GetSlotCoords(int a_SlotNum, int & a_X, int & a_Y) const;
// tolua_begin
// Retrieve slots by coords or slot number; Logs warning and returns the first slot on invalid coords / slotnum
const cItem & GetSlot(int a_X, int a_Y) const;
cItem & GetSlot(int a_X, int a_Y);
const cItem & GetSlot(int a_SlotNum) const;
cItem & GetSlot(int a_SlotNum);
// Set slot by coords or slot number; Logs warning and doesn't set on invalid coords / slotnum
void SetSlot(int a_X, int a_Y, const cItem & a_Item);
void SetSlot(int a_X, int a_Y, short a_ItemType, char a_ItemCount, short a_ItemDamage);
void SetSlot(int a_SlotNum, const cItem & a_Item);
void SetSlot(int a_SlotNum, short a_ItemType, char a_ItemCount, short a_ItemDamage);
// Empty the specified slot; Logs warning and doesn't set on invalid coords / slotnum
void EmptySlot(int a_X, int a_Y);
void EmptySlot(int a_SlotNum);
/// Sets all items as empty
void Clear(void);
/// Returns number of items out of a_ItemStack that can fit in the storage
int HowManyCanFit(const cItem & a_ItemStack);
/** Adds as many items out of a_ItemStack as can fit.
If a_AllowNewStacks is set to false, only existing stacks can be topped up;
if a_AllowNewStacks is set to true, empty slots can be used for the rest
Returns the number of items that fit.
*/
int AddItem(cItem & a_ItemStack, bool a_AllowNewStacks);
/** Same as AddItem, but works on an entire list of item stacks.
The a_ItemStackList is modified to reflect the leftover items.
If a_AllowNewStacks is set to false, only existing stacks can be topped up;
if a_AllowNewStacks is set to true, empty slots can be used for the rest
Returns the total number of items that fit.
*/
int AddItems(cItems & a_ItemStackList, bool a_AllowNewStacks);
/** Adds (or subtracts, if a_AddToCount is negative) to the count of items in the specified slot.
If the slot is empty, ignores the call.
Returns the new count.
*/
int ChangeSlotCount(int a_SlotNum, int a_AddToCount);
/// Returns the number of items of type a_Item that are stored
int HowManyItems(const cItem & a_Item);
/// Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack
bool HasItems(const cItem & a_ItemStack);
/// Returns the index of the first empty slot; -1 if all full
int GetFirstEmptySlot(void) const;
/// Returns the index of the last empty slot; -1 if all full
int GetLastEmptySlot(void) const;
/// Returns the index of the first empty slot following a_StartFrom (a_StartFrom is not checked)
int GetNextEmptySlot(int a_StartFrom) const;
/// Copies the contents into a cItems object; preserves the original a_Items contents
void CopyToItems(cItems & a_Items) const;
/// Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact)
bool DamageItem(int a_SlotNum, short a_Amount);
// tolua_end
/** Generates random loot from the specified loot probability table, with a chance of enchanted books added.
A total of a_NumSlots are taken by the loot.
Cannot export to Lua due to raw array a_LootProbabs. TODO: Make this exportable / export through ManualBindings.cpp with a Lua table as LootProbabs
*/
void GenerateRandomLootWithBooks(const cLootProbab * a_LootProbabs, int a_CountLootProbabs, int a_NumSlots, int a_Seed);
/// Adds a callback that gets called whenever a slot changes. Must not be called from within the listener callback!
void AddListener(cListener & a_Listener);
/// Removes a slot-change-callback. Must not be called from within the listener callback!
void RemoveListener(cListener & a_Listener);
// tolua_begin
protected:
int m_Width;
int m_Height;
int m_NumSlots; // m_Width * m_Height, for easier validity checking in the access functions
cItem * m_Slots; // x + m_Width * y
cListeners m_Listeners; ///< Listeners which should be notified on slot changes; the pointers are not owned by this object
cCriticalSection m_CSListeners; ///< CS that guards the m_Listeners against multi-thread access
bool m_IsInTriggerListeners; ///< Set to true while TriggerListeners is running, to detect attempts to manipulate listener list while triggerring
/// Calls all m_Listeners for the specified slot number
void TriggerListeners(int a_SlotNum);
} ;
// tolua_end