KoPVP Logo
Bildirimler
Yükleniyor...
Ayın Serverı

DeathKO | v1453 Fire Drake | Official Açılış: 12 HAZİRAN - 21:00 GMT+3

12 gün 5 saat önce açıldı
Server'a Göz At

v20xx Npc'den İtem Çekme

Admin
Admin
22.06.2026, 21:17 • #1

Merhaba v20xx Npc'den İtem Çekme umarım işinize yarar

void CUser::ItemTrade(Packet & pkt)

{

	Packet result(WIZ_ITEM_TRADE);

	uint32 transactionPrice;

	int itemid = 0, money = 0, group = 0;

	uint16 npcid;

	uint8 ibuy;

	uint16 count, real_count = 0;

	_ITEM_TABLE* pTable = nullptr;

	CNpc* pNpc = nullptr;

	uint8 type, pos, destpos, errorCode = 1;

	bool bSuccess = true;

	if (isDead())

	{

		errorCode = 1;

		goto send_packet;

	}

	pkt >> type;

	// Buy == 1, Sell == 2//

	if (type == 1 || type == 2)

	{

		pkt >> group >> npcid >>ibuy;

;

		if (!g_pMain->m_bPointCheckFlag

			|| (pNpc = g_pMain->GetNpcPtr(npcid)) == nullptr

			|| (pNpc->GetType() != NPC_MERCHANT && pNpc->GetType() != NPC_TINKER)

			|| pNpc->m_iSellingGroup != group

			|| !isInRange(pNpc, MAX_NPC_RANGE))

			goto fail_return;

	}

	pkt >> itemid >> pos;

	if (type == 3) 	// Move only (this is so useless mgame -- why not just handle it with the CUser::ItemMove(). Gah.)

		pkt >> destpos;

	else

		pkt >> count;

	// Moving an item in the inventory

	if (type == 3)

	{

		if (pos >= HAVE_MAX || destpos >= HAVE_MAX

			|| itemid != m_sItemArray[SLOT_MAX+pos].nNum)

		{

			errorCode = 4;

			goto send_packet;

		}

		short duration = m_sItemArray[SLOT_MAX+pos].sDuration;

		short itemcount = m_sItemArray[SLOT_MAX+pos].sCount;

		m_sItemArray[SLOT_MAX+pos].nNum = m_sItemArray[SLOT_MAX+destpos].nNum;

		m_sItemArray[SLOT_MAX+pos].sDuration = m_sItemArray[SLOT_MAX+destpos].sDuration;

		m_sItemArray[SLOT_MAX+pos].sCount = m_sItemArray[SLOT_MAX+destpos].sCount;

		m_sItemArray[SLOT_MAX+destpos].nNum = itemid;

		m_sItemArray[SLOT_MAX+destpos].sDuration = duration;

		m_sItemArray[SLOT_MAX+destpos].sCount = itemcount;

		result << uint8(3);

		Send(&result);

		return;

	}

	if (isTrading()

		|| (pTable = g_pMain->GetItemPtr(itemid)) == nullptr

		|| (type == 2 // if we're selling an item...

		&& (itemid >= ITEM_NO_TRADE // Cannot be traded, sold or stored.

		|| pTable->m_bRace == RACE_UNTRADEABLE))) // Cannot be traded or sold.

		goto fail_return;

	if (pos >= HAVE_MAX

		|| count <= 0 || count > MAX_ITEM_COUNT)

	{

		errorCode = 2;

		goto fail_return;

	}

	// Buying from an NPC

	if (type == 1)

	{	

		if (m_sItemArray[SLOT_MAX+pos].nNum != 0)

		{

			if (m_sItemArray[SLOT_MAX+pos].nNum != itemid)

			{

				errorCode = 2;

				goto fail_return;

			}

			if (!pTable->m_bCountable || count <= 0)

			{

				errorCode = 2;

				goto fail_return;

			}

			if (pTable->m_bCountable 

				&& (count + m_sItemArray[SLOT_MAX+pos].sCount) > MAX_ITEM_COUNT)

			{

				errorCode = 4;

				goto fail_return;				

			}

		}

		//transactionPrice = ((uint32)pTable->m_iBuyPrice * count);

		transactionPrice = ((uint32)pTable->m_iBuyPrice * count);

		if (!hasCoins(transactionPrice))

		{

			errorCode = 3;

			goto fail_return;

		}

		if (((pTable->m_sWeight * count) + m_sItemWeight) > m_sMaxWeight)

		{

			errorCode = 4;

			goto fail_return;

		}

   

		m_sItemArray[SLOT_MAX+pos].nNum = itemid;

		m_sItemArray[SLOT_MAX+pos].sDuration = pTable->m_sDuration;

		m_sItemArray[SLOT_MAX+pos].sCount += count;

		m_iGold -= transactionPrice;

		if (!pTable->m_bCountable)

			m_sItemArray[SLOT_MAX+pos].nSerialNum = g_pMain->GenerateItemSerial();

		SetUserAbility(false);

		SendItemWeight();

	}

	// Selling an item to an NPC

	else

	{

		_ITEM_DATA *pItem = &m_sItemArray[SLOT_MAX+pos];

		if (pItem->nNum != itemid

			|| pItem->isSealed() // need to check the error codes for these

			|| pItem->isRented())

		{

			errorCode = 2;

			goto fail_return;

		}

		if (pItem->sCount < count)

		{

			errorCode = 3;

			goto fail_return;

		}

		short oldDurability = pItem->sDuration;

		if (pTable->m_iSellPrice != SellTypeFullPrice)

			transactionPrice = ((pTable->m_iBuyPrice / 6) * count); // /6 is normal, /4 for prem/discount

		else

			transactionPrice = (pTable->m_iBuyPrice * count);

		GoldGain(transactionPrice, false);

		if (count >= pItem->sCount)

			memset(pItem, 0, sizeof(_ITEM_DATA));

		else

			pItem->sCount -= count;

		SetUserAbility(false);

		SendItemWeight();

	}

	goto send_packet;

fail_return:

	bSuccess = false;

send_packet:

	result << bSuccess;

	if (!bSuccess)

		result << errorCode;

	else 

		result << pTable->m_bSellingGroup << m_iGold << transactionPrice; // price bought or sold for

	Send(&result);

}
Kayıt: 2026 Mesaj: 0 İtibar: 0
Cevap yazabilmek için giriş yapmalısınız.