SHARE
TWEET

Untitled

a guest Apr 19th, 2019 91 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "stdafx.h"
  2. #include "constants.h"
  3. #include "item.h"
  4. #include "item_manager.h"
  5. #include "unique_item.h"
  6. #include "packet.h"
  7. #include "desc.h"
  8. #include "char.h"
  9. #include "dragon_soul_table.h"
  10. #include "log.h"
  11. #include "DragonSoul.h"
  12. #include <boost/lexical_cast.hpp>
  13.  
  14. typedef std::vector <std::string> TTokenVector;
  15.  
  16. int Gamble(std::vector<float>& vec_probs)
  17. {
  18.     float range = 0.f;
  19.     for (int i = 0; i < vec_probs.size(); i++)
  20.     {
  21.         range += vec_probs[i];
  22.     }
  23.     float fProb = fnumber(0.f, range);
  24.     float sum = 0.f;
  25.     for (int idx = 0; idx < vec_probs.size(); idx++)
  26.     {
  27.         sum += vec_probs[idx];
  28.         if (sum >= fProb)
  29.             return idx;
  30.     }
  31.     return -1;
  32. }
  33.  
  34. // °¡ÁßÄ¡ Å×À̺í(prob_lst)À» ¹Þ¾Æ random_set.size()°³ÀÇ index¸¦ ¼±ÅÃÇÏ¿© random_setÀ» return
  35. bool MakeDistinctRandomNumberSet(std::list <float> prob_lst, OUT std::vector<int>& random_set)
  36. {
  37.     int size = prob_lst.size();
  38.     int n = random_set.size();
  39.     if (size < n)
  40.         return false;
  41.  
  42.     std::vector <int> select_bit(size, 0);
  43.     for (int i = 0; i < n; i++)
  44.     {
  45.         float range = 0.f;
  46.         for (auto it = prob_lst.begin(); it != prob_lst.end(); it++)
  47.         {
  48.             range += *it;
  49.         }
  50.         float r = fnumber (0.f, range);
  51.         float sum = 0.f;
  52.         int idx = 0;
  53.         for (auto it = prob_lst.begin(); it != prob_lst.end(); it++)
  54.         {
  55.             while (select_bit[idx++]);
  56.  
  57.             sum += *it;
  58.             if (sum >= r)
  59.             {
  60.                 select_bit[idx - 1] = 1;
  61.                 random_set[i] = idx - 1;
  62.                 prob_lst.erase(it);
  63.                 break;
  64.             }
  65.         }
  66.     }
  67.     return true;
  68. }
  69.  
  70. /* ¿ëÈ¥¼® Vnum¿¡ ´ëÇÑ comment  
  71.  * ITEM VNUMÀ» 10¸¸ ÀÚ¸®ºÎÅÍ, FEDCBA¶ó°í ÇÑ´Ù¸é
  72.  * FE : ¿ëÈ¥¼® Á¾·ù.  D : µî±Þ
  73.  * C : ´Ü°è         B : °­È­       
  74.  * A : ¿©¹úÀÇ ¹øÈ£µé...    
  75.  */
  76.  
  77. BYTE GetType(DWORD dwVnum)
  78. {
  79.     return (dwVnum / 10000);
  80. }
  81.  
  82. BYTE GetGradeIdx(DWORD dwVnum)
  83. {
  84.     return (dwVnum / 1000) % 10;
  85. }
  86.  
  87. BYTE GetStepIdx(DWORD dwVnum)
  88. {
  89.     return (dwVnum / 100) % 10;
  90. }
  91.  
  92. BYTE GetStrengthIdx(DWORD dwVnum)
  93. {
  94.     return (dwVnum / 10) % 10;
  95. }
  96.  
  97. bool DSManager::ReadDragonSoulTableFile(const char * c_pszFileName)
  98. {
  99.     m_pTable = new DragonSoulTable();
  100.     return m_pTable->ReadDragonSoulTableFile(c_pszFileName);
  101. }
  102.  
  103. void DSManager::GetDragonSoulInfo(DWORD dwVnum, BYTE& bType, BYTE& bGrade, BYTE& bStep, BYTE& bStrength) const
  104. {
  105.     bType = GetType(dwVnum);
  106.     bGrade = GetGradeIdx(dwVnum);
  107.     bStep = GetStepIdx(dwVnum);
  108.     bStrength = GetStrengthIdx(dwVnum);
  109. }
  110.  
  111. bool DSManager::IsValidCellForThisItem(const LPITEM pItem, const TItemPos& Cell) const
  112. {
  113.     if (NULL == pItem)
  114.         return false;
  115.  
  116.     WORD wBaseCell = GetBasePosition(pItem);
  117.     if (WORD_MAX == wBaseCell)
  118.         return false;
  119.  
  120.     if (Cell.window_type != DRAGON_SOUL_INVENTORY
  121.         || (Cell.cell < wBaseCell || Cell.cell >= wBaseCell + DRAGON_SOUL_BOX_SIZE))
  122.     {
  123.         return false;
  124.     }
  125.     else
  126.         return true;
  127.  
  128. }
  129.  
  130. WORD DSManager::GetBasePosition(const LPITEM pItem) const
  131. {
  132.     if (NULL == pItem)
  133.         return WORD_MAX;
  134.  
  135.     BYTE type, grade_idx, step_idx, strength_idx;
  136.     GetDragonSoulInfo(pItem->GetVnum(), type, grade_idx, step_idx, strength_idx);
  137.  
  138.     BYTE col_type = pItem->GetSubType();
  139.     BYTE row_type = grade_idx;
  140.     if (row_type > DRAGON_SOUL_GRADE_MAX)
  141.         return WORD_MAX;
  142.  
  143.     return col_type * DRAGON_SOUL_STEP_MAX * DRAGON_SOUL_BOX_SIZE + row_type * DRAGON_SOUL_BOX_SIZE;
  144. }
  145.  
  146. bool DSManager::RefreshItemAttributes(LPITEM pDS)
  147. {
  148.     if (!pDS->IsDragonSoul())
  149.     {
  150.         sys_err ("This item(ID : %d) is not DragonSoul.", pDS->GetID());
  151.         return false;
  152.     }
  153.  
  154.     BYTE ds_type, grade_idx, step_idx, strength_idx;
  155.     GetDragonSoulInfo(pDS->GetVnum(), ds_type, grade_idx, step_idx, strength_idx);
  156.  
  157.     DragonSoulTable::TVecApplys vec_basic_applys;
  158.     DragonSoulTable::TVecApplys vec_addtional_applys;
  159.  
  160.     if (!m_pTable->GetBasicApplys(ds_type, vec_basic_applys))
  161.     {
  162.         sys_err ("There is no BasicApply about %d type dragon soul.", ds_type);
  163.         return false;
  164.     }
  165.  
  166.     if (!m_pTable->GetAdditionalApplys(ds_type, vec_addtional_applys))
  167.     {
  168.         sys_err ("There is no AdditionalApply about %d type dragon soul.", ds_type);
  169.         return false;
  170.     }
  171.  
  172.     // add_min°ú add_max´Â ´õ¹Ì·Î ÀÐÀ½.
  173.     int basic_apply_num, add_min, add_max;
  174.     if (!m_pTable->GetApplyNumSettings(ds_type, grade_idx, basic_apply_num, add_min, add_max))
  175.     {
  176.         sys_err ("In ApplyNumSettings, INVALID VALUES Group type(%d), GRADE idx(%d)", ds_type, grade_idx);
  177.         return false;
  178.     }
  179.  
  180.     float fWeight = 0.f;
  181.     if (!m_pTable->GetWeight(ds_type, grade_idx, step_idx, strength_idx, fWeight))
  182.     {
  183.         return false;
  184.     }
  185.     fWeight /= 100.f;
  186.  
  187.     int n = MIN(basic_apply_num, vec_basic_applys.size());
  188.     for (int i = 0; i < n; i++)
  189.     {  
  190.         const SApply& basic_apply = vec_basic_applys[i];
  191.         BYTE bType = basic_apply.apply_type;
  192.         short sValue = (short)(ceil((float)basic_apply.apply_value * fWeight - 0.01f));
  193.  
  194.         pDS->SetForceAttribute(i, bType, sValue);
  195.     }
  196.  
  197.     for (int i = DRAGON_SOUL_ADDITIONAL_ATTR_START_IDX; i < ITEM_ATTRIBUTE_MAX_NUM; i++)
  198.     {
  199.         BYTE bType = pDS->GetAttributeType(i);
  200.         short sValue = 0;
  201.         if (APPLY_NONE == bType)
  202.             continue;
  203.         for (int j = 0; j < vec_addtional_applys.size(); j++)
  204.         {
  205.             if (vec_addtional_applys[j].apply_type == bType)
  206.             {
  207.                 sValue = vec_addtional_applys[j].apply_value;
  208.                 break;
  209.             }
  210.         }
  211.         pDS->SetForceAttribute(i, bType, (short)(ceil((float)sValue * fWeight - 0.01f)));
  212.     }
  213.     return true;
  214. }
  215.  
  216. bool DSManager::PutAttributes(LPITEM pDS)
  217. {
  218.     if (!pDS->IsDragonSoul())
  219.     {
  220.         sys_err ("This item(ID : %d) is not DragonSoul.", pDS->GetID());
  221.         return false;
  222.     }
  223.  
  224.     BYTE ds_type, grade_idx, step_idx, strength_idx;
  225.     GetDragonSoulInfo(pDS->GetVnum(), ds_type, grade_idx, step_idx, strength_idx);
  226.  
  227.     DragonSoulTable::TVecApplys vec_basic_applys;
  228.     DragonSoulTable::TVecApplys vec_addtional_applys;
  229.  
  230.     if (!m_pTable->GetBasicApplys(ds_type, vec_basic_applys))
  231.     {
  232.         sys_err ("There is no BasicApply about %d type dragon soul.", ds_type);
  233.         return false;
  234.     }
  235.     if (!m_pTable->GetAdditionalApplys(ds_type, vec_addtional_applys))
  236.     {
  237.         sys_err ("There is no AdditionalApply about %d type dragon soul.", ds_type);
  238.         return false;
  239.     }
  240.  
  241.    
  242.     int basic_apply_num, add_min, add_max;
  243.     if (!m_pTable->GetApplyNumSettings(ds_type, grade_idx, basic_apply_num, add_min, add_max))
  244.     {
  245.         sys_err ("In ApplyNumSettings, INVALID VALUES Group type(%d), GRADE idx(%d)", ds_type, grade_idx);
  246.         return false;
  247.     }
  248.  
  249.     float fWeight = 0.f;
  250.     if (!m_pTable->GetWeight(ds_type, grade_idx, step_idx, strength_idx, fWeight))
  251.     {
  252.         return false;
  253.     }
  254.     fWeight /= 100.f;
  255.  
  256.     int n = MIN(basic_apply_num, vec_basic_applys.size());
  257.     for (int i = 0; i < n; i++)
  258.     {  
  259.         const SApply& basic_apply = vec_basic_applys[i];
  260.         BYTE bType = basic_apply.apply_type;
  261.         short sValue = (short)(ceil((float)basic_apply.apply_value * fWeight - 0.01f));
  262.  
  263.         pDS->SetForceAttribute(i, bType, sValue);
  264.     }
  265.  
  266.     BYTE additional_attr_num = MIN(number (add_min, add_max), 3);
  267.  
  268.     std::vector <int> random_set;
  269.     if (additional_attr_num > 0)
  270.     {
  271.         random_set.resize(additional_attr_num);
  272.         std::list <float> list_probs;
  273.         for (int i = 0; i < vec_addtional_applys.size(); i++)
  274.         {
  275.             list_probs.push_back(vec_addtional_applys[i].prob);
  276.         }
  277.         if (!MakeDistinctRandomNumberSet(list_probs, random_set))
  278.         {
  279.             sys_err ("MakeDistinctRandomNumberSet error.");
  280.             return false;
  281.         }
  282.  
  283.         for (int i = 0; i < additional_attr_num; i++)
  284.         {
  285.             int r = random_set[i];
  286.             const SApply& additional_attr = vec_addtional_applys[r];
  287.             BYTE bType = additional_attr.apply_type;
  288.             short sValue = (short)(ceil((float)additional_attr.apply_value * fWeight - 0.01f));
  289.  
  290.             pDS->SetForceAttribute(DRAGON_SOUL_ADDITIONAL_ATTR_START_IDX + i, bType, sValue);
  291.         }
  292.     }
  293.  
  294.     return true;
  295. }
  296.  
  297. bool DSManager::DragonSoulItemInitialize(LPITEM pItem)
  298. {
  299.     if (NULL == pItem || !pItem->IsDragonSoul())
  300.         return false;
  301.     PutAttributes(pItem);
  302.     int time = DSManager::instance().GetDuration(pItem);
  303.     if (time > 0)
  304.         pItem->SetSocket(ITEM_SOCKET_REMAIN_SEC, time);
  305.     return true;
  306. }
  307.  
  308. DWORD DSManager::MakeDragonSoulVnum(BYTE bType, BYTE grade, BYTE step, BYTE refine)
  309. {
  310.     return bType * 10000 + grade * 1000 + step * 100 + refine * 10;
  311. }
  312.  
  313. int DSManager::GetDuration(const LPITEM pItem) const
  314. {
  315.     return pItem->GetDuration();
  316. }
  317.  
  318. // ¿ëÈ¥¼®À» ¹Þ¾Æ¼­ ¿ë½ÉÀ» ÃßÃâÇÏ´Â ÇÔ¼ö
  319. bool DSManager::ExtractDragonHeart(LPCHARACTER ch, LPITEM pItem, LPITEM pExtractor)
  320. {
  321.     if (NULL == ch || NULL == pItem)
  322.         return false;
  323.     if (pItem->IsEquipped())
  324.     {
  325.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Âø¿ë ÁßÀÎ ¿ëÈ¥¼®Àº ÃßÃâÇÒ ¼ö ¾ø½À´Ï´Ù."));
  326.         return false;
  327.     }
  328.  
  329.     DWORD dwVnum = pItem->GetVnum();
  330.     BYTE ds_type, grade_idx, step_idx, strength_idx;
  331.     GetDragonSoulInfo(dwVnum, ds_type, grade_idx, step_idx, strength_idx);
  332.  
  333.     int iBonus = 0;
  334.  
  335.     if (NULL != pExtractor)
  336.     {
  337.         iBonus = pExtractor->GetValue(0);
  338.     }
  339.  
  340.     std::vector <float> vec_chargings;
  341.     std::vector <float> vec_probs;
  342.  
  343.     if (!m_pTable->GetDragonHeartExtValues(ds_type, grade_idx, vec_chargings, vec_probs))
  344.     {
  345.         return false;
  346.     }
  347.  
  348.     int idx = Gamble(vec_probs);
  349.  
  350.     float sum = 0.f;
  351.     if (-1 == idx)
  352.     {
  353.         sys_err ("Gamble is failed. ds_type(%d), grade_idx(%d)", ds_type, grade_idx);
  354.         return false;
  355.     }
  356.  
  357.     float fCharge = vec_chargings[idx] * (100 + iBonus) / 100.f;
  358.     fCharge = std::MINMAX <float> (0.f, fCharge, 100.f);
  359.  
  360.     if (fCharge < FLT_EPSILON)
  361.     {
  362.         pItem->SetCount(pItem->GetCount() - 1);
  363.         if (NULL != pExtractor)
  364.         {
  365.             pExtractor->SetCount(pExtractor->GetCount() - 1);
  366.         }
  367.         LogManager::instance().ItemLog(ch, pItem, "DS_HEART_EXTRACT_FAIL", "");
  368.    
  369.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¿ë½É ÃßÃâ¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."));
  370.         return false;
  371.     }
  372.     else
  373.     {
  374.         LPITEM pDH = ITEM_MANAGER::instance().CreateItem(DRAGON_HEART_VNUM);
  375.        
  376.         if (NULL == pDH)
  377.         {
  378.             sys_err ("Cannot create DRAGON_HEART(%d).", DRAGON_HEART_VNUM);
  379.             return NULL;
  380.         }
  381.  
  382.         pItem->SetCount(pItem->GetCount() - 1);
  383.         if (NULL != pExtractor)
  384.         {
  385.             pExtractor->SetCount(pExtractor->GetCount() - 1);
  386.         }
  387.  
  388.         int iCharge = (int)(fCharge + 0.5f);
  389.         pDH->SetSocket(ITEM_SOCKET_CHARGING_AMOUNT_IDX, iCharge);
  390.         ch->AutoGiveItem(pDH, true);
  391.  
  392.         std::string s = boost::lexical_cast <std::string> (iCharge);
  393.         s += "%s";
  394.         LogManager::instance().ItemLog(ch, pItem, "DS_HEART_EXTRACT_SUCCESS", s.c_str());
  395.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¿ë½É ÃßÃâ¿¡ ¼º°øÇÏ¿´½À´Ï´Ù."));
  396.         return true;
  397.     }
  398. }
  399.  
  400. // ƯÁ¤ ¿ëÈ¥¼®À» Àåºñâ¿¡¼­ Á¦°ÅÇÒ ¶§¿¡ ¼º°ø ¿©ºÎ¸¦ °áÁ¤ÇÏ°í, ½ÇÆнà ºÎ»ê¹°À» ÁÖ´Â ÇÔ¼ö.
  401. bool DSManager::PullOut(LPCHARACTER ch, TItemPos DestCell, LPITEM& pItem, LPITEM pExtractor)
  402. {
  403.     if (NULL == ch || NULL == pItem)
  404.     {
  405.         sys_err ("NULL POINTER. ch(%p) or pItem(%p)", ch, pItem);
  406.         return false;
  407.     }
  408.  
  409.     // ¸ñÇ¥ À§Ä¡°¡ validÇÑÁö °Ë»ç ÈÄ, validÇÏÁö ¾Ê´Ù¸é ÀÓÀÇÀÇ ºó °ø°£À» ã´Â´Ù.
  410.     if (!IsValidCellForThisItem(pItem, DestCell))
  411.     {
  412.         int iEmptyCell = ch->GetEmptyDragonSoulInventory(pItem);
  413.         if (iEmptyCell < 0)
  414.         {
  415.             ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Es ist nicht genug Platz im Inventar."));
  416.             return false;
  417.         }
  418.         else
  419.         {
  420.             DestCell.window_type = DRAGON_SOUL_INVENTORY;
  421.             DestCell.cell = iEmptyCell;
  422.         }
  423.     }
  424.  
  425.     if (!pItem->IsEquipped() || !pItem->RemoveFromCharacter())
  426.         return false;
  427.  
  428.     bool bSuccess;
  429.     DWORD dwByProduct = 0;
  430.     int iBonus = 0;
  431.     float fProb;
  432.     float fDice;
  433.     // ¿ëÈ¥¼® ÃßÃâ ¼º°ø ¿©ºÎ °áÁ¤.
  434.     {
  435.         DWORD dwVnum = pItem->GetVnum();
  436.  
  437.         BYTE ds_type, grade_idx, step_idx, strength_idx;
  438.         GetDragonSoulInfo(pItem->GetVnum(), ds_type, grade_idx, step_idx, strength_idx);
  439.  
  440.         // ÃßÃâ Á¤º¸°¡ ¾ø´Ù¸é ÀÏ´Ü ¹«Á¶°Ç ¼º°øÇÏ´Â °ÍÀ̶ó »ý°¢ÇÏÀÚ.
  441.         if (!m_pTable->GetDragonSoulExtValues(ds_type, grade_idx, fProb, dwByProduct))
  442.         {
  443.             pItem->AddToCharacter(ch, DestCell);
  444.             return true;
  445.         }
  446.  
  447.  
  448.         if (NULL != pExtractor)
  449.         {
  450.             iBonus = pExtractor->GetValue(ITEM_VALUE_DRAGON_SOUL_POLL_OUT_BONUS_IDX);
  451.             pExtractor->SetCount(pExtractor->GetCount() - 1);
  452.         }
  453.         fDice = fnumber(0.f, 100.f);
  454.         bSuccess = fDice <= (fProb * (100 + iBonus) / 100.f);
  455.     }
  456.  
  457.     // ij¸¯ÅÍÀÇ ¿ëÈ¥¼® ÃßÃâ ¹× Ãß°¡ ȤÀº Á¦°Å. ºÎ»ê¹° Á¦°ø.
  458.     {
  459.         char buf[128];
  460.  
  461.         if (bSuccess)
  462.         {
  463.             if (pExtractor)
  464.             {
  465.                 sprintf(buf, "dice(%d) prob(%d + %d) EXTR(VN:%d)", (int)fDice, (int)fProb, iBonus, pExtractor->GetVnum());
  466.             }
  467.             else
  468.             {
  469.                 sprintf(buf, "dice(%d) prob(%d)", fDice, fProb);
  470.             }
  471.             LogManager::instance().ItemLog(ch, pItem, "DS_PULL_OUT_SUCCESS", buf);
  472.             ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¿ëÈ¥¼® ÃßÃâ¿¡ ¼º°øÇÏ¿´½À´Ï´Ù."));
  473.             pItem->AddToCharacter(ch, DestCell);
  474.             return true;
  475.         }
  476.         else
  477.         {
  478.             if (pExtractor)
  479.             {
  480.                 sprintf(buf, "dice(%d) prob(%d + %d) EXTR(VN:%d) ByProd(VN:%d)", (int)fDice, (int)fProb, iBonus, pExtractor->GetVnum(), dwByProduct);
  481.             }
  482.             else
  483.             {
  484.                 sprintf(buf, "dice(%d) prob(%d) ByProd(VNUM:%d)", (int)fDice, (int)fProb, dwByProduct);
  485.             }
  486.             LogManager::instance().ItemLog(ch, pItem, "DS_PULL_OUT_FAILED", buf);
  487.             M2_DESTROY_ITEM(pItem);
  488.             pItem = NULL;
  489.             if (dwByProduct)
  490.             {
  491.                 LPITEM pByProduct = ch->AutoGiveItem(dwByProduct, true);
  492.                 if (pByProduct)
  493.                     ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¿ëÈ¥¼® ÃßÃâ¿¡ ½ÇÆÐÇÏ¿© %s¸¦ ¾ò¾ú½À´Ï´Ù."), pByProduct->GetName());
  494.                 else
  495.                     ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¿ëÈ¥¼® ÃßÃâ¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."));
  496.             }
  497.             else
  498.                 ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¿ëÈ¥¼® ÃßÃâ¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."));
  499.         }
  500.     }
  501.  
  502.     return bSuccess;
  503. }
  504.  
  505. bool DSManager::DoRefineGrade(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_REFINE_GRID_SIZE])
  506. {
  507.     if (NULL == ch)
  508.         return false;
  509.  
  510.     if (NULL == aItemPoses)
  511.     {
  512.         return false;
  513.     }
  514.  
  515.     if (!ch->DragonSoul_RefineWindow_CanRefine())
  516.     {
  517.         sys_err ("%s do not activate DragonSoulRefineWindow. But how can he come here?", ch->GetName());
  518.         ch->ChatPacket(CHAT_TYPE_INFO, "[SYSTEM ERROR]You cannot upgrade dragon soul without refine window.");
  519.         return false;
  520.     }
  521.  
  522.     // Ȥ½Ã³ª ¸ð¸¦ Áߺ¹µÇ´Â item pointer ¾ø¾Ö±â À§Çؼ­ set »ç¿ë
  523.     // ÀÌ»óÇÑ ÆÐŶÀ» º¸³¾ °æ¿ì, Áߺ¹µÈ TItemPos°¡ ÀÖÀ» ¼öµµ ÀÖ°í, À߸øµÈ TItemPos°¡ ÀÖÀ» ¼öµµ ÀÖ´Ù.
  524.     std::set <LPITEM> set_items;
  525.     for (int i = 0; i < DRAGON_SOUL_REFINE_GRID_SIZE; i++)
  526.     {
  527.         if (aItemPoses[i].IsEquipPosition())
  528.             return false;
  529.         LPITEM pItem = ch->GetItem(aItemPoses[i]);
  530.         if (NULL != pItem)
  531.         {
  532.             // ¿ëÈ¥¼®ÀÌ ¾Æ´Ñ ¾ÆÀÌÅÛÀÌ °³·®Ã¢¿¡ ÀÖÀ» ¼ö ¾ø´Ù.
  533.             if (!pItem->IsDragonSoul())
  534.             {
  535.                 ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("µî±Þ °³·®¿¡ ÇÊ¿äÇÑ Àç·á°¡ ¾Æ´Õ´Ï´Ù."));
  536.                 SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell()));
  537.  
  538.                 return false;
  539.             }
  540.  
  541.             set_items.insert(pItem);
  542.         }
  543.     }
  544.  
  545.     if (set_items.size() == 0)
  546.     {
  547.         SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL, NPOS);
  548.         return false;
  549.     }
  550.  
  551.     int count = set_items.size();
  552.     int need_count = 0;
  553.     int fee = 0;
  554.     std::vector <float> vec_probs;
  555.     float prob_sum;
  556.  
  557.     BYTE ds_type, grade_idx, step_idx, strength_idx;
  558.     int result_grade;
  559.  
  560.     // °¡Àå óÀ½ °ÍÀ» °­È­ÀÇ ±âÁØÀ¸·Î »ï´Â´Ù.
  561.     auto it = set_items.begin();
  562.     {
  563.         LPITEM pItem = *it;
  564.  
  565.         GetDragonSoulInfo(pItem->GetVnum(), ds_type, grade_idx, step_idx, strength_idx);
  566.        
  567.         if (!m_pTable->GetRefineGradeValues(ds_type, grade_idx, need_count, fee, vec_probs))
  568.         {
  569.             ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("µî±Þ °³·®ÇÒ ¼ö ¾ø´Â ¿ëÈ¥¼®ÀÔ´Ï´Ù."));
  570.             SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell()));
  571.  
  572.             return false;
  573.         }
  574.     }
  575.     while (++it != set_items.end())
  576.     {
  577.         LPITEM pItem = *it;
  578.  
  579.         // Ŭ¶ó ui¿¡¼­ ÀåÂøÇÑ ¾ÆÀÌÅÛÀº °³·®Ã¢¿¡ ¿Ã¸± ¼ö ¾øµµ·Ï ¸·¾Ò±â ¶§¹®¿¡,
  580.         // º°µµÀÇ ¾Ë¸² 󸮴 ¾ÈÇÔ.
  581.         if (pItem->IsEquipped())
  582.         {
  583.             return false;
  584.         }
  585.        
  586.         if (ds_type != GetType(pItem->GetVnum()) || grade_idx != GetGradeIdx(pItem->GetVnum()))
  587.         {
  588.             ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("µî±Þ °³·®¿¡ ÇÊ¿äÇÑ Àç·á°¡ ¾Æ´Õ´Ï´Ù."));
  589.             SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell()));
  590.  
  591.             return false;
  592.         }
  593.     }
  594.  
  595.     // Ŭ¶ó¿¡¼­ Çѹø °¹¼ö üũ¸¦ Çϱ⠶§¹®¿¡ count != need_count¶ó¸é invalid Ŭ¶óÀÏ °¡´É¼ºÀÌ Å©´Ù.
  596.     if (count != need_count)
  597.     {
  598.         sys_err ("Possiblity of invalid client. Name %s", ch->GetName());
  599.         BYTE bSubHeader = count < need_count? DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL : DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL;
  600.         SendRefineResultPacket(ch, bSubHeader, NPOS);
  601.         return false;
  602.     }
  603.  
  604.     if (ch->GetGold() < fee)
  605.     {
  606.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Nicht genug Yang fuer eine Verbesserung."));
  607.         SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY, NPOS);
  608.         return false;
  609.     }
  610.    
  611.     if (-1 == (result_grade = Gamble(vec_probs)))
  612.     {
  613.         sys_err ("Gamble failed. See RefineGardeTables' probabilities");
  614.         return false;
  615.     }
  616.  
  617.     LPITEM pResultItem = ITEM_MANAGER::instance().CreateItem(MakeDragonSoulVnum(ds_type, (BYTE)result_grade, 0, 0));
  618.  
  619.     if (NULL == pResultItem)
  620.     {
  621.         sys_err ("INVALID DRAGON SOUL(%d)", MakeDragonSoulVnum(ds_type, (BYTE)result_grade, 0, 0));
  622.         return false;
  623.     }
  624.  
  625.     ch->PointChange(POINT_GOLD, -fee);
  626.     int left_count = need_count;
  627.    
  628.     for (auto it = set_items.begin(); it != set_items.end(); it++)
  629.     {
  630.         LPITEM pItem = *it;
  631.         int n = pItem->GetCount();
  632.         if (left_count > n)
  633.         {
  634.             pItem->RemoveFromCharacter();
  635.             M2_DESTROY_ITEM(pItem);
  636.             left_count -= n;
  637.         }
  638.         else
  639.         {
  640.             pItem->SetCount(n - left_count);
  641.         }
  642.     }
  643.  
  644.     ch->AutoGiveItem(pResultItem, true);
  645.  
  646.     if (result_grade > grade_idx)
  647.     {
  648.         char buf[128];
  649.         sprintf(buf, "GRADE : %d -> %d", grade_idx, result_grade);
  650.         LogManager::instance().ItemLog(ch, pResultItem, "DS_GRADE_REFINE_SUCCESS", buf);
  651.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("µî±Þ °³·®¿¡ ¼º°øÇß½À´Ï´Ù."));
  652.         SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_SUCCEED, TItemPos (pResultItem->GetWindow(), pResultItem->GetCell()));
  653.         return true;
  654.     }
  655.     else
  656.     {
  657.         char buf[128];
  658.         sprintf(buf, "GRADE : %d -> %d", grade_idx, result_grade);
  659.         LogManager::instance().ItemLog(ch, pResultItem, "DS_GRADE_REFINE_FAIL", buf);
  660.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("µî±Þ °³·®¿¡ ½ÇÆÐÇß½À´Ï´Ù."));
  661.         SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL, TItemPos (pResultItem->GetWindow(), pResultItem->GetCell()));
  662.         return false;
  663.     }
  664. }
  665.  
  666. bool DSManager::DoRefineStep(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_REFINE_GRID_SIZE])
  667. {
  668.     if (NULL == ch)
  669.         return false;
  670.     if (NULL == aItemPoses)
  671.     {
  672.         return false;
  673.     }
  674.  
  675.     if (!ch->DragonSoul_RefineWindow_CanRefine())
  676.     {
  677.         sys_err ("%s do not activate DragonSoulRefineWindow. But how can he come here?", ch->GetName());
  678.         ch->ChatPacket(CHAT_TYPE_INFO, "[SYSTEM ERROR]You cannot use dragon soul refine window.");
  679.         return false;
  680.     }
  681.  
  682.     // Ȥ½Ã³ª ¸ð¸¦ Áߺ¹µÇ´Â item pointer ¾ø¾Ö±â À§Çؼ­ set »ç¿ë
  683.     // ÀÌ»óÇÑ ÆÐŶÀ» º¸³¾ °æ¿ì, Áߺ¹µÈ TItemPos°¡ ÀÖÀ» ¼öµµ ÀÖ°í, À߸øµÈ TItemPos°¡ ÀÖÀ» ¼öµµ ÀÖ´Ù.
  684.     std::set <LPITEM> set_items;
  685.     for (int i = 0; i < DRAGON_SOUL_REFINE_GRID_SIZE; i++)
  686.     {
  687.         LPITEM pItem = ch->GetItem(aItemPoses[i]);
  688.         if (NULL != pItem)
  689.         {
  690.             // ¿ëÈ¥¼®ÀÌ ¾Æ´Ñ ¾ÆÀÌÅÛÀÌ °³·®Ã¢¿¡ ÀÖÀ» ¼ö ¾ø´Ù.
  691.             if (!pItem->IsDragonSoul())
  692.             {
  693.                 ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´Ü°è °³·®¿¡ ÇÊ¿äÇÑ Àç·á°¡ ¾Æ´Õ´Ï´Ù."));
  694.                 SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell()));
  695.                 return false;
  696.             }
  697.             set_items.insert(pItem);
  698.         }
  699.     }
  700.  
  701.     if (set_items.size() == 0)
  702.     {
  703.         SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL, NPOS);
  704.         return false;
  705.     }
  706.  
  707.     std::string stGroupName;
  708.     int count = set_items.size();
  709.     int need_count = 0;
  710.     int fee = 0;
  711.     std::vector <float> vec_probs;
  712.  
  713.     BYTE ds_type, grade_idx, step_idx, strength_idx;
  714.     int result_step;
  715.  
  716.     // °¡Àå óÀ½ °ÍÀ» °­È­ÀÇ ±âÁØÀ¸·Î »ï´Â´Ù.
  717.     auto it = set_items.begin();
  718.     {
  719.         LPITEM pItem = *it;
  720.         GetDragonSoulInfo(pItem->GetVnum(), ds_type, grade_idx, step_idx, strength_idx);
  721.  
  722.         if (!m_pTable->GetRefineStepValues(ds_type, step_idx, need_count, fee, vec_probs))
  723.         {
  724.             ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´Ü°è °³·®ÇÒ ¼ö ¾ø´Â ¿ëÈ¥¼®ÀÔ´Ï´Ù."));
  725.             SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell()));
  726.             return false;
  727.         }
  728.     }
  729.  
  730.     while(++it != set_items.end())
  731.     {
  732.         LPITEM pItem = *it;
  733.         // Ŭ¶ó ui¿¡¼­ ÀåÂøÇÑ ¾ÆÀÌÅÛÀº °³·®Ã¢¿¡ ¿Ã¸± ¼ö ¾øµµ·Ï ¸·¾Ò±â ¶§¹®¿¡,
  734.         // º°µµÀÇ ¾Ë¸² 󸮴 ¾ÈÇÔ.
  735.         if (pItem->IsEquipped())
  736.         {
  737.             return false;
  738.         }
  739.         if (ds_type != GetType(pItem->GetVnum()) || grade_idx != GetGradeIdx(pItem->GetVnum()) || step_idx != GetStepIdx(pItem->GetVnum()))
  740.         {
  741.             ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´Ü°è °³·®¿¡ ÇÊ¿äÇÑ Àç·á°¡ ¾Æ´Õ´Ï´Ù."));
  742.             SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell()));
  743.             return false;
  744.         }
  745.     }
  746.  
  747.     // Ŭ¶ó¿¡¼­ Çѹø °¹¼ö üũ¸¦ Çϱ⠶§¹®¿¡ count != need_count¶ó¸é invalid Ŭ¶óÀÏ °¡´É¼ºÀÌ Å©´Ù.
  748.     if (count != need_count)
  749.     {
  750.         sys_err ("Possiblity of invalid client. Name %s", ch->GetName());
  751.         BYTE bSubHeader = count < need_count? DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL : DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL;
  752.         SendRefineResultPacket(ch, bSubHeader, NPOS);
  753.         return false;
  754.     }
  755.    
  756.     if (ch->GetGold() < fee)
  757.     {
  758.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Nicht genug Yang fuer eine Verbesserung."));
  759.         SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY, NPOS);
  760.         return false;
  761.     }
  762.    
  763.     float sum = 0.f;
  764.  
  765.     if (-1 == (result_step = Gamble(vec_probs)))
  766.     {
  767.         sys_err ("Gamble failed. See RefineStepTables' probabilities");
  768.         return false;
  769.     }
  770.  
  771.     LPITEM pResultItem = ITEM_MANAGER::instance().CreateItem(MakeDragonSoulVnum(ds_type, grade_idx, (BYTE)result_step, 0));
  772.  
  773.     if (NULL == pResultItem)
  774.     {
  775.         sys_err ("INVALID DRAGON SOUL(%d)", MakeDragonSoulVnum(ds_type, grade_idx, (BYTE)result_step, 0));
  776.         return false;
  777.     }
  778.  
  779.     ch->PointChange(POINT_GOLD, -fee);
  780.     int left_count = need_count;
  781.     for (auto it = set_items.begin(); it != set_items.end(); it++)
  782.     {
  783.         LPITEM pItem = *it;
  784.         int n = pItem->GetCount();
  785.         if (left_count > n)
  786.         {
  787.             pItem->RemoveFromCharacter();
  788.             M2_DESTROY_ITEM(pItem);
  789.             left_count -= n;
  790.         }
  791.         else
  792.         {
  793.             pItem->SetCount(n - left_count);
  794.         }
  795.     }
  796.  
  797.     ch->AutoGiveItem(pResultItem, true);
  798.     if (result_step > step_idx)
  799.     {
  800.         char buf[128];
  801.         sprintf(buf, "STEP : %d -> %d", step_idx, result_step);
  802.         LogManager::instance().ItemLog(ch, pResultItem, "DS_STEP_REFINE_SUCCESS", buf);
  803.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´Ü°è °³·®¿¡ ¼º°øÇß½À´Ï´Ù."));
  804.         SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_SUCCEED, TItemPos (pResultItem->GetWindow(), pResultItem->GetCell()));
  805.         return true;
  806.     }
  807.     else
  808.     {
  809.         char buf[128];
  810.         sprintf(buf, "STEP : %d -> %d", step_idx, result_step);
  811.         LogManager::instance().ItemLog(ch, pResultItem, "DS_STEP_REFINE_FAIL", buf);
  812.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("´Ü°è °³·®¿¡ ½ÇÆÐÇß½À´Ï´Ù."));
  813.         SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL, TItemPos (pResultItem->GetWindow(), pResultItem->GetCell()));
  814.         return false;
  815.     }
  816. }
  817.  
  818. bool IsDragonSoulRefineMaterial(LPITEM pItem)
  819. {
  820.     if (pItem->GetType() != ITEM_MATERIAL)
  821.         return false;
  822.     return (pItem->GetSubType() == MATERIAL_DS_REFINE_NORMAL ||
  823.         pItem->GetSubType() == MATERIAL_DS_REFINE_BLESSED ||
  824.         pItem->GetSubType() == MATERIAL_DS_REFINE_HOLLY);
  825. }
  826.  
  827. bool DSManager::DoRefineStrength(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_REFINE_GRID_SIZE])
  828. {
  829.     if (NULL == ch)
  830.         return false;
  831.     if (NULL == aItemPoses)
  832.     {
  833.         return false;
  834.     }
  835.  
  836.     if (!ch->DragonSoul_RefineWindow_CanRefine())
  837.     {
  838.         sys_err ("%s do not activate DragonSoulRefineWindow. But how can he come here?", ch->GetName());
  839.         ch->ChatPacket(CHAT_TYPE_INFO, "[SYSTEM ERROR]You cannot use dragon soul refine window.");
  840.         return false;
  841.     }
  842.  
  843.     // Ȥ½Ã³ª ¸ð¸¦ Áߺ¹µÇ´Â item pointer ¾ø¾Ö±â À§Çؼ­ set »ç¿ë
  844.     // ÀÌ»óÇÑ ÆÐŶÀ» º¸³¾ °æ¿ì, Áߺ¹µÈ TItemPos°¡ ÀÖÀ» ¼öµµ ÀÖ°í, À߸øµÈ TItemPos°¡ ÀÖÀ» ¼öµµ ÀÖ´Ù.
  845.     std::set <LPITEM> set_items;
  846.     for (int i = 0; i < DRAGON_SOUL_REFINE_GRID_SIZE; i++)
  847.     {
  848.         LPITEM pItem = ch->GetItem(aItemPoses[i]);
  849.         if (pItem)
  850.         {
  851.             set_items.insert(pItem);
  852.         }
  853.     }
  854.     if (set_items.size() == 0)
  855.     {
  856.         return false;
  857.     }
  858.  
  859.     int fee;
  860.  
  861.     LPITEM pRefineStone = NULL;
  862.     LPITEM pDragonSoul = NULL;
  863.     for (auto it = set_items.begin(); it != set_items.end(); it++)
  864.     {
  865.         LPITEM pItem = *it;
  866.         // Ŭ¶ó ui¿¡¼­ ÀåÂøÇÑ ¾ÆÀÌÅÛÀº °³·®Ã¢¿¡ ¿Ã¸± ¼ö ¾øµµ·Ï ¸·¾Ò±â ¶§¹®¿¡,
  867.         // º°µµÀÇ ¾Ë¸² 󸮴 ¾ÈÇÔ.
  868.         if (pItem->IsEquipped())
  869.         {
  870.             return false;
  871.         }
  872.  
  873.         // ¿ëÈ¥¼®°ú °­È­¼®¸¸ÀÌ °³·®Ã¢¿¡ ÀÖÀ» ¼ö ÀÖ´Ù.
  874.         // ±×¸®°í Çϳª¾¿¸¸ ÀÖ¾î¾ßÇÑ´Ù.
  875.         if (pItem->IsDragonSoul())
  876.         {
  877.             if (pDragonSoul != NULL)
  878.             {
  879.                 SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell()));
  880.                 return false;  
  881.             }
  882.             pDragonSoul = pItem;
  883.         }
  884.         else if(IsDragonSoulRefineMaterial(pItem))
  885.         {
  886.             if (pRefineStone != NULL)
  887.             {
  888.                 SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell()));
  889.                 return false;  
  890.             }
  891.             pRefineStone = pItem;
  892.         }
  893.         else
  894.         {
  895.             ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°­È­¿¡ ÇÊ¿äÇÑ Àç·á°¡ ¾Æ´Õ´Ï´Ù."));
  896.             SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pItem->GetWindow(), pItem->GetCell()));
  897.             return false;
  898.         }
  899.     }
  900.  
  901.     BYTE bType, bGrade, bStep, bStrength;
  902.    
  903.     if (!pDragonSoul || !pRefineStone)
  904.     {
  905.         SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL, NPOS);
  906.  
  907.         return false;
  908.     }
  909.    
  910.     if (NULL != pDragonSoul)
  911.     {
  912.         GetDragonSoulInfo(pDragonSoul->GetVnum(), bType, bGrade, bStep, bStrength);
  913.  
  914.         float fWeight = 0.f;
  915.         // °¡ÁßÄ¡ °ªÀÌ ¾ø´Ù¸é °­È­ÇÒ ¼ö ¾ø´Â ¿ëÈ¥¼®
  916.         if (!m_pTable->GetWeight(bType, bGrade, bStep, bStrength + 1, fWeight))
  917.         {
  918.             ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°­È­ÇÒ ¼ö ¾ø´Â ¿ëÈ¥¼®ÀÔ´Ï´Ù."));
  919.             SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE, TItemPos(pDragonSoul->GetWindow(), pDragonSoul->GetCell()));
  920.             return false;
  921.         }
  922.         // °­È­ÇßÀ» ¶§ °¡ÁßÄ¡°¡ 0À̶ó¸é ´õ ÀÌ»ó °­È­µÇ¼­´Â ¾ÈµÈ´Ù.
  923.         if (fWeight < FLT_EPSILON)
  924.         {
  925.             ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°­È­ÇÒ ¼ö ¾ø´Â ¿ëÈ¥¼®ÀÔ´Ï´Ù."));
  926.             SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE, TItemPos(pDragonSoul->GetWindow(), pDragonSoul->GetCell()));
  927.             return false;
  928.         }
  929.     }
  930.  
  931.     float fProb;
  932.     if (!m_pTable->GetRefineStrengthValues(bType, pRefineStone->GetSubType(), bStrength, fee, fProb))
  933.     {
  934.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°­È­ÇÒ ¼ö ¾ø´Â ¿ëÈ¥¼®ÀÔ´Ï´Ù."));
  935.         SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL, TItemPos(pDragonSoul->GetWindow(), pDragonSoul->GetCell()));
  936.  
  937.         return false;
  938.     }
  939.  
  940.     if (ch->GetGold() < fee)
  941.     {
  942.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Nicht genug Yang fuer eine Verbesserung."));
  943.         SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY, NPOS);
  944.         return false;
  945.     }
  946.    
  947.     ch->PointChange(POINT_GOLD, -fee);
  948.     LPITEM pResult = NULL;
  949.     BYTE bSubHeader;
  950.  
  951.     if (fnumber(0.f, 100.f) <= fProb)
  952.     {
  953.         pResult = ITEM_MANAGER::instance().CreateItem(MakeDragonSoulVnum(bType, bGrade, bStep, bStrength + 1));
  954.         if (NULL == pResult)
  955.         {
  956.             sys_err ("INVALID DRAGON SOUL(%d)", MakeDragonSoulVnum(bType, bGrade, bStep, bStrength + 1));
  957.             return false;
  958.         }
  959.         pDragonSoul->RemoveFromCharacter();
  960.  
  961.         pDragonSoul->CopyAttributeTo(pResult);
  962.         RefreshItemAttributes(pResult);
  963.  
  964.         pDragonSoul->SetCount(pDragonSoul->GetCount() - 1);
  965.         pRefineStone->SetCount(pRefineStone->GetCount() - 1);
  966.  
  967.         char buf[128];
  968.         sprintf(buf, "STRENGTH : %d -> %d", bStrength, bStrength + 1);
  969.         LogManager::instance().ItemLog(ch, pDragonSoul, "DS_STRENGTH_REFINE_SUCCESS", buf);
  970.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°­È­¿¡ ¼º°øÇß½À´Ï´Ù."));
  971.         ch->AutoGiveItem(pResult, true);
  972.         bSubHeader = DS_SUB_HEADER_REFINE_SUCCEED;
  973.     }
  974.     else
  975.     {
  976.         if (bStrength != 0)
  977.         {
  978.             pResult = ITEM_MANAGER::instance().CreateItem(MakeDragonSoulVnum(bType, bGrade, bStep, bStrength - 1));
  979.             if (NULL == pResult)
  980.             {
  981.                 sys_err ("INVALID DRAGON SOUL(%d)", MakeDragonSoulVnum(bType, bGrade, bStep, bStrength - 1));
  982.                 return false;
  983.             }
  984.             pDragonSoul->CopyAttributeTo(pResult);
  985.             RefreshItemAttributes(pResult);
  986.         }
  987.         bSubHeader = DS_SUB_HEADER_REFINE_FAIL;
  988.  
  989.         char buf[128];
  990.         sprintf(buf, "STRENGTH : %d -> %d", bStrength, bStrength - 1);
  991.         // strength°­È­´Â ½ÇÆнà ±úÁú ¼öµµ ÀÖ¾î, ¿øº» ¾ÆÀÌÅÛÀ» ¹ÙÅÁÀ¸·Î ·Î±×¸¦ ³²±è.
  992.         LogManager::instance().ItemLog(ch, pDragonSoul, "DS_STRENGTH_REFINE_FAIL", buf);
  993.  
  994.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°­È­¿¡ ½ÇÆÐÇß½À´Ï´Ù."));
  995.         pDragonSoul->SetCount(pDragonSoul->GetCount() - 1);
  996.         pRefineStone->SetCount(pRefineStone->GetCount() - 1);
  997.         if (NULL != pResult)
  998.             ch->AutoGiveItem(pResult, true);
  999.        
  1000.     }
  1001.    
  1002.     SendRefineResultPacket(ch, bSubHeader, NULL == pResult? NPOS : TItemPos (pResult->GetWindow(), pResult->GetCell()));
  1003.  
  1004.     return true;
  1005. }
  1006.  
  1007. void DSManager::SendRefineResultPacket(LPCHARACTER ch, BYTE bSubHeader, const TItemPos& pos)
  1008. {
  1009.     TPacketGCDragonSoulRefine pack;
  1010.     pack.bSubType = bSubHeader;
  1011.  
  1012.     if (pos.IsValidItemPosition())
  1013.     {
  1014.         pack.Pos = pos;
  1015.     }
  1016.     LPDESC d = ch->GetDesc();
  1017.     if (NULL == d)
  1018.     {
  1019.         return ;
  1020.     }
  1021.     else
  1022.     {
  1023.         d->Packet(&pack, sizeof(pack));
  1024.     }
  1025. }
  1026.  
  1027. int DSManager::LeftTime(LPITEM pItem) const
  1028. {
  1029.     if (pItem == NULL)
  1030.         return false;
  1031.  
  1032.     // ÀÏ´ÜÀº timer based on wearÀÎ ¿ëÈ¥¼®¸¸ ½Ã°£ ´Ù µÇ¾îµµ ¾È ¾ø¾îÁø´Ù.
  1033.     if (pItem->GetProto()->cLimitTimerBasedOnWearIndex >= 0)
  1034.     {
  1035.         return pItem->GetSocket(ITEM_SOCKET_REMAIN_SEC);
  1036.     }
  1037.     // ´Ù¸¥ limit typeÀÎ ¿ëÈ¥¼®µéÀº ½Ã°£ µÇ¸é ¸ðµÎ »ç¶óÁö±â ¶§¹®¿¡ ¿©±â µé¾î¿Â ¾ÆÀÌÅÛÀº ÀÏ´Ü ½Ã°£ÀÌ ³²¾Ò´Ù°í ÆÇ´Ü.
  1038.     else
  1039.     {
  1040.         return INT_MAX;
  1041.     }
  1042. }
  1043.  
  1044. bool DSManager::IsTimeLeftDragonSoul(LPITEM pItem) const
  1045. {
  1046.     if (pItem == NULL)
  1047.         return false;
  1048.  
  1049.     // ÀÏ´ÜÀº timer based on wearÀÎ ¿ëÈ¥¼®¸¸ ½Ã°£ ´Ù µÇ¾îµµ ¾È ¾ø¾îÁø´Ù.
  1050.     if (pItem->GetProto()->cLimitTimerBasedOnWearIndex >= 0)
  1051.     {
  1052.         return pItem->GetSocket(ITEM_SOCKET_REMAIN_SEC) > 0;
  1053.     }
  1054.     // ´Ù¸¥ limit typeÀÎ ¿ëÈ¥¼®µéÀº ½Ã°£ µÇ¸é ¸ðµÎ »ç¶óÁö±â ¶§¹®¿¡ ¿©±â µé¾î¿Â ¾ÆÀÌÅÛÀº ÀÏ´Ü ½Ã°£ÀÌ ³²¾Ò´Ù°í ÆÇ´Ü.
  1055.     else
  1056.     {
  1057.         return true;
  1058.     }
  1059. }
  1060.  
  1061. bool DSManager::IsActiveDragonSoul(LPITEM pItem) const
  1062. {
  1063.     return pItem->GetSocket(ITEM_SOCKET_DRAGON_SOUL_ACTIVE_IDX);
  1064. }
  1065.  
  1066. bool DSManager::ActivateDragonSoul(LPITEM pItem)
  1067. {
  1068.     if (NULL == pItem)
  1069.         return false;
  1070.     LPCHARACTER pOwner = pItem->GetOwner();
  1071.     if (NULL == pOwner)
  1072.         return false;
  1073.  
  1074.     int deck_idx = pOwner->DragonSoul_GetActiveDeck();
  1075.    
  1076.     if (deck_idx < 0)
  1077.         return false;
  1078.    
  1079.     if (INVENTORY_MAX_NUM + WEAR_MAX_NUM + DS_SLOT_MAX * deck_idx <= pItem->GetCell() &&
  1080.             pItem->GetCell() < INVENTORY_MAX_NUM + WEAR_MAX_NUM + DS_SLOT_MAX * (deck_idx + 1))
  1081.     {
  1082.         if (IsTimeLeftDragonSoul(pItem) && !IsActiveDragonSoul(pItem))
  1083.         {
  1084.             char buf[128];
  1085.             sprintf (buf, "LEFT TIME(%d)", LeftTime(pItem));
  1086.             LogManager::instance().ItemLog(pOwner, pItem, "DS_ACTIVATE", buf);
  1087.             pItem->ModifyPoints(true);
  1088.             pItem->SetSocket(ITEM_SOCKET_DRAGON_SOUL_ACTIVE_IDX, 1);
  1089.  
  1090.             pItem->StartTimerBasedOnWearExpireEvent();
  1091.         }
  1092.         return true;
  1093.     }
  1094.     else
  1095.         return false;
  1096. }
  1097.  
  1098. bool DSManager::DeactivateDragonSoul(LPITEM pItem, bool bSkipRefreshOwnerActiveState)
  1099. {
  1100.     if (NULL == pItem)
  1101.         return false;
  1102.  
  1103.     LPCHARACTER pOwner = pItem->GetOwner();
  1104.     if (NULL == pOwner)
  1105.         return false;
  1106.  
  1107.     if (!IsActiveDragonSoul(pItem))
  1108.         return false;
  1109.  
  1110.     char buf[128];
  1111.     pItem->StopTimerBasedOnWearExpireEvent();
  1112.     pItem->SetSocket(ITEM_SOCKET_DRAGON_SOUL_ACTIVE_IDX, 0);
  1113.     pItem->ModifyPoints(false);
  1114.  
  1115.     sprintf (buf, "LEFT TIME(%d)", LeftTime(pItem));
  1116.     LogManager::instance().ItemLog(pOwner, pItem, "DS_DEACTIVATE", buf);
  1117.  
  1118.     if (false == bSkipRefreshOwnerActiveState)
  1119.         RefreshDragonSoulState(pOwner);
  1120.  
  1121.     return true;
  1122. }
  1123.  
  1124. void DSManager::RefreshDragonSoulState(LPCHARACTER ch)
  1125. {
  1126.     if (NULL == ch)
  1127.         return ;
  1128.     for (int i = WEAR_MAX_NUM; i < WEAR_MAX_NUM + DS_SLOT_MAX * DRAGON_SOUL_DECK_MAX_NUM; i++)
  1129.     {
  1130.         LPITEM pItem = ch->GetWear(i);
  1131.         if (pItem != NULL)
  1132.         {
  1133.             if(IsActiveDragonSoul(pItem))
  1134.             {
  1135.                 return;
  1136.             }
  1137.         }
  1138.     }
  1139.     ch->DragonSoul_DeactivateAll();
  1140. }
  1141.  
  1142. DSManager::DSManager()
  1143. {
  1144.     m_pTable = NULL;
  1145. }
  1146.  
  1147. DSManager::~DSManager()
  1148. {
  1149.     if (m_pTable)
  1150.         delete m_pTable;
  1151. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top