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
cube.cpp eksik
 
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());

   
}

Kodları pasteye atıp paylaşırmısınız çogu yerde sorun oluştu bu şekilde teşekkür ederim :)
 
bu fix daha çok cpu yorması yapar böyle bir fix zararlıdır intden uinte çekmişsin sayı oranını büyütmüşsün bu daha çok zararlıdır.
 

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

Geri
Üst