Guest User

Untitled

a guest
May 9th, 2025
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 51.88 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "utils.h"
  3. #include "config.h"
  4. #include "char.h"
  5. #include "char_manager.h"
  6. #include "desc_client.h"
  7. #include "db.h"
  8. #include "log.h"
  9. #include "skill.h"
  10. #include "text_file_loader.h"
  11. #include "priv_manager.h"
  12. #include "questmanager.h"
  13. #include "unique_item.h"
  14. #include "safebox.h"
  15. #include "blend_item.h"
  16. #include "locale_service.h"
  17. #include "item.h"
  18. #include "item_manager.h"
  19. #include "../../common/service.h"
  20. #include "../../common/VnumHelper.h"
  21. #include "DragonSoul.h"
  22. #ifndef ENABLE_CUBE_RENEWAL_WORLDARD
  23. #include "cube.h"
  24. #else
  25. #include "cuberenewal.h"
  26. #endif
  27.  
  28. ITEM_MANAGER::ITEM_MANAGER()
  29.     : m_iTopOfTable(0), m_dwVIDCount(0), m_dwCurrentID(0)
  30. {
  31.     m_ItemIDRange.dwMin = m_ItemIDRange.dwMax = m_ItemIDRange.dwUsableItemIDMin = 0;
  32.     m_ItemIDSpareRange.dwMin = m_ItemIDSpareRange.dwMax = m_ItemIDSpareRange.dwUsableItemIDMin = 0;
  33. }
  34.  
  35. ITEM_MANAGER::~ITEM_MANAGER()
  36. {
  37.     Destroy();
  38. }
  39.  
  40. void ITEM_MANAGER::Destroy()
  41. {
  42.     itertype(m_VIDMap) it = m_VIDMap.begin();
  43.     for ( ; it != m_VIDMap.end(); ++it) {
  44. #ifdef M2_USE_POOL
  45.         pool_.Destroy(it->second);
  46. #else
  47.         M2_DELETE(it->second);
  48. #endif
  49.     }
  50.     m_VIDMap.clear();
  51. }
  52.  
  53. void ITEM_MANAGER::GracefulShutdown()
  54. {
  55.     TR1_NS::unordered_set<LPITEM>::iterator it = m_set_pkItemForDelayedSave.begin();
  56.  
  57.     while (it != m_set_pkItemForDelayedSave.end())
  58.         SaveSingleItem(*(it++));
  59.  
  60.     m_set_pkItemForDelayedSave.clear();
  61. }
  62.  
  63. bool ITEM_MANAGER::Initialize(TItemTable * table, int size)
  64. {
  65.     if (!m_vec_prototype.empty())
  66.         m_vec_prototype.clear();
  67.  
  68.     int i;
  69.  
  70.     m_vec_prototype.resize(size);
  71.     thecore_memcpy(&m_vec_prototype[0], table, sizeof(TItemTable) * size);
  72.     for (int i = 0; i < size; i++)
  73.     {
  74.         if (0 != m_vec_prototype[i].dwVnumRange)
  75.         {
  76.             m_vec_item_vnum_range_info.push_back( &m_vec_prototype[i]);
  77.         }
  78.     }
  79.  
  80.     m_map_ItemRefineFrom.clear();
  81.     for (i = 0; i < size; ++i)
  82.     {
  83.  
  84.         if (m_vec_prototype[i].dwRefinedVnum)
  85.             m_map_ItemRefineFrom.insert(std::make_pair(m_vec_prototype[i].dwRefinedVnum, m_vec_prototype[i].dwVnum));
  86.  
  87.        
  88.         if (m_vec_prototype[i].bType == ITEM_QUEST || IS_SET(m_vec_prototype[i].dwFlags, ITEM_FLAG_QUEST_USE | ITEM_FLAG_QUEST_USE_MULTIPLE)
  89. #ifdef ENABLE_MOUNT_COSTUME_SYSTEM
  90.             || (m_vec_prototype[i].bType == ITEM_COSTUME && m_vec_prototype[i].bSubType == COSTUME_MOUNT)
  91. #endif
  92. // #ifdef __PET_SYSTEM__
  93.             // || (m_vec_prototype[i].bType == ITEM_NORMAL_PET)
  94. // #endif
  95.         )
  96.             quest::CQuestManager::instance().RegisterNPCVnum(m_vec_prototype[i].dwVnum);
  97.  
  98.         m_map_vid.insert( std::map<DWORD,TItemTable>::value_type( m_vec_prototype[i].dwVnum, m_vec_prototype[i] ) );
  99.         if ( test_server )
  100.             sys_log( 0, "ITEM_INFO %d %s ", m_vec_prototype[i].dwVnum, m_vec_prototype[i].szName );
  101.     }
  102.  
  103.     int len = 0, len2;
  104.     char buf[512];
  105.  
  106.     for (i = 0; i < size; ++i)
  107.     {
  108.         len2 = snprintf(buf + len, sizeof(buf) - len, "%5u %-16s", m_vec_prototype[i].dwVnum, m_vec_prototype[i].szLocaleName);
  109.  
  110.         if (len2 < 0 || len2 >= (int) sizeof(buf) - len)
  111.             len += (sizeof(buf) - len) - 1;
  112.         else
  113.             len += len2;
  114.  
  115.         if (!((i + 1) % 4))
  116.         {
  117.             if ( !test_server )
  118.                 sys_log(0, "%s", buf);
  119.             len = 0;
  120.         }
  121.         else
  122.         {
  123.             buf[len++] = '\t';
  124.             buf[len] = '\0';
  125.         }
  126.     }
  127.  
  128.     if ((i + 1) % 4)
  129.     {
  130.         if ( !test_server )
  131.             sys_log(0, "%s", buf);
  132.     }
  133.  
  134.     ITEM_VID_MAP::iterator it = m_VIDMap.begin();
  135.  
  136.     sys_log (1, "ITEM_VID_MAP %d", m_VIDMap.size() );
  137.  
  138.     while (it != m_VIDMap.end())
  139.     {
  140.         LPITEM item = it->second;
  141.         ++it;
  142.  
  143.         const TItemTable* tableInfo = GetTable(item->GetOriginalVnum());
  144.  
  145.         if (NULL == tableInfo)
  146.         {
  147.             sys_err("cannot reset item table");
  148.             item->SetProto(NULL);
  149.         }
  150.  
  151.         item->SetProto(tableInfo);
  152.     }
  153.  
  154.     return true;
  155. }
  156.  
  157. LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagic, int iRarePct, bool bSkipSave)
  158. {
  159.     if (0 == vnum)
  160.         return NULL;
  161.  
  162.     DWORD dwMaskVnum = 0;
  163.     if (GetMaskVnum(vnum))
  164.     {
  165.         dwMaskVnum = GetMaskVnum(vnum);
  166.     }
  167.  
  168.     const TItemTable* table = GetTable(vnum);
  169.  
  170.     if (NULL == table)
  171.         return NULL;
  172.  
  173.     LPITEM item = NULL;
  174.  
  175.     if (m_map_pkItemByID.find(id) != m_map_pkItemByID.end())
  176.     {
  177.         item = m_map_pkItemByID[id];
  178.         LPCHARACTER owner = item->GetOwner();
  179.         sys_err("ITEM_ID_DUP: %u %s owner %p", id, item->GetName(), get_pointer(owner));
  180.         return NULL;
  181.     }
  182.  
  183. #ifdef M2_USE_POOL
  184.     item = pool_.Construct();
  185. #else
  186.     item = M2_NEW CItem(vnum);
  187. #endif
  188.  
  189.     bool bIsNewItem = (0 == id);
  190.  
  191.     item->Initialize();
  192.     item->SetProto(table);
  193.     item->SetMaskVnum(dwMaskVnum);
  194.  
  195.     if (item->GetType() == ITEM_ELK)
  196.         item->SetSkipSave(true);
  197. #ifdef ENABLE_CHEQUE_SYSTEM
  198.     else if (item->GetType() == ITEM_CHEQUE)
  199.         item->SetSkipSave(true);
  200. #endif
  201.     else if (!bIsNewItem)
  202.     {
  203.         item->SetID(id);
  204.         item->SetSkipSave(true);
  205.     }
  206.     else
  207.     {
  208.         item->SetID(GetNewID());
  209.  
  210.         if (item->GetType() == ITEM_UNIQUE)
  211.         {
  212.             if (item->GetValue(2) == 0)
  213.                 item->SetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME, item->GetValue(0));
  214.             else
  215.             {
  216.                 //int globalTime = get_global_time();
  217.                 //int lastTime = item->GetValue(0);
  218.                 //int endTime = get_global_time() + item->GetValue(0);
  219.                 item->SetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME, get_global_time() + item->GetValue(0));
  220.             }
  221.         }
  222.     }
  223.  
  224.  
  225.     switch (item->GetVnum())
  226.     {
  227.         case ITEM_AUTO_HP_RECOVERY_S:
  228.         case ITEM_AUTO_HP_RECOVERY_M:
  229.         case ITEM_AUTO_HP_RECOVERY_L:
  230.         case ITEM_AUTO_HP_RECOVERY_X:
  231.         case ITEM_AUTO_SP_RECOVERY_S:
  232.         case ITEM_AUTO_SP_RECOVERY_M:
  233.         case ITEM_AUTO_SP_RECOVERY_L:
  234.         case ITEM_AUTO_SP_RECOVERY_X:
  235.         case REWARD_BOX_ITEM_AUTO_SP_RECOVERY_XS:
  236.         case REWARD_BOX_ITEM_AUTO_SP_RECOVERY_S:
  237.         case REWARD_BOX_ITEM_AUTO_HP_RECOVERY_XS:
  238.         case REWARD_BOX_ITEM_AUTO_HP_RECOVERY_S:
  239.         case FUCKING_BRAZIL_ITEM_AUTO_SP_RECOVERY_S:
  240.         case FUCKING_BRAZIL_ITEM_AUTO_HP_RECOVERY_S:
  241.             if (bIsNewItem)
  242.                 item->SetSocket(2, item->GetValue(0), true);
  243.             else
  244.                 item->SetSocket(2, item->GetValue(0), false);
  245.             break;
  246.     }
  247.  
  248. #ifdef ENABLE_CHEQUE_SYSTEM
  249.     if (item->GetType() == ITEM_ELK || item->GetType() == ITEM_CHEQUE)
  250.         ;
  251. #else
  252.     if (item->GetType() == ITEM_ELK) // ?? ?? ??? ???? ??
  253.         ;
  254. #endif
  255.     else if (item->IsStackable())  
  256.     {
  257.         count = MINMAX(1, count, g_bItemCountLimit);
  258.  
  259.         if (bTryMagic && count <= 1 && IS_SET(item->GetFlag(), ITEM_FLAG_MAKECOUNT))
  260.             count = item->GetValue(1);
  261.     }
  262.     else
  263.         count = 1;
  264.  
  265.     item->SetVID(++m_dwVIDCount);
  266.  
  267.     if (bSkipSave == false)
  268.         m_VIDMap.insert(ITEM_VID_MAP::value_type(item->GetVID(), item));
  269.  
  270.     if (item->GetID() != 0 && bSkipSave == false)
  271.         m_map_pkItemByID.insert(std::map<DWORD, LPITEM>::value_type(item->GetID(), item));
  272.  
  273.     if (!item->SetCount(count))
  274.         return NULL;
  275.  
  276.     item->SetSkipSave(false);
  277.  
  278.     if (item->GetType() == ITEM_UNIQUE && item->GetValue(2) != 0)
  279.         item->StartUniqueExpireEvent();
  280.  
  281.     for (int i=0 ; i < ITEM_LIMIT_MAX_NUM ; i++)
  282.     {
  283.        
  284.         if (LIMIT_REAL_TIME == item->GetLimitType(i))
  285.         {
  286.             if (item->GetLimitValue(i))
  287.             {
  288.                 item->SetSocket(0, time(0) + item->GetLimitValue(i));
  289.             }
  290.             else
  291.             {
  292.                 item->SetSocket(0, time(0) + 60*60*24*7);
  293.             }
  294.  
  295.             item->StartRealTimeExpireEvent();
  296.         }
  297.  
  298.        
  299.         else if (LIMIT_TIMER_BASED_ON_WEAR == item->GetLimitType(i))
  300.         {
  301.            
  302.            
  303.             if (true == item->IsEquipped())
  304.             {
  305.                 item->StartTimerBasedOnWearExpireEvent();
  306.             }
  307.             else if(0 == id)
  308.             {
  309.                 long duration = item->GetSocket(0);
  310.                 if (0 == duration)
  311.                     duration = item->GetLimitValue(i);
  312.  
  313.                 if (0 == duration)
  314.                     duration = 60 * 60 * 10;   
  315.  
  316.                 item->SetSocket(0, duration);
  317.             }
  318.         }
  319.     }
  320.  
  321. #if defined(__SOUL_SYSTEM__)
  322.     if (item->GetType() == ITEM_SOUL)
  323.         item->StartSoulTimerUseEvent();
  324. #endif
  325.  
  326.     if (id == 0)
  327.     {
  328.         if (ITEM_BLEND==item->GetType())
  329.         {
  330.             if (Blend_Item_find(item->GetVnum()))
  331.             {
  332.                 Blend_Item_set_value(item);
  333.                 return item;
  334.             }
  335.         }
  336.  
  337.         if (table->sAddonType)
  338.         {
  339.             item->ApplyAddon(table->sAddonType);
  340.         }
  341.  
  342.         if (bTryMagic)
  343.         {
  344.             if (iRarePct == -1)
  345.                 iRarePct = table->bAlterToMagicItemPct;
  346.  
  347.             if (number(1, 100) <= iRarePct)
  348.                 item->AlterToMagicItem();
  349.         }
  350.  
  351.         /*
  352.         if (item->GetType() == ITEM_COSTUME && (item->GetSubType() != COSTUME_ACCE && item->GetSubType() != COSTUME_MOUNT))
  353.         {
  354.             // DROP ITEM BONUS - COSTUMES
  355.             //if (vnum >= 10 && vnum <= 12){ //vnum == 45055 || vnum == 42009 an theloume xorista vmums(paradeigma)
  356.             bool is_costume_weapon = false;
  357.             bool is_costume_armor = false;
  358.             bool is_costume_hair = false;
  359.            
  360.             // ITEM TYPE
  361.             if (item->GetSubType() == COSTUME_WEAPON){
  362.                 is_costume_weapon = true;
  363.             } else if (item->GetSubType() == COSTUME_BODY){
  364.                 is_costume_armor = true;
  365.             } else if (item->GetSubType() == COSTUME_HAIR){
  366.                 is_costume_hair = true;
  367.             }
  368.            
  369.             int weapon_bonus_list[] = {3, 4, 5, 6, 15, 16, 12, 17, 63, 22, 19, 21}; // 12 (11)
  370.             int armor_bonus_list[] = {23, 24, 1, 2, 9, 53, 39}; // 7 (6)
  371.             int hair_bonus_list[] = {17, 63, 19, 22, 21, 45, 10, 11}; // 8 (7)
  372.  
  373.             int weapon_value_list[] = {
  374.                                       8, 10, 12,  //bonus zwtikotita 3
  375.                                       8, 10, 12,  //bonus eufuia 4
  376.                                       8, 10, 12,  //bonus dinami 5
  377.                                       8, 10, 12,  //bonus eukinisia 6
  378.                                       5, 10, 10,  //bonus crit 15
  379.                                       5, 10, 10,  //bonus diatrisi 16
  380.                                       5, 8, 8,    //bonus poison 12
  381.                                       5, 10, 10,  //bonus imi 17
  382.                                       5, 10, 15,  //bonus terata 63
  383.                                       10, 20, 20, //bonus diavolos 22
  384.                                       10, 20, 20, //bonus ork 19
  385.                                       10, 20, 20  //bonus apethanto 21
  386.                                       };
  387.             int armor_value_list[] = {
  388.                                      5, 10, 10,         //bonus apporofisi hp 23
  389.                                      5, 10, 10,         //bonus apporofisi sp 24
  390.                                      1000, 2000, 3000,  //megisto hp 1
  391.                                      100, 200, 300,     //megisto sp 2
  392.                                      5, 10, 20,         //taxitita mageias 9
  393.                                      25, 50, 75,        //aksia epithesis 53
  394.                                      5, 10, 10          //pithanotita anaklasis fusikwn epithesewn
  395.                                      };
  396.             int hair_value_list[] =  {
  397.                                      5, 10, 10,     //bonus imi 17
  398.                                      5, 10, 15,     //bonus terata 63
  399.                                      10, 20, 20,    //bonus ork 19
  400.                                      10, 20, 20,    //bonus diavolo 22
  401.                                      10, 20, 20,    //bonus apethanto 21
  402.                                      10, 20, 20,    //bonus diplasia antikeimena 45
  403.                                      5, 10, 20,     //bonus anagenisi hp 10
  404.                                      5, 10, 20      //bonus anagenisi sp 11
  405.                                      };
  406.  
  407.             int bonus_number = 0;
  408.             int bonus_count = 1;
  409.             int bonus1 = 0;
  410.             int bonus2 = 0;
  411.             int bonus3 = 0;
  412.             int bonus1_id = 0;
  413.             int bonus2_id = 0;
  414.             int bonus3_id = 0;
  415.             int bonus1_value = 0;
  416.             int bonus2_value = 0;
  417.             int bonus3_value = 0;
  418.  
  419.             // TYPE PERC
  420.             int type_perc = number(1, 100);
  421.             if (type_perc <= 10){
  422.                 bonus_count = 3;
  423.             } else if (type_perc <= 25){
  424.                 bonus_count = 2;
  425.             }
  426.  
  427.             // int x = 0;
  428.  
  429.             while(bonus_number != bonus_count)
  430.             {
  431.                 if (bonus_count >= 1){
  432.                     if (is_costume_weapon){
  433.                         bonus1 = number(0, 11);
  434.                         bonus1_id = number((0+bonus1*3), (2+bonus1*3));
  435.                         bonus1_value = weapon_value_list[bonus1_id];
  436.                         bonus1 = weapon_bonus_list[bonus1];
  437.                     } else if (is_costume_armor){
  438.                         bonus1 = number(0, 6);
  439.                         bonus1_id = number((0+bonus1*3), (2+bonus1*3));
  440.                         bonus1_value = armor_value_list[bonus1_id];
  441.                         bonus1 = armor_bonus_list[bonus1];
  442.                     } else if (is_costume_hair){
  443.                         bonus1 = number(0, 7);
  444.                         bonus1_id = number((0+bonus1*3), (2+bonus1*3));
  445.                         bonus1_value = hair_value_list[bonus1_id];
  446.                         bonus1 = hair_bonus_list[bonus1];
  447.                     }
  448.                 }
  449.                 if (bonus_count >= 2){
  450.                     if (is_costume_weapon){
  451.                         bonus2 = number(0, 11);
  452.                         bonus2_id = number((0+bonus2*3), (2+bonus2*3));
  453.                         bonus2_value = weapon_value_list[bonus2_id];
  454.                         bonus2 = weapon_bonus_list[bonus2];
  455.                     } else if (is_costume_armor){
  456.                         bonus2 = number(0, 6);
  457.                         bonus2_id = number((0+bonus2*3), (2+bonus2*3));
  458.                         bonus2_value = armor_value_list[bonus2_id];
  459.                         bonus2 = armor_bonus_list[bonus2];
  460.                     } else if (is_costume_hair){
  461.                         bonus2 = number(0, 7);
  462.                         bonus2_id = number((0+bonus2*3), (2+bonus2*3));
  463.                         bonus2_value = hair_value_list[bonus2_id];
  464.                         bonus2 = hair_bonus_list[bonus2];
  465.                     }
  466.                 }
  467.                 if (bonus_count >= 3){
  468.                     if (is_costume_weapon){
  469.                         bonus3 = number(0, 11);
  470.                         bonus3_id = number((0+bonus3*3), (2+bonus3*3));
  471.                         bonus3_value = weapon_value_list[bonus3_id];
  472.                         bonus3 = weapon_bonus_list[bonus3];
  473.                     } else if (is_costume_armor){
  474.                         bonus3 = number(0, 6);
  475.                         bonus3_id = number((0+bonus3*3), (2+bonus3*3));
  476.                         bonus3_value = armor_value_list[bonus3_id];
  477.                         bonus3 = armor_bonus_list[bonus3];
  478.                     } else if (is_costume_hair){
  479.                         bonus3 = number(0, 7);
  480.                         bonus3_id = number((0+bonus3*3), (2+bonus3*3));
  481.                         bonus3_value = hair_value_list[bonus3_id];
  482.                         bonus3 = hair_bonus_list[bonus3];
  483.                     }
  484.                 }
  485.                 // PASS...
  486.                 if (bonus_count == 1 || (bonus_count == 2 && bonus1 != bonus2) || (bonus_count == 3 && bonus1 != bonus2 && bonus1 != bonus3 && bonus2 != bonus3)){
  487.                     bonus_number = bonus_count;
  488.                 }
  489.             }
  490.  
  491.             // SET BONUS
  492.             item->ClearAttribute();
  493.             if (bonus_count >= 1){
  494.                 item->SetForceAttribute(0, bonus1, bonus1_value);
  495.             }
  496.             if (bonus_count >= 2){
  497.                 item->SetForceAttribute(1, bonus2, bonus2_value);
  498.             }
  499.             if (bonus_count >= 3){
  500.                 item->SetForceAttribute(2, bonus3, bonus3_value);
  501.             }
  502.            
  503.         } else {
  504.             // HAS BONUS
  505.             if (bTryMagic)
  506.             {
  507.                 if (iRarePct == -1){
  508.                     iRarePct = table->bAlterToMagicItemPct;
  509.                 }
  510.  
  511.                 if (number(1, 100) <= iRarePct){
  512.                     item->AlterToMagicItem();
  513.                 }
  514.             }
  515.         }
  516.         */
  517.  
  518.         if (table->bGainSocketPct)
  519.             item->AlterToSocketItem(table->bGainSocketPct);
  520.  
  521.         if (vnum == 50300 || vnum == ITEM_SKILLFORGET_VNUM)
  522.         {
  523.             extern const DWORD GetRandomSkillVnum(BYTE bJob = JOB_MAX_NUM);
  524.             item->SetSocket(0, GetRandomSkillVnum());
  525.         }
  526.         else if (ITEM_SKILLFORGET2_VNUM == vnum)
  527.         {
  528.             DWORD dwSkillVnum;
  529.  
  530.             do
  531.             {
  532.                 dwSkillVnum = number(112, 119);
  533.  
  534.                 if (NULL != CSkillManager::instance().Get(dwSkillVnum))
  535.                     break;
  536.             } while (true);
  537.  
  538.             item->SetSocket(0, dwSkillVnum);
  539.         }
  540.     }
  541.     else
  542.     {
  543.        
  544.         if (100 == table->bAlterToMagicItemPct && 0 == item->GetAttributeCount())
  545.         {
  546.             item->AlterToMagicItem();
  547.         }
  548.     }
  549.  
  550.     if (item->GetType() == ITEM_QUEST)
  551.     {
  552.         for (itertype (m_map_pkQuestItemGroup) it = m_map_pkQuestItemGroup.begin(); it != m_map_pkQuestItemGroup.end(); it++)
  553.         {
  554.             if (it->second->m_bType == CSpecialItemGroup::QUEST && it->second->Contains(vnum))
  555.             {
  556.                 item->SetSIGVnum(it->first);
  557.             }
  558.         }
  559.     }
  560.     else if (item->GetType() == ITEM_UNIQUE)
  561.     {
  562.         for (itertype (m_map_pkSpecialItemGroup) it = m_map_pkSpecialItemGroup.begin(); it != m_map_pkSpecialItemGroup.end(); it++)
  563.         {
  564.             if (it->second->m_bType == CSpecialItemGroup::SPECIAL && it->second->Contains(vnum))
  565.             {
  566.                 item->SetSIGVnum(it->first);
  567.             }
  568.         }
  569.     }
  570.  
  571.    
  572.     if (item->IsDragonSoul() && 0 == id)
  573.     {
  574.         DSManager::instance().DragonSoulItemInitialize(item);
  575.     }
  576.     return item;
  577. }
  578.  
  579. void ITEM_MANAGER::DelayedSave(LPITEM item)
  580. {
  581.     if (item->GetID() != 0)
  582.         m_set_pkItemForDelayedSave.insert(item);
  583. }
  584.  
  585. void ITEM_MANAGER::FlushDelayedSave(LPITEM item)
  586. {
  587.     TR1_NS::unordered_set<LPITEM>::iterator it = m_set_pkItemForDelayedSave.find(item);
  588.  
  589.     if (it == m_set_pkItemForDelayedSave.end())
  590.     {
  591.         return;
  592.     }
  593.  
  594.     m_set_pkItemForDelayedSave.erase(it);
  595.     SaveSingleItem(item);
  596. }
  597.  
  598. void ITEM_MANAGER::SaveSingleItem(LPITEM item)
  599. {
  600.     if (!item->GetOwner())
  601.     {
  602.         DWORD dwID = item->GetID();
  603.         DWORD dwOwnerID = item->GetLastOwnerPID();
  604.  
  605.         db_clientdesc->DBPacketHeader(HEADER_GD_ITEM_DESTROY, 0, sizeof(DWORD) + sizeof(DWORD));
  606.         db_clientdesc->Packet(&dwID, sizeof(DWORD));
  607.         db_clientdesc->Packet(&dwOwnerID, sizeof(DWORD));
  608.  
  609.         sys_log(1, "ITEM_DELETE %s:%u", item->GetName(), dwID);
  610.         return;
  611.     }
  612.  
  613.     sys_log(1, "ITEM_SAVE %s:%d in %s window %d", item->GetName(), item->GetID(), item->GetOwner()->GetName(), item->GetWindow());
  614.  
  615.     TPlayerItem t;
  616.  
  617.     t.id = item->GetID();
  618.     t.window = item->GetWindow();
  619.     switch (t.window)
  620.     {
  621.         case EQUIPMENT:
  622.             t.pos = item->GetCell() - INVENTORY_MAX_NUM;
  623.             break;
  624. #ifdef ENABLE_BELT_INVENTORY_EX
  625.         case INVENTORY:
  626.             if (BELT_INVENTORY_SLOT_START <= item->GetCell() && BELT_INVENTORY_SLOT_END > item->GetCell())
  627.             {
  628.                 t.window = BELT_INVENTORY;
  629.                 t.pos = item->GetCell() - BELT_INVENTORY_SLOT_START;
  630.                 break;
  631.             }
  632. #endif
  633.         default:
  634.             t.pos = item->GetCell();
  635.             break;
  636.     }
  637.     t.count = item->GetCount();
  638.     t.vnum = item->GetOriginalVnum();
  639. #if defined(__BL_TRANSMUTATION__)
  640.     t.dwTransmutationVnum = item->GetTransmutationVnum();
  641. #endif
  642.     t.owner = (t.window == SAFEBOX || t.window == MALL) ? item->GetOwner()->GetDesc()->GetAccountTable().id : item->GetOwner()->GetPlayerID();
  643.     thecore_memcpy(t.alSockets, item->GetSockets(), sizeof(t.alSockets));
  644.     thecore_memcpy(t.aAttr, item->GetAttributes(), sizeof(t.aAttr));
  645.  
  646.     db_clientdesc->DBPacketHeader(HEADER_GD_ITEM_SAVE, 0, sizeof(TPlayerItem));
  647.     db_clientdesc->Packet(&t, sizeof(TPlayerItem));
  648. }
  649.  
  650. void ITEM_MANAGER::RemoveFromDelayedSave(LPITEM item)
  651. {
  652.     if (!item)
  653.         return;
  654.  
  655.     auto it = m_set_pkItemForDelayedSave.find(item);
  656.     if (it != m_set_pkItemForDelayedSave.end())
  657.         m_set_pkItemForDelayedSave.erase(it);
  658. }
  659.  
  660. void ITEM_MANAGER::Update()
  661. {
  662.     TR1_NS::unordered_set<LPITEM>::iterator it = m_set_pkItemForDelayedSave.begin();
  663.     TR1_NS::unordered_set<LPITEM>::iterator this_it;
  664.  
  665.     while (it != m_set_pkItemForDelayedSave.end())
  666.     {
  667.         this_it = it++;
  668.         LPITEM item = *this_it;
  669.  
  670.        
  671.         if (item->GetOwner() && IS_SET(item->GetFlag(), ITEM_FLAG_SLOW_QUERY))
  672.             continue;
  673.  
  674.         SaveSingleItem(item);
  675.  
  676.         m_set_pkItemForDelayedSave.erase(this_it);
  677.     }
  678. }
  679.  
  680. void ITEM_MANAGER::RemoveItem(LPITEM item, const char * c_pszReason)
  681. {
  682.     if (!item)
  683.         return; //check#1
  684.    
  685.     LPCHARACTER o;
  686.  
  687.     if ((o = item->GetOwner()))
  688.     {
  689.         char szHint[64];
  690.         snprintf(szHint, sizeof(szHint), "%s %u ", item->GetName(), item->GetCount());
  691.         LogManager::instance().ItemLog(o, item, c_pszReason ? c_pszReason : "REMOVE", szHint);
  692.  
  693.         // SAFEBOX_TIME_LIMIT_ITEM_BUG_FIX
  694.         if (item->GetWindow() == MALL || item->GetWindow() == SAFEBOX)
  695.         {
  696.             CSafebox* pSafebox = item->GetWindow() == MALL ? o->GetMall() : o->GetSafebox();
  697.             if (pSafebox)
  698.             {
  699.                 sys_log(0, "I'm here 2");
  700.                 pSafebox->Remove(item->GetCell());
  701.             }
  702.         }
  703.         // END_OF_SAFEBOX_TIME_LIMIT_ITEM_BUG_FIX
  704.         else
  705.         {
  706. #ifdef ENABLE_MOUNT_LIKE_HORSE
  707.             if (o->GetWear(WEAR_COSTUME_MOUNT) && item == o->GetWear(WEAR_COSTUME_MOUNT)) {
  708.                 o->StopRiding();
  709.                 o->HorseSummon(false);
  710.             }
  711. #endif
  712.  
  713.             o->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);
  714.             item->RemoveFromCharacter();
  715.         }
  716.     }
  717.  
  718.     M2_DESTROY_ITEM(item);
  719. }
  720.  
  721. #ifndef DEBUG_ALLOC
  722. void ITEM_MANAGER::DestroyItem(LPITEM item)
  723. #else
  724. void ITEM_MANAGER::DestroyItem(LPITEM item, const char* file, size_t line)
  725. #endif
  726. {
  727.     if (item == nullptr)
  728.         return; //Check2
  729.    
  730.     if (item->GetSectree())
  731.         item->RemoveFromGround();
  732.  
  733.     if (item->GetOwner())
  734.     {
  735.         if (CHARACTER_MANAGER::instance().Find(item->GetOwner()->GetPlayerID()) != NULL)
  736.         {
  737.             sys_err("DestroyItem: GetOwner %s %s!!", item->GetName(), item->GetOwner()->GetName());
  738.             item->RemoveFromCharacter();
  739.         }
  740.         else
  741.         {
  742.             sys_err ("WTH! Invalid item owner. owner pointer : %p", item->GetOwner());
  743.         }
  744.     }
  745.  
  746.     TR1_NS::unordered_set<LPITEM>::iterator it = m_set_pkItemForDelayedSave.find(item);
  747.  
  748.     if (it != m_set_pkItemForDelayedSave.end())
  749.         m_set_pkItemForDelayedSave.erase(it);
  750.  
  751.     DWORD dwID = item->GetID();
  752.     sys_log(2, "ITEM_DESTROY %s:%u", item->GetName(), dwID);
  753.  
  754.     if (!item->GetSkipSave() && dwID)
  755.     {
  756.         DWORD dwOwnerID = item->GetLastOwnerPID();
  757.  
  758.         db_clientdesc->DBPacketHeader(HEADER_GD_ITEM_DESTROY, 0, sizeof(DWORD) + sizeof(DWORD));
  759.         db_clientdesc->Packet(&dwID, sizeof(DWORD));
  760.         db_clientdesc->Packet(&dwOwnerID, sizeof(DWORD));
  761.     }
  762.     else
  763.     {
  764.         sys_log(2, "ITEM_DESTROY_SKIP %s:%u (skip=%d)", item->GetName(), dwID, item->GetSkipSave());
  765.     }
  766.  
  767.     if (dwID)
  768.         m_map_pkItemByID.erase(dwID);
  769.  
  770.     m_VIDMap.erase(item->GetVID());
  771.  
  772. #ifdef M2_USE_POOL
  773.     pool_.Destroy(item);
  774. #else
  775. #ifndef DEBUG_ALLOC
  776.     if(item->GetDeleted()) // dracaryS
  777.     {
  778.         sys_err("<ERROR> This item pointer already deleted in memory o.O itemId: %u ownerpid: %u itemVnum: %u", dwID, item->GetLastOwnerPID(), item->GetVnum());
  779.     }
  780.     else
  781.     {
  782.         M2_DELETE(item);
  783.     }
  784. #else
  785.     M2_DELETE_EX(item, file, line);
  786. #endif
  787. #endif
  788. }
  789.  
  790. LPITEM ITEM_MANAGER::Find(DWORD id)
  791. {
  792.     itertype(m_map_pkItemByID) it = m_map_pkItemByID.find(id);
  793.     if (it == m_map_pkItemByID.end())
  794.         return NULL;
  795.     return it->second;
  796. }
  797.  
  798. LPITEM ITEM_MANAGER::FindByVID(DWORD vid)
  799. {
  800.     ITEM_VID_MAP::iterator it = m_VIDMap.find(vid);
  801.  
  802.     if (it == m_VIDMap.end())
  803.         return NULL;
  804.  
  805.     return (it->second);
  806. }
  807.  
  808. TItemTable * ITEM_MANAGER::GetTable(DWORD vnum)
  809. {
  810.     int rnum = RealNumber(vnum);
  811.  
  812.     if (rnum < 0)
  813.     {
  814.         for (size_t i = 0; i < m_vec_item_vnum_range_info.size(); i++)
  815.         {
  816.             TItemTable* p = m_vec_item_vnum_range_info[i];
  817.             if ((p->dwVnum < vnum) &&
  818.                 vnum < (p->dwVnum + p->dwVnumRange))
  819.             {
  820.                 return p;
  821.             }
  822.         }
  823.  
  824.         return NULL;
  825.     }
  826.  
  827.     return &m_vec_prototype[rnum];
  828. }
  829.  
  830. int ITEM_MANAGER::RealNumber(DWORD vnum)
  831. {
  832.     int bot, top, mid;
  833.  
  834.     bot = 0;
  835.     top = m_vec_prototype.size();
  836.  
  837.     TItemTable * pTable = &m_vec_prototype[0];
  838.  
  839.     while (1)
  840.     {
  841.         mid = (bot + top) >> 1;
  842.  
  843.         if ((pTable + mid)->dwVnum == vnum)
  844.             return (mid);
  845.  
  846.         if (bot >= top)
  847.             return (-1);
  848.  
  849.         if ((pTable + mid)->dwVnum > vnum)
  850.             top = mid - 1;
  851.         else
  852.             bot = mid + 1;
  853.     }
  854. }
  855.  
  856. bool ITEM_MANAGER::GetVnum(const char * c_pszName, DWORD & r_dwVnum)
  857. {
  858.     int len = strlen(c_pszName);
  859.  
  860.     TItemTable * pTable = &m_vec_prototype[0];
  861.  
  862.     for (DWORD i = 0; i < m_vec_prototype.size(); ++i, ++pTable)
  863.     {
  864.         if (!strncasecmp(c_pszName, pTable->szLocaleName, len))
  865.         {
  866.             r_dwVnum = pTable->dwVnum;
  867.             return true;
  868.         }
  869.     }
  870.  
  871.     return false;
  872. }
  873.  
  874. bool ITEM_MANAGER::GetVnumByOriginalName(const char * c_pszName, DWORD & r_dwVnum)
  875. {
  876.     int len = strlen(c_pszName);
  877.  
  878.     TItemTable * pTable = &m_vec_prototype[0];
  879.  
  880.     for (DWORD i = 0; i < m_vec_prototype.size(); ++i, ++pTable)
  881.     {
  882.         if (!strncasecmp(c_pszName, pTable->szName, len))
  883.         {
  884.             r_dwVnum = pTable->dwVnum;
  885.             return true;
  886.         }
  887.     }
  888.  
  889.     return false;
  890. }
  891.  
  892. std::set<DWORD> g_set_lotto;
  893.  
  894. void load_lotto()
  895. {
  896.     static int bLoaded = false;
  897.  
  898.     if (bLoaded)
  899.         return;
  900.  
  901.     bLoaded = true;
  902.     FILE * fp = fopen("lotto.txt", "r");
  903.  
  904.     if (!fp)
  905.         return;
  906.  
  907.     char buf[256];
  908.  
  909.     while (fgets(buf, 256, fp))
  910.     {
  911.         char * psz = strchr(buf, '\n');
  912.  
  913.         if (NULL != psz)
  914.             *psz = '\0';
  915.  
  916.         DWORD dw = 0;
  917.         str_to_number(dw, buf);
  918.         g_set_lotto.insert(dw);
  919.     }
  920.  
  921.     fclose(fp);
  922. }
  923.  
  924. DWORD lotto()
  925. {
  926.     load_lotto();
  927.  
  928.     char szBuf[6 + 1];
  929.  
  930.     do
  931.     {
  932.         for (int i = 0; i < 6; ++i)
  933.             szBuf[i] = 48 + number(1, 9);
  934.  
  935.         szBuf[6] = '\0';
  936.  
  937.         DWORD dw = 0;
  938.         str_to_number(dw, szBuf);
  939.  
  940.         if (g_set_lotto.end() == g_set_lotto.find(dw))
  941.         {
  942.             FILE * fp = fopen("lotto.txt", "a+");
  943.             if (fp)
  944.             {
  945.                 fprintf(fp, "%u\n", dw);
  946.                 fclose(fp);
  947.             }
  948.             return dw;
  949.         }
  950.     }
  951.     while (1);
  952. }
  953.  
  954.  
  955. class CItemDropInfo
  956. {
  957.     public:
  958.         CItemDropInfo(int iLevelStart, int iLevelEnd, int iPercent, DWORD dwVnum) :
  959.             m_iLevelStart(iLevelStart), m_iLevelEnd(iLevelEnd), m_iPercent(iPercent), m_dwVnum(dwVnum)
  960.             {
  961.             }
  962.  
  963.         int m_iLevelStart;
  964.         int m_iLevelEnd;
  965.         int m_iPercent; // 1 ~ 1000
  966.         DWORD   m_dwVnum;
  967.  
  968.         friend bool operator < (const CItemDropInfo & l, const CItemDropInfo & r)
  969.         {
  970.             return l.m_iLevelEnd < r.m_iLevelEnd;
  971.         }
  972. };
  973.  
  974. extern std::vector<CItemDropInfo> g_vec_pkCommonDropItem[MOB_RANK_MAX_NUM];
  975.  
  976. // 20050503.ipkn.
  977.  
  978.  
  979. int GetDropPerKillPct(int iMinimum, int iDefault, int iDeltaPercent, const char * c_pszFlag)
  980. {
  981.     int iVal = 0;
  982.  
  983.     if ((iVal = quest::CQuestManager::instance().GetEventFlag(c_pszFlag)))
  984.     {
  985.         if (!test_server)
  986.         {
  987.             if (iVal < iMinimum)
  988.                 iVal = iDefault;
  989.  
  990.             if (iVal < 0)
  991.                 iVal = iDefault;
  992.         }
  993.     }
  994.  
  995.     if (iVal == 0)
  996.         return 0;
  997.  
  998.     // 기본 세팅일때 (iDeltaPercent=100)
  999.    
  1000.     return (40000 * iDeltaPercent / iVal);
  1001. }
  1002.  
  1003. #ifdef ENABLE_TARGET_INFORMATION_SYSTEM
  1004. bool ITEM_MANAGER::CreateDropItemVector(LPCHARACTER pkChr, LPCHARACTER pkKiller, std::vector<std::pair<int,int> > & vec_item)
  1005. {
  1006.     if (pkChr->IsPolymorphed() || pkChr->IsPC())
  1007.     {
  1008.         return false;
  1009.     }
  1010.  
  1011.     int iLevel = pkKiller->GetLevel();
  1012.  
  1013.     BYTE bRank = pkChr->GetMobRank();
  1014.  
  1015.     std::vector<CItemDropInfo>::iterator it = g_vec_pkCommonDropItem[bRank].begin();
  1016.  
  1017.     while (it != g_vec_pkCommonDropItem[bRank].end())
  1018.     {
  1019.         const CItemDropInfo & c_rInfo = *(it++);
  1020.  
  1021.         if (iLevel < c_rInfo.m_iLevelStart || iLevel > c_rInfo.m_iLevelEnd)
  1022.             continue;
  1023.  
  1024.         TItemTable * table = GetTable(c_rInfo.m_dwVnum);
  1025.  
  1026.         if (!table)
  1027.             continue;
  1028.  
  1029.         if(c_rInfo.m_dwVnum > 70103 && c_rInfo.m_dwVnum < 70108)
  1030.         {  
  1031.            
  1032.             if (c_rInfo.m_dwVnum != pkChr->GetPolymorphItemVnum())
  1033.             {
  1034.                 continue;
  1035.             }
  1036.         }
  1037.  
  1038.         vec_item.push_back(std::make_pair(c_rInfo.m_dwVnum, 1));
  1039.     }
  1040.  
  1041.     // Drop Item Group
  1042.     {
  1043.         itertype(m_map_pkDropItemGroup) it;
  1044.         it = m_map_pkDropItemGroup.find(pkChr->GetRaceNum());
  1045.  
  1046.         if (it != m_map_pkDropItemGroup.end())
  1047.         {
  1048.             typeof(it->second->GetVector()) v = it->second->GetVector();
  1049.  
  1050.             for (DWORD i = 0; i < v.size(); ++i)
  1051.             {
  1052.                 vec_item.push_back(std::make_pair(v[i].dwVnum, v[i].iCount));
  1053.             }
  1054.         }
  1055.     }
  1056.  
  1057.     // MobDropItem Group
  1058.     {
  1059.         itertype(m_map_pkMobItemGroup) it;
  1060.         it = m_map_pkMobItemGroup.find(pkChr->GetRaceNum());
  1061.  
  1062.         if ( it != m_map_pkMobItemGroup.end() )
  1063.         {
  1064.             CMobItemGroup* pGroup = it->second;
  1065.  
  1066.             if (pGroup && !pGroup->IsEmpty())
  1067.             {
  1068.                 const CMobItemGroup::SMobItemGroupInfo& info = pGroup->GetOne();
  1069.                 vec_item.push_back(std::make_pair(info.dwItemVnum, info.iCount));
  1070.             }
  1071.         }
  1072.     }
  1073.  
  1074.     // Level Item Group
  1075.     {
  1076.         itertype(m_map_pkLevelItemGroup) it;
  1077.         it = m_map_pkLevelItemGroup.find(pkChr->GetRaceNum());
  1078.  
  1079.         if ( it != m_map_pkLevelItemGroup.end() )
  1080.         {
  1081.             if (it->second->GetLevelLimit() <= (DWORD)iLevel)
  1082.             {
  1083.                 typeof(it->second->GetVector()) v = it->second->GetVector();
  1084.  
  1085.                 for ( DWORD i=0; i < v.size(); i++ )
  1086.                 {
  1087.                     DWORD dwVnum = v[i].dwVNum;
  1088.                     vec_item.push_back(std::make_pair(dwVnum, v[i].iCount));
  1089.                 }
  1090.             }
  1091.         }
  1092.     }
  1093.  
  1094.     // ETC DropItem
  1095.     if (pkChr->GetMobDropItemVnum())
  1096.     {
  1097.         itertype(m_map_dwEtcItemDropProb) it = m_map_dwEtcItemDropProb.find(pkChr->GetMobDropItemVnum());
  1098.  
  1099.         if (it != m_map_dwEtcItemDropProb.end())
  1100.         {      
  1101.             vec_item.push_back(std::make_pair(pkChr->GetMobDropItemVnum(), 1));
  1102.         }
  1103.     }
  1104.  
  1105.     //Metin
  1106.     if (pkChr->IsStone())
  1107.     {
  1108.         if (pkChr->GetDropMetinStoneVnum())
  1109.         {
  1110.             vec_item.push_back(std::make_pair(pkChr->GetDropMetinStoneVnum(), 1));
  1111.         }
  1112.     }
  1113.  
  1114.  
  1115.     return vec_item.size();
  1116. }
  1117. #endif
  1118.  
  1119. bool ITEM_MANAGER::GetDropPct(LPCHARACTER pkChr, LPCHARACTER pkKiller, OUT int& iDeltaPercent, OUT int& iRandRange)
  1120. {
  1121.     if (NULL == pkChr || NULL == pkKiller)
  1122.         return false;
  1123.  
  1124.     int iLevel = pkKiller->GetLevel();
  1125.     iDeltaPercent = 100;
  1126.  
  1127.     // DISABLE CAP FOR DROP
  1128.     // if (!pkChr->IsStone() && pkChr->GetMobRank() >= MOB_RANK_BOSS)
  1129.         // iDeltaPercent = PERCENT_LVDELTA_BOSS(pkKiller->GetLevel(), pkChr->GetLevel());
  1130.     // else
  1131.         // iDeltaPercent = PERCENT_LVDELTA(pkKiller->GetLevel(), pkChr->GetLevel());
  1132.     // DROP
  1133.  
  1134.     BYTE bRank = pkChr->GetMobRank();
  1135.  
  1136.     if (1 == number(1, 50000))
  1137.         iDeltaPercent += 1000;
  1138.     else if (1 == number(1, 10000))
  1139.         iDeltaPercent += 500;
  1140.  
  1141.     sys_log(3, "CreateDropItem for level: %d rank: %u pct: %d", iLevel, bRank, iDeltaPercent);
  1142.     iDeltaPercent = iDeltaPercent * CHARACTER_MANAGER::instance().GetMobItemRate(pkKiller) / 100;
  1143.  
  1144.     //if (pkKiller->GetPoint(POINT_MALL_ITEMBONUS) > 0)
  1145.     //iDeltaPercent += iDeltaPercent * pkKiller->GetPoint(POINT_MALL_ITEMBONUS) / 100;
  1146.     // ADD_PREMIUM
  1147.     if (pkKiller->GetPremiumRemainSeconds(PREMIUM_ITEM) > 0 ||
  1148.             pkKiller->IsEquipUniqueGroup(UNIQUE_GROUP_DOUBLE_ITEM))
  1149.         iDeltaPercent += iDeltaPercent;
  1150.     // END_OF_ADD_PREMIUM
  1151.  
  1152.     // PC_BANG_ITEM_ADD
  1153.     if (pkKiller->GetPoint(POINT_PC_BANG_DROP_BONUS) > 0)
  1154.     {
  1155.         if (pkKiller->IsPCBang() == true)
  1156.             iDeltaPercent += iDeltaPercent * pkKiller->GetPoint(POINT_PC_BANG_DROP_BONUS)/100;
  1157.     }
  1158.     // END_PC_BANG_ITEM_ADD
  1159.  
  1160.     iRandRange = 4000000;
  1161.     iRandRange = iRandRange * 100 /
  1162.         (100 +
  1163.          CPrivManager::instance().GetPriv(pkKiller, PRIV_ITEM_DROP) +
  1164.          (pkKiller->IsEquipUniqueItem(UNIQUE_ITEM_DOUBLE_ITEM)?100:0));
  1165.  
  1166.     if (distribution_test_server) iRandRange /= 3;
  1167.  
  1168.     return true;
  1169. }
  1170.  
  1171. bool ITEM_MANAGER::CreateDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, std::vector<LPITEM> & vec_item)
  1172. {
  1173.     int iLevel = pkKiller->GetLevel();
  1174.  
  1175.     int iDeltaPercent, iRandRange;
  1176.     if (!GetDropPct(pkChr, pkKiller, iDeltaPercent, iRandRange))
  1177.         return false;
  1178.  
  1179.     BYTE bRank = pkChr->GetMobRank();
  1180.     LPITEM item = NULL;
  1181.  
  1182.     // Common Drop Items
  1183.     std::vector<CItemDropInfo>::iterator it = g_vec_pkCommonDropItem[bRank].begin();
  1184.  
  1185.     while (it != g_vec_pkCommonDropItem[bRank].end())
  1186.     {
  1187.         const CItemDropInfo & c_rInfo = *(it++);
  1188.  
  1189.         if (iLevel < c_rInfo.m_iLevelStart || iLevel > c_rInfo.m_iLevelEnd)
  1190.             continue;
  1191.  
  1192.         int iPercent = (c_rInfo.m_iPercent * iDeltaPercent) / 100;
  1193.         sys_log(3, "CreateDropItem %d ~ %d %d(%d)", c_rInfo.m_iLevelStart, c_rInfo.m_iLevelEnd, c_rInfo.m_dwVnum, iPercent, c_rInfo.m_iPercent);
  1194.  
  1195.         if (iPercent >= number(1, iRandRange))
  1196.         {
  1197.             TItemTable * table = GetTable(c_rInfo.m_dwVnum);
  1198.  
  1199.             if (!table)
  1200.                 continue;
  1201.  
  1202.             item = NULL;
  1203.  
  1204.             if (table->bType == ITEM_POLYMORPH)
  1205.             {
  1206.                 if (c_rInfo.m_dwVnum == pkChr->GetPolymorphItemVnum())
  1207.                 {
  1208.                     item = CreateItem(c_rInfo.m_dwVnum, 1, 0, true);
  1209.  
  1210.                     if (item)
  1211.                         item->SetSocket(0, pkChr->GetRaceNum());
  1212.                 }
  1213.             }
  1214.             else
  1215.                 item = CreateItem(c_rInfo.m_dwVnum, 1, 0, true);
  1216.  
  1217.             if (item) vec_item.push_back(item);
  1218.         }
  1219.     }
  1220.  
  1221.     // Drop Item Group
  1222.     {
  1223.         itertype(m_map_pkDropItemGroup) it;
  1224.         it = m_map_pkDropItemGroup.find(pkChr->GetRaceNum());
  1225.  
  1226.         if (it != m_map_pkDropItemGroup.end())
  1227.         {
  1228.             __typeof(it->second->GetVector()) v = it->second->GetVector();
  1229.  
  1230.             for (DWORD i = 0; i < v.size(); ++i)
  1231.             {
  1232.                 int iPercent = (v[i].dwPct * iDeltaPercent) / 100;
  1233.  
  1234.                 if (iPercent >= number(1, iRandRange))
  1235.                 {
  1236.                     item = CreateItem(v[i].dwVnum, v[i].iCount, 0, true);
  1237.  
  1238.                     if (item)
  1239.                     {
  1240.                         if (item->GetType() == ITEM_POLYMORPH)
  1241.                         {
  1242.                             if (item->GetVnum() == pkChr->GetPolymorphItemVnum())
  1243.                             {
  1244.                                 item->SetSocket(0, pkChr->GetRaceNum());
  1245.                             }
  1246.                         }
  1247.  
  1248.                         vec_item.push_back(item);
  1249.                     }
  1250.                 }
  1251.             }
  1252.         }
  1253.     }
  1254.  
  1255.     // MobDropItem Group
  1256.     {
  1257.         itertype(m_map_pkMobItemGroup) it;
  1258.         it = m_map_pkMobItemGroup.find(pkChr->GetRaceNum());
  1259.  
  1260.         if ( it != m_map_pkMobItemGroup.end() )
  1261.         {
  1262.             CMobItemGroup* pGroup = it->second;
  1263.  
  1264.             // MOB_DROP_ITEM_BUG_FIX
  1265.            
  1266.             if (pGroup && !pGroup->IsEmpty())
  1267.             {
  1268.                 int iPercent = 40000 * iDeltaPercent / pGroup->GetKillPerDrop();
  1269.                 if (iPercent >= number(1, iRandRange))
  1270.                 {
  1271.                     const CMobItemGroup::SMobItemGroupInfo& info = pGroup->GetOne();
  1272.                     item = CreateItem(info.dwItemVnum, info.iCount, 0, true, info.iRarePct);
  1273.  
  1274.                     if (item) vec_item.push_back(item);
  1275.                 }
  1276.             }
  1277.             // END_OF_MOB_DROP_ITEM_BUG_FIX
  1278.         }
  1279.     }
  1280.  
  1281.     // Level Item Group
  1282.     {
  1283.         itertype(m_map_pkLevelItemGroup) it;
  1284.         it = m_map_pkLevelItemGroup.find(pkChr->GetRaceNum());
  1285.  
  1286.         if ( it != m_map_pkLevelItemGroup.end() )
  1287.         {
  1288.             if ( it->second->GetLevelLimit() <= (DWORD)iLevel )
  1289.             {
  1290.                 __typeof(it->second->GetVector()) v = it->second->GetVector();
  1291.  
  1292.                 for ( DWORD i=0; i < v.size(); i++ )
  1293.                 {
  1294.                     if ( v[i].dwPct >= (DWORD)number(1, 1000000/*iRandRange*/) )
  1295.                     {
  1296.                         DWORD dwVnum = v[i].dwVNum;
  1297.                         item = CreateItem(dwVnum, v[i].iCount, 0, true);
  1298.                         if ( item ) vec_item.push_back(item);
  1299.                     }
  1300.                 }
  1301.             }
  1302.         }
  1303.     }
  1304.  
  1305.     // BuyerTheitGloves Item Group
  1306.     {
  1307.        
  1308.         if (pkKiller->GetPremiumRemainSeconds(PREMIUM_ITEM) > 0 ||
  1309.                 pkKiller->IsEquipUniqueGroup(UNIQUE_GROUP_DOUBLE_ITEM))
  1310.         {
  1311.             itertype(m_map_pkGloveItemGroup) it;
  1312.             it = m_map_pkGloveItemGroup.find(pkChr->GetRaceNum());
  1313.  
  1314.             if (it != m_map_pkGloveItemGroup.end())
  1315.             {
  1316.                 __typeof(it->second->GetVector()) v = it->second->GetVector();
  1317.  
  1318.                 for (DWORD i = 0; i < v.size(); ++i)
  1319.                 {
  1320.                     int iPercent = (v[i].dwPct * iDeltaPercent) / 100;
  1321.  
  1322.                     if (iPercent >= number(1, iRandRange))
  1323.                     {
  1324.                         DWORD dwVnum = v[i].dwVnum;
  1325.                         item = CreateItem(dwVnum, v[i].iCount, 0, true);
  1326.                         if (item) vec_item.push_back(item);
  1327.                     }
  1328.                 }
  1329.             }
  1330.         }
  1331.     }
  1332.  
  1333.    
  1334.     if (pkChr->GetMobDropItemVnum())
  1335.     {
  1336.         itertype(m_map_dwEtcItemDropProb) it = m_map_dwEtcItemDropProb.find(pkChr->GetMobDropItemVnum());
  1337.  
  1338.         if (it != m_map_dwEtcItemDropProb.end())
  1339.         {
  1340.             int iPercent = (it->second * iDeltaPercent) / 100;
  1341.  
  1342.             if (iPercent >= number(1, iRandRange))
  1343.             {
  1344.                 item = CreateItem(pkChr->GetMobDropItemVnum(), 1, 0, true);
  1345.                 if (item) vec_item.push_back(item);
  1346.             }
  1347.         }
  1348.     }
  1349.  
  1350.     if (pkChr->IsStone())
  1351.     {
  1352.         if (pkChr->GetDropMetinStoneVnum())
  1353.         {
  1354.             int iPercent = (pkChr->GetDropMetinStonePct() * iDeltaPercent) * 400;
  1355.  
  1356.             if (iPercent >= number(1, iRandRange))
  1357.             {
  1358.                 item = CreateItem(pkChr->GetDropMetinStoneVnum(), 1, 0, true);
  1359.                 if (item) vec_item.push_back(item);
  1360.             }
  1361.         }
  1362.     }
  1363.  
  1364.     if (pkKiller->IsHorseRiding() &&
  1365.             GetDropPerKillPct(1000, 1000000, iDeltaPercent, "horse_skill_book_drop") >= number(1, iRandRange))
  1366.     {
  1367.         sys_log(0, "EVENT HORSE_SKILL_BOOK_DROP");
  1368.  
  1369.         if ((item = CreateItem(ITEM_HORSE_SKILL_TRAIN_BOOK, 1, 0, true)))
  1370.             vec_item.push_back(item);
  1371.     }
  1372.  
  1373.  
  1374.     if (GetDropPerKillPct(100, 1000, iDeltaPercent, "lotto_drop") >= number(1, iRandRange))
  1375.     {
  1376.         DWORD * pdw = M2_NEW DWORD[3];
  1377.  
  1378.         pdw[0] = 50001;
  1379.         pdw[1] = 1;
  1380.         pdw[2] = quest::CQuestManager::instance().GetEventFlag("lotto_round");
  1381.  
  1382.        
  1383.         DBManager::instance().ReturnQuery(QID_LOTTO, pkKiller->GetPlayerID(), pdw,
  1384.                 "INSERT INTO lotto_list VALUES(0, 'server%s', %u, NOW())",
  1385.                 get_table_postfix(), pkKiller->GetPlayerID());
  1386.     }
  1387.  
  1388.     //
  1389.    
  1390.     //
  1391.     CreateQuestDropItem(pkChr, pkKiller, vec_item, iDeltaPercent, iRandRange);
  1392. #ifdef ENABLE_EVENT_MANAGER
  1393.     CHARACTER_MANAGER::Instance().CheckEventForDrop(pkChr, pkKiller, vec_item);
  1394. #endif
  1395.  
  1396.     for (itertype(vec_item) it = vec_item.begin(); it != vec_item.end(); ++it)
  1397.     {
  1398.         LPITEM item = *it;
  1399.         DBManager::instance().SendMoneyLog(MONEY_LOG_DROP, item->GetVnum(), item->GetCount());
  1400.     }
  1401.  
  1402.     return vec_item.size();
  1403. }
  1404.  
  1405. // ADD_GRANDMASTER_SKILL
  1406. int GetThreeSkillLevelAdjust(int level)
  1407. {
  1408.     if (level < 40)
  1409.         return 32;
  1410.     if (level < 45)
  1411.         return 16;
  1412.     if (level < 50)
  1413.         return 8;
  1414.     if (level < 55)
  1415.         return 4;
  1416.     if (level < 60)
  1417.         return 2;
  1418.     return 1;
  1419. }
  1420. // END_OF_ADD_GRANDMASTER_SKILL
  1421.  
  1422. // DROPEVENT_CHARSTONE
  1423. // drop_char_stone 1
  1424. // drop_char_stone.percent_lv01_10 5
  1425. // drop_char_stone.percent_lv11_30 10
  1426. // drop_char_stone.percent_lv31_MX 15
  1427. // drop_char_stone.level_range     10
  1428. static struct DropEvent_CharStone
  1429. {
  1430.     int percent_lv01_10;
  1431.     int percent_lv11_30;
  1432.     int percent_lv31_MX;
  1433.     int level_range;
  1434.     bool alive;
  1435.  
  1436.     DropEvent_CharStone()
  1437.     {
  1438.         percent_lv01_10 =  100;
  1439.         percent_lv11_30 =  200;
  1440.         percent_lv31_MX =  300;
  1441.         level_range = 10;
  1442.         alive = false;
  1443.     }
  1444. } gs_dropEvent_charStone;
  1445.  
  1446. static int __DropEvent_CharStone_GetDropPercent(int killer_level)
  1447. {
  1448.     int killer_levelStep = (killer_level-1)/10;
  1449.  
  1450.     switch (killer_levelStep)
  1451.     {
  1452.         case 0:
  1453.             return gs_dropEvent_charStone.percent_lv01_10;
  1454.  
  1455.         case 1:
  1456.         case 2:
  1457.             return gs_dropEvent_charStone.percent_lv11_30;
  1458.     }
  1459.  
  1460.     return gs_dropEvent_charStone.percent_lv31_MX;
  1461. }
  1462.  
  1463. static void __DropEvent_CharStone_DropItem(CHARACTER & killer, CHARACTER & victim, ITEM_MANAGER& itemMgr, std::vector<LPITEM>& vec_item)
  1464. {
  1465.     if (!gs_dropEvent_charStone.alive)
  1466.         return;
  1467.  
  1468.     int killer_level = killer.GetLevel();
  1469.     int dropPercent = __DropEvent_CharStone_GetDropPercent(killer_level);
  1470.  
  1471.     int MaxRange = 10000;
  1472.  
  1473.     if (number(1, MaxRange) <= dropPercent)
  1474.     {
  1475.         int log_level = (test_server || killer.GetGMLevel() >= GM_LOW_WIZARD) ? 0 : 1;
  1476.         int victim_level = victim.GetLevel();
  1477.         int level_diff = victim_level - killer_level;
  1478.  
  1479.         if (level_diff >= +gs_dropEvent_charStone.level_range || level_diff <= -gs_dropEvent_charStone.level_range)
  1480.         {
  1481.             sys_log(log_level,
  1482.                     "dropevent.drop_char_stone.level_range_over: killer(%s: lv%d), victim(%s: lv:%d), level_diff(%d)",
  1483.                     killer.GetName(), killer.GetLevel(), victim.GetName(), victim.GetLevel(), level_diff);
  1484.             return;
  1485.         }
  1486.  
  1487.         static const int Stones[] = { 30210, 30211, 30212, 30213, 30214, 30215, 30216, 30217, 30218, 30219, 30258, 30259, 30260, 30261, 30262, 30263 };
  1488.         // int item_vnum = Stones[number(0, _countof(Stones))];
  1489.         //fix
  1490.         int item_vnum = Stones[number(0, _countof(Stones)-1)]; // @fixme189
  1491.  
  1492.         LPITEM p_item = NULL;
  1493.  
  1494.         if ((p_item = itemMgr.CreateItem(item_vnum, 1, 0, true)))
  1495.         {
  1496.             vec_item.push_back(p_item);
  1497.  
  1498.             sys_log(log_level,
  1499.                     "dropevent.drop_char_stone.item_drop: killer(%s: lv%d), victim(%s: lv:%d), item_name(%s)",
  1500.                     killer.GetName(), killer.GetLevel(), victim.GetName(), victim.GetLevel(), p_item->GetName());
  1501.         }
  1502.     }
  1503. }
  1504.  
  1505. bool DropEvent_CharStone_SetValue(const std::string& name, int value)
  1506. {
  1507.     if (name == "drop_char_stone")
  1508.     {
  1509.         gs_dropEvent_charStone.alive = value;
  1510.  
  1511.         if (value)
  1512.             sys_log(0, "dropevent.drop_char_stone = on");
  1513.         else
  1514.             sys_log(0, "dropevent.drop_char_stone = off");
  1515.  
  1516.     }
  1517.     else if (name == "drop_char_stone.percent_lv01_10")
  1518.         gs_dropEvent_charStone.percent_lv01_10 = value;
  1519.     else if (name == "drop_char_stone.percent_lv11_30")
  1520.         gs_dropEvent_charStone.percent_lv11_30 = value;
  1521.     else if (name == "drop_char_stone.percent_lv31_MX")
  1522.         gs_dropEvent_charStone.percent_lv31_MX = value;
  1523.     else if (name == "drop_char_stone.level_range")
  1524.         gs_dropEvent_charStone.level_range = value;
  1525.     else
  1526.         return false;
  1527.  
  1528.     sys_log(0, "dropevent.drop_char_stone: %d", gs_dropEvent_charStone.alive ? true : false);
  1529.     sys_log(0, "dropevent.drop_char_stone.percent_lv01_10: %f", gs_dropEvent_charStone.percent_lv01_10/100.0f);
  1530.     sys_log(0, "dropevent.drop_char_stone.percent_lv11_30: %f", gs_dropEvent_charStone.percent_lv11_30/100.0f);
  1531.     sys_log(0, "dropevent.drop_char_stone.percent_lv31_MX: %f", gs_dropEvent_charStone.percent_lv31_MX/100.0f);
  1532.     sys_log(0, "dropevent.drop_char_stone.level_range: %d", gs_dropEvent_charStone.level_range);
  1533.  
  1534.     return true;
  1535. }
  1536.  
  1537. // END_OF_DROPEVENT_CHARSTONE
  1538.  
  1539. // fixme
  1540.  
  1541.  
  1542.  
  1543.  
  1544.  
  1545. static struct DropEvent_RefineBox
  1546. {
  1547.     int percent_low;
  1548.     int low;
  1549.     int percent_mid;
  1550.     int mid;
  1551.     int percent_high;
  1552.     //int level_range;
  1553.     bool alive;
  1554.  
  1555.     DropEvent_RefineBox()
  1556.     {
  1557.         percent_low =  100;
  1558.         low = 20;
  1559.         percent_mid =  100;
  1560.         mid = 45;
  1561.         percent_high =  100;
  1562.         //level_range = 10;
  1563.         alive = false;
  1564.     }
  1565. } gs_dropEvent_refineBox;
  1566.  
  1567. static LPITEM __DropEvent_RefineBox_GetDropItem(CHARACTER & killer, CHARACTER & victim, ITEM_MANAGER& itemMgr)
  1568. {
  1569.     static const int lowerBox[] = { 50197, 50198, 50199 };
  1570.     static const int lowerBox_range = 3;
  1571.     static const int midderBox[] = { 50203, 50204, 50205, 50206 };
  1572.     static const int midderBox_range = 4;
  1573.     static const int higherBox[] = { 50207, 50208, 50209, 50210, 50211 };
  1574.     static const int higherBox_range = 5;
  1575.  
  1576.     if (victim.GetMobRank() < MOB_RANK_KNIGHT)
  1577.         return NULL;
  1578.  
  1579.     int killer_level = killer.GetLevel();
  1580.     //int level_diff = victim_level - killer_level;
  1581.  
  1582.     //if (level_diff >= +gs_dropEvent_refineBox.level_range || level_diff <= -gs_dropEvent_refineBox.level_range)
  1583.     //{
  1584.     //  sys_log(log_level,
  1585.     //      "dropevent.drop_refine_box.level_range_over: killer(%s: lv%d), victim(%s: lv:%d), level_diff(%d)",
  1586.     //      killer.GetName(), killer.GetLevel(), victim.GetName(), victim.GetLevel(), level_diff);
  1587.     //  return NULL;
  1588.     //}
  1589.  
  1590.     if (killer_level <= gs_dropEvent_refineBox.low)
  1591.     {
  1592.         if (number (1, gs_dropEvent_refineBox.percent_low) == 1)
  1593.         {
  1594.             return itemMgr.CreateItem(lowerBox [number (1,lowerBox_range) - 1], 1, 0, true);
  1595.         }
  1596.     }
  1597.     else if (killer_level <= gs_dropEvent_refineBox.mid)
  1598.     {
  1599.         if (number (1, gs_dropEvent_refineBox.percent_mid) == 1)
  1600.         {
  1601.             return itemMgr.CreateItem(midderBox [number (1,midderBox_range) - 1], 1, 0, true);
  1602.         }
  1603.     }
  1604.     else
  1605.     {
  1606.         if (number (1, gs_dropEvent_refineBox.percent_high) == 1)
  1607.         {
  1608.             return itemMgr.CreateItem(higherBox [number (1,higherBox_range) - 1], 1, 0, true);
  1609.         }
  1610.     }
  1611.     return NULL;
  1612. }
  1613.  
  1614. static void __DropEvent_RefineBox_DropItem(CHARACTER & killer, CHARACTER & victim, ITEM_MANAGER& itemMgr, std::vector<LPITEM>& vec_item)
  1615. {
  1616.     if (!gs_dropEvent_refineBox.alive)
  1617.         return;
  1618.  
  1619.     int log_level = (test_server || killer.GetGMLevel() >= GM_LOW_WIZARD) ? 0 : 1;
  1620.  
  1621.     LPITEM p_item = __DropEvent_RefineBox_GetDropItem(killer, victim, itemMgr);
  1622.  
  1623.     if (p_item)
  1624.     {
  1625.         vec_item.push_back(p_item);
  1626.  
  1627.         sys_log(log_level,
  1628.             "dropevent.drop_refine_box.item_drop: killer(%s: lv%d), victim(%s: lv:%d), item_name(%s)",
  1629.             killer.GetName(), killer.GetLevel(), victim.GetName(), victim.GetLevel(), p_item->GetName());
  1630.     }
  1631. }
  1632.  
  1633. bool DropEvent_RefineBox_SetValue(const std::string& name, int value)
  1634. {
  1635.     if (name == "refine_box_drop")
  1636.     {
  1637.         gs_dropEvent_refineBox.alive = value;
  1638.  
  1639.         if (value)
  1640.             sys_log(0, "refine_box_drop = on");
  1641.         else
  1642.             sys_log(0, "refine_box_drop = off");
  1643.  
  1644.     }
  1645.     else if (name == "refine_box_low")
  1646.         gs_dropEvent_refineBox.percent_low = value < 100 ? 100 : value;
  1647.     else if (name == "refine_box_mid")
  1648.         gs_dropEvent_refineBox.percent_mid = value < 100 ? 100 : value;
  1649.     else if (name == "refine_box_high")
  1650.         gs_dropEvent_refineBox.percent_high = value < 100 ? 100 : value;
  1651.     //else if (name == "refine_box_level_range")
  1652.     //  gs_dropEvent_refineBox.level_range = value;
  1653.     else
  1654.         return false;
  1655.  
  1656.     sys_log(0, "refine_box_drop: %d", gs_dropEvent_refineBox.alive ? true : false);
  1657.     sys_log(0, "refine_box_low: %d", gs_dropEvent_refineBox.percent_low);
  1658.     sys_log(0, "refine_box_mid: %d", gs_dropEvent_refineBox.percent_mid);
  1659.     sys_log(0, "refine_box_high: %d", gs_dropEvent_refineBox.percent_high);
  1660.     //sys_log(0, "refine_box_low_level_range: %d", gs_dropEvent_refineBox.level_range);
  1661.  
  1662.     return true;
  1663. }
  1664.  
  1665.  
  1666.  
  1667. void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, std::vector<LPITEM> & vec_item, int iDeltaPercent, int iRandRange)
  1668. {
  1669.     LPITEM item = NULL;
  1670.  
  1671.     if (!pkChr)
  1672.         return;
  1673.  
  1674.     if (!pkKiller)
  1675.         return;
  1676.  
  1677.     sys_log(1, "CreateQuestDropItem victim(%s), killer(%s)", pkChr->GetName(), pkKiller->GetName() );
  1678.  
  1679.     // DROPEVENT_CHARSTONE
  1680.     __DropEvent_CharStone_DropItem(*pkKiller, *pkChr, *this, vec_item);
  1681.     // END_OF_DROPEVENT_CHARSTONE
  1682.     __DropEvent_RefineBox_DropItem(*pkKiller, *pkChr, *this, vec_item);
  1683.  
  1684.    
  1685.     if (quest::CQuestManager::instance().GetEventFlag("xmas_sock"))
  1686.     {
  1687.         const DWORD SOCK_ITEM_VNUM = 50010;
  1688.  
  1689.         int iDropPerKill[MOB_RANK_MAX_NUM] =
  1690.         {
  1691.             2000,
  1692.             1000,
  1693.             300,
  1694.             50,
  1695.             0,
  1696.             0,
  1697.         };
  1698.  
  1699.         if ( iDropPerKill[pkChr->GetMobRank()] != 0 )
  1700.         {
  1701.             int iPercent = 40000 * iDeltaPercent / iDropPerKill[pkChr->GetMobRank()];
  1702.  
  1703.             sys_log(0, "SOCK DROP %d %d", iPercent, iRandRange);
  1704.             if (iPercent >= number(1, iRandRange))
  1705.             {
  1706.                 if ((item = CreateItem(SOCK_ITEM_VNUM, 1, 0, true)))
  1707.                     vec_item.push_back(item);
  1708.             }
  1709.         }
  1710.     }
  1711.  
  1712.    
  1713.     if (quest::CQuestManager::instance().GetEventFlag("drop_moon"))
  1714.     {
  1715.         const DWORD ITEM_VNUM = 50011;
  1716.  
  1717.         int iDropPerKill[MOB_RANK_MAX_NUM] =
  1718.         {
  1719.             2000,
  1720.             1000,
  1721.             300,
  1722.             50,
  1723.             0,
  1724.             0,
  1725.         };
  1726.  
  1727.         if (iDropPerKill[pkChr->GetMobRank()])
  1728.         {
  1729.             int iPercent = 40000 * iDeltaPercent / iDropPerKill[pkChr->GetMobRank()];
  1730.  
  1731.             if (iPercent >= number(1, iRandRange))
  1732.             {
  1733.                 if ((item = CreateItem(ITEM_VNUM, 1, 0, true)))
  1734.                     vec_item.push_back(item);
  1735.             }
  1736.         }
  1737.     }
  1738.  
  1739.     if (pkKiller->GetLevel() >= 15 && abs(pkKiller->GetLevel() - pkChr->GetLevel()) <= 5)
  1740.     {
  1741.         int pct = quest::CQuestManager::instance().GetEventFlag("hc_drop");
  1742.  
  1743.         if (pct > 0)
  1744.         {
  1745.             const DWORD ITEM_VNUM = 30178;
  1746.  
  1747.             if (number(1,100) <= pct)
  1748.             {
  1749.                 if ((item = CreateItem(ITEM_VNUM, 1, 0, true)))
  1750.                     vec_item.push_back(item);
  1751.             }
  1752.         }
  1753.     }
  1754.  
  1755.    
  1756.     if (GetDropPerKillPct(100, 2000, iDeltaPercent, "2006_drop") >= number(1, iRandRange))
  1757.     {
  1758.         sys_log(0, "육각보합 DROP EVENT ");
  1759.  
  1760.         const static DWORD dwVnum = 50037;
  1761.  
  1762.         if ((item = CreateItem(dwVnum, 1, 0, true)))
  1763.             vec_item.push_back(item);
  1764.  
  1765.     }
  1766.  
  1767.    
  1768.     if (GetDropPerKillPct(100, 2000, iDeltaPercent, "2007_drop") >= number(1, iRandRange))
  1769.     {
  1770.         sys_log(0, "육각보합 DROP EVENT ");
  1771.  
  1772.         const static DWORD dwVnum = 50043;
  1773.  
  1774.         if ((item = CreateItem(dwVnum, 1, 0, true)))
  1775.             vec_item.push_back(item);
  1776.     }
  1777.  
  1778.    
  1779.     if (GetDropPerKillPct(/* minimum */ 100, /* default */ 1000, iDeltaPercent, "newyear_fire") >= number(1, iRandRange))
  1780.     {
  1781.        
  1782.         const DWORD ITEM_VNUM_FIRE = 50107;
  1783.  
  1784.         if ((item = CreateItem(ITEM_VNUM_FIRE, 1, 0, true)))
  1785.             vec_item.push_back(item);
  1786.     }
  1787.  
  1788.    
  1789.     if (GetDropPerKillPct(100, 500, iDeltaPercent, "newyear_moon") >= number(1, iRandRange))
  1790.     {
  1791.         sys_log(0, "EVENT NEWYEAR_MOON DROP");
  1792.  
  1793.         const static DWORD wonso_items[6] = { 50016, 50017, 50018, 50019, 50019, 50019, };
  1794.         DWORD dwVnum = wonso_items[number(0,5)];
  1795.  
  1796.         if ((item = CreateItem(dwVnum, 1, 0, true)))
  1797.             vec_item.push_back(item);
  1798.     }
  1799.  
  1800.    
  1801.     if (GetDropPerKillPct(1, 2000, iDeltaPercent, "valentine_drop") >= number(1, iRandRange))
  1802.     {
  1803.         sys_log(0, "EVENT VALENTINE_DROP");
  1804.  
  1805.         const static DWORD valentine_items[2] = { 50024, 50025 };
  1806.         DWORD dwVnum = valentine_items[number(0, 1)];
  1807.  
  1808.         if ((item = CreateItem(dwVnum, 1, 0, true)))
  1809.             vec_item.push_back(item);
  1810.     }
  1811.  
  1812.    
  1813.     if (GetDropPerKillPct(100, 2000, iDeltaPercent, "icecream_drop") >= number(1, iRandRange))
  1814.     {
  1815.         const static DWORD icecream = 50123;
  1816.  
  1817.         if ((item = CreateItem(icecream, 1, 0, true)))
  1818.             vec_item.push_back(item);
  1819.     }
  1820.  
  1821.    
  1822.    
  1823.     if ((pkKiller->CountSpecifyItem(53002) > 0) && (GetDropPerKillPct(50, 100, iDeltaPercent, "new_xmas_event") >= number(1, iRandRange)))
  1824.     {
  1825.         const static DWORD xmas_sock = 50010;
  1826.         pkKiller->AutoGiveItem (xmas_sock, 1);
  1827.     }
  1828.  
  1829.     if ((pkKiller->CountSpecifyItem(53007) > 0) && (GetDropPerKillPct(50, 100, iDeltaPercent, "new_xmas_event") >= number(1, iRandRange)))
  1830.     {
  1831.         const static DWORD xmas_sock = 50010;
  1832.         pkKiller->AutoGiveItem (xmas_sock, 1);
  1833.     }
  1834.  
  1835.     //if (pkChr->GetLevel() >= 30 && (GetDropPerKillPct(50, 100, iDeltaPercent, "ds_drop") >= number(1, iRandRange)))
  1836.     //{
  1837.     //  const static DWORD dragon_soul_gemstone = 30270;
  1838.     //  if ((item = CreateItem(dragon_soul_gemstone, 1, 0, true)))
  1839.     //      vec_item.push_back(item);
  1840.     //}
  1841.  
  1842.     if ( GetDropPerKillPct(100, 2000, iDeltaPercent, "halloween_drop") >= number(1, iRandRange) )
  1843.     {
  1844.         const static DWORD halloween_item = 30321;
  1845.  
  1846.         if ( (item=CreateItem(halloween_item, 1, 0, true)) )
  1847.             vec_item.push_back(item);
  1848.     }
  1849.  
  1850.    
  1851.     if ( GetDropPerKillPct(100, 2000, iDeltaPercent, "ramadan_drop") >= number(1, iRandRange) )
  1852.     {
  1853.         const static DWORD ramadan_item = 30315;
  1854.  
  1855.         if ( (item=CreateItem(ramadan_item, 1, 0, true)) )
  1856.             vec_item.push_back(item);
  1857.     }
  1858.  
  1859.     if ( GetDropPerKillPct(100, 2000, iDeltaPercent, "easter_drop") >= number(1, iRandRange) )
  1860.     {
  1861.         const static DWORD easter_item_base = 50160;
  1862.  
  1863.         if ( (item=CreateItem(easter_item_base+number(0,19), 1, 0, true)) )
  1864.             vec_item.push_back(item);
  1865.     }
  1866.  
  1867.    
  1868.     if ( GetDropPerKillPct(100, 2000, iDeltaPercent, "football_drop") >= number(1, iRandRange) )
  1869.     {
  1870.         const static DWORD football_item = 50096;
  1871.  
  1872.         if ( (item=CreateItem(football_item, 1, 0, true)) )
  1873.             vec_item.push_back(item);
  1874.     }
  1875.  
  1876.    
  1877.     if (GetDropPerKillPct(100, 2000, iDeltaPercent, "whiteday_drop") >= number(1, iRandRange))
  1878.     {
  1879.         sys_log(0, "EVENT WHITEDAY_DROP");
  1880.         const static DWORD whiteday_items[2] = { ITEM_WHITEDAY_ROSE, ITEM_WHITEDAY_CANDY };
  1881.         DWORD dwVnum = whiteday_items[number(0,1)];
  1882.  
  1883.         if ((item = CreateItem(dwVnum, 1, 0, true)))
  1884.             vec_item.push_back(item);
  1885.     }
  1886.  
  1887.    
  1888.     if (pkKiller->GetLevel()>=50)
  1889.     {
  1890.         if (GetDropPerKillPct(100, 1000, iDeltaPercent, "kids_day_drop_high") >= number(1, iRandRange))
  1891.         {
  1892.             DWORD ITEM_QUIZ_BOX = 50034;
  1893.  
  1894.             if ((item = CreateItem(ITEM_QUIZ_BOX, 1, 0, true)))
  1895.                 vec_item.push_back(item);
  1896.         }
  1897.     }
  1898.     else
  1899.     {
  1900.         if (GetDropPerKillPct(100, 1000, iDeltaPercent, "kids_day_drop") >= number(1, iRandRange))
  1901.         {
  1902.             DWORD ITEM_QUIZ_BOX = 50034;
  1903.  
  1904.             if ((item = CreateItem(ITEM_QUIZ_BOX, 1, 0, true)))
  1905.                 vec_item.push_back(item);
  1906.         }
  1907.     }
  1908.  
  1909.    
  1910.     if (pkChr->GetLevel() >= 30 && GetDropPerKillPct(50, 100, iDeltaPercent, "medal_part_drop") >= number(1, iRandRange))
  1911.     {
  1912.         const static DWORD drop_items[] = { 30265, 30266, 30267, 30268, 30269 };
  1913.         int i = number (0, 4);
  1914.         item = CreateItem(drop_items[i]);
  1915.         if (item != NULL)
  1916.             vec_item.push_back(item);
  1917.     }
  1918.  
  1919.     // ADD_GRANDMASTER_SKILL
  1920.    
  1921.     if (pkChr->GetLevel() >= 40 && pkChr->GetMobRank() >= MOB_RANK_BOSS && GetDropPerKillPct(/* minimum */ 1, /* default */ 1000, iDeltaPercent, "three_skill_item") / GetThreeSkillLevelAdjust(pkChr->GetLevel()) >= number(1, iRandRange))
  1922.     {
  1923.         const DWORD ITEM_VNUM = 50513;
  1924.  
  1925.         if ((item = CreateItem(ITEM_VNUM, 1, 0, true)))
  1926.             vec_item.push_back(item);
  1927.     }
  1928.     // END_OF_ADD_GRANDMASTER_SKILL
  1929.  
  1930.     //
  1931.    
  1932.     //
  1933.     if (GetDropPerKillPct(100, 1000, iDeltaPercent, "dragon_boat_festival_drop") >= number(1, iRandRange))
  1934.     {
  1935.         const DWORD ITEM_SEED = 50085;
  1936.  
  1937.         if ((item = CreateItem(ITEM_SEED, 1, 0, true)))
  1938.             vec_item.push_back(item);
  1939.     }
  1940.  
  1941.    
  1942.     if (pkKiller->GetLevel() >= 15 && quest::CQuestManager::instance().GetEventFlag("mars_drop"))
  1943.     {
  1944.         const DWORD ITEM_HANIRON = 70035;
  1945.         int iDropMultiply[MOB_RANK_MAX_NUM] =
  1946.         {
  1947.             50,
  1948.             30,
  1949.             5,
  1950.             1,
  1951.             0,
  1952.             0,
  1953.         };
  1954.  
  1955.         if (iDropMultiply[pkChr->GetMobRank()] &&
  1956.                 GetDropPerKillPct(1000, 1500, iDeltaPercent, "mars_drop") >= number(1, iRandRange) * iDropMultiply[pkChr->GetMobRank()])
  1957.         {
  1958.             if ((item = CreateItem(ITEM_HANIRON, 1, 0, true)))
  1959.                 vec_item.push_back(item);
  1960.         }
  1961.     }
  1962. }
  1963.  
  1964. DWORD ITEM_MANAGER::GetRefineFromVnum(DWORD dwVnum)
  1965. {
  1966.     itertype(m_map_ItemRefineFrom) it = m_map_ItemRefineFrom.find(dwVnum);
  1967.     if (it != m_map_ItemRefineFrom.end())
  1968.         return it->second;
  1969.     return 0;
  1970. }
  1971.  
  1972. const CSpecialItemGroup* ITEM_MANAGER::GetSpecialItemGroup(DWORD dwVnum)
  1973. {
  1974.     itertype(m_map_pkSpecialItemGroup) it = m_map_pkSpecialItemGroup.find(dwVnum);
  1975.     if (it != m_map_pkSpecialItemGroup.end())
  1976.     {
  1977.         return it->second;
  1978.     }
  1979.     return NULL;
  1980. }
  1981.  
  1982. const CSpecialAttrGroup* ITEM_MANAGER::GetSpecialAttrGroup(DWORD dwVnum)
  1983. {
  1984.     itertype(m_map_pkSpecialAttrGroup) it = m_map_pkSpecialAttrGroup.find(dwVnum);
  1985.     if (it != m_map_pkSpecialAttrGroup.end())
  1986.     {
  1987.         return it->second;
  1988.     }
  1989.     return NULL;
  1990. }
  1991.  
  1992. DWORD ITEM_MANAGER::GetMaskVnum(DWORD dwVnum)
  1993. {
  1994.     TMapDW2DW::iterator it = m_map_new_to_ori.find (dwVnum);
  1995.     if (it != m_map_new_to_ori.end())
  1996.     {
  1997.         return it->second;
  1998.     }
  1999.     else
  2000.         return 0;
  2001. }
  2002.  
  2003. #ifdef ENABLE_SHOW_CHEST_DROP
  2004. #include "../../libgame/include/grid.h"
  2005. void ITEM_MANAGER::GetChestItemList(DWORD dwChestVnum, std::vector<TChestDropInfoTable>& vec_item)
  2006. {
  2007.     TChestDropInfoTable kTempTab;
  2008.    
  2009.     BYTE dwChestDropPageCount = 5;
  2010.  
  2011.     CGrid* pGrids[dwChestDropPageCount];
  2012.    
  2013.     for (int i = 0; i < dwChestDropPageCount; ++i)
  2014.     {
  2015.         pGrids[i] = new CGrid(15, 5);
  2016.         pGrids[i]->Clear();
  2017.     }
  2018.    
  2019.     const CSpecialItemGroup* pGroup = GetSpecialItemGroup(dwChestVnum);
  2020.    
  2021.     if (pGroup)
  2022.     {
  2023.         for (int i = 0; i < pGroup->GetGroupSize(); i++)
  2024.         {
  2025.             const TItemTable* itemTable = GetTable(pGroup->GetVnum(i));
  2026.  
  2027.             if(itemTable != NULL)
  2028.             {
  2029.                 for (int iPage = 0; iPage < dwChestDropPageCount; ++iPage)
  2030.                 {
  2031.                     int iPos = pGrids[iPage]->FindBlank(1, itemTable->bSize);
  2032.            
  2033.                     if (iPos >= 0)
  2034.                     {
  2035.                         pGrids[iPage]->Put(iPos, 1, itemTable->bSize);
  2036.                        
  2037.                         kTempTab.bPageIndex = iPage + 1;
  2038.                         kTempTab.bSlotIndex = iPos;
  2039.                        
  2040.                         kTempTab.bItemCount = pGroup->GetCount(i);
  2041.                         kTempTab.dwItemVnum = pGroup->GetVnum(i);
  2042.                        
  2043.                         vec_item.push_back(kTempTab);
  2044.                    
  2045.                         break;
  2046.                     }
  2047.                 }
  2048.             }
  2049.         }
  2050.     }
  2051. }
  2052. #endif
  2053.  
  2054. void ITEM_MANAGER::CopyAllAttrTo(LPITEM pkOldItem, LPITEM pkNewItem)
  2055. {
  2056. #if defined(__SOUL_SYSTEM__)
  2057.     if (pkOldItem == nullptr || pkNewItem == nullptr)
  2058.         return;
  2059.  
  2060.     if (pkOldItem->GetType() == ITEM_SOUL)
  2061.         return;
  2062. #endif
  2063.  
  2064.     // ACCESSORY_REFINE
  2065.     if (pkOldItem->IsAccessoryForSocket())
  2066.     {
  2067.         for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  2068.         {
  2069.             pkNewItem->SetSocket(i, pkOldItem->GetSocket(i));
  2070.         }
  2071.         //pkNewItem->StartAccessorySocketExpireEvent();
  2072.     }
  2073.     // END_OF_ACCESSORY_REFINE
  2074.     else
  2075.     {
  2076.        
  2077.         for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  2078.         {
  2079.             if (!pkOldItem->GetSocket(i))
  2080.                 break;
  2081.             else
  2082.                 pkNewItem->SetSocket(i, 1);
  2083.         }
  2084.  
  2085.        
  2086.         int slot = 0;
  2087.  
  2088.         for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  2089.         {
  2090.             long socket = pkOldItem->GetSocket(i);
  2091.             const int ITEM_BROKEN_METIN_VNUM = 28960;
  2092.             if (socket > 2 && socket != ITEM_BROKEN_METIN_VNUM)
  2093.                 pkNewItem->SetSocket(slot++, socket);
  2094.         }
  2095.  
  2096.     }
  2097.  
  2098.    
  2099.     pkOldItem->CopyAttributeTo(pkNewItem);
  2100. }
  2101.  
Advertisement
Add Comment
Please, Sign In to add comment