/* * Ascent MMORPG Server * Copyright (C) 2005-2007 Ascent Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "StdAfx.h" void WorldSession::HandleInitiateTrade(WorldPacket & recv_data) { if(!_player->IsInWorld()) return; CHECK_PACKET_SIZE(recv_data, 8); uint64 guid; recv_data >> guid; Player * pTarget = _player->GetMapMgr()->GetPlayer(guid); uint32 TradeStatus = TRADE_STATUS_PROPOSED; WorldPacket data(SMSG_TRADE_STATUS, 12); if(pTarget == 0) { TradeStatus = TRADE_STATUS_PLAYER_NOT_FOUND; OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); return; } // Handle possible error outcomes if(pTarget->CalcDistance(_player) > 10.0f) // This needs to be checked TradeStatus = TRADE_STATUS_TOO_FAR_AWAY; else if(pTarget->isDead()) TradeStatus = TRADE_STATUS_DEAD; else if(pTarget->mTradeTarget != 0) TradeStatus = TRADE_STATUS_ALREADY_TRADING; else if(pTarget->GetTeam() != _player->GetTeam() && GetPermissionCount() == 0) TradeStatus = TRADE_STATUS_WRONG_FACTION; data << TradeStatus; if(TradeStatus == TRADE_STATUS_PROPOSED) { _player->ResetTradeVariables(); pTarget->ResetTradeVariables(); pTarget->mTradeTarget = _player->GetGUID(); _player->mTradeTarget = pTarget->GetGUID(); pTarget->mTradeStatus = TradeStatus; _player->mTradeStatus = TradeStatus; data << _player->GetGUID(); } pTarget->m_session->SendPacket(&data); } void WorldSession::HandleBeginTrade(WorldPacket & recv_data) { if(!_player->IsInWorld()) return; uint32 TradeStatus = TRADE_STATUS_INITIATED; Player * plr = _player->GetTradeTarget(); if(_player->mTradeTarget == 0 || plr == 0) { TradeStatus = TRADE_STATUS_PLAYER_NOT_FOUND; OutPacket(TRADE_STATUS_PLAYER_NOT_FOUND, 4, &TradeStatus); return; } OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); plr->m_session->OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); plr->mTradeStatus = TradeStatus; _player->mTradeStatus = TradeStatus; } void WorldSession::HandleBusyTrade(WorldPacket & recv_data) { if(!_player->IsInWorld()) return; uint32 TradeStatus = TRADE_STATUS_PLAYER_BUSY; Player * plr = _player->GetTradeTarget(); if(_player->mTradeTarget == 0 || plr == 0) { TradeStatus = TRADE_STATUS_PLAYER_NOT_FOUND; OutPacket(TRADE_STATUS_PLAYER_NOT_FOUND, 4, &TradeStatus); return; } OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); plr->m_session->OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); plr->mTradeStatus = TradeStatus; _player->mTradeStatus = TradeStatus; plr->mTradeTarget = 0; _player->mTradeTarget = 0; } void WorldSession::HandleIgnoreTrade(WorldPacket & recv_data) { if(!_player->IsInWorld()) return; uint32 TradeStatus = TRADE_STATUS_PLAYER_IGNORED; Player * plr = _player->GetTradeTarget(); if(_player->mTradeTarget == 0 || plr == 0) { TradeStatus = TRADE_STATUS_PLAYER_NOT_FOUND; OutPacket(TRADE_STATUS_PLAYER_NOT_FOUND, 4, &TradeStatus); return; } OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); plr->m_session->OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); plr->mTradeStatus = TradeStatus; _player->mTradeStatus = TradeStatus; plr->mTradeTarget = 0; _player->mTradeTarget = 0; } void WorldSession::HandleCancelTrade(WorldPacket & recv_data) { if(!_player->IsInWorld()) return; if(_player->mTradeTarget == 0 || _player->mTradeStatus == TRADE_STATUS_COMPLETE) return; uint32 TradeStatus = TRADE_STATUS_CANCELLED; OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); Player * plr = _player->GetTradeTarget(); if(plr) { if(plr->m_session && plr->m_session->GetSocket()) plr->m_session->OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); plr->mTradeTarget = 0; } _player->mTradeTarget = 0; } void WorldSession::HandleUnacceptTrade(WorldPacket & recv_data) { if(!_player->IsInWorld()) return; Player * plr = _player->GetTradeTarget(); if(_player->mTradeTarget == 0 || plr == 0) return; uint32 TradeStatus = TRADE_STATUS_UNACCEPTED; OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); plr->m_session->OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); plr->mTradeTarget = 0; _player->mTradeTarget = 0; } void WorldSession::HandleSetTradeItem(WorldPacket & recv_data) { if(_player->mTradeTarget == 0) return; CHECK_PACKET_SIZE(recv_data, 3); uint8 TradeSlot = recv_data.contents()[0]; uint8 SourceBag = recv_data.contents()[1]; uint8 SourceSlot = recv_data.contents()[2]; Item * pItem = _player->GetItemInterface()->GetInventoryItem(SourceBag, SourceSlot); if(pItem == 0 || TradeSlot > 6) return; _player->mTradeItems[TradeSlot] = pItem; _player->SendTradeUpdate(); } void WorldSession::HandleSetTradeGold(WorldPacket & recv_data) { if(_player->mTradeTarget == 0) return; uint32 Gold; recv_data >> Gold; if(_player->mTradeGold != Gold) { _player->mTradeGold = (Gold > _player->GetUInt32Value(PLAYER_FIELD_COINAGE) ? _player->GetUInt32Value(PLAYER_FIELD_COINAGE) : Gold); _player->SendTradeUpdate(); } } void WorldSession::HandleClearTradeItem(WorldPacket & recv_data) { CHECK_PACKET_SIZE(recv_data, 1); if(_player->mTradeTarget == 0) return; uint8 TradeSlot = recv_data.contents()[0]; if(TradeSlot > 6) return; _player->mTradeItems[TradeSlot] = 0; _player->SendTradeUpdate(); } void WorldSession::HandleAcceptTrade(WorldPacket & recv_data) { Player * plr = _player->GetTradeTarget(); if(_player->mTradeTarget == 0 || !plr) return; uint32 TradeStatus = TRADE_STATUS_ACCEPTED; // Tell the other player we're green. plr->m_session->OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); _player->mTradeStatus = TradeStatus; if(plr->mTradeStatus == TRADE_STATUS_ACCEPTED) { // Ready! uint32 ItemCount = 0; uint32 TargetItemCount = 0; Player * pTarget = plr; // Calculate Item Count for(uint32 Index = 0; Index < 7; ++Index) { if(_player->mTradeItems[Index] != 0) ++ItemCount; if(pTarget->mTradeItems[Index] != 0) ++TargetItemCount; } if( (_player->m_ItemInterface->CalculateFreeSlots(NULL) + ItemCount) < TargetItemCount || (pTarget->m_ItemInterface->CalculateFreeSlots(NULL) + TargetItemCount) < ItemCount ) { // Not enough slots on one end. TradeStatus = TRADE_STATUS_CANCELLED; } else { TradeStatus = TRADE_STATUS_COMPLETE; uint64 Guid; Item * pItem; // Remove all items from the players inventory for(uint32 Index = 0; Index < 6; ++Index) { Guid = _player->mTradeItems[Index] ? _player->mTradeItems[Index]->GetGUID() : 0; if(Guid != 0) { if(GetPermissionCount()>0) { sGMLog.writefromsession(this, "traded item %s to %s", _player->mTradeItems[Index]->GetProto()->Name1, pTarget->GetName()); } pItem = _player->m_ItemInterface->SafeRemoveAndRetreiveItemByGuid(Guid, true); } Guid = pTarget->mTradeItems[Index] ? pTarget->mTradeItems[Index]->GetGUID() : 0; if(Guid != 0) pTarget->m_ItemInterface->SafeRemoveAndRetreiveItemByGuid(Guid, true); } // Dump all items back into the opposite players inventory for(uint32 Index = 0; Index < 6; ++Index) { pItem = _player->mTradeItems[Index]; if(pItem != 0) { pItem->SetOwner(pTarget); pTarget->m_ItemInterface->AddItemToFreeSlot(pItem); } pItem = pTarget->mTradeItems[Index]; if(pItem != 0) { pItem->SetOwner(pTarget); _player->m_ItemInterface->AddItemToFreeSlot(pItem); } } // Trade Gold if(pTarget->mTradeGold) { _player->ModUInt32Value(PLAYER_FIELD_COINAGE, pTarget->mTradeGold); pTarget->ModUInt32Value(PLAYER_FIELD_COINAGE, -(int32)pTarget->mTradeGold); } if(_player->mTradeGold) { pTarget->ModUInt32Value(PLAYER_FIELD_COINAGE, _player->mTradeGold); _player->ModUInt32Value(PLAYER_FIELD_COINAGE, -(int32)_player->mTradeGold); } // Close Window TradeStatus = TRADE_STATUS_COMPLETE; OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); plr->m_session->OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); _player->mTradeStatus = TRADE_STATUS_COMPLETE; plr->mTradeStatus = TRADE_STATUS_COMPLETE; // Reset Trade Vars _player->ResetTradeVariables(); pTarget->ResetTradeVariables(); plr->mTradeTarget = 0; _player->mTradeTarget = 0; } } }