Hikayeler

Reklam vermek için turkmmo@gmail.com

BK Envanteri Cube Fix - Metin2Hizmet Farkı İle

  • Konuyu başlatan Ryuuku
  • Başlangıç tarihi
  • Cevaplar 23
  • Görüntüleme 6K

Ryuuku

Level 4
Telefon Numarası Onaylanmış Üye TC Kimlik Numarası Doğrulanmış Üye
TM Üye
Katılım
19 May 2018
Konular
54
Mesajlar
409
Online süresi
2ay 16g
Reaksiyon Skoru
271
Altın Konu
0
Başarım Puanı
153
TM Yaşı
7 Yıl 11 Ay 7 Gün
MmoLira
790
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!

Uzatmadan fixe geçelim. Altta vereceğim işlemleri yaptığınız taktirde cube sorunu tamamen kalkacaktır.

Gerekli dosyalar: cmd_general.cpp - cube.cpp - cube.h
Not: Kodlar karışık geldiyse int olarak geçen tüm satırları uint olarak değiştireceksiniz cube.cpp ve cube.h içindeki!
cpp:
ACMD(do_cube)[/CENTER]
{
    if (!ch->CanDoCube())
        return;

    dev_log(LOG_DEB0, "CUBE COMMAND <%s>: %s", ch->GetName(), argument);
    //www.metin2hizmet.com Cube Fixed
    UINT cube_index = 0, inven_index = 0;
    //www.metin2hizmet.com Cube Fixed
    const char *line;

    char arg1[256], arg2[256], arg3[256];

    line = two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
    one_argument(line, arg3, sizeof(arg3));

    if (0 == arg1[0])
    {
        // print usage
        ch->ChatPacket(CHAT_TYPE_INFO, "Usage: cube open");
        ch->ChatPacket(CHAT_TYPE_INFO, "       cube close");
        ch->ChatPacket(CHAT_TYPE_INFO, "       cube add <inveltory_index>");
        ch->ChatPacket(CHAT_TYPE_INFO, "       cube delete <cube_index>");
        ch->ChatPacket(CHAT_TYPE_INFO, "       cube list");
        ch->ChatPacket(CHAT_TYPE_INFO, "       cube cancel");
        ch->ChatPacket(CHAT_TYPE_INFO, "       cube make [all]");
        return;
    }

    const std::string& strArg1 = std::string(arg1);
    
    if (strArg1 == "r_info")
    {
        if (0 == arg2[0])
            Cube_request_result_list(ch);
        else
        {
            if (isdigit(*arg2))
            {
                //www.metin2hizmet.com Cube Fixed
                UINT listIndex = 0, requestCount = 1;
                //www.metin2hizmet.com Cube Fixed
                str_to_number(listIndex, arg2);

                if (0 != arg3[0] && isdigit(*arg3))
                    str_to_number(requestCount, arg3);

                Cube_request_material_info(ch, listIndex, requestCount);
            }
        }

        return;
    }

    switch (LOWER(arg1[0]))
    {
        case 'o':    // open
            Cube_open(ch);
            break;

        case 'c':    // close
            Cube_close(ch);
            break;

        case 'l':    // list
            Cube_show_list(ch);
            break;

        case 'a':    // add cue_index inven_index
            {
                if (0 == arg2[0] || !isdigit(*arg2) ||
                    0 == arg3[0] || !isdigit(*arg3))
                    return;

                str_to_number(cube_index, arg2);
                str_to_number(inven_index, arg3);
                Cube_add_item (ch, cube_index, inven_index);
            }
            break;

        case 'd':    // delete
            {
                if (0 == arg2[0] || !isdigit(*arg2))
                    return;

                str_to_number(cube_index, arg2);
                Cube_delete_item (ch, cube_index);
            }
            break;

        case 'm':    // make
            if (0 != arg2[0])
            {
                while (true == Cube_make(ch))
                    dev_log (LOG_DEB0, "cube make success");
            }
            else
                Cube_make(ch);
            break;

        default:
            return;
    }
}
cpp:
Bulunacak satırlar;
void Cube_add_item (LPCHARACTER ch, int cube_index, int inven_index);
void Cube_delete_item(LPCHARACTER ch, int cube_index);
void Cube_request_material_info(LPCHARACTER ch, int request_start_index, int request_count = 1);
Bu şekilde değiştirin;
void Cube_add_item (LPCHARACTER ch, UINT cube_index, UINT inven_index);
void Cube_delete_item(LPCHARACTER ch, UINT cube_index);
void Cube_request_material_info(LPCHARACTER ch, UINT request_start_index, UINT request_count = 1);
cpp:
static bool FN_check_item_count (LPITEM *items, DWORD item_vnum, UINT need_count)
{
    UINT    count = 0;

    // for all cube
    for (UINT i=0; i<CUBE_MAX_NUM; ++i)
    {
        if (NULL==items[i])    continue;

        if (item_vnum==items[i]->GetVnum())
        {
            count += items[i]->GetCount();
        }
    }

    return (count>=need_count);
}

// 큐브내의 재료를 지운다.
static void FN_remove_material (LPITEM *items, DWORD item_vnum, UINT need_count)
{
    UINT        count    = 0;
    LPITEM    item    = NULL;

    // for all cube
    for (UINT i=0; i<CUBE_MAX_NUM; ++i)
    {
        if (NULL==items[i])    continue;

        item = items[i];
        if (item_vnum==item->GetVnum())
        {
            count += item->GetCount();

            if (count>need_count)
            {
                item->SetCount(count-need_count);
                return;
            }
            else
            {
                item->SetCount(0);
                items[i] = NULL;
            }
        }
    }
}

void Cube_clean_item (LPCHARACTER ch)
{
    LPITEM    *cube_item;

    cube_item = ch->GetCubeItem();

    for (UINT i = 0; i<CUBE_MAX_NUM; ++i)
    {
        if (NULL == cube_item[i])
            continue;

        cube_item[i] = NULL;
    }
}

void Cube_show_list (LPCHARACTER ch)
{
    LPITEM    *cube_item;
    LPITEM    item;

    RETURN_IF_CUBE_IS_NOT_OPENED(ch);

    cube_item = ch->GetCubeItem();

    for (UINT i = 0; i<CUBE_MAX_NUM; ++i)
    {
        item = cube_item[i];
        if (NULL==item)    continue;

        ch->ChatPacket(CHAT_TYPE_INFO, "cube[%d]: inventory[%d]: %s",
                i, item->GetCell(), item->GetName());
    }
}


// 인벤토리에 있는 아이템을 큐브에 등록
void Cube_add_item (LPCHARACTER ch, UINT cube_index, UINT inven_index)
{
    // 아이템이 있는가?
    // 큐브내의 빈자리 찾기
    // 큐브세팅
    // 메시지 전송
    LPITEM    item;
    LPITEM    *cube_item;

    RETURN_IF_CUBE_IS_NOT_OPENED(ch);

#ifdef WJ_SPLIT_INVENTORY_SYSTEM
    if (inven_index<0 || INVENTORY_AND_EQUIP_SLOT_MAX <= inven_index)
        return;
#else
    if (inven_index<0 || INVENTORY_MAX_NUM <= inven_index)
        return;
#endif

    if (cube_index<0 || CUBE_MAX_NUM<=cube_index)
        return;

    item = ch->GetInventoryItem(inven_index);

    if (NULL==item)    return;

    cube_item = ch->GetCubeItem();

    // 이미 다른위치에 등록되었던 아이템이면 기존 indext삭제
    for (UINT i=0; i<CUBE_MAX_NUM; ++i)
    {
        if (item==cube_item[i])
        {
            cube_item[i] = NULL;
            break;
        }
    }

    cube_item[cube_index] = item;

    if (test_server)
        ch->ChatPacket(CHAT_TYPE_INFO, "cube[%d]: inventory[%d]: %s added",
                                    cube_index, inven_index, item->GetName());

    // 현재 상자에 올라온 아이템들로 무엇을 만들 수 있는지 클라이언트에 정보 전달
    // 을 하고싶었으나 그냥 필요한 골드가 얼마인지 전달
    FN_update_cube_status(ch);

    return;
}

// 큐브에있는 아이템을 제거
void Cube_delete_item(LPCHARACTER ch, UINT cube_index)
{
    LPITEM    item;
    LPITEM    *cube_item;

    RETURN_IF_CUBE_IS_NOT_OPENED(ch);

    if (cube_index<0 || CUBE_MAX_NUM<=cube_index)    return;

    cube_item = ch->GetCubeItem();

    if ( NULL== cube_item[cube_index] )    return;

    item = cube_item[cube_index];
    cube_item[cube_index] = NULL;

    if (test_server)
        ch->ChatPacket(CHAT_TYPE_INFO, "cube[%d]: cube[%d]: %s deleted",
                cube_index, item->GetCell(), item->GetName());

    // 현재 상자에 올라온 아이템들로 무엇을 만들 수 있는지 클라이언트에 정보 전달
    // 을 하고싶었으나 그냥 필요한 골드가 얼마인지 전달
    FN_update_cube_status(ch);

    return;
}

bool Cube_InformationInitialize()
{
    for (UINT i = 0; i < s_cube_proto.size(); ++i)
    {
        CUBE_DATA* cubeData = s_cube_proto[i];

        const std::vector<CUBE_VALUE>& rewards = cubeData->reward;

        // 하드코딩 ㅈㅅ
        if (1 != rewards.size())
        {
            sys_err("[CubeInfo] WARNING! Does not support multiple rewards (count: %d)", rewards.size());           
            continue;
        }
        //if (1 != cubeData->npc_vnum.size())
        //{
        //    sys_err("[CubeInfo] WARNING! Does not support multiple NPC (count: %d)", cubeData->npc_vnum.size());           
        //    continue;
        //}

        const CUBE_VALUE& reward = rewards.at(0);
        const WORD& npcVNUM = cubeData->npc_vnum.at(0);
        bool bComplicate = false;
        
        TCubeMapByNPC& cubeMap = cube_info_map;
        TCubeResultList& resultList = cubeMap[npcVNUM];
        SCubeMaterialInfo materialInfo;

        materialInfo.reward = reward;
        materialInfo.gold = cubeData->gold;
        materialInfo.material = cubeData->item;

        for (TCubeResultList::iterator iter = resultList.begin(); resultList.end() != iter; ++iter)
        {
            SCubeMaterialInfo& existInfo = *iter;

            // 이미 중복되는 보상이 등록되어 있다면 아예 다른 조합으로 만드는 것인지,
            // 거의 같은 조합인데 특정 부분만 틀린 것인지 구분함.
            // 예를들면 특정 부분만 틀린 아이템들은 아래처럼 하나로 묶어서 하나의 결과로 보여주기 위함임:
            // 용신지검:
            //        무쌍검+5 ~ +9 x 1
            //        붉은 칼자루 조각 x1
            //        녹색 검장식 조각 x1
            if (reward.vnum == existInfo.reward.vnum)
            {
                for (TCubeValueVector::iterator existMaterialIter = existInfo.material.begin(); existInfo.material.end() != existMaterialIter; ++existMaterialIter)
                {
                    TItemTable* existMaterialProto = ITEM_MANAGER::Instance().GetTable(existMaterialIter->vnum);
                    if (NULL == existMaterialProto)
                    {
                        sys_err("There is no item(%u)", existMaterialIter->vnum);
                        return false;
                    }
                    SItemNameAndLevel existItemInfo = SplitItemNameAndLevelFromName(existMaterialProto->szName);

                    if (0 < existItemInfo.level)
                    {
                        // 지금 추가하는 큐브 결과물의 재료와, 기존에 등록되어있던 큐브 결과물의 재료 중
                        // 중복되는 부분이 있는지 검색한다
                        for (TCubeValueVector::iterator currentMaterialIter = materialInfo.material.begin(); materialInfo.material.end() != currentMaterialIter; ++currentMaterialIter)
                        {
                            TItemTable* currentMaterialProto = ITEM_MANAGER::Instance().GetTable(currentMaterialIter->vnum);
                            SItemNameAndLevel currentItemInfo = SplitItemNameAndLevelFromName(currentMaterialProto->szName);

                            if (currentItemInfo.name == existItemInfo.name)
                            {
                                bComplicate = true;
                                existInfo.complicateMaterial.push_back(*currentMaterialIter);

                                if (std::find(existInfo.complicateMaterial.begin(), existInfo.complicateMaterial.end(), *existMaterialIter) == existInfo.complicateMaterial.end())
                                    existInfo.complicateMaterial.push_back(*existMaterialIter);

                                //currentMaterialIter = materialInfo.material.erase(currentMaterialIter);

                                // TODO: 중복되는 아이템 두 개 이상 검출해야 될 수도 있음
                                break;
                            }
                        } // for currentMaterialIter
                    }    // if level
                }    // for existMaterialInfo
            }    // if (reward.vnum == existInfo.reward.vnum)

        }    // for resultList

        if (false == bComplicate)
            resultList.push_back(materialInfo);
    }

    Cube_MakeCubeInformationText();

    s_isInitializedCubeMaterialInformation = true;
    return true;
}
void Cube_request_material_info(LPCHARACTER ch, UINT requestStartIndex, UINT requestCount)
{
    RETURN_IF_CUBE_IS_NOT_OPENED(ch);

    LPCHARACTER    npc = ch->GetQuestNPC();
    if (NULL == npc)
        return;

    DWORD npcVNUM = npc->GetRaceNum();
    std::string materialInfoText = "";

    UINT index = 0;
    bool bCatchInfo = false;

    const TCubeResultList& resultList = cube_info_map[npcVNUM];
    for (TCubeResultList::const_iterator iter = resultList.begin(); resultList.end() != iter; ++iter)
    {
        const SCubeMaterialInfo& materialInfo = *iter;

        if (index++ == requestStartIndex)
        {
            bCatchInfo = true;
        }
        
        if (bCatchInfo)
        {
            materialInfoText += materialInfo.infoText + "@";
        }

        if (index >= requestStartIndex + requestCount)
            break;
    }

    if (!bCatchInfo || materialInfoText.size() == 0)
    {
        sys_err("[CubeInfo] Can't find matched material info (NPC: %d, index: %d, request count: %d)", npcVNUM, requestStartIndex, requestCount);
        return;
    }

    materialInfoText.erase(materialInfoText.size() - 1);

    //
    // (Server -> Client) /cube m_info start_index count 125,1|126,2|127,2|123,5&555,5&555,4/120000
    if (materialInfoText.size() - 20 >= CHAT_MAX_LEN)
    {
        sys_err("[CubeInfo] Too long material info. (NPC: %d, requestStart: %d, requestCount: %d, length: %d)", npcVNUM, requestStartIndex, requestCount, materialInfoText.size());
    }

    ch->ChatPacket(CHAT_TYPE_COMMAND, "cube m_info %d %d %s", requestStartIndex, requestCount, materialInfoText.c_str());

    
}
 
Uzatmadan fixe geçelim. Altta vereceğim işlemleri yaptığınız taktirde cube sorunu tamamen kalkacaktır.

Gerekli dosyalar: cmd_general.cpp - cube.cpp - cube.h
Not: Kodlar karışık geldiyse int olarak geçen tüm satırları uint olarak değiştireceksiniz cube.cpp ve cube.h içindeki!
cpp:
ACMD(do_cube)[/CENTER]
{
    if (!ch->CanDoCube())
        return;

    dev_log(LOG_DEB0, "CUBE COMMAND <%s>: %s", ch->GetName(), argument);
    //www.metin2hizmet.com Cube Fixed
    UINT cube_index = 0, inven_index = 0;
    //www.metin2hizmet.com Cube Fixed
    const char *line;

    char arg1[256], arg2[256], arg3[256];

    line = two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
    one_argument(line, arg3, sizeof(arg3));

    if (0 == arg1[0])
    {
        // print usage
        ch->ChatPacket(CHAT_TYPE_INFO, "Usage: cube open");
        ch->ChatPacket(CHAT_TYPE_INFO, "       cube close");
        ch->ChatPacket(CHAT_TYPE_INFO, "       cube add <inveltory_index>");
        ch->ChatPacket(CHAT_TYPE_INFO, "       cube delete <cube_index>");
        ch->ChatPacket(CHAT_TYPE_INFO, "       cube list");
        ch->ChatPacket(CHAT_TYPE_INFO, "       cube cancel");
        ch->ChatPacket(CHAT_TYPE_INFO, "       cube make [all]");
        return;
    }

    const std::string& strArg1 = std::string(arg1);
   
    if (strArg1 == "r_info")
    {
        if (0 == arg2[0])
            Cube_request_result_list(ch);
        else
        {
            if (isdigit(*arg2))
            {
                //www.metin2hizmet.com Cube Fixed
                UINT listIndex = 0, requestCount = 1;
                //www.metin2hizmet.com Cube Fixed
                str_to_number(listIndex, arg2);

                if (0 != arg3[0] && isdigit(*arg3))
                    str_to_number(requestCount, arg3);

                Cube_request_material_info(ch, listIndex, requestCount);
            }
        }

        return;
    }

    switch (LOWER(arg1[0]))
    {
        case 'o':    // open
            Cube_open(ch);
            break;

        case 'c':    // close
            Cube_close(ch);
            break;

        case 'l':    // list
            Cube_show_list(ch);
            break;

        case 'a':    // add cue_index inven_index
            {
                if (0 == arg2[0] || !isdigit(*arg2) ||
                    0 == arg3[0] || !isdigit(*arg3))
                    return;

                str_to_number(cube_index, arg2);
                str_to_number(inven_index, arg3);
                Cube_add_item (ch, cube_index, inven_index);
            }
            break;

        case 'd':    // delete
            {
                if (0 == arg2[0] || !isdigit(*arg2))
                    return;

                str_to_number(cube_index, arg2);
                Cube_delete_item (ch, cube_index);
            }
            break;

        case 'm':    // make
            if (0 != arg2[0])
            {
                while (true == Cube_make(ch))
                    dev_log (LOG_DEB0, "cube make success");
            }
            else
                Cube_make(ch);
            break;

        default:
            return;
    }
}
cpp:
Bulunacak satırlar;
void Cube_add_item (LPCHARACTER ch, int cube_index, int inven_index);
void Cube_delete_item(LPCHARACTER ch, int cube_index);
void Cube_request_material_info(LPCHARACTER ch, int request_start_index, int request_count = 1);
Bu şekilde değiştirin;
void Cube_add_item (LPCHARACTER ch, UINT cube_index, UINT inven_index);
void Cube_delete_item(LPCHARACTER ch, UINT cube_index);
void Cube_request_material_info(LPCHARACTER ch, UINT request_start_index, UINT request_count = 1);
cpp:
static bool FN_check_item_count (LPITEM *items, DWORD item_vnum, UINT need_count)
{
    UINT    count = 0;

    // for all cube
    for (UINT i=0; i<CUBE_MAX_NUM; ++i)
    {
        if (NULL==items[i])    continue;

        if (item_vnum==items[i]->GetVnum())
        {
            count += items[i]->GetCount();
        }
    }

    return (count>=need_count);
}

// 큐브내의 재료를 지운다.
static void FN_remove_material (LPITEM *items, DWORD item_vnum, UINT need_count)
{
    UINT        count    = 0;
    LPITEM    item    = NULL;

    // for all cube
    for (UINT i=0; i<CUBE_MAX_NUM; ++i)
    {
        if (NULL==items[i])    continue;

        item = items[i];
        if (item_vnum==item->GetVnum())
        {
            count += item->GetCount();

            if (count>need_count)
            {
                item->SetCount(count-need_count);
                return;
            }
            else
            {
                item->SetCount(0);
                items[i] = NULL;
            }
        }
    }
}

void Cube_clean_item (LPCHARACTER ch)
{
    LPITEM    *cube_item;

    cube_item = ch->GetCubeItem();

    for (UINT i = 0; i<CUBE_MAX_NUM; ++i)
    {
        if (NULL == cube_item[i])
            continue;

        cube_item[i] = NULL;
    }
}

void Cube_show_list (LPCHARACTER ch)
{
    LPITEM    *cube_item;
    LPITEM    item;

    RETURN_IF_CUBE_IS_NOT_OPENED(ch);

    cube_item = ch->GetCubeItem();

    for (UINT i = 0; i<CUBE_MAX_NUM; ++i)
    {
        item = cube_item[i];
        if (NULL==item)    continue;

        ch->ChatPacket(CHAT_TYPE_INFO, "cube[%d]: inventory[%d]: %s",
                i, item->GetCell(), item->GetName());
    }
}


// 인벤토리에 있는 아이템을 큐브에 등록
void Cube_add_item (LPCHARACTER ch, UINT cube_index, UINT inven_index)
{
    // 아이템이 있는가?
    // 큐브내의 빈자리 찾기
    // 큐브세팅
    // 메시지 전송
    LPITEM    item;
    LPITEM    *cube_item;

    RETURN_IF_CUBE_IS_NOT_OPENED(ch);

#ifdef WJ_SPLIT_INVENTORY_SYSTEM
    if (inven_index<0 || INVENTORY_AND_EQUIP_SLOT_MAX <= inven_index)
        return;
#else
    if (inven_index<0 || INVENTORY_MAX_NUM <= inven_index)
        return;
#endif

    if (cube_index<0 || CUBE_MAX_NUM<=cube_index)
        return;

    item = ch->GetInventoryItem(inven_index);

    if (NULL==item)    return;

    cube_item = ch->GetCubeItem();

    // 이미 다른위치에 등록되었던 아이템이면 기존 indext삭제
    for (UINT i=0; i<CUBE_MAX_NUM; ++i)
    {
        if (item==cube_item[i])
        {
            cube_item[i] = NULL;
            break;
        }
    }

    cube_item[cube_index] = item;

    if (test_server)
        ch->ChatPacket(CHAT_TYPE_INFO, "cube[%d]: inventory[%d]: %s added",
                                    cube_index, inven_index, item->GetName());

    // 현재 상자에 올라온 아이템들로 무엇을 만들 수 있는지 클라이언트에 정보 전달
    // 을 하고싶었으나 그냥 필요한 골드가 얼마인지 전달
    FN_update_cube_status(ch);

    return;
}

// 큐브에있는 아이템을 제거
void Cube_delete_item(LPCHARACTER ch, UINT cube_index)
{
    LPITEM    item;
    LPITEM    *cube_item;

    RETURN_IF_CUBE_IS_NOT_OPENED(ch);

    if (cube_index<0 || CUBE_MAX_NUM<=cube_index)    return;

    cube_item = ch->GetCubeItem();

    if ( NULL== cube_item[cube_index] )    return;

    item = cube_item[cube_index];
    cube_item[cube_index] = NULL;

    if (test_server)
        ch->ChatPacket(CHAT_TYPE_INFO, "cube[%d]: cube[%d]: %s deleted",
                cube_index, item->GetCell(), item->GetName());

    // 현재 상자에 올라온 아이템들로 무엇을 만들 수 있는지 클라이언트에 정보 전달
    // 을 하고싶었으나 그냥 필요한 골드가 얼마인지 전달
    FN_update_cube_status(ch);

    return;
}

bool Cube_InformationInitialize()
{
    for (UINT i = 0; i < s_cube_proto.size(); ++i)
    {
        CUBE_DATA* cubeData = s_cube_proto[i];

        const std::vector<CUBE_VALUE>& rewards = cubeData->reward;

        // 하드코딩 ㅈㅅ
        if (1 != rewards.size())
        {
            sys_err("[CubeInfo] WARNING! Does not support multiple rewards (count: %d)", rewards.size());          
            continue;
        }
        //if (1 != cubeData->npc_vnum.size())
        //{
        //    sys_err("[CubeInfo] WARNING! Does not support multiple NPC (count: %d)", cubeData->npc_vnum.size());          
        //    continue;
        //}

        const CUBE_VALUE& reward = rewards.at(0);
        const WORD& npcVNUM = cubeData->npc_vnum.at(0);
        bool bComplicate = false;
       
        TCubeMapByNPC& cubeMap = cube_info_map;
        TCubeResultList& resultList = cubeMap[npcVNUM];
        SCubeMaterialInfo materialInfo;

        materialInfo.reward = reward;
        materialInfo.gold = cubeData->gold;
        materialInfo.material = cubeData->item;

        for (TCubeResultList::iterator iter = resultList.begin(); resultList.end() != iter; ++iter)
        {
            SCubeMaterialInfo& existInfo = *iter;

            // 이미 중복되는 보상이 등록되어 있다면 아예 다른 조합으로 만드는 것인지,
            // 거의 같은 조합인데 특정 부분만 틀린 것인지 구분함.
            // 예를들면 특정 부분만 틀린 아이템들은 아래처럼 하나로 묶어서 하나의 결과로 보여주기 위함임:
            // 용신지검:
            //        무쌍검+5 ~ +9 x 1
            //        붉은 칼자루 조각 x1
            //        녹색 검장식 조각 x1
            if (reward.vnum == existInfo.reward.vnum)
            {
                for (TCubeValueVector::iterator existMaterialIter = existInfo.material.begin(); existInfo.material.end() != existMaterialIter; ++existMaterialIter)
                {
                    TItemTable* existMaterialProto = ITEM_MANAGER::Instance().GetTable(existMaterialIter->vnum);
                    if (NULL == existMaterialProto)
                    {
                        sys_err("There is no item(%u)", existMaterialIter->vnum);
                        return false;
                    }
                    SItemNameAndLevel existItemInfo = SplitItemNameAndLevelFromName(existMaterialProto->szName);

                    if (0 < existItemInfo.level)
                    {
                        // 지금 추가하는 큐브 결과물의 재료와, 기존에 등록되어있던 큐브 결과물의 재료 중
                        // 중복되는 부분이 있는지 검색한다
                        for (TCubeValueVector::iterator currentMaterialIter = materialInfo.material.begin(); materialInfo.material.end() != currentMaterialIter; ++currentMaterialIter)
                        {
                            TItemTable* currentMaterialProto = ITEM_MANAGER::Instance().GetTable(currentMaterialIter->vnum);
                            SItemNameAndLevel currentItemInfo = SplitItemNameAndLevelFromName(currentMaterialProto->szName);

                            if (currentItemInfo.name == existItemInfo.name)
                            {
                                bComplicate = true;
                                existInfo.complicateMaterial.push_back(*currentMaterialIter);

                                if (std::find(existInfo.complicateMaterial.begin(), existInfo.complicateMaterial.end(), *existMaterialIter) == existInfo.complicateMaterial.end())
                                    existInfo.complicateMaterial.push_back(*existMaterialIter);

                                //currentMaterialIter = materialInfo.material.erase(currentMaterialIter);

                                // TODO: 중복되는 아이템 두 개 이상 검출해야 될 수도 있음
                                break;
                            }
                        } // for currentMaterialIter
                    }    // if level
                }    // for existMaterialInfo
            }    // if (reward.vnum == existInfo.reward.vnum)

        }    // for resultList

        if (false == bComplicate)
            resultList.push_back(materialInfo);
    }

    Cube_MakeCubeInformationText();

    s_isInitializedCubeMaterialInformation = true;
    return true;
}
void Cube_request_material_info(LPCHARACTER ch, UINT requestStartIndex, UINT requestCount)
{
    RETURN_IF_CUBE_IS_NOT_OPENED(ch);

    LPCHARACTER    npc = ch->GetQuestNPC();
    if (NULL == npc)
        return;

    DWORD npcVNUM = npc->GetRaceNum();
    std::string materialInfoText = "";

    UINT index = 0;
    bool bCatchInfo = false;

    const TCubeResultList& resultList = cube_info_map[npcVNUM];
    for (TCubeResultList::const_iterator iter = resultList.begin(); resultList.end() != iter; ++iter)
    {
        const SCubeMaterialInfo& materialInfo = *iter;

        if (index++ == requestStartIndex)
        {
            bCatchInfo = true;
        }
       
        if (bCatchInfo)
        {
            materialInfoText += materialInfo.infoText + "@";
        }

        if (index >= requestStartIndex + requestCount)
            break;
    }

    if (!bCatchInfo || materialInfoText.size() == 0)
    {
        sys_err("[CubeInfo] Can't find matched material info (NPC: %d, index: %d, request count: %d)", npcVNUM, requestStartIndex, requestCount);
        return;
    }

    materialInfoText.erase(materialInfoText.size() - 1);

    //
    // (Server -> Client) /cube m_info start_index count 125,1|126,2|127,2|123,5&555,5&555,4/120000
    if (materialInfoText.size() - 20 >= CHAT_MAX_LEN)
    {
        sys_err("[CubeInfo] Too long material info. (NPC: %d, requestStart: %d, requestCount: %d, length: %d)", npcVNUM, requestStartIndex, requestCount, materialInfoText.size());
    }

    ch->ChatPacket(CHAT_TYPE_COMMAND, "cube m_info %d %d %s", requestStartIndex, requestCount, materialInfoText.c_str());

   
}
Paylaşım için teşekkürler.
 
Teşekkürler
 
Paylaşım için teşekkürler..
 

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

Geri
Üst