K Envanteri Ticaret Problemi

ProBrain

Level 2
Katılım
28 Ağu 2015
Konular
16
Mesajlar
79
Online süresi
10g 68148s
Reaksiyon Skoru
3
Altın Konu
0
Başarım Puanı
91
TM Yaşı
10 Yıl 7 Ay 27 Gün
MmoLira
1,767
DevLira
0

Metin2 EP, Valorant VP dahil tüm oyun ürünlerini en uygun fiyatlarla bulabilir, Item ve Karakterlerinizi hızlıca satabilirsiniz. HEMEN TIKLA!

Merhaba kolay gelsin.

Şu problemi bir türlü çözemedim. Ticaretten K Envanterinde bulunan bir itemi verdiğimde normal envanterdeki 1.envanter slotunu baz alıyor boşluğu öğrenmek için.
Yani eğer 1. envanter doluysa k envanterinden örnek beceri kitabı karşı tarafa ticaretten gitmiyor. Boş yer yok diyor.

Eğer 1. envanter boşsa boş olan slot sayısınca karşı tarafa beceri kitabı verebiliyorum. Normal envanter 1. Sayfasında diyelim 1 slot boşluğum var. K Envanteri Beceri kitabında sayfası full dolu. Buna rağmen ticaret başarıyla gerçekleşti diyor. Ama item k envanter beceri kitabı sayfası dolu olduğun için kayboluyor.


1. Video
Envanterde 1. Sayfam dolu, K Envanteri boş. Ona rağmen 1. sayfayı baz aldığı için yer yok diyor.





2. Video
Envanterde 1. Sayfamdan slot boşalttım. Ticaret gerçekleşti sorunsuz. K Envanteri de boş olduğu için item gitti.







3. Video
Envanter 1. sayfa boş. Bu seferde K Envanterini full bk doldurdum. Bu seferde yine envanter 1. sayfayı baz aldığı için ticareti başarıyla yaptı ama item kayboldu. Dolu çünkü BK sayfası.





Kullandığım exchange.cpp :

Kod:
#include "stdafx.h"
#include "../../libgame/include/grid.h"
#include "utils.h"
#include "desc.h"
#include "desc_client.h"
#include "char.h"
#include "item.h"
#include "item_manager.h"
#include "packet.h"
#include "log.h"
#include "db.h"
#include "locale_service.h"
#include "../../common/length.h"
#include "exchange.h"
#include "DragonSoul.h"
#include "questmanager.h"

void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, void * pvData = NULL);

// 교환 패킷
void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, void * pvData)
{
    if (!ch->GetDesc())
        return;

    struct packet_exchange pack_exchg;

    pack_exchg.header         = HEADER_GC_EXCHANGE;
    pack_exchg.sub_header     = sub_header;
    pack_exchg.is_me        = is_me;
    pack_exchg.arg1        = arg1;
    pack_exchg.arg2        = arg2;
    pack_exchg.arg3        = arg3;

    if (sub_header == EXCHANGE_SUBHEADER_GC_ITEM_ADD && pvData)
    {
#ifdef WJ_ENABLE_TRADABLE_ICON
        pack_exchg.arg4 = TItemPos(((LPITEM) pvData)->GetWindow(), ((LPITEM) pvData)->GetCell());
#endif
        thecore_memcpy(&pack_exchg.alSockets, ((LPITEM) pvData)->GetSockets(), sizeof(pack_exchg.alSockets));
        thecore_memcpy(&pack_exchg.aAttr, ((LPITEM) pvData)->GetAttributes(), sizeof(pack_exchg.aAttr));
    }
    else
    {
#ifdef WJ_ENABLE_TRADABLE_ICON
        pack_exchg.arg4 = TItemPos(RESERVED_WINDOW, 0);
#endif
        memset(&pack_exchg.alSockets, 0, sizeof(pack_exchg.alSockets));
        memset(&pack_exchg.aAttr, 0, sizeof(pack_exchg.aAttr));
    }

    ch->GetDesc()->Packet(&pack_exchg, sizeof(pack_exchg));
}

// 교환을 시작
bool CHARACTER::ExchangeStart(LPCHARACTER victim)
{
    if (this == victim)    // 자기 자신과는 교환을 못한다.
        return false;

    if (IsObserverMode())
    {
        ChatPacket(CHAT_TYPE_INFO, LC_TEXT("관전 상태에서는 교환을 할 수 없습니다."));
        return false;
    }

    if (victim->IsNPC())
        return false;

    //PREVENT_TRADE_WINDOW
#ifdef ENABLE_OFFLINE_SHOP_SYSTEM
    if (IsOpenSafebox() || GetShopOwner() || GetMyShop() || IsCubeOpen() || IsAcceOpen() || GetOfflineShopOwner())
#else
    if (IsOpenSafebox() || GetShopOwner() || GetMyShop() || IsCubeOpen() || IsAcceOpen())
#endif
    {
        ChatPacket( CHAT_TYPE_INFO, LC_TEXT("다른 거래창이 열려있을경우 거래를 할수 없습니다." ) );
        return false;
    }

#ifdef ENABLE_OFFLINE_SHOP_SYSTEM
    if (victim->IsOpenSafebox() || victim->GetShopOwner() || victim->GetMyShop() || victim->IsCubeOpen() || victim->IsAcceOpen() || victim->GetOfflineShopOwner())
#else
    if (victim->IsOpenSafebox() || victim->GetShopOwner() || victim->GetMyShop() || victim->IsCubeOpen() || victim->IsAcceOpen())
#endif
    {
        ChatPacket( CHAT_TYPE_INFO, LC_TEXT("상대방이 다른 거래중이라 거래를 할수 없습니다." ) );
        return false;
    }
    //END_PREVENT_TRADE_WINDOW
#ifdef ENABLE_SECURITY_SYSTEM
    if (IsActivateSecurity() == true)
    {
        ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Cannot start exchange with security key activate"));
        return false;
    }

    if (victim->IsActivateSecurity() == true)
    {
        ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Cannot start exchange with victim security key activate"));
        return false;
    }
#endif

    int iDist = DISTANCE_APPROX(GetX() - victim->GetX(), GetY() - victim->GetY());

    // 거리 체크
    /*if (iDist >= EXCHANGE_MAX_DISTANCE)
        return false;*/

    if (GetExchange())
        return false;

    if (victim->GetExchange())
    {
        exchange_packet(this, EXCHANGE_SUBHEADER_GC_ALREADY, 0, 0, NPOS, 0);
        return false;
    }

    if (victim->IsBlockMode(BLOCK_EXCHANGE))
    {
        ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방이 교환 거부 상태입니다."));
        return false;
    }
   
    SetExchange(M2_NEW CExchange(this));
    victim->SetExchange(M2_NEW CExchange(victim));

    victim->GetExchange()->SetCompany(GetExchange());
    GetExchange()->SetCompany(victim->GetExchange());

    //
    SetExchangeTime();
    victim->SetExchangeTime();

    exchange_packet(victim, EXCHANGE_SUBHEADER_GC_START, 0, GetVID(), NPOS, 0);
    exchange_packet(this, EXCHANGE_SUBHEADER_GC_START, 0, victim->GetVID(), NPOS, 0);

    victim->ChatPacket(CHAT_TYPE_COMMAND, "ex_title %s", GetName());
    ChatPacket(CHAT_TYPE_COMMAND, "ex_title %s", victim->GetName());
    return true;
}

CExchange::CExchange(LPCHARACTER pOwner)
{
    m_pCompany = NULL;

    m_bAccept = false;

    for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
    {
        m_apItems[i] = NULL;
        m_aItemPos[i] = NPOS;
        m_abItemDisplayPos[i] = 0;
    }

    m_lGold = 0;
#ifdef ENABLE_CHEQUE_SYSTEM
    m_lCheque = 0;
#endif

    m_pOwner = pOwner;
    pOwner->SetExchange(this);

    m_pGrid = M2_NEW CGrid(6,4);
}

CExchange::~CExchange()
{
    M2_DELETE(m_pGrid);
}

bool CExchange::AddItem(TItemPos item_pos, BYTE display_pos)
{
    assert(m_pOwner != NULL && GetCompany());

    if (!item_pos.IsValidItemPosition())
        return false;

    // 장비는 교환할 수 없음
    if (item_pos.IsEquipPosition())
        return false;

    LPITEM item;

    if (!(item = m_pOwner->GetItem(item_pos)))
        return false;

    if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_GIVE))
    {
        m_pOwner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템을 건네줄 수 없습니다."));
        return false;
    }

    if (true == item->isLocked())
    {
        m_pOwner->ChatPacket(CHAT_TYPE_INFO, "Kilitli itemi ticarete koyamazsiniz.");
        return false;
    }

    // 이미 교환창에 추가된 아이템인가?
    if (item->IsExchanging())
    {
        sys_log(0, "EXCHANGE under exchanging");
        return false;
    }

    if (!m_pGrid->IsEmpty(display_pos, 1, item->GetSize()))
    {
        sys_log(0, "EXCHANGE not empty item_pos %d %d %d", display_pos, 1, item->GetSize());
        return false;
    }

    Accept(false);
    GetCompany()->Accept(false);

    for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
    {
        if (m_apItems[i])
            continue;

        m_apItems[i]        = item;
        m_aItemPos[i]        = item_pos;
        m_abItemDisplayPos[i]    = display_pos;
        m_pGrid->Put(display_pos, 1, item->GetSize());

        item->SetExchanging(true);

        exchange_packet(m_pOwner,
                EXCHANGE_SUBHEADER_GC_ITEM_ADD,
                true,
                item->GetVnum(),
                TItemPos(RESERVED_WINDOW, display_pos),
                item->GetCount(),
                item);

        exchange_packet(GetCompany()->GetOwner(),
                EXCHANGE_SUBHEADER_GC_ITEM_ADD,
                false,
                item->GetVnum(),
                TItemPos(RESERVED_WINDOW, display_pos),
                item->GetCount(),
                item);

        sys_log(0, "EXCHANGE AddItem success %s pos(%d, %d) %d", item->GetName(), item_pos.window_type, item_pos.cell, display_pos);

        return true;
    }

    // 추가할 공간이 없음
    return false;
}

bool CExchange::RemoveItem(BYTE pos)
{
    if (pos >= EXCHANGE_ITEM_MAX_NUM)
        return false;

    if (!m_apItems[pos])
        return false;

    TItemPos PosOfInventory = m_aItemPos[pos];
    m_apItems[pos]->SetExchanging(false);

    m_pGrid->Get(m_abItemDisplayPos[pos], 1, m_apItems[pos]->GetSize());

    exchange_packet(GetOwner(),    EXCHANGE_SUBHEADER_GC_ITEM_DEL, true, pos, NPOS, 0);
    exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ITEM_DEL, false, pos, PosOfInventory, 0);

    Accept(false);
    GetCompany()->Accept(false);

    m_apItems[pos]        = NULL;
    m_aItemPos[pos]        = NPOS;
    m_abItemDisplayPos[pos] = 0;
    return true;
}

bool CExchange::AddGold(long gold)
{
    if (gold <= 0)
        return false;

    if (GetOwner()->GetGold() < gold)
    {
        // 가지고 있는 돈이 부족.
        exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_LESS_GOLD, 0, 0, NPOS, 0);
        return false;
    }

    if ( LC_IsCanada() == true || LC_IsEurope() == true )
    {
        if ( m_lGold > 0 )
        {
            return false;
        }
    }

    Accept(false);
    GetCompany()->Accept(false);

    m_lGold = gold;

    exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_GOLD_ADD, true, m_lGold, NPOS, 0);
    exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_GOLD_ADD, false, m_lGold, NPOS, 0);
    return true;
}

#ifdef ENABLE_CHEQUE_SYSTEM
bool CExchange::AddCheque(long cheque)
{
    if (cheque <= 0)
        return false;
    if (GetOwner()->GetCheque() < cheque)
    {
        exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_LESS_CHEQUE, 0, 0, NPOS, 0);
        return false;
    }
    Accept(false);
    GetCompany()->Accept(false);
    m_lCheque = cheque;
    exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_CHEQUE_ADD, true, m_lCheque, NPOS, 0);
    exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_CHEQUE_ADD, false, m_lCheque, NPOS, 0);
    return true;
}
#endif

// 돈이 충분히 있는지, 교환하려는 아이템이 실제로 있는지 확인 한다.
bool CExchange::Check(int * piItemCount)
{
    if (GetOwner()->GetGold() < m_lGold)
        return false;

#ifdef ENABLE_CHEQUE_SYSTEM
    if (GetOwner()->GetCheque() < (int)m_lCheque)
        return false;
#endif
   
    int item_count = 0;

    for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
    {
        if (!m_apItems[i])
            continue;

        if (!m_aItemPos[i].IsValidItemPosition())
            return false;

        if (m_apItems[i] != GetOwner()->GetItem(m_aItemPos[i]))
            return false;

        ++item_count;
    }

    *piItemCount = item_count;
    return true;
}

bool CExchange::CheckSpace()
{
    static CGrid s_grid1(5, INVENTORY_MAX_NUM/5 / 5); // envanter_1
    static CGrid s_grid2(5, INVENTORY_MAX_NUM/5 / 5); // envanter_2
    static CGrid s_grid3(5, INVENTORY_MAX_NUM/5 / 5); // envanter_3
    static CGrid s_grid4(5, INVENTORY_MAX_NUM/5 / 5); // envanter_4
    static CGrid s_grid5(5, INVENTORY_MAX_NUM/5 / 5); // envanter_5
#ifdef WJ_SPLIT_INVENTORY_SYSTEM
    static CGrid s_grid6(5, SKILL_BOOK_INVENTORY_MAX_NUM / 5 / 3);
    static CGrid s_grid7(5, UPGRADE_ITEMS_INVENTORY_MAX_NUM / 5 / 3);
    static CGrid s_grid8(5, STONE_INVENTORY_MAX_NUM / 5 / 3);
    static CGrid s_grid9(5, SANDIK_INVENTORY_MAX_NUM / 5 / 3);
#endif

    s_grid1.Clear();
    s_grid2.Clear();
    s_grid3.Clear();
    s_grid4.Clear();
    s_grid5.Clear();
#ifdef WJ_SPLIT_INVENTORY_SYSTEM
    s_grid6.Clear();
    s_grid7.Clear();
    s_grid8.Clear();
    s_grid9.Clear();
#endif

    LPCHARACTER    victim = GetCompany()->GetOwner();
    LPITEM item;

    int i;

    for (i = 0; i < INVENTORY_MAX_NUM / 5; ++i)
    {
        if (!(item = victim->GetInventoryItem(i)))
            continue;

        s_grid1.Put(i, 1, item->GetSize());
    }
    for (i = INVENTORY_MAX_NUM / 5; i < (INVENTORY_MAX_NUM / 5) * 2; ++i)
    {
        if (!(item = victim->GetInventoryItem(i)))
            continue;

        s_grid2.Put(i - INVENTORY_MAX_NUM / 5, 1, item->GetSize());
    }
    for (i = (INVENTORY_MAX_NUM / 5) * 2; i < (INVENTORY_MAX_NUM / 5) * 3; ++i)
    {
        if (!(item = victim->GetInventoryItem(i)))
            continue;

        s_grid3.Put(i - (INVENTORY_MAX_NUM / 5) * 2, 1, item->GetSize());
    }
    for (i = (INVENTORY_MAX_NUM / 5) * 3; i < (INVENTORY_MAX_NUM / 5) * 4; ++i)
    {
        if (!(item = victim->GetInventoryItem(i)))
            continue;

        s_grid4.Put(i - (INVENTORY_MAX_NUM / 5) * 3, 1, item->GetSize());
    }
    for (i = (INVENTORY_MAX_NUM / 5) * 4; i < (INVENTORY_MAX_NUM / 5) * 5; ++i)
    {
        if (!(item = victim->GetInventoryItem(i)))
            continue;

        s_grid5.Put(i - (INVENTORY_MAX_NUM / 5) * 4, 1, item->GetSize());
    }
#ifdef WJ_SPLIT_INVENTORY_SYSTEM
    int x;
    int y;
    const int perPageSkillBookSlotCount = SKILL_BOOK_INVENTORY_MAX_NUM / 1;
    const int perPageUpgradeItemsSlotCount = UPGRADE_ITEMS_INVENTORY_MAX_NUM / 1;
    const int perPageStoneSlotCount = STONE_INVENTORY_MAX_NUM / 1;
    const int perPageSandikSlotCount = SANDIK_INVENTORY_MAX_NUM / 1;
    for (x = 0; x < SKILL_BOOK_INVENTORY_MAX_NUM; ++x) {
        if (!(item = victim->GetSkillBookInventoryItem(x)))
            continue;
       
        BYTE itemSize = item->GetSize();
       
        if (x < perPageSkillBookSlotCount)
            s_grid6.Put(x, 1, itemSize);
    }
   
    for (y = 0; y < UPGRADE_ITEMS_INVENTORY_MAX_NUM; ++y) {
        if (!(item = victim->GetUpgradeItemsInventoryItem(y)))
            continue;
       
        BYTE itemSize = item->GetSize();
       
        if (y < perPageUpgradeItemsSlotCount)
            s_grid7.Put(y, 1, itemSize);
    }
   
    for (y = 0; y < STONE_INVENTORY_MAX_NUM; ++y) {
        if (!(item = victim->GetStoneInventoryItem(y)))
            continue;
       
        BYTE itemSize = item->GetSize();
       
        if (y < perPageStoneSlotCount)
            s_grid8.Put(y, 1, itemSize);
    }
   
    for (y = 0; y < SANDIK_INVENTORY_MAX_NUM; ++y) {
        if (!(item = victim->GetSandikInventoryItem(y)))
            continue;
       
        BYTE itemSize = item->GetSize();
       
        if (y < perPageSandikSlotCount)
            s_grid9.Put(y, 1, itemSize);
    }
#endif

    // ¾Æ... ¹º°¡ °³º´½A °°Ao¸¸... ¿eE¥¼® AIº¥A≫ ³e¸O AIº¥ º¸°i μu¶o ¸¸μc ³≫ A߸øAI´U ¤?¤?
    static std::vector <WORD> s_vDSGrid(DRAGON_SOUL_INVENTORY_MAX_NUM);
   
    // AI´U ¿eE¥¼®A≫ ±³E?CIAo ¾EA≫ °¡´E¼ºAI Aⓒ¹C·I, ¿eE¥¼® AIº¥ º¹≫c´A ¿eE¥¼®AI AOA≫ ¶§ CIμμ·I CN´U.
    bool bDSInitialized = false;
   
    for (i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
    {
        if (!(item = m_apItems[i]))
            continue;

        if (item->IsDragonSoul())
        {
            if (!victim->DragonSoul_IsQualified())
            {
                return false;
            }

            if (!bDSInitialized)
            {
                bDSInitialized = true;
                victim->CopyDragonSoulItemGrid(s_vDSGrid);
            }

            bool bExistEmptySpace = false;
            WORD wBasePos = DSManager::instance().GetBasePosition(item);
            if (wBasePos >= DRAGON_SOUL_INVENTORY_MAX_NUM)
                return false;

            for (int i = 0; i < DRAGON_SOUL_BOX_SIZE; i++)
            {
                WORD wPos = wBasePos + i;
                if (0 == s_vDSGrid[wBasePos])
                {
                    bool bEmpty = true;
                    for (int j = 1; j < item->GetSize(); j++)
                    {
                        if (s_vDSGrid[wPos + j * DRAGON_SOUL_BOX_COLUMN_NUM])
                        {
                            bEmpty = false;
                            break;
                        }
                    }
                    if (bEmpty)
                    {
                        for (int j = 0; j < item->GetSize(); j++)
                        {
                            s_vDSGrid[wPos + j * DRAGON_SOUL_BOX_COLUMN_NUM] = wPos + 1;
                        }
                        bExistEmptySpace = true;
                        break;
                    }
                }
                if (bExistEmptySpace)
                    break;
            }
            if (!bExistEmptySpace)
                return false;
        }
#ifdef WJ_SPLIT_INVENTORY_SYSTEM
        else if (item->IsSkillBook())
        {
            int iPos = s_grid6.FindBlank(1, item->GetSize());
            if (iPos >= 0) {
                s_grid6.Put(iPos, 1, item->GetSize());
                continue;
            }
           
            return false;
        }
        else if (item->IsUpgradeItem())
        {
            int iPos = s_grid7.FindBlank(1, item->GetSize());
            if (iPos >= 0) {
                s_grid7.Put(iPos, 1, item->GetSize());
                continue;
            }
           
            return false;
        }
        else if (item->IsStone())
        {
            int iPos = s_grid8.FindBlank(1, item->GetSize());
            if (iPos >= 0) {
                s_grid8.Put(iPos, 1, item->GetSize());
                continue;
            }
           
            return false;
        }
        else if (item->IsSandik())
        {
            int iPos = s_grid9.FindBlank(1, item->GetSize());
            if (iPos >= 0) {
                s_grid9.Put(iPos, 1, item->GetSize());
                continue;
            }
           
            return false;
        }
#endif  
        else
        {
            int iPos = s_grid1.FindBlank(1, item->GetSize());

            if (iPos >= 0)
            {
                s_grid1.Put(iPos, 1, item->GetSize());
            }
            else
            {
                iPos = s_grid2.FindBlank(1, item->GetSize());

                if (iPos >= 0)
                {
                    s_grid2.Put(iPos, 1, item->GetSize());
                }
                else
                {
                    iPos = s_grid3.FindBlank(1, item->GetSize());

                    if (iPos >= 0)
                    {
                        s_grid3.Put(iPos, 1, item->GetSize());
                    }
                    else
                    {
                        iPos = s_grid4.FindBlank(1, item->GetSize());

                        if (iPos >= 0)
                        {
                            s_grid4.Put(iPos, 1, item->GetSize());
                        }
                        else
                        {
                            iPos = s_grid5.FindBlank(1, item->GetSize());

                            if (iPos >= 0)
                            {
                                s_grid5.Put(iPos, 1, item->GetSize());
                            }
                            else
                            {
                                return false;
                            }
                        }
                    }
                }
            }
        }
    }

    return true;
}

// 교환 끝 (아이템과 돈 등을 실제로 옮긴다)
bool CExchange::Done()
{
    int        empty_pos, i;
    LPITEM    item;

    LPCHARACTER    victim = GetCompany()->GetOwner();

    for (i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
    {
        if (!(item = m_apItems[i]))
            continue;

        if (item->IsDragonSoul())
            empty_pos = victim->GetEmptyDragonSoulInventory(item);
#ifdef WJ_SPLIT_INVENTORY_SYSTEM
        else if (item->IsSkillBook())
            empty_pos = victim->GetEmptySkillBookInventory(item->GetSize());
        else if (item->IsUpgradeItem())
            empty_pos = victim->GetEmptyUpgradeItemsInventory(item->GetSize());
        else if (item->IsStone())
            empty_pos = victim->GetEmptyStoneInventory(item->GetSize());
        else if (item->IsSandik())
            empty_pos = victim->GetEmptySandikInventory(item->GetSize());
#endif
        else
            empty_pos = victim->GetEmptyInventory(item->GetSize());

        if (empty_pos < 0)
        {
            sys_err("Exchange::Done : Cannot find blank position in inventory %s <-> %s item %s",
                    m_pOwner->GetName(), victim->GetName(), item->GetName());
            continue;
        }

        assert(empty_pos >= 0);

        if (item->GetVnum() == 90008 || item->GetVnum() == 90009) // VCARD
        {
            VCardUse(m_pOwner, victim, item);
            continue;
        }

        m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);

        item->RemoveFromCharacter();
        if (item->IsDragonSoul())
            item->AddToCharacter(victim, TItemPos(DRAGON_SOUL_INVENTORY, empty_pos));
#ifdef WJ_SPLIT_INVENTORY_SYSTEM
        else if (item->IsSkillBook())
            item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
        else if (item->IsUpgradeItem())
            item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
        else if (item->IsStone())
            item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
        else if (item->IsSandik())
            item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
#endif
        else
            item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
        ITEM_MANAGER::instance().FlushDelayedSave(item);

        item->SetExchanging(false);
        {
            char exchange_buf[51];

            snprintf(exchange_buf, sizeof(exchange_buf), "%s %u %u", item->GetName(), GetOwner()->GetPlayerID(), item->GetCount());
            LogManager::instance().ItemLog(victim, item, "EXCHANGE_TAKE", exchange_buf);

            snprintf(exchange_buf, sizeof(exchange_buf), "%s %u %u", item->GetName(), victim->GetPlayerID(), item->GetCount());
            LogManager::instance().ItemLog(GetOwner(), item, "EXCHANGE_GIVE", exchange_buf);

            if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007)
            {
                LogManager::instance().GoldBarLog(victim->GetPlayerID(), item->GetID(), EXCHANGE_TAKE, "");
                LogManager::instance().GoldBarLog(GetOwner()->GetPlayerID(), item->GetID(), EXCHANGE_GIVE, "");
            }
           
            m_pOwner->CreateFly(FLY_SP_MEDIUM, victim);                            //Ticaret efekti
            for (int i = 0; i < 3; i++){
                m_pOwner->CreateFly(FLY_SP_SMALL, victim);
            }
        }

        m_apItems[i] = NULL;
    }

    if (m_lGold)
    {
        GetOwner()->PointChange(POINT_GOLD, -m_lGold, true);
        victim->PointChange(POINT_GOLD, m_lGold, true);

        if (m_lGold > 1000)
        {
            char exchange_buf[51];
            snprintf(exchange_buf, sizeof(exchange_buf), "%u %s", GetOwner()->GetPlayerID(), GetOwner()->GetName());
            LogManager::instance().CharLog(victim, m_lGold, "EXCHANGE_GOLD_TAKE", exchange_buf);

            snprintf(exchange_buf, sizeof(exchange_buf), "%u %s", victim->GetPlayerID(), victim->GetName());
            LogManager::instance().CharLog(GetOwner(), m_lGold, "EXCHANGE_GOLD_GIVE", exchange_buf);
        }
    }
#ifdef ENABLE_CHEQUE_SYSTEM
    if (m_lCheque)
    {
        GetOwner()->PointChange(POINT_CHEQUE, -m_lCheque, true);
        victim->PointChange(POINT_CHEQUE, m_lCheque, true);
    }
#endif

    m_pGrid->Clear();
    return true;
}

// 교환을 동의
bool CExchange::Accept(bool bAccept)
{
    if (m_bAccept == bAccept)
        return true;

    m_bAccept = bAccept;

    // 둘 다 동의 했으므로 교환 성립
    if (m_bAccept && GetCompany()->m_bAccept)
    {
        int    iItemCount;

        LPCHARACTER victim = GetCompany()->GetOwner();

        //PREVENT_PORTAL_AFTER_EXCHANGE
        GetOwner()->SetExchangeTime();
        victim->SetExchangeTime();      
        //END_PREVENT_PORTAL_AFTER_EXCHANGE
        if (quest::CQuestManager::instance().GetPCForce(GetOwner()->GetPlayerID())->IsRunning() == true)
        {
            GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot trade if you're using quests"));
            victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot trade if the other part using quests"));
            goto EXCHANGE_END;
        }
        else if (quest::CQuestManager::instance().GetPCForce(victim->GetPlayerID())->IsRunning() == true)
        {
            victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot trade if you're using quests"));
            GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot trade if the other part using quests"));
            goto EXCHANGE_END;
        }
        // exchange_check 에서는 교환할 아이템들이 제자리에 있나 확인하고,
        // 엘크도 충분히 있나 확인한다, 두번째 인자로 교환할 아이템 개수
        // 를 리턴한다.
        if (!Check(&iItemCount))
        {
            GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다."));
            victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다."));
            goto EXCHANGE_END;
        }

        // 리턴 받은 아이템 개수로 상대방의 소지품에 남은 자리가 있나 확인한다.
        if (!CheckSpace())
        {
            GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다."));
            victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다."));
            goto EXCHANGE_END;
        }

        // 상대방도 마찬가지로..
        if (!GetCompany()->Check(&iItemCount))
        {
            victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다."));
            GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 돈이 부족하거나 아이템이 제자리에 없습니다."));
            goto EXCHANGE_END;
        }

        if (!GetCompany()->CheckSpace())
        {
            victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상대방의 소지품에 빈 공간이 없습니다."));
            GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지품에 빈 공간이 없습니다."));
            goto EXCHANGE_END;
        }

        if (db_clientdesc->GetSocket() == INVALID_SOCKET)
        {
            sys_err("Cannot use exchange feature while DB cache connection is dead.");
            victim->ChatPacket(CHAT_TYPE_INFO, "Unknown error");
            GetOwner()->ChatPacket(CHAT_TYPE_INFO, "Unknown error");
            goto EXCHANGE_END;
        }

        if (Done())
        {
            if (m_lGold) // 돈이 있을 만 저장
                GetOwner()->Save();
               
#ifdef ENABLE_CHEQUE_SYSTEM
            if (m_lCheque)
                GetOwner()->Save();
#endif

            if (GetCompany()->Done())
            {
                if (GetCompany()->m_lGold) // 돈이 있을 때만 저장
                    victim->Save();
                   
#ifdef ENABLE_CHEQUE_SYSTEM
                if (GetCompany()->m_lCheque)
                    victim->Save();
#endif

                // INTERNATIONAL_VERSION
                GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님과의 교환이 성사 되었습니다."), victim->GetName());
                victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s 님과의 교환이 성사 되었습니다."), GetOwner()->GetName());
                // END_OF_INTERNATIONAL_VERSION

                //TRADE_LOG
                DBManager::instance().DirectQuery("INSERT INTO log.trade_log (owner_id, buyer_name, date, time, datetime) VALUES (%u, '%s', NOW(), NOW(), NOW())", GetOwner()->GetPlayerID(), victim->GetName());
                //TRADE_LOG
            }
        }

EXCHANGE_END:
        Cancel();
        return false;
    }
    else
    {
        // 아니면 accept에 대한 패킷을 보내자.
        exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, true, m_bAccept, NPOS, 0);
        exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, false, m_bAccept, NPOS, 0);
        return true;
    }
}

// 교환 취소
void CExchange::Cancel()
{
    exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_END, 0, 0, NPOS, 0);
    GetOwner()->SetExchange(NULL);

    for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
    {
        if (m_apItems[i])
            m_apItems[i]->SetExchanging(false);
    }

    if (GetCompany())
    {
        GetCompany()->SetCompany(NULL);
        GetCompany()->Cancel();
    }

    M2_DELETE(this);
}
 

Şu an konuyu görüntüleyenler (Toplam : 1, Üye: 0, Misafir: 1)