void WorldSession::HandleAcceptTrade(WorldPacket & recv_data)
{
	if(!_player->IsInWorld() || _player->mTradeTarget == 0)
		return;

	uint32 TradeStatus = TRADE_STATUS_ACCEPTED;

	PlayerPointer pTarget = _player->GetTradeTarget();
	if(pTarget == NULL || !pTarget->IsInWorld())
		TradeStatus = TRADE_STATUS_PLAYER_NOT_FOUND;

	// Tell the other player we're green.
	if(pTarget->m_session && pTarget->m_session->GetSocket())
		pTarget->m_session->SendTradeStatus(TradeStatus);

	_player->mTradeStatus = TradeStatus;

	//Both sides accepted? Let's trade!
	if(_player->mTradeStatus == TRADE_STATUS_ACCEPTED && pTarget->mTradeStatus == TRADE_STATUS_ACCEPTED)
	{
		// Ready!
		uint32 ItemCount = 0;
		uint32 TargetItemCount = 0;
		ItemPointer pItem;

		// Count items on both sides, check if bags are empty.
		for(uint32 Index = 0; Index < 6; ++Index)
		{
			if(_player->mTradeItems[Index] != NULL)
			{
				pItem = _player->mTradeItems[Index];
				if( pItem != NULL && pItem->IsContainer() && TO_CONTAINER(pItem)->HasItems())
				{
					sCheatLog.writefromsession(this, "%s involved in bag-trick trade with %s", _player->GetName(),pTarget->GetName());
					_player->GetItemInterface()->BuildInventoryChangeError(	pItem, NULLITEM, INV_ERR_CANT_TRADE_EQUIP_BAGS);
					TradeStatus = TRADE_STATUS_CANCELLED;
					break;
				}
				else
					++ItemCount;
			}
			if(pTarget->mTradeItems[Index] != NULL)
			{
				pItem = pTarget->mTradeItems[Index];
				if( pItem != NULL && pItem->IsContainer() && TO_CONTAINER(pItem)->HasItems() )
				{
					sCheatLog.writefromsession(this, "%s involved in bag-trick trade with %s.", pTarget->GetName(),_player->GetName());
					pTarget->GetItemInterface()->BuildInventoryChangeError(	pItem, NULLITEM, INV_ERR_CANT_TRADE_EQUIP_BAGS);
					TradeStatus = TRADE_STATUS_CANCELLED;
					break;
				}
				else
					++TargetItemCount;
			}
		}
		//Do we have something to trade?
		if( ItemCount == 0 && TargetItemCount == 0 && _player->mTradeGold == 0 && pTarget->mTradeGold == 0 )
			TradeStatus = TRADE_STATUS_CANCELLED;
		//Do we have enough free slots on both sides?
		else if((_player->m_ItemInterface->CalculateFreeSlots(NULL) + ItemCount) < TargetItemCount || (pTarget->m_ItemInterface->CalculateFreeSlots(NULL) + TargetItemCount) < ItemCount )
			TradeStatus = TRADE_STATUS_CANCELLED;
		//Everything still ok?
		else if(TradeStatus == TRADE_STATUS_ACCEPTED)
		{
			uint64 Guid;
			
			//Swapp 6 itemslots (7th will not trade)
			for(uint32 Index = 0; Index < 6; ++Index)
			{
				Guid = _player->mTradeItems[Index] ? _player->mTradeItems[Index]->GetGUID() : 0;
				if(Guid != 0)
				{
					if( _player->mTradeItems[Index]->IsSoulbound())
						_player->GetItemInterface()->BuildInventoryChangeError(	_player->mTradeItems[Index], NULLITEM, INV_ERR_CANNOT_TRADE_THAT);
					else
					{
						//Remove from player
						pItem = _player->m_ItemInterface->SafeRemoveAndRetreiveItemByGuidRemoveStats(Guid, true);

						//and add to pTarget
						if(pItem != NULL)
						{
							pItem->SetOwner(pTarget);
							if( !pTarget->m_ItemInterface->AddItemToFreeSlot(pItem) )
							{
								pItem->Destructor();
								pItem = NULLITEM;
							}
						}

						if(GetPermissionCount()>0 || pTarget->GetSession()->GetPermissionCount()>0)
							sGMLog.writefromsession(this, "trade item %s with %s (soulbound = %d)", _player->mTradeItems[Index]->GetProto()->Name1, pTarget->GetName());
					}
				}

				Guid = pTarget->mTradeItems[Index] ? pTarget->mTradeItems[Index]->GetGUID() : 0;
				if(Guid != 0)
				{
					if( pTarget->mTradeItems[Index]->IsSoulbound())
						pTarget->GetItemInterface()->BuildInventoryChangeError(	pTarget->mTradeItems[Index], NULLITEM, INV_ERR_CANNOT_TRADE_THAT);
					else
					{
						//Remove from pTarget
						pItem = pTarget->m_ItemInterface->SafeRemoveAndRetreiveItemByGuidRemoveStats(Guid, true);

						//and add to initiator
						if(pItem != NULL)
						{
							pItem->SetOwner(_player);
							if( !_player->m_ItemInterface->AddItemToFreeSlot(pItem) )
							{
								pItem->Destructor();
								pItem = NULLITEM;
							}

						}

						if(GetPermissionCount()>0 || pTarget->GetSession()->GetPermissionCount()>0)
							sGMLog.writefromsession(this, "trade item %s with %s", pTarget->mTradeItems[Index]->GetProto()->Name1, _player->GetName());
					}
				}
			}


			// Trade Gold
			if(_player->mTradeGold)
			{
				pTarget->ModUnsigned32Value(PLAYER_FIELD_COINAGE, _player->mTradeGold);
				_player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -(int32)_player->mTradeGold);
			}
			if(pTarget->mTradeGold)
			{
				_player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, pTarget->mTradeGold);
				pTarget->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -(int32)pTarget->mTradeGold);
			}

			pTarget->SaveToDB(false);
			_player->SaveToDB(false);

			TradeStatus = TRADE_STATUS_COMPLETE;
		}

		SendTradeStatus(TradeStatus);
		if(pTarget->m_session && pTarget->m_session->GetSocket())
			pTarget->m_session->SendTradeStatus(TradeStatus);

		// Reset Trade Vars
		_player->ResetTradeVariables();
		pTarget->ResetTradeVariables();
	}
}
Example #2
0
int32 Item::AddEnchantment( EnchantEntry* Enchantment, uint32 Duration, bool Perm /* = false */, bool apply /* = true */, bool RemoveAtLogout /* = false */, uint32 Slot_, uint32 RandomSuffix )
{
	int32 Slot = Slot_;
	m_isDirty = true;

/*
	if(Perm)
	{
		if(Slot_)
		{
			Slot=Slot_;
		}
		else
        {
			Slot = FindFreeEnchantSlot(Enchantment);
        }
	}
	else
	{
		if(Enchantment->EnchantGroups > 1) // replaceable temp enchants
		{
			Slot = 1;
			RemoveEnchantment(1);
		}
		else
		{
			Slot = FindFreeEnchantSlot(Enchantment);*/
			/*
			Slot = Enchantment->type ? 3 : 0;
			 //that's 's code
			for(uint32 Index = ITEM_FIELD_ENCHANTMENT_09; Index < ITEM_FIELD_ENCHANTMENT_32; Index += 3)
			{
				if(m_uint32Values[Index] == 0) break;;	
				++Slot;
			}

			//Slot = FindFreeEnchantSlot(Enchantment);
			// reach max of temp enchants
			if(Slot >= 11) return -1;
			*/
		/*}
	}   
*/

	// Create the enchantment struct.
	EnchantmentInstance Instance;
	Instance.ApplyTime = UNIXTIME;
	Instance.BonusApplied = false;
	Instance.Slot = Slot;
	Instance.Enchantment = Enchantment;
	Instance.Duration = Duration;
	Instance.RemoveAtLogout = RemoveAtLogout;
	Instance.RandomSuffix = RandomSuffix;

	// Set the enchantment in the item fields.
	uint32 EnchantBase = Slot * 3 + ITEM_FIELD_ENCHANTMENT_1_1;
	SetUInt32Value( EnchantBase, Enchantment->Id );
	SetUInt32Value( EnchantBase + 1, (uint32)Instance.ApplyTime );
	SetUInt32Value( EnchantBase + 2, 0 ); // charges

	// Add it to our map.
	Enchantments[Slot] = Instance;

	if( m_owner == NULL )
		return Slot;

	PlayerPointer owner = m_owner;

	// Add the removal event.
	if( Duration )
	{
		sEventMgr.AddEvent( item_shared_from_this(), &Item::RemoveEnchantment, uint32(Slot), EVENT_REMOVE_ENCHANTMENT1 + Slot, Duration * 1000, 1, 0 );
	}

	// No need to send the log packet, if the owner isn't in world (we're still loading)
	if( !owner->IsInWorld() )
		return Slot;

	if( apply )
	{
		WorldPacket EnchantLog( SMSG_ENCHANTMENTLOG, 25 );
		EnchantLog << m_owner->GetGUID();
		EnchantLog << m_owner->GetGUID();
		EnchantLog << m_uint32Values[OBJECT_FIELD_ENTRY];
		EnchantLog << Enchantment->Id;
		EnchantLog << uint8(0);
		owner->GetSession()->SendPacket( &EnchantLog );

		if( owner->GetTradeTarget() )
		{
			owner->SendTradeUpdate();
		}
	
		/* Only apply the enchantment bonus if we're equipped */
		uint8 slot = m_owner->GetItemInterface()->GetInventorySlotByGuid( GetGUID() );
		if( slot > EQUIPMENT_SLOT_START && slot < EQUIPMENT_SLOT_END )
            ApplyEnchantmentBonus( Slot, APPLY );
	}

	owner->SaveToDB(false);
	return Slot;
}