2013-04-10 15:52:03 -04:00
|
|
|
|
|
|
|
// 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
|
2013-05-24 03:30:39 -04:00
|
|
|
|
|
|
|
/// 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;
|
|
|
|
|
2013-04-10 15:52:03 -04:00
|
|
|
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
|
2013-05-24 05:16:09 -04:00
|
|
|
|
2013-04-10 15:52:03 -04:00
|
|
|
/// 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;
|
2013-05-24 05:16:09 -04:00
|
|
|
|
2013-04-10 15:52:03 -04:00
|
|
|
// tolua_begin
|
|
|
|
|
2013-04-10 17:03:15 -04:00
|
|
|
// 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;
|
|
|
|
const cItem & GetSlot(int a_SlotNum) const;
|
2013-04-10 15:52:03 -04:00
|
|
|
|
2013-04-10 17:03:15 -04:00
|
|
|
// 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);
|
2013-04-10 15:52:03 -04:00
|
|
|
|
2013-05-24 03:30:39 -04:00
|
|
|
// 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);
|
|
|
|
|
2013-06-13 02:13:56 -04:00
|
|
|
/// Returns true if the specified slot is empty or the slot doesn't exist
|
|
|
|
bool IsSlotEmpty(int a_SlotNum) const;
|
|
|
|
|
|
|
|
/// Returns true if the specified slot is empty or the slot doesn't exist
|
|
|
|
bool IsSlotEmpty(int a_X, int a_Y) const;
|
|
|
|
|
2013-04-10 15:52:03 -04:00
|
|
|
/// 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);
|
|
|
|
|
2013-05-24 03:30:39 -04:00
|
|
|
/** 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;
|
2013-07-03 09:56:11 -04:00
|
|
|
if a_AllowNewStacks is set to true, empty slots can be used for the rest.
|
|
|
|
If a_PrioritarySlot is set to a positive value, then the corresponding slot will be used in
|
|
|
|
first (if empty or compatible with added items)
|
|
|
|
if a_PrioritarySlot is set to -1, regular order apply
|
2013-05-24 03:30:39 -04:00
|
|
|
Returns the number of items that fit.
|
|
|
|
*/
|
2013-07-03 09:56:11 -04:00
|
|
|
int AddItem(cItem & a_ItemStack, bool a_AllowNewStacks = true, int a_PrioritarySlot = -1);
|
2013-05-24 03:30:39 -04:00
|
|
|
|
|
|
|
/** 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;
|
2013-07-03 09:56:11 -04:00
|
|
|
if a_AllowNewStacks is set to true, empty slots can be used for the rest.
|
|
|
|
If a_PrioritarySlot is set to a positive value, then the corresponding slot will be used in
|
|
|
|
first (if empty or compatible with added items)
|
|
|
|
if a_PrioritarySlot is set to -1, regular order apply
|
2013-05-24 03:30:39 -04:00
|
|
|
Returns the total number of items that fit.
|
|
|
|
*/
|
2013-07-03 09:56:11 -04:00
|
|
|
int AddItems(cItems & a_ItemStackList, bool a_AllowNewStacks = true, int a_PrioritarySlot = -1);
|
2013-05-24 03:30:39 -04:00
|
|
|
|
|
|
|
/** 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);
|
2013-04-10 15:52:03 -04:00
|
|
|
|
2013-05-24 05:16:09 -04:00
|
|
|
/** 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_X, int a_Y, int a_AddToCount);
|
|
|
|
|
2013-05-26 16:18:56 -04:00
|
|
|
/** Removes one item from the stack in the specified slot, and returns it.
|
|
|
|
If the slot was empty, returns an empty item
|
|
|
|
*/
|
2013-05-26 10:34:26 -04:00
|
|
|
cItem RemoveOneItem(int a_SlotNum);
|
|
|
|
|
2013-05-26 16:18:56 -04:00
|
|
|
/** Removes one item from the stack in the specified slot, and returns it.
|
|
|
|
If the slot was empty, returns an empty item
|
|
|
|
*/
|
2013-05-26 10:34:26 -04:00
|
|
|
cItem RemoveOneItem(int a_X, int a_Y);
|
|
|
|
|
2013-05-24 03:30:39 -04:00
|
|
|
/// 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);
|
2013-04-10 15:52:03 -04:00
|
|
|
|
|
|
|
/// Returns the index of the first empty slot; -1 if all full
|
|
|
|
int GetFirstEmptySlot(void) const;
|
|
|
|
|
2013-05-25 07:59:13 -04:00
|
|
|
/// Returns the index of the first non-empty slot; -1 if all empty
|
|
|
|
int GetFirstUsedSlot(void) const;
|
|
|
|
|
2013-04-10 15:52:03 -04:00
|
|
|
/// Returns the index of the last empty slot; -1 if all full
|
|
|
|
int GetLastEmptySlot(void) const;
|
|
|
|
|
2013-05-25 07:59:13 -04:00
|
|
|
/// Returns the index of the last used slot; -1 if all empty
|
|
|
|
int GetLastUsedSlot(void) const;
|
|
|
|
|
2013-04-10 15:52:03 -04:00
|
|
|
/// Returns the index of the first empty slot following a_StartFrom (a_StartFrom is not checked)
|
|
|
|
int GetNextEmptySlot(int a_StartFrom) const;
|
|
|
|
|
2013-05-25 07:59:13 -04:00
|
|
|
/// Returns the index of the first used slot following a_StartFrom (a_StartFrom is not checked)
|
|
|
|
int GetNextUsedSlot(int a_StartFrom) const;
|
|
|
|
|
2013-05-24 03:30:39 -04:00
|
|
|
/// Copies the contents into a cItems object; preserves the original a_Items contents
|
2013-04-10 15:52:03 -04:00
|
|
|
void CopyToItems(cItems & a_Items) const;
|
|
|
|
|
2013-05-24 03:30:39 -04:00
|
|
|
/// 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);
|
|
|
|
|
2013-05-24 05:16:09 -04:00
|
|
|
/// Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact)
|
|
|
|
bool DamageItem(int a_X, int a_Y, short a_Amount);
|
|
|
|
|
2013-04-10 15:52:03 -04:00
|
|
|
// tolua_end
|
|
|
|
|
2013-05-24 03:30:39 -04:00
|
|
|
|
2013-04-10 15:52:03 -04:00
|
|
|
/** 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.
|
2013-05-24 03:30:39 -04:00
|
|
|
Cannot export to Lua due to raw array a_LootProbabs. TODO: Make this exportable / export through ManualBindings.cpp with a Lua table as LootProbabs
|
2013-04-10 15:52:03 -04:00
|
|
|
*/
|
|
|
|
void GenerateRandomLootWithBooks(const cLootProbab * a_LootProbabs, int a_CountLootProbabs, int a_NumSlots, int a_Seed);
|
2013-05-24 03:30:39 -04:00
|
|
|
|
|
|
|
/// 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);
|
2013-04-10 15:52:03 -04:00
|
|
|
|
|
|
|
// tolua_begin
|
2013-07-03 09:56:11 -04:00
|
|
|
|
2013-04-10 15:52:03 -04:00
|
|
|
protected:
|
|
|
|
int m_Width;
|
|
|
|
int m_Height;
|
|
|
|
int m_NumSlots; // m_Width * m_Height, for easier validity checking in the access functions
|
2013-05-24 03:30:39 -04:00
|
|
|
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);
|
2013-07-03 09:56:11 -04:00
|
|
|
|
|
|
|
/** Adds up to a_Num items out of a_ItemStack, as many as can fit, in specified slot
|
|
|
|
Returns the number of items that did fit.
|
|
|
|
*/
|
|
|
|
int AddItemToSlot(const cItem & a_ItemStack, int a_Slot, int a_Num, int a_MaxStack);
|
2013-04-10 15:52:03 -04:00
|
|
|
} ;
|
|
|
|
// tolua_end
|
|
|
|
|
|
|
|
|
|
|
|
|