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 char 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 char 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 char NumToRemove = std::min<char>(NumLeft,
m_Slots[i].m_ItemCount);
424 NumLeft -= NumToRemove;
425 m_Slots[i].m_ItemCount -= NumToRemove;
427 if (
m_Slots[i].m_ItemCount <= 0)
454 if (!compare(a_RecipeItem,
m_Slots[i]) &&
455 !compare(
m_Slots[i], a_RecipeItem))
472 LOGWARNING(
"%s: Invalid slot number %d out of %d slots, ignoring the call, returning -1",
484 if (
m_Slots[a_SlotNum].m_ItemCount <= -a_AddToCount)
492 m_Slots[a_SlotNum].m_ItemCount += a_AddToCount;
494 if (
m_Slots[a_SlotNum].m_ItemCount >
m_Slots[a_SlotNum].GetMaxStackSize())
496 m_Slots[a_SlotNum].m_ItemCount =
m_Slots[a_SlotNum].GetMaxStackSize();
500 return m_Slots[a_SlotNum].m_ItemCount;
520 LOGWARNING(
"%s: Invalid slot number %d out of %d slots, ignoring the call, returning empty item",
535 m_Slots[a_SlotNum].m_ItemCount -= 1;
538 if (
m_Slots[a_SlotNum].m_ItemCount == 0)
573 if (Slot.IsEqual(a_Item))
575 res += Slot.m_ItemCount;
654 LOGWARNING(
"%s: Invalid slot number %d out of %d slots",
660 for (
int i = a_StartFrom + 1; i <
m_Slots.
size(); i++)
678 LOGWARNING(
"%s: Invalid slot number %d out of %d slots",
689 for (
int i = a_StartFrom + 1; i <
m_Slots.
size(); i++)
710 for (
const auto & Slot :
m_Slots)
714 a_Items.push_back(Slot);
727 LOGWARNING(
"%s: invalid slot number %d out of %d slots, ignoring.", __FUNCTION__, a_SlotNum,
m_Slots.
size());
736 return m_Slots[a_SlotNum].DamageItem(a_Amount);
756 for (
size_t i = 0; i < a_CountLootProbabs; i++)
758 TotalProbab += a_LootProbabs[i].
m_Weight;
763 for (
int i = 0; i < a_NumSlots; i++)
766 int LootRnd = Rnd % TotalProbab;
773 int NumEnchantments = Noise.
IntNoise3DInt(TotalProbab, Rnd, a_Seed) % 5;
775 for (
int j = 0; j <= NumEnchantments; j++)
783 for (
size_t j = 0; j < a_CountLootProbabs; j++)
785 LootRnd -= a_LootProbabs[j].
m_Weight;
788 CurrentLoot = a_LootProbabs[j].
m_Item;
789 if ((a_LootProbabs[j].m_MaxAmount - a_LootProbabs[j].m_MinAmount) > 0)
826 if (*itr == &a_Listener)
846 for (cListeners::iterator itr = Listeners.begin(), end = Listeners.end(); itr != end; ++itr)
848 (*itr)->OnSlotChanged(
this, a_SlotNum);
std::vector< cWeightedEnchantment > cWeightedEnchantments
void LOGWARNING(std::string_view a_Format, const Args &... args)
Class that stores item enchantments or stored-enchantments The enchantments may be serialized to a st...
void Add(const cEnchantments &a_Other)
Adds the enchantments contained in a_Other into this object.
static cEnchantments SelectEnchantmentFromVector(const cWeightedEnchantments &a_Enchantments, int a_Seed)
Selects one enchantment from a Vector using cNoise.
static void RemoveEnchantmentWeightFromVector(cWeightedEnchantments &a_Enchantments, int a_EnchantmentID)
Remove the entire enchantment (with weight) from the vector.
static void CheckEnchantmentConflictsFromVector(cWeightedEnchantments &a_Enchantments, const cEnchantments &a_FirstEnchantment)
Check enchantment conflicts from enchantments from the vector.
static void AddItemEnchantmentWeights(cWeightedEnchantments &a_Enchantments, short a_ItemType, unsigned a_EnchantmentLevel)
Add enchantment weights from item to the vector.
cEnchantments m_Enchantments
char GetMaxStackSize(void) const
Returns the maximum amount of stacked items of this type.
bool IsEmpty(void) const
Returns true if the item represents an empty stack - either the type is invalid, or count is zero.
Compares two items for the same type or category.
This class bridges a vector of cItem for safe access via Lua.
Used to store loot probability tables.
int GetFirstEmptySlot(void) const
Returns the index of the first empty slot; -1 if all full.
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.
char AddItems(cItems &a_ItemStackList, bool a_AllowNewStacks=true, int a_PrioritySlot=-1)
Same as AddItem, but works on an entire list of item stacks.
bool IsSlotEmpty(int a_SlotNum) const
Returns true if the specified slot is empty or the slot doesn't exist.
bool IsValidSlotCoords(int a_X, int a_Y) const
Returns true if slot coordinates lie within the grid.
void CopyFrom(const cItemGrid &a_Src)
Copies all items from a_Src to this grid.
char ChangeSlotCount(int a_SlotNum, char a_AddToCount)
Adds (or subtracts, if a_AddToCount is negative) to the count of items in the specified slot.
cItemGrid(int a_Width, int a_Height)
cCriticalSection m_CSListeners
CS that guards the m_Listeners against multi-thread access.
void TriggerListeners(int a_SlotNum)
Calls all m_Listeners for the specified slot number.
int GetLastEmptySlot(void) const
Returns the index of the last empty slot; -1 if all full.
void SetSlot(int a_X, int a_Y, const cItem &a_Item)
int GetFirstUsedSlot(void) const
Returns the index of the first non-empty slot; -1 if all empty.
std::vector< cListener * > cListeners
int GetLastUsedSlot(void) const
Returns the index of the last used slot; -1 if all empty.
char 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...
cLazyArray< cItem > m_Slots
cItem * FindItem(const cItem &a_RecipeItem)
Finds an item based on ItemType and ItemDamage (<- defines the itemType, too)
const cItem & GetSlot(int a_X, int a_Y) const
int GetNextUsedSlot(int a_StartFrom) const
Returns the index of the first used slot following a_StartFrom (a_StartFrom is not checked)
void Clear(void)
Sets all items as empty.
void EmptySlot(int a_X, int a_Y)
bool HasItems(const cItem &a_ItemStack)
Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack.
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 GetNextEmptySlot(int a_StartFrom) const
Returns the index of the first empty slot following a_StartFrom (a_StartFrom is not checked)
bool IsValidSlotNum(int a_SlotNum) const
Returns true if slot number is within the grid.
bool m_IsInTriggerListeners
Set to true while TriggerListeners is running, to detect attempts to manipulate listener list while t...
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.
int GetSlotNum(int a_X, int a_Y) const
Converts XY coords into slot number; returns -1 on invalid coords.
int HowManyItems(const cItem &a_Item)
Returns the number of items of type a_Item that are stored.
int HowManyCanFit(const cItem &a_ItemStack, bool a_AllowNewStacks=true)
Returns number of items out of a_ItemStack that can fit in the storage.
char RemoveItem(const cItem &a_ItemStack)
Removes the specified item from the grid, as many as possible, up to a_ItemStack.m_ItemCount.
void RemoveListener(cListener &a_Listener)
Removes a slot-change-callback.
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...
cItem RemoveOneItem(int a_SlotNum)
Removes one item from the stack in the specified slot, and returns it.
char AddItem(cItem &a_ItemStack, bool a_AllowNewStacks=true, int a_PrioritySlot=-1)
Adds as many items out of a_ItemStack as can fit.
void CopyToItems(cItems &a_Items) const
Copies the contents into a cItems object; preserves the original a_Items contents.
This class is used as a callback for when a slot changes.
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.
size_type size() const noexcept
int IntNoise1DInt(int a_X) const
int IntNoise3DInt(int a_X, int a_Y, int a_Z) const
int IntNoise2DInt(int a_X, int a_Y) const
RAII for cCriticalSection - locks the CS on creation, unlocks on destruction.