Çözüldü Kilitli eşyalar yerden alınınca üst üste geliyor ve kitleniyor (kod bloğuna yardım)

  • Konuyu açan Konuyu açan asilords
  • Açılış Tarihi Açılış Tarihi
  • Yanıt Yanıt 4
  • Gösterim Gösterim 104
Bu konu çözüme ulaştırılmıştır. Çözüm için konuya yazılan tüm yorumları okumayı unutmayın. Eğer konudaki yorumlar sorununuzu çözmediyse yeni bir konu açabilirsiniz.
Durum
İçerik kilitlendiği için mesaj gönderimine kapatıldı.

asilords

MT Üye
MT Üye
Mesaj
354
Çözümler
13
Beğeni
92
Puan
729
Ticaret Puanı
0
Örneğin Mor potu başlangıçta 10 adet verdim ve kilitli şekilde ancak yerden aynı mor pot alınca kilitlilerin üstüne geliyor ve hepsi kilitli oluyor kod kısmı aşağıda ama çalışmadı. ENABLE_BASIC_ITEM_SYSTEM benim eklediğim örnek ama çalışmadı.


1:
Genişlet Daralt Kopyala
#ifdef ENABLE_EXTENDED_COUNT_ITEMS
std::pair<bool, LPITEM> CHARACTER::AutoStackItemProto(DWORD dwItemVnum, short & bCount)
#else
std::pair<bool, LPITEM> CHARACTER::AutoStackItemProto(DWORD dwItemVnum, BYTE & bCount)
#endif
{
    TItemTable * p = ITEM_MANAGER::instance().GetTable(dwItemVnum);
    if (!p)
        return {false, nullptr};

    if (p->dwFlags & ITEM_FLAG_STACKABLE && p->bType != ITEM_BLEND)
    {
        for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
        {
            LPITEM item = GetInventoryItem(i);
            if (!item)
                continue;

            if (item->GetVnum() == dwItemVnum && FN_check_item_socket(item)
[COLOR=rgb(226, 80, 65)]#ifdef ENABLE_BASIC_ITEM_SYSTEM
            && !item->IsBasicItem()
#endif[/COLOR]
                )
            {
                if (IS_SET(p->dwFlags, ITEM_FLAG_MAKECOUNT))
                {
                    if (bCount < p->alValues[1])
                        bCount = p->alValues[1];
                }

                auto bCount2 = MIN(g_bItemCountLimit - item->GetCount(), bCount);
                bCount -= bCount2;
                item->SetCount(item->GetCount() + bCount2);

                if (bCount == 0)
                    return {true, item};
            }
        }
    }

    return {true, nullptr};
}

2:
Genişlet Daralt Kopyala
LPITEM CHARACTER::AutoStackItem(LPITEM item)
{
    if (item->IsStackable() && !IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK))
    {
        auto bCount = item->GetCount();

        for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
        {
            LPITEM item2 = GetInventoryItem(i);
            if (!item2)
                continue;

            if (item == item2)
                continue;

            if (item2->GetVnum() == item->GetVnum())
            {
                int j = 0;
                for (; j < ITEM_SOCKET_MAX_NUM; ++j)
                    if (item2->GetSocket(j) != item->GetSocket(j))
                        break;

                if (j != ITEM_SOCKET_MAX_NUM)
                    continue;

                auto bCount2 = MIN(g_bItemCountLimit - item2->GetCount(), bCount);
                bCount -= bCount2;
                item2->SetCount(item2->GetCount() + bCount2);

                if (bCount == 0)
                {
                    M2_DESTROY_ITEM(item);
                    return item2;
                }
            }
        }

        item->SetCount(bCount);
    }

    return nullptr;
}

3:
Genişlet Daralt Kopyala
#ifdef ENABLE_EXTENDED_COUNT_ITEMS
LPITEM CHARACTER::AutoGiveItem(DWORD dwItemVnum, short bCount, int iRarePct, bool bMsg)
#else
LPITEM CHARACTER::AutoGiveItem(DWORD dwItemVnum, BYTE bCount, int iRarePct, bool bMsg)
#endif
{
    auto [foundTable, foundItem] = AutoStackItemProto(dwItemVnum, bCount);
    if (!foundTable)
        return nullptr;

    DBManager::instance().SendMoneyLog(MONEY_LOG_DROP, dwItemVnum, bCount);

    if (foundItem)
    {
        if (bMsg)
            ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), foundItem->GetName());
        return foundItem;
    }

    LPITEM item = ITEM_MANAGER::instance().CreateItem(dwItemVnum, bCount, 0, true);
    if (!item)
    {
        sys_err("cannot create item by vnum %u (name: %s)", dwItemVnum, GetName());
        return NULL;
    }

    auto finalItem = AutoStackItem(item); // @fixme316
    if (finalItem)
    {
        if (bMsg)
            ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), finalItem->GetName());
        return finalItem;
    }

    if (item->GetType() == ITEM_BLEND)
    {
        for (int i=0; i < INVENTORY_MAX_NUM; i++)
        {
            LPITEM inv_item = GetInventoryItem(i);

            if (inv_item == NULL) continue;

            if (inv_item->GetType() == ITEM_BLEND)
            {
                if (inv_item->GetVnum() == item->GetVnum())
                {
                    if (inv_item->GetSocket(0) == item->GetSocket(0) &&
                            inv_item->GetSocket(1) == item->GetSocket(1) &&
                            inv_item->GetSocket(2) == item->GetSocket(2) &&
                            inv_item->GetCount() < g_bItemCountLimit)
                    {
                        inv_item->SetCount(inv_item->GetCount() + item->GetCount());
                        return inv_item;
                    }
                }
            }
        }
    }

    int iEmptyCell = GetEmptyInventoryEx(item);
    if (iEmptyCell != -1)
    {
        if (bMsg)
            ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), item->GetName());

        item->AddToCharacter(this, TItemPos(item->GetWindowInventoryEx(), iEmptyCell));
        LogManager::instance().ItemLog(this, item, "SYSTEM", item->GetName());

        if (item->GetType() == ITEM_USE && item->GetSubType() == USE_POTION)
        {
            TQuickslot * pSlot;

            if (GetQuickslot(0, &pSlot) && pSlot->type == QUICKSLOT_TYPE_NONE)
            {
                TQuickslot slot;
                slot.type = QUICKSLOT_TYPE_ITEM;
                slot.pos = iEmptyCell;
                SetQuickslot(0, slot);
            }
        }
    }
    else
    {
        item->AddToGround(GetMapIndex(), GetXYZ());
#ifdef ENABLE_NEWSTUFF
        item->StartDestroyEvent(g_aiItemDestroyTime[ITEM_DESTROY_TIME_AUTOGIVE]);
#else
        item->StartDestroyEvent();
#endif

        if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_DROP))
            item->SetOwnership(this, 300);
        else
            item->SetOwnership(this, 60);
        LogManager::instance().ItemLog(this, item, "SYSTEM_DROP", item->GetName());
    }

    sys_log(0,
        "7: %d %d", dwItemVnum, bCount);
    return item;
}
 
Çözüm
Kodlar farklı olduğu için çalışma mantığı aynı mı emin değilim ancak aşağıdaki işlemi doğru yere uygularsan sorunun çözülecektir.

Ayrıca; PickupItem fonksiyonuna da göz atman gerekebilir.

C++:
Genişlet Daralt Kopyala
LPITEM CHARACTER::AutoStackItem(LPITEM item)
{
    if (item->IsStackable() && !IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK))
    {
        auto bCount = item->GetCount();
        for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
        {
            [...]
            
            if (item2->GetVnum() == item->GetVnum()) // bunun içine >
            {
                // IsSealed() envanterdeki ilgili itemin ruha bağlı olup olmadığını sorgulama.
                // Sendeki ismi farklı olabilir...
Kodlar farklı olduğu için çalışma mantığı aynı mı emin değilim ancak aşağıdaki işlemi doğru yere uygularsan sorunun çözülecektir.

Ayrıca; PickupItem fonksiyonuna da göz atman gerekebilir.

C++:
Genişlet Daralt Kopyala
LPITEM CHARACTER::AutoStackItem(LPITEM item)
{
    if (item->IsStackable() && !IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK))
    {
        auto bCount = item->GetCount();
        for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
        {
            [...]
            
            if (item2->GetVnum() == item->GetVnum()) // bunun içine >
            {
                // IsSealed() envanterdeki ilgili itemin ruha bağlı olup olmadığını sorgulama.
                // Sendeki ismi farklı olabilir.
                if(item2->IsSealed())
                    continue;
                
                [...]
            }
        }
        item->SetCount(bCount);
    }
    return nullptr;
}
 
Çözüm
Kodlar farklı olduğu için çalışma mantığı aynı mı emin değilim ancak aşağıdaki işlemi doğru yere uygularsan sorunun çözülecektir.

Ayrıca; PickupItem fonksiyonuna da göz atman gerekebilir.

C++:
Genişlet Daralt Kopyala
LPITEM CHARACTER::AutoStackItem(LPITEM item)
{
    if (item->IsStackable() && !IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK))
    {
        auto bCount = item->GetCount();
        for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
        {
            [...]
           
            if (item2->GetVnum() == item->GetVnum()) // bunun içine >
            {
                // IsSealed() envanterdeki ilgili itemin ruha bağlı olup olmadığını sorgulama.
                // Sendeki ismi farklı olabilir.
                if(item2->IsSealed())
                    continue;
               
                [...]
            }
        }
        item->SetCount(bCount);
    }
    return nullptr;
}
İlk fırsatta deniycem teşekkürler. Bu arada continue; demek istediği nedir ? Eğer item2 ruha bağlıysa stak yapmasın mı?
 
Durum
İçerik kilitlendiği için mesaj gönderimine kapatıldı.
Geri
Üst