18 m_Slots(a_Width * a_Height),
19 m_IsInTriggerListeners(false)
29 return ((a_SlotNum >= 0) && (a_SlotNum <
m_Slots.
size()));
39 (a_X >= 0) && (a_X <
m_Width) &&
52 LOGWARNING(
"%s: coords out of range: (%d, %d) in grid of size (%d, %d)",
68 LOGWARNING(
"%s: SlotNum out of range: %d in grid of range %d",
109 LOGWARNING(
"%s: Invalid slot number, %d out of %d slots",
143 LOGWARNING(
"%s: Invalid slot number %d out of %d slots",
162 SetSlot(a_SlotNum,
cItem(a_ItemType, a_ItemCount, a_ItemDamage));
182 LOGWARNING(
"%s: Invalid slot number %d out of %d slots",
207 LOGWARNING(
"%s: Invalid slot number %d out of %d slots",
254 return a_AllowNewStacks ? std::min(NumLeft,
m_Slots.
size() * MaxStack) : 0;
257 for (
const auto & Slot :
m_Slots)
261 if (a_AllowNewStacks)
266 else if (Slot.IsEqual(a_ItemStack))
268 NumLeft -= MaxStack - Slot.m_ItemCount;
287 LOGWARNING(
"%s: Invalid slot number %d out of %d slots",
301 PrevCount =
m_Slots[a_Slot].m_ItemCount;
303 m_Slots[a_Slot].m_ItemCount =
static_cast<char>(std::min(a_MaxStack, PrevCount + a_Num));
304 int toReturn =
m_Slots[a_Slot].m_ItemCount - PrevCount;
320 LOGWARNING(
"%s: Invalid slot number %d out of %d slots",
333 (a_PrioritySlot != -1) &&
335 m_Slots[a_PrioritySlot].IsEmpty() ||
336 m_Slots[a_PrioritySlot].IsEqual(a_ItemStack)
340 NumLeft -=
AddItemToSlot(a_ItemStack, a_PrioritySlot, NumLeft, MaxStack);
346 if (
m_Slots[i].IsEqual(a_ItemStack))
357 if (!a_AllowNewStacks)
384 for (cItems::iterator itr = a_ItemStackList.begin(); itr != a_ItemStackList.end();)
386 int NumAdded =
AddItem(*itr, a_AllowNewStacks, a_PrioritySlot);
387 if (itr->m_ItemCount == NumAdded)
389 itr = a_ItemStackList.erase(itr);
393 itr->m_ItemCount -= NumAdded;
396 TotalAdded += NumAdded;
421 if (
m_Slots[i].IsEqual(a_ItemStack))
423 int NumToRemove = std::min(NumLeft, static_cast<int>(
m_Slots[i].m_ItemCount));
424 NumLeft -= NumToRemove;
425 m_Slots[i].m_ItemCount -= NumToRemove;
427 if (
m_Slots[i].m_ItemCount <= 0)
447 LOGWARNING(
"%s: Invalid slot number %d out of %d slots, ignoring the call, returning -1",
459 if (
m_Slots[a_SlotNum].m_ItemCount <= -a_AddToCount)
467 m_Slots[a_SlotNum].m_ItemCount += a_AddToCount;
476 return m_Slots[a_SlotNum].m_ItemCount;
496 LOGWARNING(
"%s: Invalid slot number %d out of %d slots, ignoring the call, returning empty item",
511 m_Slots[a_SlotNum].m_ItemCount -= 1;
514 if (
m_Slots[a_SlotNum].m_ItemCount == 0)
549 if (Slot.IsEqual(a_Item))
551 res += Slot.m_ItemCount;
630 LOGWARNING(
"%s: Invalid slot number %d out of %d slots",
636 for (
int i = a_StartFrom + 1; i <
m_Slots.
size(); i++)
654 LOGWARNING(
"%s: Invalid slot number %d out of %d slots",
665 for (
int i = a_StartFrom + 1; i <
m_Slots.
size(); i++)
686 for (
const auto & Slot :
m_Slots)
690 a_Items.push_back(Slot);
703 LOGWARNING(
"%s: invalid slot number %d out of %d slots, ignoring.", __FUNCTION__, a_SlotNum,
m_Slots.
size());
712 return m_Slots[a_SlotNum].DamageItem(a_Amount);
732 for (
size_t i = 0; i < a_CountLootProbabs; i++)
734 TotalProbab += a_LootProbabs[i].
m_Weight;
739 for (
int i = 0; i < a_NumSlots; i++)
742 int LootRnd = Rnd % TotalProbab;
749 int NumEnchantments = Noise.
IntNoise3DInt(TotalProbab, Rnd, a_Seed) % 5;
751 for (
int j = 0; j <= NumEnchantments; j++)
759 for (
size_t j = 0; j < a_CountLootProbabs; j++)
761 LootRnd -= a_LootProbabs[j].
m_Weight;
764 CurrentLoot = a_LootProbabs[j].
m_Item;
765 if ((a_LootProbabs[j].m_MaxAmount - a_LootProbabs[j].m_MinAmount) > 0)
802 if (*itr == &a_Listener)
822 for (cListeners::iterator itr = Listeners.begin(), end = Listeners.end(); itr != end; ++itr)
824 (*itr)->OnSlotChanged(
this, a_SlotNum);
int GetSlotNum(int a_X, int a_Y) const
Converts XY coords into slot number; returns -1 on invalid coords.
std::vector< cListener * > cListeners
void TriggerListeners(int a_SlotNum)
Calls all m_Listeners for the specified slot number.
void GenerateRandomLootWithBooks(const cLootProbab *a_LootProbabs, size_t a_CountLootProbabs, int a_NumSlots, int a_Seed)
Generates random loot from the specified loot probability table, with a chance of enchanted books add...
int GetFirstUsedSlot(void) const
Returns the index of the first non-empty slot; -1 if all empty.
int IntNoise2DInt(int a_X, int a_Y) const
void EmptySlot(int a_X, int a_Y)
void CopyFrom(const cItemGrid &a_Src)
Copies all items from a_Src to this grid.
int HowManyItems(const cItem &a_Item)
Returns the number of items of type a_Item that are stored.
int RemoveItem(const cItem &a_ItemStack)
Removes the specified item from the grid, as many as possible, up to a_ItemStack.m_ItemCount.
cItemGrid(int a_Width, int a_Height)
virtual char GetMaxStackSize(void)
Returns the maximum stack size for a given item.
int ChangeSlotCount(int a_SlotNum, int a_AddToCount)
Adds (or subtracts, if a_AddToCount is negative) to the count of items in the specified slot...
static void RemoveEnchantmentWeightFromVector(cWeightedEnchantments &a_Enchantments, int a_EnchantmentID)
Remove the entire enchantment (with weight) from the vector.
static cItemHandler * GetItemHandler(int a_ItemType)
int IntNoise3DInt(int a_X, int a_Y, int a_Z) const
int GetFirstEmptySlot(void) const
Returns the index of the first empty slot; -1 if all full.
void CopyToItems(cItems &a_Items) const
Copies the contents into a cItems object; preserves the original a_Items contents.
static void AddItemEnchantmentWeights(cWeightedEnchantments &a_Enchantments, short a_ItemType, int a_EnchantmentLevel)
Add enchantment weights from item to the vector.
cItem RemoveOneItem(int a_SlotNum)
Removes one item from the stack in the specified slot, and returns it.
void Clear(void)
Sets all items as empty.
This class is used as a callback for when a slot changes.
cListeners m_Listeners
Listeners which should be notified on slot changes; the pointers are not owned by this object...
void AddListener(cListener &a_Listener)
Adds a callback that gets called whenever a slot changes.
bool IsSlotEmpty(int a_SlotNum) const
Returns true if the specified slot is empty or the slot doesn't exist.
cEnchantments m_Enchantments
int IntNoise1DInt(int a_X) const
bool HasItems(const cItem &a_ItemStack)
Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack.
std::vector< cWeightedEnchantment > cWeightedEnchantments
void RemoveListener(cListener &a_Listener)
Removes a slot-change-callback.
bool m_IsInTriggerListeners
Set to true while TriggerListeners is running, to detect attempts to manipulate listener list while t...
void Add(const cEnchantments &a_Other)
Adds the enchantments contained in a_Other into this object.
void GetSlotCoords(int a_SlotNum, int &a_X, int &a_Y) const
Converts slot number into XY coords; sets coords to -1 on invalid slot number.
int AddItem(cItem &a_ItemStack, bool a_AllowNewStacks=true, int a_PrioritySlot=-1)
Adds as many items out of a_ItemStack as can fit.
void LOGWARNING(const char *a_Format, fmt::ArgList a_ArgList)
int GetLastEmptySlot(void) const
Returns the index of the last empty slot; -1 if all full.
size_type size() const NOEXCEPT
int GetLastUsedSlot(void) const
Returns the index of the last used slot; -1 if all empty.
int GetNextUsedSlot(int a_StartFrom) const
Returns the index of the first used slot following a_StartFrom (a_StartFrom is not checked) ...
int HowManyCanFit(const cItem &a_ItemStack, bool a_AllowNewStacks=true)
Returns number of items out of a_ItemStack that can fit in the storage.
cLazyArray< cItem > m_Slots
char GetMaxStackSize(void) const
Returns the maximum amount of stacked items of this type.
cCriticalSection m_CSListeners
CS that guards the m_Listeners against multi-thread access.
bool IsValidSlotNum(int a_SlotNum) const
Returns true if slot number is within the grid.
RAII for cCriticalSection - locks the CS on creation, unlocks on destruction.
Used to store loot probability tables.
bool IsValidSlotCoords(int a_X, int a_Y) const
Returns true if slot coordinates lie within the grid.
Class that stores item enchantments or stored-enchantments The enchantments may be serialized to a st...
const cItem & GetSlot(int a_X, int a_Y) const
static void CheckEnchantmentConflictsFromVector(cWeightedEnchantments &a_Enchantments, cEnchantments a_FirstEnchantment)
Check enchantment conflicts from enchantments from the vector.
int AddItemToSlot(const cItem &a_ItemStack, int a_Slot, int a_Num, int a_MaxStack)
Adds up to a_Num items out of a_ItemStack, as many as can fit, in specified slot Returns the number o...
int AddItems(cItems &a_ItemStackList, bool a_AllowNewStacks=true, int a_PrioritySlot=-1)
Same as AddItem, but works on an entire list of item stacks.
int GetNextEmptySlot(int a_StartFrom) const
Returns the index of the first empty slot following a_StartFrom (a_StartFrom is not checked) ...
cItemHandler * ItemHandler(int a_ItemType)
bool IsStorageAllocated() const NOEXCEPT
Returns true if the array has already been allocated.
const T & GetAt(size_type a_Idx) const
A const view of an element of the array.
static cEnchantments SelectEnchantmentFromVector(const cWeightedEnchantments &a_Enchantments, int a_Seed)
Selects one enchantment from a Vector using cNoise.
This class bridges a vector of cItem for safe access via Lua.
bool DamageItem(int a_SlotNum, short a_Amount)
Adds the specified damage to the specified item; returns true if the item broke (but the item is left...
void SetSlot(int a_X, int a_Y, const cItem &a_Item)