bool CUser::GiveItem(uint32 itemid, uint16 count, bool send_packet /*= true*/) { int8 pos; bool bNewItem = true; _ITEM_TABLE* pTable = g_pMain->GetItemPtr( itemid ); if (pTable == nullptr) return false; pos = FindSlotForItem(itemid, count); if (pos < 0) return false; _ITEM_DATA *pItem = &m_sItemArray[pos]; if (pItem->nNum != 0) bNewItem = false; if (bNewItem) pItem->nSerialNum = g_pMain->GenerateItemSerial(); pItem->nNum = itemid; pItem->sCount += count; if (pItem->sCount > MAX_ITEM_COUNT) pItem->sCount = MAX_ITEM_COUNT; pItem->sDuration = pTable->m_sDuration; // This is really silly, but match the count up with the duration // for this special items that behave this way. if (pTable->m_bKind == 255) pItem->sCount = pItem->sDuration; if (send_packet) SendStackChange(itemid, m_sItemArray[pos].sCount, m_sItemArray[pos].sDuration, pos - SLOT_MAX, true); return true; }
// Fills an array with inventory indices correlating to a trader's required items size_t _Inventory::GetRequiredItemSlots(const _Trader *Trader, std::vector<size_t> &BagIndex) { // Find a slot for the reward size_t RewardItemSlot = FindSlotForItem(Trader->RewardItem, Trader->Count); // Go through required items for(size_t i = 0; i < Trader->TraderItems.size(); i++) { const _Item *RequiredItem = Trader->TraderItems[i].Item; int RequiredCount = Trader->TraderItems[i].Count; BagIndex[i] = Slots.size(); // Search for the required item for(size_t j = InventoryType::HEAD; j < InventoryType::TRADE; j++) { _InventorySlot *InventoryItem = &Slots[j]; if(InventoryItem->Item == RequiredItem && InventoryItem->Count >= RequiredCount) { BagIndex[i] = j; break; } } // Didn't find an item if(BagIndex[i] >= Slots.size()) RewardItemSlot = Slots.size(); } return RewardItemSlot; }
// Attempts to add an item to the inventory bool _Inventory::AddItem(const _Item *Item, int Count, size_t Slot) { // Place somewhere in bag if(Slot >= Slots.size()) { // Search for a suitable slot Slot = FindSlotForItem(Item, Count); if(Slot >= Slots.size()) return false; } // Trying to equip an item else if(Slot < InventoryType::BAG) { // Make sure it can be equipped if(!CanEquipItem(Slot, Item)) return false; } // Add item if(Slots[Slot].Item == Item && Slots[Slot].Count + Count <= INVENTORY_MAX_STACK) { Slots[Slot].Count += Count; return true; } else if(Slots[Slot].Item == nullptr) { Slots[Slot].Item = Item; Slots[Slot].Count = Count; return true; } return false; }
bool CUser::CheckWeight(_ITEM_TABLE * pTable, uint32 nItemID, uint16 sCount) { return (pTable != nullptr // Make sure the item exists // and that the weight doesn't exceed our limit && (m_sItemWeight + (pTable->m_sWeight * sCount)) <= m_sMaxWeight // and we have room for the item. && FindSlotForItem(nItemID, sCount) >= 0); }
bool CUser::CheckWeight(int itemid, short count) { _ITEM_TABLE* pTable = g_pMain->GetItemPtr(itemid); return (pTable != NULL // Make sure the item exists // and that the weight doesn't exceed our limit && (m_sItemWeight + (pTable->m_sWeight * count)) <= m_sMaxWeight // and we have room for the item. && FindSlotForItem(itemid, count) >= 0); }
bool CUser::CheckExchange(int nExchangeID) { // Does the exchange exist? _ITEM_EXCHANGE * pExchange = g_pMain->m_ItemExchangeArray.GetData(nExchangeID); if (pExchange == nullptr) return false; // Find free slots in the inventory, so that we can check against this later. uint8 bFreeSlots = 0; for (int i = SLOT_MAX; i < SLOT_MAX+HAVE_MAX; i++) { if (GetItem(i)->nNum == 0 && ++bFreeSlots >= ITEMS_IN_EXCHANGE_GROUP) break; } // Add up the rates for this exchange to obtain a total percentage int nTotalPercent = 0; for (int i = 0; i < ITEMS_IN_EXCHANGE_GROUP; i++) nTotalPercent += pExchange->sExchangeItemCount[i]; if (nTotalPercent > 9000) return (bFreeSlots > 0); // Can we hold all of these items? If we can't, we have a problem. uint8 bReqSlots = 0; uint32 nReqWeight = 0; for (int i = 0; i < ITEMS_IN_EXCHANGE_GROUP; i++) { uint32 nItemID = pExchange->nExchangeItemNum[i]; // Does the item exist? If not, we'll ignore it (NOTE: not official behaviour). _ITEM_TABLE * pTable = nullptr; if (nItemID == 0 || (pTable = g_pMain->GetItemPtr(nItemID)) == nullptr) continue; // Try to find a slot for the item. // If we can't find an applicable slot with our inventory as-is, // there's no point even checking further. int pos; if ((pos = FindSlotForItem(nItemID, 1)) < 0) return false; // Now that we have our slot, see if it's in use (i.e. if adding a stackable item) // If it's in use, then we don't have to worry about requiring an extra slot for this item. // The only caveat here is with having multiple of the same stackable item: // theoretically we could give them OK, but when it comes time to adding them, we'll find that // there's too many of them and they can't fit in the same slot. // As this isn't an issue with real use cases, we can ignore it. _ITEM_DATA *pItem = GetItem(pos); if (pItem->nNum == 0) bReqSlots++; // new item? new required slot. // Also take into account weight (not official behaviour) nReqWeight += pTable->m_sWeight; } // Holding too much already? if (m_sItemWeight + nReqWeight > m_sMaxWeight) return false; // Do we have enough slots? return (bFreeSlots >= bReqSlots); }