void CItemContainer::Trade_Delete() { ADDTOCALLSTACK("CItemContainer::Trade_Delete"); // Called when object deleted. ASSERT( IsType(IT_EQ_TRADE_WINDOW) ); CChar * pChar = dynamic_cast <CChar*> (GetParent()); if ( pChar == NULL ) return; if ( pChar->IsClient()) { // Send the cancel trade message. PacketTradeAction cmd(SECURE_TRADE_CLOSE); cmd.prepareClose(this); cmd.send(pChar->GetClient()); } // Drop items back in my pack. CItem * pItemNext; for ( CItem* pItem = GetContentHead(); pItem!=NULL; pItem=pItemNext) { pItemNext = pItem->GetNext(); pChar->ItemBounce( pItem ); } // Kill my trading partner. CItemContainer * pPartner = dynamic_cast <CItemContainer *> ( m_uidLink.ItemFind()); if ( pPartner == NULL ) return; if ( IsTrigUsed(TRIGGER_TRADECLOSE) ) { CChar * pChar2 = dynamic_cast <CChar*> (pPartner->GetParent()); CScriptTriggerArgs Args( pChar2 ); pChar->OnTrigger( CTRIG_TradeClose, pChar , &Args ); CScriptTriggerArgs Args2( pChar ); pChar2->OnTrigger( CTRIG_TradeClose, pChar, &Args2); } m_uidLink.InitUID(); // unlink. pPartner->m_uidLink.InitUID(); pPartner->Delete(); }
void CItemContainer::Trade_UpdateGold( DWORD platinum, DWORD gold ) { ADDTOCALLSTACK("CItemContainer::Trade_UpdateGold"); // Update trade gold/platinum values. CItemContainer *pPartner = dynamic_cast<CItemContainer*>(m_uidLink.ItemFind()); if ( !pPartner ) return; CChar *pChar1 = dynamic_cast<CChar*>(GetParent()); if ( !pChar1 || !pChar1->IsClient() ) return; CChar *pChar2 = dynamic_cast<CChar*>(pPartner->GetParent()); if ( !pChar2 || !pChar2->IsClient() ) return; // Fix for a client bug when total value is > 1.000.000.000 (1 platinum) it // allow the user insert a gold value higher than it have. So these values // must be checked again on server-side to prevent cheating. bool bResend = false; DWORD iMaxGold = static_cast<DWORD>(pChar1->m_virtualGold % 1000000000); if ( gold > iMaxGold ) { gold = iMaxGold; bResend = true; } DWORD iMaxPlatinum = static_cast<DWORD>(pChar1->m_virtualGold % 1000000000); if ( platinum > iMaxPlatinum ) { platinum = iMaxPlatinum; bResend = true; } m_itEqTradeWindow.m_iGold = gold; m_itEqTradeWindow.m_iPlatinum = platinum; PacketTradeAction cmd(SECURE_TRADE_UPDATEGOLD); cmd.prepareUpdateGold(this, platinum, gold); if ( bResend ) cmd.send(pChar1->GetClient()); if ( pChar2->GetClient()->GetNetState()->isClientVersion(MINCLIVER_NEWSECURETRADE) ) cmd.send(pChar2->GetClient()); }
void CItemContainer::Trade_Status( bool bCheck ) { ADDTOCALLSTACK("CItemContainer::Trade_Status"); // Update trade status check boxes to both sides. CItemContainer *pPartner = dynamic_cast<CItemContainer*>(m_uidLink.ItemFind()); if ( !pPartner ) return; CChar *pChar1 = dynamic_cast<CChar*>(GetParent()); if ( !pChar1 ) return; CChar *pChar2 = dynamic_cast<CChar*>(pPartner->GetParent()); if ( !pChar2 ) return; m_itEqTradeWindow.m_bCheck = bCheck ? 1 : 0; if ( !bCheck ) pPartner->m_itEqTradeWindow.m_bCheck = 0; PacketTradeAction cmd(SECURE_TRADE_CHANGE); if ( pChar1->IsClient() ) { cmd.prepareReadyChange(this, pPartner); cmd.send(pChar1->GetClient()); } if ( pChar2->IsClient() ) { cmd.prepareReadyChange(pPartner, this); cmd.send(pChar2->GetClient()); } // Check if both clients had pressed the 'accept' buttom if ( pPartner->m_itEqTradeWindow.m_bCheck == 0 || m_itEqTradeWindow.m_bCheck == 0 ) return; CItem *pItem, *pItemNext; int iCont1, iCont2; unsigned short i; CScriptTriggerArgs Args1(pChar1); pItem = pPartner->GetContentHead(); for ( i = 1; pItem != NULL; pItem = pItemNext, ++i ) { pItemNext = pItem->GetNext(); Args1.m_VarObjs.Insert(i, pItem, true); } Args1.m_iN1 = iCont1 = --i; pItemNext = NULL; CScriptTriggerArgs Args2(pChar2); pItem = GetContentHead(); for ( i = 1; pItem != NULL; pItem = pItemNext, ++i ) { pItemNext = pItem->GetNext(); Args2.m_VarObjs.Insert(i, pItem, true); } Args2.m_iN1 = iCont2 = --i; pItemNext = NULL; if ( (IsTrigUsed(TRIGGER_TRADEACCEPTED)) || (IsTrigUsed(TRIGGER_CHARTRADEACCEPTED)) ) { Args1.m_iN2 = iCont2; Args2.m_iN2 = iCont1; if ( (pChar1->OnTrigger(CTRIG_TradeAccepted, pChar2, &Args1) == TRIGRET_RET_TRUE) || (pChar2->OnTrigger(CTRIG_TradeAccepted, pChar1, &Args2) == TRIGRET_RET_TRUE) ) Delete(); } // Transfer items pItem = GetContentHead(); for ( ; pItem != NULL; pItem = pItemNext ) { pItemNext = pItem->GetNext(); pChar2->ItemBounce(pItem); } pItemNext = NULL; pItem = pPartner->GetContentHead(); for ( ; pItem != NULL; pItem = pItemNext ) { pItemNext = pItem->GetNext(); pChar1->ItemBounce(pItem); } // Transfer gold/platinum if ( g_Cfg.m_iFeatureTOL & FEATURE_TOL_VIRTUALGOLD ) { INT64 iGold1 = m_itEqTradeWindow.m_iGold + (m_itEqTradeWindow.m_iPlatinum * 1000000000); INT64 iGold2 = pPartner->m_itEqTradeWindow.m_iGold + (pPartner->m_itEqTradeWindow.m_iPlatinum * 1000000000); pChar1->m_virtualGold += iGold2 - iGold1; pChar2->m_virtualGold += iGold1 - iGold2; pChar1->UpdateStatsFlag(); pChar2->UpdateStatsFlag(); } // done with trade. Delete(); }