Jump to content

Jorila

Inactive Member
  • Posts

    58
  • Joined

  • Last visited

  • Feedback

    0%

Posts posted by Jorila

  1. i haven't a cube.lua

    i have checked all files and i see its a binary mistake - look the binary-part. need help <.<

    Spoiler

    else if (!strcmpi(szCmd, "cube"))
     {
      if (TokenVector.size() < 2)
      {
       TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand);
       return;
      }

      if ("open" == TokenVector[1])
      {
       if (3 > TokenVector.size())
       {
        TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand);
        return;
       }

       DWORD npcVNUM = (DWORD)atoi(TokenVector[2].c_str());
       PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_Open", Py_BuildValue("(i)", npcVNUM));
      }
      else if ("close" == TokenVector[1])
      {
       PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_Close", Py_BuildValue("()"));
      }
      else if ("info" == TokenVector[1])
      {
       if (5 != TokenVector.size())
       {
        TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand);
        return;
       }

       UINT gold = atoi(TokenVector[2].c_str());
       UINT itemVnum = atoi(TokenVector[3].c_str());
       UINT count = atoi(TokenVector[4].c_str());
       PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_UpdateInfo", Py_BuildValue("(iii)", gold, itemVnum, count));
      }
      else if ("success" == TokenVector[1])
      {
       if (4 != TokenVector.size())
       {
        TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand);
        return;
       }

       UINT itemVnum = atoi(TokenVector[2].c_str());
       UINT count = atoi(TokenVector[3].c_str());
       PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_Succeed", Py_BuildValue("(ii)", itemVnum, count));
      }
      else if ("fail" == TokenVector[1])
      {
       PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_Failed", Py_BuildValue("()"));
      }
      else if ("r_list" == TokenVector[1])
      {
       //result list (/cube r_list npcVNUM resultCount resultText)
       //20383 4 72723,1/72725,1/72730.1/50001,5 <- ÀÌ·±½ÄÀ¸·Î "/" ¹®ÀÚ·Î ±¸ºÐµÈ ¸®½ºÆ®¸¦ ÁÜ
       if (5 != TokenVector.size())
       {
        TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %d", c_szCommand, 5);
        return;
       }

       DWORD npcVNUM = (DWORD)atoi(TokenVector[2].c_str());

       PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_ResultList", Py_BuildValue("(is)", npcVNUM, TokenVector[4].c_str()));
      }

     

  2. Spoiler

    /*********************************************************************
     * date        : 2006.11.20
     * file        : cube.cpp
     * author      : mhh
     * description : 
     */

    #define _cube_cpp_

    #include "stdafx.h"
    #include "constants.h"
    #include "utils.h"
    #include "log.h"
    #include "char.h"
    #include "dev_log.h"
    #include "locale_service.h"
    #include "item.h"
    #include "item_manager.h"

    #include <sstream>

    extern int test_server;


    #define RETURN_IF_CUBE_IS_NOT_OPENED(ch) if (!(ch)->IsCubeOpen()) return


    /*--------------------------------------------------------*/
    /*                   GLOBAL VARIABLES                     */
    /*--------------------------------------------------------*/
    static std::vector<CUBE_DATA*>    s_cube_proto;
    static bool s_isInitializedCubeMaterialInformation = false;

    /*--------------------------------------------------------*/
    /*               Cube Material Information                */ 
    /*--------------------------------------------------------*/
    enum ECubeResultCategory
    {
        CUBE_CATEGORY_POTION,                // ¾àÃÊ, Áø¾× µîµî..  (Æ÷¼ÇÀ¸·Î ƯÁ¤ÇÒ ¼ö ¾øÀ¸´Ï »ç¿ë ¾È ÇÔ. ¾àÃÊ°°Àº°Ç ´Ù °Á ±âŸ)
        CUBE_CATEGORY_WEAPON,                // ¹«±â
        CUBE_CATEGORY_ARMOR,                // ¹æ¾î±¸
        CUBE_CATEGORY_ACCESSORY,            // Àå½Å±¸
        CUBE_CATEGORY_ETC,                // ±âŸ µîµî...
    };

    typedef std::vector<CUBE_VALUE>    TCubeValueVector;

    struct SCubeMaterialInfo
    {
        SCubeMaterialInfo()
        {
            bHaveComplicateMaterial = false;
        };

        CUBE_VALUE            reward;                            // º¸»óÀÌ ¹¹³Ä
        TCubeValueVector    material;                        // Àç·áµéÀº ¹¹³Ä
        DWORD                gold;                            // µ·Àº ¾ó¸¶µå³Ä
        TCubeValueVector    complicateMaterial;                // º¹ÀâÇÑ-_- Àç·áµé

        // .. Ŭ¶óÀ̾ðÆ®¿¡¼­ Àç·á¸¦ º¸¿©ÁÖ±â À§ÇÏ¿© ¾à¼ÓÇÑ Æ÷¸Ë
        // 72723,1&72724,2&72730,1
        // 52001,1|52002,1|52003,1&72723,1&72724,5
        //    => ( 52001,1 or 52002,1 or 52003,1 ) and 72723,1 and 72724,5
        std::string            infoText;        
        bool                bHaveComplicateMaterial;        //
    };

    struct SItemNameAndLevel
    {
        SItemNameAndLevel() { level = 0; }

        std::string        name;
        int                level;
    };


    // ÀڷᱸÁ¶³ª ÀÌ·±°Å º´½ÅÀ롂 ÀÌÇØÁ»... ´©±¸¶«¿¡ ¿µÈ¥ÀÌ ¾ø´Â »óÅ¿¡¼­ ¸¸µé¾ú¾¸
    typedef std::vector<SCubeMaterialInfo>                                TCubeResultList;
    typedef boost::unordered_map<DWORD, TCubeResultList>                TCubeMapByNPC;                // °¢°¢ÀÇ NPCº°·Î ¾î¶² °É ¸¸µé ¼ö ÀÖ°í Àç·á°¡ ¹ºÁö...
    typedef boost::unordered_map<DWORD, std::string>                    TCubeResultInfoTextByNPC;    // °¢°¢ÀÇ NPCº°·Î ¸¸µé ¼ö ÀÖ´Â ¸ñ·ÏÀ» Á¤ÇØÁø Æ÷¸ËÀ¸·Î Á¤¸®ÇÑ Á¤º¸

    TCubeMapByNPC cube_info_map;
    TCubeResultInfoTextByNPC cube_result_info_map_by_npc;                // ³×ÀÌ¹Ö Á¸³ª º´½Å°°´Ù ¤»¤»¤»

    class CCubeMaterialInfoHelper
    {
    public:
    public:
    };

    /*--------------------------------------------------------*/
    /*                  STATIC FUNCTIONS                      */ 
    /*--------------------------------------------------------*/
     // ÇÊ¿äÇÑ ¾ÆÀÌÅÛ °³¼ö¸¦ °¡Áö°íÀִ°¡?
    static bool FN_check_item_count (LPITEM *items, DWORD item_vnum, int need_count)
    {
        int    count = 0;

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

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

        return (count>=need_count);
    }

    // Å¥ºê³»ÀÇ Àç·á¸¦ Áö¿î´Ù.
    static void FN_remove_material (LPITEM *items, DWORD item_vnum, int need_count)
    {
        int        count    = 0;
        LPITEM    item    = NULL;

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

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

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


    static CUBE_DATA* FN_find_cube (LPITEM *items, WORD npc_vnum)
    {
        DWORD    i, end_index;

        if (0==npc_vnum)    return NULL;

        // FOR ALL CUBE_PROTO
        end_index = s_cube_proto.size();
        for (i=0; i<end_index; ++i)
        {
            if ( s_cube_proto->can_make_item(items, npc_vnum) )
                return s_cube_proto;
        }

        return NULL;
    }

    static bool FN_check_valid_npc( WORD vnum )
    {
        for ( std::vector<CUBE_DATA*>::iterator iter = s_cube_proto.begin(); iter != s_cube_proto.end(); iter++ )
        {
            if ( std::find((*iter)->npc_vnum.begin(), (*iter)->npc_vnum.end(), vnum) != (*iter)->npc_vnum.end() )
                return true;
        }

        return false;
    }

    // Å¥ºêµ¥ÀÌŸ°¡ ¿Ã¹Ù¸£°Ô ÃʱâÈ­ µÇ¾ú´ÂÁö üũÇÑ´Ù.
    static bool FN_check_cube_data (CUBE_DATA *cube_data)
    {
        DWORD    i = 0;
        DWORD    end_index = 0;

        end_index = cube_data->npc_vnum.size();
        for (i=0; i<end_index; ++i)
        {
            if ( cube_data->npc_vnum == 0 )    return false;
        }

        end_index = cube_data->item.size();
        for (i=0; i<end_index; ++i)
        {
            if ( cube_data->item.vnum == 0 )        return false;
            if ( cube_data->item.count == 0 )    return false;
        }

        end_index = cube_data->reward.size();
        for (i=0; i<end_index; ++i)
        {
            if ( cube_data->reward.vnum == 0 )    return false;
            if ( cube_data->reward.count == 0 )    return false;
        }
        return true;
    }

    CUBE_DATA::CUBE_DATA()
    {
        this->percent = 0;
        this->gold = 0;
    }

    // ÇÊ¿äÇÑ Àç·áÀÇ ¼ö·®À» ¸¸Á·ÇÏ´ÂÁö üũÇÑ´Ù.
    bool CUBE_DATA::can_make_item (LPITEM *items, WORD npc_vnum)
    {
        // ÇÊ¿äÇÑ Àç·á, ¼ö·®À» ¸¸Á·ÇÏ´ÂÁö üũÇÑ´Ù.
        DWORD    i, end_index;
        DWORD    need_vnum;
        int        need_count;
        int        found_npc = false;

        // check npc_vnum
        end_index = this->npc_vnum.size();
        for (i=0; i<end_index; ++i)
        {
            if (npc_vnum == this->npc_vnum)
                found_npc = true;
        }
        if (false==found_npc)    return false;

        end_index = this->item.size();
        for (i=0; i<end_index; ++i)
        {
            need_vnum    = this->item.vnum;
            need_count    = this->item.count;

            if ( false==FN_check_item_count(items, need_vnum, need_count) )
                return false;
        }

        return true;
    }

    // Å¥ºê¸¦ µ¹·ÈÀ»¶§ ³ª¿À´Â ¾ÆÀÌÅÛÀÇ Á¾·ù¸¦ °áÁ¤ÇÔ
    CUBE_VALUE* CUBE_DATA::reward_value ()
    {
        int        end_index        = 0;
        DWORD    reward_index    = 0;

        end_index = this->reward.size();
        reward_index = number(0, end_index);
        reward_index = number(0, end_index-1);

        return &this->reward[reward_index];
    }

    // Å¥ºê¿¡ µé¾îÀÖ´Â Àç·á¸¦ Áö¿î´Ù
    void CUBE_DATA::remove_material (LPCHARACTER ch)
    {
        DWORD    i, end_index;
        DWORD    need_vnum;
        int        need_count;
        LPITEM    *items = ch->GetCubeItem();

        end_index = this->item.size();
        for (i=0; i<end_index; ++i)
        {
            need_vnum    = this->item.vnum;
            need_count    = this->item.count;

            FN_remove_material (items, need_vnum, need_count);
        }
    }

    void Cube_clean_item (LPCHARACTER ch)
    {
        LPITEM    *cube_item;

        cube_item = ch->GetCubeItem();

        for (int i=0; i<CUBE_MAX_NUM; ++i)
        {
            if (NULL == cube_item)
                continue;

            cube_item = NULL;
        }
    }

    // Å¥ºêâ ¿­±â
    void Cube_open (LPCHARACTER ch)
    {
        if (false == s_isInitializedCubeMaterialInformation)
        {
            Cube_InformationInitialize();
        }

        if (NULL == ch)
            return;

        LPCHARACTER    npc;
        npc = ch->GetQuestNPC();
        if (NULL==npc)
        {
            if (test_server)
                dev_log(LOG_DEB0, "cube_npc is NULL");
            return;
        }

        if ( FN_check_valid_npc(npc->GetRaceNum()) == false )
        {
            if ( test_server == true )
            {
                dev_log(LOG_DEB0, "cube not valid NPC");
            }
            return;
        }

        if (ch->IsCubeOpen())
        {
            ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ÀÌ¹Ì Á¦Á¶Ã¢ÀÌ ¿­·ÁÀÖ½À´Ï´Ù."));
            return;
        }
        if ( ch->GetExchange() || ch->GetMyShop() || ch->GetShopOwner() || ch->IsOpenSafebox() || ch->IsCubeOpen() )
        {
            ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´Ù¸¥ °Å·¡Áß(â°í,±³È¯,»óÁ¡)¿¡´Â »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù."));
            return;
        }

        long distance = DISTANCE_APPROX(ch->GetX() - npc->GetX(), ch->GetY() - npc->GetY());

        if (distance >= CUBE_MAX_DISTANCE)
        {
            sys_log(1, "CUBE: TOO_FAR: %s distance %d", ch->GetName(), distance);
            return;
        }


        Cube_clean_item(ch);
        ch->SetCubeNpc(npc);
        ch->ChatPacket(CHAT_TYPE_COMMAND, "cube open %d", npc->GetRaceNum());
    }

    // Å¥ºê ĵ½½
    void Cube_close (LPCHARACTER ch)
    {
        RETURN_IF_CUBE_IS_NOT_OPENED(ch);
        Cube_clean_item(ch);
        ch->SetCubeNpc(NULL);
        ch->ChatPacket(CHAT_TYPE_COMMAND, "cube close");
        dev_log(LOG_DEB0, "<CUBE> close (%s)", ch->GetName());
    }

    void Cube_init()
    {
        CUBE_DATA * p_cube = NULL;
        std::vector<CUBE_DATA*>::iterator iter;

        char file_name[256+1];
        snprintf(file_name, sizeof(file_name), "%s/cube.txt", LocaleService_GetBasePath().c_str());

        sys_log(0, "Cube_Init %s", file_name);

        for (iter = s_cube_proto.begin(); iter!=s_cube_proto.end(); iter++)
        {
            p_cube = *iter;
            M2_DELETE(p_cube);
        }

        s_cube_proto.clear();

        if (false == Cube_load(file_name))
            sys_err("Cube_Init failed");
    }

    bool Cube_load (const char *file)
    {
        FILE    *fp;
        char    one_line[256];
        int        value1, value2;
        const char    *delim = " \t\r\n";
        char    *v, *token_string;
        CUBE_DATA    *cube_data = NULL;
        CUBE_VALUE    cube_value = {0,0};

        if (0 == file || 0 == file[0])
            return false;

        if ((fp = fopen(file, "r")) == 0)
            return false;

        while (fgets(one_line, 256, fp))
        {
            value1 = value2 = 0;

            if (one_line[0] == '#')
                continue;

            token_string = strtok(one_line, delim);

            if (NULL == token_string)
                continue;

            // set value1, value2
            if ((v = strtok(NULL, delim)))
                str_to_number(value1, v);

            if ((v = strtok(NULL, delim)))
                str_to_number(value2, v);

            TOKEN("section")
            {
                cube_data = M2_NEW CUBE_DATA;
            }
            else TOKEN("npc")
            {
                cube_data->npc_vnum.push_back((WORD)value1);
            }
            else TOKEN("item")
            {
                cube_value.vnum        = value1;
                cube_value.count    = value2;

                cube_data->item.push_back(cube_value);
            }
            else TOKEN("reward")
            {
                cube_value.vnum        = value1;
                cube_value.count    = value2;

                cube_data->reward.push_back(cube_value);
            }
            else TOKEN("percent")
            {
                cube_data->percent = value1;
            }
            else TOKEN("gold")
            {
                // Á¦Á¶¿¡ ÇÊ¿äÇÑ ±Ý¾×
                cube_data->gold = value1;
            }
            else TOKEN("end")
            {
                // TODO : check cube data
                if (false == FN_check_cube_data(cube_data))
                {
                    dev_log(LOG_DEB0, "something wrong");
                    M2_DELETE(cube_data);
                    continue;
                }
                s_cube_proto.push_back(cube_data);
            }
        }

        fclose(fp);
        return true;
    }

    static void FN_cube_print (CUBE_DATA *data, DWORD index)
    {
        DWORD    i;
        dev_log(LOG_DEB0, "--------------------------------");
        dev_log(LOG_DEB0, "CUBE_DATA[%d]", index);

        for (i=0; i<data->npc_vnum.size(); ++i)
        {
            dev_log(LOG_DEB0, "\tNPC_VNUM[%d] = %d", i, data->npc_vnum);
        }
        for (i=0; i<data->item.size(); ++i)
        {
            dev_log(LOG_DEB0, "\tITEM[%d]   = (%d, %d)", i, data->item.vnum, data->item.count);
        }
        for (i=0; i<data->reward.size(); ++i)
        {
            dev_log(LOG_DEB0, "\tREWARD[%d] = (%d, %d)", i, data->reward.vnum, data->reward.count);
        }
        dev_log(LOG_DEB0, "\tPERCENT = %d", data->percent);
        dev_log(LOG_DEB0, "--------------------------------");
    }

    void Cube_print ()
    {
        for (DWORD i=0; i<s_cube_proto.size(); ++i)
        {
            FN_cube_print(s_cube_proto, i);
        }
    }


    static bool FN_update_cube_status(LPCHARACTER ch)
    {
        if (NULL == ch)
            return false;

        if (!ch->IsCubeOpen())
            return false;

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

        CUBE_DATA* cube = FN_find_cube(ch->GetCubeItem(), npc->GetRaceNum());

        if (NULL == cube)
        {
            ch->ChatPacket(CHAT_TYPE_COMMAND, "cube info 0 0 0");
            return false;
        }

        ch->ChatPacket(CHAT_TYPE_COMMAND, "cube info %d %d %d", cube->gold, 0, 0);
        return true;
    }

    // return new item
    bool Cube_make (LPCHARACTER ch)
    {
        // ÁÖ¾îÁø ¾ÆÀÌÅÛÀ» ÇÊ¿ä·ÎÇÏ´Â Á¶ÇÕÀ» ã´Â´Ù. (Å¥ºêµ¥ÀÌŸ·Î ĪÇÔ)
        // Å¥ºê µ¥ÀÌŸ°¡ ÀÖ´Ù¸é ¾ÆÀÌÅÛÀÇ Àç·á¸¦ üũÇÑ´Ù.
        // »õ·Î¿î ¾ÆÀÌÅÛÀ» ¸¸µç´Ù.
        // »õ·Î¿î ¾ÆÀÌÅÛ Áö±Þ

        LPCHARACTER    npc;
        int            percent_number = 0;
        CUBE_DATA    *cube_proto;
        LPITEM    *items;
        LPITEM    new_item;

        if (!(ch)->IsCubeOpen())
        {
            (ch)->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Á¦Á¶Ã¢ÀÌ ¿­·ÁÀÖÁö ¾Ê½À´Ï´Ù"));
            return false;
        }

        npc = ch->GetQuestNPC();
        if (NULL == npc)
        {
            return false;
        }

        items = ch->GetCubeItem();
        cube_proto = FN_find_cube(items, npc->GetRaceNum());

        if (NULL == cube_proto)
        {
            ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Á¦Á¶ Àç·á°¡ ºÎÁ·ÇÕ´Ï´Ù"));
            return false;
        }

        if (ch->GetGold() < cube_proto->gold)
        {
            ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("µ·ÀÌ ºÎÁ·Çϰųª ¾ÆÀÌÅÛÀÌ Á¦ÀÚ¸®¿¡ ¾ø½À´Ï´Ù."));    // ÀÌ ÅؽºÆ®´Â ÀÌ¹Ì ³Î¸® ¾²À̴°Ŷó Ãß°¡¹ø¿ª ÇÊ¿ä ¾øÀ½
            return false;
        }

        CUBE_VALUE    *reward_value = cube_proto->reward_value();

        // »ç¿ëµÇ¾ú´ø Àç·á¾ÆÀÌÅÛ »èÁ¦
        cube_proto->remove_material (ch);
        
        // Á¦Á¶½Ã ÇÊ¿äÇÑ °ñµå Â÷°¨
        if (0 < cube_proto->gold)
            ch->PointChange(POINT_GOLD, -(cube_proto->gold), false);

        percent_number = number(1,100);
        if ( percent_number<=cube_proto->percent)
        {
            // ¼º°ø
            ch->ChatPacket(CHAT_TYPE_COMMAND, "cube success %d %d", reward_value->vnum, reward_value->count);
            new_item = ch->AutoGiveItem(reward_value->vnum, reward_value->count);

            LogManager::instance().CubeLog(ch->GetPlayerID(), ch->GetX(), ch->GetY(),
                    reward_value->vnum, new_item->GetID(), reward_value->count, 1);
            return true;
        }
        else
        {
            // ½ÇÆÐ
            ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Á¦Á¶¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."));    // 2012.11.12 »õ·Î Ãß°¡µÈ ¸Þ¼¼Áö (locale_string.txt ¿¡ Ãß°¡ÇØ¾ß ÇÔ)
            ch->ChatPacket(CHAT_TYPE_COMMAND, "cube fail");
            LogManager::instance().CubeLog(ch->GetPlayerID(), ch->GetX(), ch->GetY(),
                    reward_value->vnum, 0, 0, 0);
            return false;
        }

        return false;
    }


    // Å¥ºê¿¡ ÀÖ´Â ¾ÆÀÌÅÛµéÀ» Ç¥½Ã
    void Cube_show_list (LPCHARACTER ch)
    {
        LPITEM    *cube_item;
        LPITEM    item;

        RETURN_IF_CUBE_IS_NOT_OPENED(ch);

        cube_item = ch->GetCubeItem();

        for (int i=0; i<CUBE_MAX_NUM; ++i)
        {
            item = cube_item;
            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, int cube_index, int inven_index)
    {
        // ¾ÆÀÌÅÛÀÌ Àִ°¡?
        // Å¥ºê³»ÀÇ ºóÀÚ¸® ã±â
        // Å¥ºê¼¼ÆÃ
        // ¸Þ½ÃÁö Àü¼Û
        LPITEM    item;
        LPITEM    *cube_item;

        RETURN_IF_CUBE_IS_NOT_OPENED(ch);

        if (inven_index<0 || INVENTORY_MAX_NUM<=inven_index)
            return;
        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 (int i=0; i<CUBE_MAX_NUM; ++i)
        {
            if (item==cube_item)
            {
                cube_item = 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, int 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;
    }

    // ¾ÆÀÌÅÛ À̸§À» ÅëÇؼ­ ¼ø¼ö À̸§°ú °­È­·¹º§À» ºÐ¸®ÇÏ´Â ÇÔ¼ö (¹«½Ö°Ë+5 -> ¹«½Ö°Ë, 5)
    SItemNameAndLevel SplitItemNameAndLevelFromName(const std::string& name)
    {
        int level = 0;
        SItemNameAndLevel info;
        info.name = name;

        size_t pos = name.find("+");
        
        if (std::string::npos != pos)
        {
            const std::string levelStr = name.substr(pos + 1, name.size() - pos - 1);
            str_to_number(level, levelStr.c_str());

            info.name = name.substr(0, pos);
        }

        info.level = level;

        return info;
    };

    bool FIsEqualCubeValue(const CUBE_VALUE& a, const CUBE_VALUE& B)
    {
        return (a.vnum == b.vnum) && (a.count == b.count);
    }

    bool FIsLessCubeValue(const CUBE_VALUE& a, const CUBE_VALUE& B)
    {
        return a.vnum < b.vnum;
    }

    void Cube_MakeCubeInformationText()
    {
        // ÀÌÁ¦ Á¤¸®µÈ Å¥ºê °á°ú ¹× Àç·áµéÀÇ Á¤º¸·Î Ŭ¶óÀ̾ðÆ®¿¡ º¸³» ÁÙ Á¤º¸·Î º¯È¯ÇÔ.
        for (TCubeMapByNPC::iterator iter = cube_info_map.begin(); cube_info_map.end() != iter; ++iter)
        {
            const DWORD& npcVNUM = iter->first;
            TCubeResultList& resultList = iter->second;

            for (TCubeResultList::iterator resultIter = resultList.begin(); resultList.end() != resultIter; ++resultIter)
            {
                SCubeMaterialInfo& materialInfo = *resultIter;
                std::string& infoText = materialInfo.infoText;

                
                // À̳ðÀÌ ³ª»Û³ðÀ̾ß
                if (0 < materialInfo.complicateMaterial.size())
                {
                    std::sort(materialInfo.complicateMaterial.begin(), materialInfo.complicateMaterial.end(), FIsLessCubeValue);
                    std::sort(materialInfo.material.begin(), materialInfo.material.end(), FIsLessCubeValue);

                    //// Áߺ¹µÇ´Â Àç·áµéÀ» Áö¿ò
                    for (TCubeValueVector::iterator iter = materialInfo.complicateMaterial.begin(); materialInfo.complicateMaterial.end() != iter; ++iter)
                    {
                        for (TCubeValueVector::iterator targetIter = materialInfo.material.begin(); materialInfo.material.end() != targetIter; ++targetIter)
                        {
                            if (*targetIter == *iter)
                            {
                                targetIter = materialInfo.material.erase(targetIter);
                            }
                        }
                    }

                    // 72723,1 or 72725,1 or ... ÀÌ·± ½ÄÀÇ ¾à¼ÓµÈ Æ÷¸ËÀ» ÁöÅ°´Â ÅؽºÆ®¸¦ »ý¼º
                    for (TCubeValueVector::iterator iter = materialInfo.complicateMaterial.begin(); materialInfo.complicateMaterial.end() != iter; ++iter)
                    {
                        char tempBuffer[128];
                        sprintf(tempBuffer, "%d,%d|", iter->vnum, iter->count);
                        
                        infoText += std::string(tempBuffer);
                    }

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

                    if (0 < materialInfo.material.size())
                        infoText.push_back('&');
                }

                // Áߺ¹µÇÁö ¾Ê´Â ÀÏ¹Ý Àç·áµéµµ Æ÷¸Ë »ý¼º
                for (TCubeValueVector::iterator iter = materialInfo.material.begin(); materialInfo.material.end() != iter; ++iter)
                {
                    char tempBuffer[128];
                    sprintf(tempBuffer, "%d,%d&", iter->vnum, iter->count);
                    infoText += std::string(tempBuffer);
                }

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

                // ¸¸µé ¶§ °ñµå°¡ ÇÊ¿äÇÏ´Ù¸é °ñµåÁ¤º¸ Ãß°¡
                if (0 < materialInfo.gold)
                {
                    char temp[128];
                    sprintf(temp, "%d", materialInfo.gold);
                    infoText += std::string("/") + temp;
                }

                //sys_err("\t\tNPC: %d, Reward: %d(%s)\n\t\t\tInfo: %s", npcVNUM, materialInfo.reward.vnum, ITEM_MANAGER::Instance().GetTable(materialInfo.reward.vnum)->szName, materialInfo.infoText.c_str());
            } // for resultList
        } // for npc
    }

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

            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;
    }

    // Ŭ¶óÀ̾ðÆ®¿¡¼­ ¼­¹ö·Î : ÇöÀç NPC°¡ ¸¸µé ¼ö ÀÖ´Â ¾ÆÀÌÅÛµéÀÇ Á¤º¸(¸ñ·Ï)¸¦ ¿äû
    void Cube_request_result_list(LPCHARACTER ch)
    {
        RETURN_IF_CUBE_IS_NOT_OPENED(ch);

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

        DWORD npcVNUM = npc->GetRaceNum();
        size_t resultCount = 0;

        std::string& resultText = cube_result_info_map_by_npc[npcVNUM];

        // ÇØ´ç NPC°¡ ¸¸µé ¼ö ÀÖ´Â ¸ñ·ÏÀÌ Á¤¸®µÈ °Ô ¾ø´Ù¸é ij½Ã¸¦ »ý¼º
        if (resultText.length() == 0)
        {
            resultText.clear();

            const TCubeResultList& resultList = cube_info_map[npcVNUM];
            for (TCubeResultList::const_iterator iter = resultList.begin(); resultList.end() != iter; ++iter)
            {
                const SCubeMaterialInfo& materialInfo = *iter;
                char temp[128];
                sprintf(temp, "%d,%d", materialInfo.reward.vnum, materialInfo.reward.count);

                resultText += std::string(temp) + "/";

                ++resultCount;
            }

            if (resultCount == 0) {
                return;
            }

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

            // äÆà ÆÐŶÀÇ ÇѰ踦 ³Ñ¾î°¡¸é ¿¡·¯ ³²±è... ±âȹÀÚ ºÐµé ²² Á¶Á¤ÇØ´Þ¶ó°í ¿äûÇϰųª, ³ªÁß¿¡ ´Ù¸¥ ¹æ½ÄÀ¸·Î ¹Ù²Ù°Å³ª...
                int WildFantasytFIXED;
                if (resultText.size() < 20)
                {
                        WildFantasytFIXED = 20 - resultText.size();
                }
                else
                {
                        WildFantasytFIXED = resultText.size() - 20;
                }
                if (WildFantasytFIXED >= CHAT_MAX_LEN)
                {
                        sys_err("[CubeInfo] Too long cube result list text. (NPC: %d, FIXED_size_value_exygo: %d, length: %d)", npcVNUM, WildFantasytFIXED, resultText.size());
                        resultText.clear();
                        resultCount = 0;
                }

        }

        // ÇöÀç NPC°¡ ¸¸µé ¼ö ÀÖ´Â ¾ÆÀÌÅÛµéÀÇ ¸ñ·ÏÀ» ¾Æ·¡ Æ÷¸ËÀ¸·Î Àü¼ÛÇÑ´Ù.
        // (Server -> Client) /cube r_list npcVNUM resultCount vnum1,count1/vnum2,count2,/vnum3,count3/...
        // (Server -> Client) /cube r_list 20383 4 123,1/125,1/128,1/130,5
        
        ch->ChatPacket(CHAT_TYPE_COMMAND, "cube r_list %d %s", npcVNUM, resultText.c_str());
    }

    // 
    void Cube_request_material_info(LPCHARACTER ch, int requestStartIndex, int requestCount)
    {
        RETURN_IF_CUBE_IS_NOT_OPENED(ch);

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

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

        int 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());

        
    }

    Here, please help s: and @iRazer

     

     

    edit: this ist the binary part

    Spoiler

     else if (!strcmpi(szCmd, "cube"))
     {
      if (TokenVector.size() < 2)
      {
       TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand);
       return;
      }

      if ("open" == TokenVector[1])
      {
       if (3 > TokenVector.size())
       {
        TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand);
        return;
       }

       DWORD npcVNUM = (DWORD)atoi(TokenVector[2].c_str());
       PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_Open", Py_BuildValue("(i)", npcVNUM));
      }
      else if ("close" == TokenVector[1])
      {
       PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_Close", Py_BuildValue("()"));
      }
      else if ("info" == TokenVector[1])
      {
       if (5 != TokenVector.size())
       {
        TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand);
        return;
       }

       UINT gold = atoi(TokenVector[2].c_str());
       UINT itemVnum = atoi(TokenVector[3].c_str());
       UINT count = atoi(TokenVector[4].c_str());
       PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_UpdateInfo", Py_BuildValue("(iii)", gold, itemVnum, count));
      }
      else if ("success" == TokenVector[1])
      {
       if (4 != TokenVector.size())
       {
        TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %s", c_szCommand);
        return;
       }

       UINT itemVnum = atoi(TokenVector[2].c_str());
       UINT count = atoi(TokenVector[3].c_str());
       PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_Succeed", Py_BuildValue("(ii)", itemVnum, count));
      }
      else if ("fail" == TokenVector[1])
      {
       PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_Failed", Py_BuildValue("()"));
      }
      else if ("r_list" == TokenVector[1])
      {
       //result list (/cube r_list npcVNUM resultCount resultText)
       //20383 4 72723,1/72725,1/72730.1/50001,5 <- ÀÌ·±½ÄÀ¸·Î "/" ¹®ÀÚ·Î ±¸ºÐµÈ ¸®½ºÆ®¸¦ ÁÜ
       if (5 != TokenVector.size())
       {
        TraceError("CPythonNetworkStream::ServerCommand(c_szCommand=%s) - Strange Parameter Count : %d", c_szCommand, 5);
        return;
       }

       DWORD npcVNUM = (DWORD)atoi(TokenVector[2].c_str());

       PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_Cube_ResultList", Py_BuildValue("(is)", npcVNUM, TokenVector[4].c_str()));
      } 

    edit2: cube.txt:
     

    2860682af4d61f27432c4416dee13a52.png

     

  3. d0fc1cc03bcb6e0daf4f077c9e660dbd.png

    @VegaS

    hmm i add the refine-system...

     

    code:

    Spoiler

    #ifndef ENABLE_ANNOUNCEMENT_REFINE_SUCCES
        #define ENABLE_ANNOUNCEMENT_REFINE_SUCCES
        #define ENABLE_ANNOUNCEMENT_REFINE_SUCCES_MIN_LEVEL 8

    Spoiler

    #ifdef ENABLE_ANNOUNCEMENT_REFINE_SUCCES
    //mefunction745
        int m_nTableMin[] = {148, 158, 168, 178, 188, 198};
        int m_nTableMax[] = {149, 159, 169, 179, 189, 199};    
        
        for (int i = 0; i < _countof(m_nTableMin); i++)
        {
            for (int j = 0; j < _countof(m_nTableMax); j++)
            {        
                if (m_nTableMin <= pkNewItem->GetVnum() && pkNewItem->GetVnum() <= m_nTableMax[j])
                {
                    char szUpgradeAnnouncement[QUERY_MAX_LEN];
                    snprintf(szUpgradeAnnouncement, sizeof(szUpgradeAnnouncement), "<Refine> Player [%s] upgraded item [%s] with succes!", GetName(), pkNewItem->GetName()); 
                    BroadcastNotice(szUpgradeAnnouncement);
                    // lalala
                }
            }    
        }
    #endif

     

  4. 4 minutes ago, VegaS said:

     

    
    	static int arg[2] = {140, 149}; // MIN - MAX
    				
    	if (arg[0] <= item->GetVnum() && item->GetVnum() <= arg[1])
    	{
    		// Do something
    	}

     

    thanks :D i have 2 very little  question. oh my gosh, i ask to much, but i am a c++ noob s:

     

    where i must add the 

    static int arg[2] = {140, 149}; // MIN - MAX

    and it is possible when i write like this: static int arg[2] = {140, 149, 10010, 10019, 20010, 20019}; // 3 different items

  5. 690e2506aa37c421de38007d0ee04708.png

     

    when i open the cube window, client syserr says:

     

    0910 01:02:36376 :: CPythonNetworkStream::ServerCommand(c_szCommand=cube r_list 20381 28630,1/28631,1/28632,1/28633,1/28634,1/28635,1/28636,1/28637,1/28638,1/28639,1/28640,1/28641,1/28642,1/28643,1) - Strange Parameter Count : 5

     

    is that a binary bug? how can i fix this?

  6. 0950383877322b7eb5d219baabc0b310.png

    when i use a emoticon my client syserr get spamed:
    0909 21:32:26421 :: ELTimer_GetMSec() - m_dwEmoticonTime
    0909 21:32:26637 :: ELTimer_GetMSec() - m_dwEmoticonTime
    0909 21:32:26817 :: ELTimer_GetMSec() - m_dwEmoticonTime
    0909 21:32:27114 :: ELTimer_GetMSec() - m_dwEmoticonTime
    0909 21:32:27131 :: ELTimer_GetMSec() - m_dwEmoticonTime
    0909 21:32:27329 :: ELTimer_GetMSec() - m_dwEmoticonTime
    0909 21:32:29027 :: ELTimer_GetMSec() - m_dwEmoticonTime

     

    how can i fix this? :(

  7. @VegaS

    Thank you ^^ sorry i am a noob. your quest is good, but i need a quest where user get the VIP when he/she use an item.

    i forgot <.< one question. can you make a little quest:

    when user use item 70007(example ID), user get the VIP for 2 weeks and he/she get (example) 50% more itemdrop, 50% more golddrop.

    thank you very much!

     

    • Love 1
  8. Hello Com,

     

    i have a "little..." HP/MP/Skill?-Bug". When i use an auto-potion or summon my pet or deactivaded a skill or sura use skill-id 66 - the client have a little "lag"

    or when i use skill like (looks gif) - i lost hp/mp

    a8eb6ba436ff9619a386ae26bbec19ef.png

    skill 66 - remove_good_affect - when sura use skill 66 - user have a lag

    look the gif's - look the hp/mp

    962c5470781090f4cb296254b4524c87.giffa42ed8d124eaa143d9cf7da8d52017a.gif

     

    i use the "fix" by @VegaS : char.cpp

    Spoiler

    void CHARACTER::ComputePoints()
    {
        long lStat = GetPoint(POINT_STAT);
        long lStatResetCount = GetPoint(POINT_STAT_RESET_COUNT);
        long lSkillActive = GetPoint(POINT_SKILL);
        long lSkillSub = GetPoint(POINT_SUB_SKILL);
        long lSkillHorse = GetPoint(POINT_HORSE_SKILL);
        long lLevelStep = GetPoint(POINT_LEVEL_STEP);

        long lAttackerBonus = GetPoint(POINT_PARTY_ATTACKER_BONUS);
        long lTankerBonus = GetPoint(POINT_PARTY_TANKER_BONUS);
        long lBufferBonus = GetPoint(POINT_PARTY_BUFFER_BONUS);
        long lSkillMasterBonus = GetPoint(POINT_PARTY_SKILL_MASTER_BONUS);
        long lHasteBonus = GetPoint(POINT_PARTY_HASTE_BONUS);
        long lDefenderBonus = GetPoint(POINT_PARTY_DEFENDER_BONUS);

        long lHPRecovery = GetPoint(POINT_HP_RECOVERY);
        long lSPRecovery = GetPoint(POINT_SP_RECOVERY);

        memset(m_pointsInstant.points, 0, sizeof(m_pointsInstant.points));
        BuffOnAttr_ClearAll();
        m_SkillDamageBonus.clear();

        SetPoint(POINT_STAT, lStat);
        SetPoint(POINT_SKILL, lSkillActive);
        SetPoint(POINT_SUB_SKILL, lSkillSub);
        SetPoint(POINT_HORSE_SKILL, lSkillHorse);
        SetPoint(POINT_LEVEL_STEP, lLevelStep);
        SetPoint(POINT_STAT_RESET_COUNT, lStatResetCount);

        SetPoint(POINT_ST, GetRealPoint(POINT_ST));
        SetPoint(POINT_HT, GetRealPoint(POINT_HT));
        SetPoint(POINT_DX, GetRealPoint(POINT_DX));
        SetPoint(POINT_IQ, GetRealPoint(POINT_IQ));

        SetPart(PART_MAIN, GetOriginalPart(PART_MAIN));
        SetPart(PART_WEAPON, GetOriginalPart(PART_WEAPON));
        SetPart(PART_HEAD, GetOriginalPart(PART_HEAD));
        SetPart(PART_HAIR, GetOriginalPart(PART_HAIR));

        SetPoint(POINT_PARTY_ATTACKER_BONUS, lAttackerBonus);
        SetPoint(POINT_PARTY_TANKER_BONUS, lTankerBonus);
        SetPoint(POINT_PARTY_BUFFER_BONUS, lBufferBonus);
        SetPoint(POINT_PARTY_SKILL_MASTER_BONUS, lSkillMasterBonus);
        SetPoint(POINT_PARTY_HASTE_BONUS, lHasteBonus);
        SetPoint(POINT_PARTY_DEFENDER_BONUS, lDefenderBonus);

        SetPoint(POINT_HP_RECOVERY, lHPRecovery);
        SetPoint(POINT_SP_RECOVERY, lSPRecovery);

        SetPoint(POINT_PC_BANG_EXP_BONUS, 0);
        SetPoint(POINT_PC_BANG_DROP_BONUS, 0);

        int iMaxHP, iMaxSP;
        int iMaxStamina;

        if(IsPC())
        {
            iMaxHP = JobInitialPoints[GetJob()].max_hp + m_points.iRandomHP + GetPoint(POINT_HT) * JobInitialPoints[GetJob()].hp_per_ht;
            iMaxSP = JobInitialPoints[GetJob()].max_sp + m_points.iRandomSP + GetPoint(POINT_IQ) * JobInitialPoints[GetJob()].sp_per_iq;
            iMaxStamina = JobInitialPoints[GetJob()].max_stamina + GetPoint(POINT_HT) * JobInitialPoints[GetJob()].stamina_per_con;

            {
                CSkillProto* pkSk = CSkillManager::instance().Get(SKILL_ADD_HP);

                if(NULL != pkSk)
                {
                    pkSk->SetPointVar("k", 1.0f * GetSkillPower(SKILL_ADD_HP) / 100.0f);

                    iMaxHP += static_cast<int>(pkSk->kPointPoly.Eval());
                }
            }

            // default value
            SetPoint(POINT_MOV_SPEED, 100);
            SetPoint(POINT_ATT_SPEED, 100);
            PointChange(POINT_ATT_SPEED, GetPoint(POINT_PARTY_HASTE_BONUS));
            SetPoint(POINT_CASTING_SPEED, 100);
        }
        else
        {
            iMaxHP = m_pkMobData->m_table.dwMaxHP;
            iMaxSP = 0;
            iMaxStamina = 0;

            SetPoint(POINT_ATT_SPEED, m_pkMobData->m_table.sAttackSpeed);
            SetPoint(POINT_MOV_SPEED, m_pkMobData->m_table.sMovingSpeed);
            SetPoint(POINT_CASTING_SPEED, m_pkMobData->m_table.sAttackSpeed);
        }

        if(IsPC())
        {
            // When riding horse makes higher if the primary stat is lower than the standard stats of the horse.
            // Therefore, because it is based on the stats of the horse is safe standards, Sura / shaman, the entire sum Stat
            // In general, more up will go.
            if(GetMountVnum())
            {
                if(GetHorseST() > GetPoint(POINT_ST))
                    PointChange(POINT_ST, GetHorseST() - GetPoint(POINT_ST));

                if(GetHorseDX() > GetPoint(POINT_DX))
                    PointChange(POINT_DX, GetHorseDX() - GetPoint(POINT_DX));

                if(GetHorseHT() > GetPoint(POINT_HT))
                    PointChange(POINT_HT, GetHorseHT() - GetPoint(POINT_HT));

                if(GetHorseIQ() > GetPoint(POINT_IQ))
                    PointChange(POINT_IQ, GetHorseIQ() - GetPoint(POINT_IQ));
            }

        }

        ComputeBattlePoints();

        // Basic HP / SP settings
        if(iMaxHP != GetMaxHP())
        {
            SetRealPoint(POINT_MAX_HP, iMaxHP); // HP sets the default save on RealPoint.
        }

        PointChange(POINT_MAX_HP, 0);

        if(iMaxSP != GetMaxSP())
        {
            SetRealPoint(POINT_MAX_SP, iMaxSP); // Place the primary SP to save RealPoint.
        }

        PointChange(POINT_MAX_SP, 0);

        SetMaxStamina(iMaxStamina);

        m_pointsInstant.dwImmuneFlag = 0;

        for(int i = 0; i < WEAR_MAX_NUM; i++)
        {
            LPITEM pItem = GetWear(i);
            if(pItem)
            {
                pItem->ModifyPoints(true);
                SET_BIT(m_pointsInstant.dwImmuneFlag, GetWear(i)->GetImmuneFlag());
            }
        }

        // Younghonseok system
        // The Compute Points reset all the property values of character,
        // Item, since the re-calculation of all the property values associated buff or the like,
        // For honseok system it must also reapply the value of a property for all honseok in ActiveDeck.
        if(DragonSoul_IsDeckActivated())
        {
            for(int i = WEAR_MAX_NUM + DS_SLOT_MAX * DragonSoul_GetActiveDeck();
                i < WEAR_MAX_NUM + DS_SLOT_MAX * (DragonSoul_GetActiveDeck() + 1); i++)
            {
                LPITEM pItem = GetWear(i);
                if(pItem)
                {
                    if(DSManager::instance().IsTimeLeftDragonSoul(pItem))
                        pItem->ModifyPoints(true);
                }
            }
        }

        UpdatePacket(); //FIX

        ComputeSkillPoints();

        RefreshAffect();

        CPetSystem* pPetSystem = GetPetSystem();
        if(NULL != pPetSystem)
        {
            pPetSystem->RefreshBuff();
        }

        for(TMapBuffOnAttrs::iterator it = m_map_buff_on_attrs.begin(); it != m_map_buff_on_attrs.end(); it++)
        {
            it->second->GiveAllAttributes();
        }
       
        if(GetHP() > GetMaxHP())
            PointChange(POINT_HP, GetMaxHP() - GetHP());
       
        if(GetSP() > GetMaxSP())
            PointChange(POINT_SP, GetMaxSP() - GetSP());

        UpdatePacket(); // FIX
    }

    and i changed HP/MP from short to long in game-source: tables.h but not worked

    How can i fix this "lag/HP/MP-bug" please help :(

  9. Spoiler

    quest bonusmanager begin
        state start begin
            when 9009.chat."Bonus-Manager-Panel" with pc.is_gm() begin
                say(col.gold("Bonus-Manager:[ENTER]"))
                say("Bonus-Manager ".. ({'offline','online'})[game.get_event_flag("skill_tree")+1])
                say()
                if select("Bonus-Manager "..({'anschalten','ausschalten'})[game.get_event_flag("skill_tree")+1], "Nichts") == 2 then return end
                notice_all("Der Bonus-Manager ist jetzt "..({"erreichbar","nicht erreichbar"})[game.get_event_flag("skill_tree")+1])
                if game.get_event_flag("skill_tree") == 0 then
                    game.set_event_flag("skill_tree", 1)
                else
                    game.set_event_flag("skill_tree", 0)
                end
            end
            
            when 33002.chat."Bonus-Manager" with game.get_event_flag("skill_tree") == 1 begin
                local bonis = {}
                local tree = {
                --    [Bonus-Managerlevel]//Bonus Name//Flag_name//Bonus pro up//Bonus Name//Benötigtes Item//Anzahl
                     [0] = {
                        {"Stark gegen Monster","tree_monster", 2, apply.ATT_BONUS_TO_MONSTER, 19, 1},
                    },
                    [1] = {
                        {"Stark gegen Tiere","tree_animals", 2, apply.ATTBONUS_ANIMAL, 19, 1},
                        {"Stark gegen Teufel","tree_devil", 2, apply.ATTBONUS_DEVIL, 19, 1},
                        {"Stark gegen Untote","tree_undead", 2, apply.ATTBONUS_UNDEAD, 19, 1},
                    },
                    [2] = {
                        {"Chance auf EXP-Bonus","tree_exp", 2, apply.EXP_DOUBLE_BONUS, 19, 1},
                        {"Chance, eine doppelte Menge Yang fallen zu lassen","tree_yang", 2, apply.GOLD_DOUBLE_BONUS, 19, 1},
                        {"Chance, eine doppelte Menge von Gegenständen fallen zu lassen","tree_item", 2, apply.ITEM_DROP_BONUS, 19, 1},
                    },
                    [3] = {
                        {"Magieverteidigung","tree_magic", 1, apply.RESIST_MAGIC, 19, 1},
                        {"Schwertverteidigung","tree_sword", 1, apply.RESIST_SWORD, 19, 1},
                        {"Zweihänderverteidigung","tree_tsword", 1, apply.RESIST_TWOHAND, 19, 1},
                        {"Glockenverteidigung","tree_bell", 1, apply.RESIST_BELL, 19, 1},
                        {"Fächerverteidigung","tree_fan", 1, apply.RESIST_FAN, 19, 1},
                        {"Dolchverteidigung","tree_dagger", 1, apply.RESIST_DAGGER, 19, 1},
                        {"Pfeilverteidigung","tree_bow", 1, apply.RESIST_BOW, 19, 1},
                    },
                    [4] = {
                        {"Stark gegen Krieger","tree_warrior", 1, apply.ATT_BONUS_TO_WARRIOR, 19, 1},
                        {"Stark gegen Ninja","tree_assasine", 1, apply.ATT_BONUS_TO_ASSASSIN, 19, 1},
                        {"Stark gegen Sura","tree_sura", 1, apply.ATT_BONUS_TO_SURA, 19, 1},
                        {"Stark gegen Schamenen","tree_shaman", 1, apply.ATT_BONUS_TO_SHAMAN, 19, 1},
                        {"Stark gegen Halbmenschen","tree_hm", 3, apply.ATTBONUS_HUMAN, 19, 1},
                    },
                }
                say(col.gold("Hallo "..pc.get_name()..","))
                say("bei mir kannst du im Tausch von")
                say("Gegenständen verschiedene Boni freischalten und aufwerten.")
                say("Möchtest du fortfahren?")
                if select("Forfahren","Abbruch") == 2 then return end
                say(col.gold("Bonus-Manager:[ENTER]"))
                say("Gut, ich werde dir Auflisten")
                say("was du alles aufwerten kannst.")
                wait()
                say(col.gold("Bonus-Manager:[ENTER]"))
                for i = 1, table.getn(tree[pc.getqf("tree_level")]), 1 do
                    if pc.getqf(tree[pc.getqf("tree_level")][2]) >= 10 then
                        table.insert(bonis, tree[pc.getqf("tree_level")][1].." - Beendet")
                    else
                        table.insert(bonis, tree[pc.getqf("tree_level")][1])
                    end
                end
                local menu = select3(bonis)
                if menu == -1 then return end
                local rnd = math.random(1, 100)
                say(col.gold("Bonus-Manager:[ENTER]"))
                say("Du hast den Bonus bereits auf "..pc.getqf(tree[pc.getqf("tree_level")][menu][2]))
                say()
                say("Du möchtest also "..tree[pc.getqf("tree_level")][menu][1].." aufwerten?")
                if select("Aufwerten","Abbruch") == 2 then return end
                if pc.getqf(tree[pc.getqf("tree_level")][menu][2]) < 10 then
                    if get_time() > pc.getqf("tree_time") then    
                        if pc.count_item(tree[pc.getqf("tree_level")][menu][5]) >= tree[pc.getqf("tree_level")][menu][6] then
                            if rnd > 1 then -- Chance ob klappen soll immoment 50%
                                say(col.gold("Bonus-Manager:[ENTER]"))
                                say("Glückwunsch dein Bonuspunkt")
                                say("wurde erfolgreich gesetzt.[ENTER]")
                                say(col.lightgreen("Erfolgreich!![ENTER]"))
                                wait()
                                pc.remove_item(tree[pc.getqf("tree_level")][menu][5], tree[pc.getqf("tree_level")][menu][6])
                                affect.add_collect(tree[pc.getqf("tree_level")][menu][4], tree[pc.getqf("tree_level")][menu][3], 60*60*24*365*60)
                                chat("Du hast "..tree[pc.getqf("tree_level")][menu][3].." mehr "..tree[pc.getqf("tree_level")][menu][1].." erhalten.")
                                pc.setqf(tree[pc.getqf("tree_level")][menu][2], pc.getqf(tree[pc.getqf("tree_level")][menu][2])+1)
                                pc.setqf("tree_time", get_time()+0)    -- Warte Zeit
                                if pc.getqf(tree[pc.getqf("tree_level")][menu][2]) >= 10 then
                                    local tree_skill = table.getn(tree[pc.getqf("tree_level")])*1
                                    say(col.gold("Bonus-Manager:[ENTER]"))
                                    say("Glückwunsch dein Bonus,")
                                    say("wurde erfolgreich auf die max.")
                                    say("Stufe gestuft.")
                                    say()
                                    say(col.lightgreen("Mach weiter so!"))
                                    say()
                                    wait()
                                    pc.setqf("tree_level_skill", pc.getqf("tree_level_skill")+1)
                                    if pc.getqf("tree_level_skill") == tree_skill then
                                        pc.setqf("tree_level", pc.getqf("tree_level")+1)
                                        say(col.gold("Bonus-Manager[ENTER]"))
                                        say("Glückwunsch du hast das Level")
                                        say("erfolgreich absolviert.")
                                        say()
                                        say(col.lightgreen("Aufstieg: Level "..pc.getqf("tree_level")))
                                        wait()
                                        pc.setqf("tree_time", get_time()+0)
                                    end    
                                end
                            else
                                say(col.gold("Bonus-Manager:[ENTER]"))
                                say("Leider ist der Bonuspunkt")
                                say("nicht gut genung gewesen.")
                                say()
                                say_reward("Fehlgeschlagen!!")
                                pc.remove_item(tree[pc.getqf("tree_level")][menu][5], tree[pc.getqf("tree_level")][menu][6])
                                say()
                                return
                            end
                        else
                            say(col.gold("Bonus-Manager:"))
                            say()
                            say("Leider fehlt dir ein")
                            say_item_vnum(tree[pc.getqf("tree_level")][menu][5])
                            say()
                            return
                        end    
                    else
                        say(col.gold("Bonus-Manager:[ENTER]"))
                        say("Du musst noch warten")
                        say("bevor du wieder skillen kannst.")
                        say()
                        return
                    end    
                else
                    say(col.gold("Bonus-Manager"))
                    say("Leider ist der Skill")
                    say("bereits auf dem Maximum.")
                    say()
                    return
                end
            end
        end
    end

    When i skill a bonus (for example strong vs monster) at once - server/quest save this. i can warp/relog and the bonus/affect remains preserved. But when i skilled 2-10 (maximum is 10 by Quest) and i logged out or i warp to an another map - the affect reset to 1(2 strong vs monster). Also i havent (for example) 4-6-8-10-20 strong vs monster. i have after relog/warp etc 2 strong vs monster. Is the affect part broken? What is broken in the affect-part? i need help... Thank you for reading. :) 

×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.