예제 #1
0
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;
}
예제 #2
0
// 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;
}
예제 #3
0
// 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;
}
예제 #4
0
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);
}
예제 #5
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);
}
예제 #6
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);
}