Files
Sun1602/Server/GameServer/TradeManager.cpp
T
2022-10-26 12:25:11 +08:00

594 lines
18 KiB
C++

#include "StdAfx.h"
#include ".\trademanager.h"
#include ".\TradeSlot.h"
#include ".\Player.h"
#include ".\ItemManager.h"
#include ".\SCItemSlotContainer.h"
#include <SCItemSlot.h>
#include ".\TradeSlotContainer.h"
#include "GameServerEx.h"
#include "FunctionalRestrictManager.h"
#include "ChaoState.h"
TradeManager g_TradeManager;
TradeManager::TradeManager(void)
{
}
TradeManager::~TradeManager(void)
{
Release();
}
VOID TradeManager::Init( DWORD maxPoolSize )
{
m_TradeKey = 0;
m_pTradePool.Initialize( maxPoolSize, 0, "TradeSlotContainer", AssertionLogger4Pool_Server );
}
VOID TradeManager::Release()
{
m_pTradePool.Release();
}
RC::eTRADE_RESULT
TradeManager::StartTrade( Player * pRequester, Player * pAcceptor )
{
if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) )
return RC::RC_TRADE_NOT_AVAILABLE_SERVICE;
if( pRequester->GetChaoState().IsChaoState() || pAcceptor->GetChaoState().IsChaoState() )
return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE;
if( pRequester->GetBehave() != PLAYER_BEHAVE_IDLE_STATE ||
pAcceptor->GetBehave() != PLAYER_BEHAVE_IDLE_STATE )
return RC::RC_TRADE_INVALID_STATE;
BOOL bEnabled = FALSE;
bEnabled = pRequester->GetItemManager()->ValidContainer( SI_INVENTORY );
if( !bEnabled )
{
ProtectorInventory& rPROTECT = pRequester->GetWarehouseInventoryProtector().INVENTORY();
if( !rPROTECT.IsUsable() )
return RC::RC_TRADE_INVENTORY_NEED_PASSWORD;
return RC::RC_TRADE_INVALID_STATE;
}
bEnabled = pAcceptor->GetItemManager()->ValidContainer( SI_INVENTORY );
if( !bEnabled )
{
ProtectorInventory& rPROTECT = pAcceptor->GetWarehouseInventoryProtector().INVENTORY();
if( !rPROTECT.IsUsable() )
return RC::RC_TRADE_INVENTORY_NEED_PASSWORD;
return RC::RC_TRADE_INVALID_STATE;
}
TradeSlotContainer * pReq_Container = _ALLOC();
if( !pReq_Container )
return RC::RC_TRADE_INVALID_STATE;
TradeSlotContainer * pAcpt_Container = _ALLOC();
if( !pAcpt_Container )
{
SUNLOG( eCRITICAL_LOG, "不能派发交易集装箱." );
if( !_FREE(pReq_Container) )
{
SUNLOG( eCRITICAL_LOG, "交易池返还失败0[%s][%s]",
pRequester->GetCharName(), pAcceptor->GetCharName() );
}
return RC::RC_TRADE_INVALID_STATE;
}
DWORD gen_key = ++m_TradeKey;
pReq_Container->Init( pRequester, pAcceptor, gen_key );
pAcpt_Container->Init( pAcceptor, pRequester, gen_key );
pRequester->SetTradeContainer( pReq_Container );
pAcceptor->SetTradeContainer( pAcpt_Container );
pRequester->SetBehave(PLAYER_BEHAVE_TRADE_STATE);
pAcceptor->SetBehave(PLAYER_BEHAVE_TRADE_STATE);
SUNLOG( eFULL_LOG, "交易开始[%s][%s]",
pRequester->GetCharName(), pAcceptor->GetCharName() );
return RC::RC_TRADE_SUCCESS;
}
__inline
BOOL TradeManager::_FREE( TradeSlotContainer* pUnit )
{
ASSERT(pUnit);
FlowControl flow;
FLOWCONTROL_START()
{
IfFailThenBreak(pUnit, 10);
TEST_HASH::iterator it = m_TestHash.find(pUnit);
IfFailThenBreak(it != m_TestHash.end(), 20);
//Player* pPlayer1 = pUnit->GetPlayer();
//Player* pPlayer2 = pUnit->GetCounterPlayer();
m_TestHash.erase(it);
return m_pTradePool.Free(pUnit);
}
FLOWCONTROL_END;
switch( flow.GetErrorCode() )
{
case 10: case 20:
{
Player* pPlayer1 = pUnit->GetPlayer();
Player* pPlayer2 = pUnit->GetCounterPlayer();
const TCHAR* pErrorStr =
flow.GetErrorCode() == 10 ? _T("Invalid Release Ptr")
: flow.GetErrorCode() == 20 ? _T("TRADE 已返回相同地址的内存")
: NULL;
SUNLOG( eCRITICAL_LOG, _T("[%s:%d][%s:%d] %s PTR(0x%p)"),
pPlayer1->GetCharName(), pPlayer1->GetBehave(), pPlayer2->GetCharName(), pPlayer2->GetBehave(),
pErrorStr, pUnit );
}
break;
}
return FALSE;
}
RC::eTRADE_RESULT
TradeManager::EndTrade( Player * pRequester )
{
if( pRequester->GetChaoState().IsChaoState() )
return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE;
if( pRequester->GetBehave() != PLAYER_BEHAVE_TRADE_STATE )
return RC::RC_TRADE_INVALID_STATE;
ASSERT( pRequester->GetTradeContainer() );
Player * pPlayer2 = pRequester->GetTradeContainer()->GetCounterPlayer();
ASSERT( pPlayer2->GetBehave() == PLAYER_BEHAVE_TRADE_STATE );
if( pPlayer2->GetBehave() != PLAYER_BEHAVE_TRADE_STATE )
{
SUNLOG( eCRITICAL_LOG, "EndTrade()[p2:%s:%d]状态异常", pPlayer2->GetCharName(), pPlayer2->GetBehave() );
pRequester->GetTradeContainer()->ClearAll();
if( !_FREE(pRequester->GetTradeContainer()) )
{
SUNLOG( eCRITICAL_LOG, "EndTrade()P1交易池返还失败[P1:%s][P2:%s:%d]",
pRequester->GetCharName(), pPlayer2->GetCharName(), pPlayer2->GetBehave() );
}
pRequester->SetTradeContainer( NULL );
pRequester->SetBehave(PLAYER_BEHAVE_IDLE_STATE);
return RC::RC_TRADE_INVALID_STATE;
}
pRequester->GetTradeContainer()->ClearAll();
pPlayer2->GetTradeContainer()->ClearAll();
if( !_FREE(pRequester->GetTradeContainer()) )
{
SUNLOG( eCRITICAL_LOG, "交易池返还失败2[%s][%s]",
pRequester->GetCharName(), pPlayer2->GetCharName() );
}
if( !_FREE(pPlayer2->GetTradeContainer()) )
{
SUNLOG( eCRITICAL_LOG, "交易池返还失败3[%s][%s]",
pRequester->GetCharName(), pPlayer2->GetCharName() );
}
pRequester->SetTradeContainer( NULL );
pPlayer2->SetTradeContainer( NULL );
pRequester->SetBehave(PLAYER_BEHAVE_IDLE_STATE);
pPlayer2->SetBehave(PLAYER_BEHAVE_IDLE_STATE);
SUNLOG( eFULL_LOG, "交易结束[%s][%s]",
pRequester->GetCharName(), pPlayer2->GetCharName() );
return RC::RC_TRADE_SUCCESS;
}
BOOL TradeManager::ValidTradeState( Player * pPlayer )
{
if( pPlayer->IsExpiredPlayer() || pPlayer->GetBehave() != PLAYER_BEHAVE_TRADE_STATE )
return FALSE;
Player * pPlayer2 = pPlayer->GetTradeContainer()->GetCounterPlayer();
if( pPlayer2->IsExpiredPlayer() || pPlayer2->GetBehave() != PLAYER_BEHAVE_TRADE_STATE )
return FALSE;
return TRUE;
}
RC::eTRADE_RESULT
TradeManager::PutItem(
Player * pPlayer,
POSTYPE org_pos,
POSTYPE & OUT trade_pos_out,
RENDER_ITEMSTREAMEX & OUT trade_stream_out )
{
if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) )
return RC::RC_TRADE_NOT_AVAILABLE_SERVICE;
if( pPlayer->GetChaoState().IsChaoState() )
return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE;
if( !ValidTradeState(pPlayer) )
return RC::RC_TRADE_INVALID_STATE;
TradeSlotContainer * pContainer = pPlayer->GetTradeContainer();
if( pContainer->GetTradeState() != TRADE_READY )
return RC::RC_TRADE_FAILED;
SCSlotContainer * pInventoryContainer = pPlayer->GetItemManager()->GetItemSlotContainer(SI_INVENTORY);
if( !pInventoryContainer->ValidPos( org_pos ) ||
pInventoryContainer->IsEmpty( org_pos ) ||
pInventoryContainer->IsLocked( org_pos ) )
return RC::RC_TRADE_FAILED;
SCItemSlot & rSlot = (SCItemSlot &)pInventoryContainer->GetSlot( org_pos );
// (CHANGES) change to more generic code 'IsPetLocked' & 'IsRiderLocked' ...
if(rSlot.IsUserBlocked())
return RC::RC_TRADE_CANNOT_TRADE_ITEM;
if( rSlot.GetLaxLock()->IsLock() )
{
//SUNLOG( eCRITICAL_LOG, "Can not Trade - LaxLock");
return RC::RC_TRADE_CANNOT_TRADE_ITEM;
}
if (rSlot.IsPossessionItem() && rSlot.GetIdentifyPossession() && (!rSlot.IsDestroyItem())) {
return RC::RC_TRADE_CANNOT_TRADE_ITEM;
}
#ifdef _NA_20101208_SET_PROGRESSTIME_ITEM_IS_NOT_TRADE
if(rSlot.IsProgressTime())
return RC::RC_TRADE_CANNOT_TRADE_ITEM;
#endif
if (rSlot.CanTradeSell(eITEM_TRADESELL_TRADE) == false) {
return RC::RC_TRADE_CANNOT_TRADE_ITEM;
}
if (rSlot.CanTradeSell(eITEM_TRADESELL_USED_ITEM) == false &&
rSlot.IsProgressTime())
{
return RC::RC_TRADE_CANNOT_TRADE_ITEM;
}
if( !pContainer->PutItem( rSlot, trade_pos_out ) )
return RC::RC_TRADE_FAILED;
((SCItemSlot &)rSlot).CopyOut( trade_stream_out );
return RC::RC_TRADE_SUCCESS;
}
RC::eTRADE_RESULT
TradeManager::GetItem( Player * pPlayer, POSTYPE trade_pos )
{
if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) )
return RC::RC_TRADE_NOT_AVAILABLE_SERVICE;
if( pPlayer->GetChaoState().IsChaoState() )
return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE;
if( !ValidTradeState(pPlayer) )
return RC::RC_TRADE_CANCEL;
TradeSlotContainer * pContainer = pPlayer->GetTradeContainer();
if( pContainer->GetTradeState() != TRADE_READY )
return RC::RC_TRADE_FAILED;
if( !pContainer->ValidPos( trade_pos ) || pContainer->IsEmpty(trade_pos ) )
return RC::RC_TRADE_FAILED;
pContainer->DeleteSlot( trade_pos, NULL );
return RC::RC_TRADE_SUCCESS;
}
RC::eTRADE_RESULT
TradeManager::PutMoney( Player * pPlayer, MONEY & IN money )
{
if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) )
return RC::RC_TRADE_NOT_AVAILABLE_SERVICE;
if( pPlayer->GetChaoState().IsChaoState() )
return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE;
if( !ValidTradeState(pPlayer) )
return RC::RC_TRADE_CANCEL;
TradeSlotContainer * pContainer = pPlayer->GetTradeContainer();
if( pContainer->GetTradeState() != TRADE_READY )
return RC::RC_TRADE_FAILED;
if( pPlayer->GetMoney() < money )
return RC::RC_TRADE_FAILED;
pContainer->SetMoney( money );
Player * pPartner = pContainer->GetCounterPlayer();
GAMELOG->LogMoney( MONEY_TRADE_PUT_PRICE, pPlayer, money, pContainer->GetMoney(), pPartner->GetUserID(), pPartner->GetCharName() );
return RC::RC_TRADE_SUCCESS;
}
RC::eTRADE_RESULT
TradeManager::GetMoney( Player * pPlayer, MONEY & IN money )
{
if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) )
return RC::RC_TRADE_NOT_AVAILABLE_SERVICE;
if( pPlayer->GetChaoState().IsChaoState() )
return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE;
if( !ValidTradeState(pPlayer) )
return RC::RC_TRADE_CANCEL;
TradeSlotContainer * pContainer = pPlayer->GetTradeContainer();
if( pContainer->GetTradeState() != TRADE_READY )
return RC::RC_TRADE_FAILED;
if( pContainer->GetMoney() < money )
return RC::RC_TRADE_FAILED;
pContainer->SetMoney( (pContainer->GetMoney() - money) );
Player * pPartner = pContainer->GetCounterPlayer();
GAMELOG->LogMoney( MONEY_TRADE_GET_PRICE, pPlayer, money, pContainer->GetMoney(), pPartner->GetUserID(), pPartner->GetCharName() );
return RC::RC_TRADE_SUCCESS;
}
RC::eTRADE_RESULT
TradeManager::Proposal( Player * pPlayer )
{
if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) )
return RC::RC_TRADE_NOT_AVAILABLE_SERVICE;
if( pPlayer->GetChaoState().IsChaoState() )
return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE;
if( !ValidTradeState(pPlayer) )
return RC::RC_TRADE_CANCEL;
TradeSlotContainer * pContainer = pPlayer->GetTradeContainer();
if( pContainer->GetTradeState() != TRADE_READY )
return RC::RC_TRADE_FAILED;
pContainer->SetTradeState( TRADE_PROPOSAL );
return RC::RC_TRADE_SUCCESS;
}
RC::eTRADE_RESULT
TradeManager::Modify( Player * pPlayer )
{
if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) )
return RC::RC_TRADE_NOT_AVAILABLE_SERVICE;
if( pPlayer->GetChaoState().IsChaoState() )
return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE;
if( !ValidTradeState(pPlayer) )
return RC::RC_TRADE_CANCEL;
TradeSlotContainer * pContainer = pPlayer->GetTradeContainer();
if( pContainer->GetTradeState() == TRADE_READY )
return RC::RC_TRADE_FAILED;
Player * pPlayer2 = PlayerManager::Instance()->FindPlayerByUserKey( pContainer->GetCounterPlayer()->GetUserKey() );
if( !pPlayer2 )
{
SUNLOG( eCRITICAL_LOG, "[TradeManager::Modify] pPartner[%d] doesn't exist!", pContainer->GetCounterPlayer()->GetUserKey() );
return RC::RC_TRADE_INVALID_STATE;
}
TradeSlotContainer * pContainer2 = pPlayer2->GetTradeContainer();
switch( pContainer2->GetTradeState() )
{
case TRADE_ACCEPT:
{
pContainer2->SetTradeState(TRADE_PROPOSAL);
}break;
}
pContainer->SetTradeState( TRADE_READY );
return RC::RC_TRADE_SUCCESS;
}
RC::eTRADE_RESULT
TradeManager::Exchange( Player * pMyself,
TRADE_TOTAL_INFO & OUT rTradeInfo1,
MONEY & OUT money1,
TRADE_TOTAL_INFO & OUT rTradeInfo2,
MONEY & OUT money2 )
{
if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) )
return RC::RC_TRADE_NOT_AVAILABLE_SERVICE;
if( pMyself->GetChaoState().IsChaoState() )
return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE;
if( !ValidTradeState(pMyself) )
return RC::RC_TRADE_CANCEL;
TradeSlotContainer * pMyContainer = pMyself->GetTradeContainer();
Player * pPartner = PlayerManager::Instance()->FindPlayerByUserKey( pMyContainer->GetCounterPlayer()->GetUserKey() );
if( !pPartner )
{
SUNLOG( eCRITICAL_LOG, "[TradeManager::Exchange] pPartner[%d] doesn't exist!", pMyContainer->GetCounterPlayer()->GetUserKey() );
return RC::RC_TRADE_INVALID_STATE;
}
TradeSlotContainer * pPartnerContainer = pPartner->GetTradeContainer();
switch ( pMyContainer->GetTradeState() )
{
case TRADE_PROPOSAL: break;
default:
return RC::RC_TRADE_INVALID_STATE;
}
switch ( pPartnerContainer->GetTradeState() )
{
case TRADE_READY: return RC::RC_TRADE_INVALID_STATE;
case TRADE_PROPOSAL:
pMyContainer->SetTradeState(TRADE_ACCEPT);
return RC::RC_TRADE_COUNTERPARTNER_NOTACCEPT;
}
//SUNLOG( eFULL_LOG, "Exchange启动1[%s][%s]", pMyself->GetCharName(), pPartner->GetCharName() );
pMyContainer->SetTradeState(TRADE_ACCEPT);
SCSlotContainer * pInventory1 = pMyself->GetItemManager()->GetItemSlotContainer(SI_INVENTORY);
SCSlotContainer * pInventory2 = pPartner->GetItemManager()->GetItemSlotContainer(SI_INVENTORY);
#if SUN_CODE_BACKUP
SCSlotContainer * pTemporary1 = pMyself->GetItemManager()->GetItemSlotContainer(SI_TEMPINVENTORY);
SCSlotContainer * pTemporary2 = pPartner->GetItemManager()->GetItemSlotContainer(SI_TEMPINVENTORY);
#endif
if( pInventory1->GetEmptySlotNum() < pPartnerContainer->GetSlotNum() )
{
return RC::RC_TRADE_PLAYER1_HAVENOTSPACE;
}
if( pInventory2->GetEmptySlotNum() < pMyContainer->GetSlotNum() )
{
return RC::RC_TRADE_PLAYER1_HAVENOTSPACE;
}
if( pMyself->GetMoney() < pMyContainer->GetMoney() )
return RC::RC_TRADE_PLAYER1_HAVENOTMONEY;
if( pPartner->GetMoney() < pPartnerContainer->GetMoney() )
return RC::RC_TRADE_PLAYER2_HAVENOTMONEY;
if( !pMyself->CanPlusMoney( pPartnerContainer->GetMoney() ) )
return RC::RC_TRADE_FAILED;
if( !pPartner->CanPlusMoney( pMyContainer->GetMoney() ) )
return RC::RC_TRADE_FAILED;
//SUNLOG( eFULL_LOG, "Exchange启动2[%s][%s]", pMyself->GetCharName(), pPartner->GetCharName() );
TradeSlot * pMyTradeSlot[MAX_TRADE_SLOT_NUM>>1] = {NULL, };
POSTYPE MyTradeItemNum = 0;
for( int i = pMyContainer->GetMaxSlotNum()-1 ; i >= 0 ; --i )
{
if( !pMyContainer->IsEmpty(i) )
{
TradeSlot & rTradeSlot = (TradeSlot &)pMyContainer->GetSlot(i);
if( rTradeSlot.GetLinkItem()->GetNum() != rTradeSlot.GetNum() )
{
return RC::RC_TRADE_DIFFERENT_ITEM_INFO;
}
pMyTradeSlot[MyTradeItemNum++] = &rTradeSlot;
}
}
TradeSlot * pPartnerTradeSlot[MAX_TRADE_SLOT_NUM>>1] = {NULL, };
POSTYPE PartnerTradeItemNum = 0;
for( int i = pPartnerContainer->GetMaxSlotNum()-1 ; i >= 0 ; --i )
{
if( !pPartnerContainer->IsEmpty(i) )
{
TradeSlot & rTradeSlot = (TradeSlot &)pPartnerContainer->GetSlot(i);
if( rTradeSlot.GetLinkItem()->GetNum() != rTradeSlot.GetNum() )
{
return RC::RC_TRADE_DIFFERENT_ITEM_INFO;
}
pPartnerTradeSlot[PartnerTradeItemNum++] = &rTradeSlot;
}
}
rTradeInfo2.m_InvenCount = 0;
rTradeInfo2.m_TmpInvenCount = 0;
POSTYPE RemainNum = MyTradeItemNum;
_GiveItem( pInventory2, pMyTradeSlot, RemainNum, &rTradeInfo2.m_Slot[0], rTradeInfo2.m_InvenCount );
#if SUN_CODE_BACKUP
if( RemainNum != 0 )
_GiveItem( pTemporary2, pMyTradeSlot, RemainNum, &rTradeInfo2.m_Slot[rTradeInfo2.m_InvenCount], rTradeInfo2.m_TmpInvenCount );
#endif
for(int i = 0 ; i < MyTradeItemNum ; ++i )
{
SCItemSlot* pItemSlot = pMyTradeSlot[i]->GetLinkItem(); ASSERT( pItemSlot );
if( !pItemSlot ) continue;
GAMELOG->LogItem( ITEM_TRADE_GIVE, pMyself, pItemSlot, 0, pItemSlot->GetNum(), pPartner->GetUserID(), pPartner->GetCharName() );
GAMELOG->LogItem( ITEM_TRADE_RECEIVE, pPartner, pItemSlot, 0, pItemSlot->GetNum(), pMyself->GetUserID(), pMyself->GetCharName() );
}
rTradeInfo1.m_InvenCount = 0;
rTradeInfo1.m_TmpInvenCount = 0;
RemainNum = PartnerTradeItemNum;
_GiveItem( pInventory1, pPartnerTradeSlot, RemainNum, &rTradeInfo1.m_Slot[0], rTradeInfo1.m_InvenCount );
#if SUN_CODE_BACKUP
if( RemainNum != 0 )
_GiveItem( pTemporary1, pPartnerTradeSlot, RemainNum, &rTradeInfo1.m_Slot[rTradeInfo1.m_InvenCount], rTradeInfo1.m_TmpInvenCount );
#endif
for(int i = 0 ; i < PartnerTradeItemNum ; ++i )
{
SCItemSlot* pItemSlot = pPartnerTradeSlot[i]->GetLinkItem(); ASSERT(pItemSlot);
if( !pItemSlot ) continue;
GAMELOG->LogItem( ITEM_TRADE_GIVE, pPartner, pItemSlot, 0, pItemSlot->GetNum(), pMyself->GetUserID(), pMyself->GetCharName() );
GAMELOG->LogItem( ITEM_TRADE_RECEIVE, pMyself, pItemSlot, 0, pItemSlot->GetNum(), pPartner->GetUserID(), pPartner->GetCharName() );
}
for( POSTYPE i = 0 ; i < (MAX_TRADE_SLOT_NUM>>1) ; ++i )
{
if( !pMyContainer->IsEmpty(i) )
pInventory1->DeleteSlot( ((TradeSlot &)pMyContainer->GetSlot(i)).GetLinkItem()->GetPos(), NULL );
if( !pPartnerContainer->IsEmpty(i) )
pInventory2->DeleteSlot( ((TradeSlot &)pPartnerContainer->GetSlot(i)).GetLinkItem()->GetPos(), NULL );
}
pMyself->MinusMoney( pMyContainer->GetMoney(), Player::eMONEY_CIRCULATING );
pMyself->PlusMoney( pPartnerContainer->GetMoney(), Player::eMONEY_CIRCULATING );
pPartner->MinusMoney( pPartnerContainer->GetMoney(), Player::eMONEY_CIRCULATING );
pPartner->PlusMoney( pMyContainer->GetMoney(), Player::eMONEY_CIRCULATING );
if( pPartnerContainer->GetMoney() + pMyContainer->GetMoney() > 0 )
{
GAMELOG->LogMoney( MONEY_TRADE, pMyself, pMyContainer->GetMoney(), pPartnerContainer->GetMoney(),
pPartner->GetUserID(), pPartner->GetCharName() );
GAMELOG->LogMoney( MONEY_TRADE, pPartner, pPartnerContainer->GetMoney(), pMyContainer->GetMoney(),
pMyself->GetUserID(), pMyself->GetCharName() );
}
money1 = pMyself->GetMoney();
money2 = pPartner->GetMoney();
pMyContainer->ClearAll();
pPartnerContainer->ClearAll();
return RC::RC_TRADE_SUCCESS;
}
VOID TradeManager::_GiveItem( SCSlotContainer * pContainer, TradeSlot ** ppSlot, POSTYPE & INOUT num, TRADE_TOTAL_INFO::SLOT_TYPE * OUT rItemSlot, POSTYPE & OUT Count )
{
for( POSTYPE pos = 0 ; pos < pContainer->GetMaxSlotNum() && (num != 0) ; ++pos )
{
if( pContainer->IsEmpty(pos) )
{
if( num == 0 )
{
SUNLOG(eCRITICAL_LOG, "[Error]Trade Num == 0" );
return;
}
--num;
rItemSlot[Count].m_Pos = pos;
ppSlot[num]->GetLinkItem()->SetLock(FALSE);
ppSlot[num]->GetLinkItem()->CopyOut( rItemSlot[Count].m_Stream );
pContainer->InsertSlot(pos, *(ppSlot[num]->GetLinkItem()) );
++Count;
}
}
}