Advertisement
Guest User

Untitled

a guest
Aug 18th, 2017
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 29.80 KB | None | 0 0
  1. acce.cpp
  2.  
  3. #define _acce_cpp_
  4. #include "stdafx.h"
  5. #include "config.h"
  6. #include "constants.h"
  7. #include "utils.h"
  8. #include "log.h"
  9. #include "char.h"
  10. #include "dev_log.h"
  11. #include "locale_service.h"
  12. #include "item.h"
  13. #include "item_manager.h"
  14. #include <stdlib.h>
  15. #include <sstream>
  16. #define RETURN_IF_ACCE_IS_NOT_OPENED(ch) if (!(ch)->IsAcceOpen()) return
  17.  
  18. extern int test_server;
  19. static std::vector<ACCE_DATA*>  s_acce_proto;
  20. static bool s_isInitializedAcceMaterialInformation = false;
  21.  
  22. enum EAcceResultCategory
  23. {
  24.     ACCE_CATEGORY_POTION,
  25.     ACCE_CATEGORY_WEAPON,
  26.     ACCE_CATEGORY_ARMOR,
  27.     ACCE_CATEGORY_ACCESSORY,
  28.     ACCE_CATEGORY_ETC,
  29. };
  30.  
  31. typedef std::vector<ACCE_VALUE> TAcceValueVector;
  32.  
  33. struct SAcceMaterialInfo
  34. {
  35.     SAcceMaterialInfo()
  36.     {
  37.         bHaveComplicateMaterial = false;
  38.     };
  39.    
  40.     ACCE_VALUE          reward;
  41.     TAcceValueVector    material;
  42.     DWORD               gold;
  43.     TAcceValueVector    complicateMaterial;
  44.    
  45.     std::string         infoText;
  46.     bool                bHaveComplicateMaterial;
  47. };
  48.  
  49. struct SItemNameAndLevel
  50. {
  51.     SItemNameAndLevel() { level = 0; }
  52.    
  53.     std::string     name;
  54.     int             level;
  55. };
  56.  
  57. typedef std::vector<SAcceMaterialInfo>                              TAcceResultList;
  58. typedef boost::unordered_map<DWORD, TAcceResultList>                TAcceMapByNPC;
  59. typedef boost::unordered_map<DWORD, std::string>                    TAcceResultInfoTextByNPC;
  60.  
  61. TAcceMapByNPC acce_info_map;
  62. TAcceResultInfoTextByNPC acce_result_info_map_by_npc;
  63.  
  64. class CAcceMaterialInfoHelper
  65. {
  66. public:
  67. public:
  68. };
  69.  
  70. static bool FN_check_item_count(LPITEM *items, DWORD item_vnum, int need_count)
  71. {
  72.     int count = 0;
  73.     for (int i=0; i<ACCE_MAX_NUM; ++i)
  74.     {
  75.         if (NULL == items[i])
  76.             continue;
  77.        
  78.         if (item_vnum==items[i]->GetVnum())
  79.         {
  80.             count += items[i]->GetCount();
  81.         }
  82.     }
  83.    
  84.     return (count>=need_count);
  85. }
  86.  
  87. static void FN_remove_material(LPITEM *items, DWORD item_vnum, int need_count, int result)
  88. {
  89.     int     count = 0;
  90.     LPITEM  item = NULL;
  91.    
  92.     item = items[1];
  93.     if (item != NULL)
  94.     {
  95.         item->SetCount(0);
  96.         items[1] = NULL;
  97.     }
  98.    
  99.     if (result == 1)
  100.     {
  101.         item = items[0];
  102.         if (item != NULL)
  103.         {
  104.             item->SetCount(0);
  105.             items[0] = NULL;
  106.         }
  107.     }
  108. }
  109.  
  110. static ACCE_DATA* FN_find_acce(LPITEM *items, WORD npc_vnum)
  111. {
  112.     DWORD   i, end_index;
  113.    
  114.     if (npc_vnum == 0)
  115.         return NULL;
  116.    
  117.     end_index = s_acce_proto.size();
  118.     for (i = 0; i < end_index; ++i)
  119.     {
  120.         if ( s_acce_proto[i]->can_make_item(items, npc_vnum) )
  121.             return s_acce_proto[i];
  122.     }
  123.    
  124.     return NULL;
  125. }
  126.  
  127. static bool FN_check_valid_npc(WORD vnum)
  128. {
  129.     for (std::vector<ACCE_DATA*>::iterator iter = s_acce_proto.begin(); iter != s_acce_proto.end(); iter++)
  130.     {
  131.         if (std::find((*iter)->npc_vnum.begin(), (*iter)->npc_vnum.end(), vnum) != (*iter)->npc_vnum.end())
  132.             return true;
  133.     }
  134.    
  135.     return false;
  136. }
  137.  
  138. static bool FN_check_acce_data(ACCE_DATA *acce_data)
  139. {
  140.     DWORD   i = 0;
  141.     DWORD   end_index = 0;
  142.    
  143.     end_index = acce_data->npc_vnum.size();
  144.     for (i=0; i<end_index; ++i)
  145.     {
  146.         if ( acce_data->npc_vnum[i] == 0 )
  147.             return false;
  148.     }
  149.    
  150.     end_index = acce_data->item.size();
  151.     for (i=0; i<end_index; ++i)
  152.     {
  153.         if ( acce_data->item[i].vnum == 0 )
  154.             return false;
  155.        
  156.         if ( acce_data->item[i].count == 0 )
  157.             return false;
  158.     }
  159.    
  160.     end_index = acce_data->reward.size();
  161.     for (i=0; i<end_index; ++i)
  162.     {
  163.         if (acce_data->reward[i].vnum == 0)
  164.             return false;
  165.        
  166.         if (acce_data->reward[i].count == 0)
  167.             return false;
  168.     }
  169.    
  170.     return true;
  171. }
  172.  
  173. ACCE_DATA::ACCE_DATA()
  174. {
  175.     this->percent = 0;
  176.     this->gold = 0;
  177.     this->abs_chance_min = 0;
  178.     this->abs_chance_max = 0;
  179. }
  180.  
  181. bool ACCE_DATA::can_make_item(LPITEM *items, WORD npc_vnum)
  182. {
  183.     DWORD   i, end_index;
  184.     DWORD   need_vnum;
  185.     int     need_count;
  186.     int     found_npc = false;
  187.    
  188.     end_index = this->npc_vnum.size();
  189.     for (i=0; i<end_index; ++i)
  190.     {
  191.         if (npc_vnum == this->npc_vnum[i])
  192.             found_npc = true;
  193.     }
  194.    
  195.     if (false == found_npc)
  196.         return false;
  197.    
  198.     end_index = this->item.size();
  199.     for (i=0; i<end_index; ++i)
  200.     {
  201.         need_vnum = this->item[i].vnum;
  202.         need_count = this->item[i].count;
  203.        
  204.         if (false == FN_check_item_count(items, need_vnum, need_count))
  205.             return false;
  206.     }
  207.    
  208.     return true;
  209. }
  210.  
  211. ACCE_VALUE* ACCE_DATA::reward_value()
  212. {
  213.     int     end_index       = 0;
  214.     DWORD   reward_index    = 0;
  215.    
  216.     end_index = this->reward.size();
  217.     reward_index = number(0, end_index);
  218.     reward_index = number(0, end_index-1);
  219.     return &this->reward[reward_index];
  220. }
  221.  
  222. void ACCE_DATA::remove_material(LPCHARACTER ch, int result)
  223. {
  224.     DWORD   i, end_index;
  225.     DWORD   need_vnum;
  226.     int     need_count;
  227.     LPITEM  *items = ch->GetAcceItem();
  228.    
  229.     end_index = this->item.size();
  230.     for (i = 0; i < ACCE_MAX_NUM; ++i)
  231.     {
  232.         need_vnum = this->item[i].vnum;
  233.         need_count = this->item[i].count;
  234.        
  235.         FN_remove_material(items, need_vnum, need_count, result);
  236.     }
  237. }
  238.  
  239. void Acce_clean_item(LPCHARACTER ch)
  240. {
  241.     LPITEM  *acce_item;
  242.    
  243.     acce_item = ch->GetAcceItem();
  244.     for (int i=0; i<ACCE_MAX_NUM; ++i)
  245.     {
  246.         if (acce_item[i] == NULL)
  247.             continue;
  248.        
  249.         //if (acce_item[i]->GetSubType() == COSTUME_ACCE)
  250.         if (acce_item[i]->GetType() == ITEM_COSTUME && acce_item[i]->GetSubType() == COSTUME_ACCE && acce_item[i]->GetType() != ITEM_WEAPON && acce_item[i]->GetType() != ITEM_ARMOR)
  251.             acce_item[i]->SetSocket(0, 0);
  252.        
  253.         acce_item[i] = NULL;
  254.     }
  255. }
  256.  
  257. void Acce_open(LPCHARACTER ch)
  258. {
  259.     if (false == s_isInitializedAcceMaterialInformation)
  260.     {
  261.         Acce_InformationInitialize();
  262.     }
  263.    
  264.     if (NULL == ch)
  265.         return;
  266.    
  267.     LPCHARACTER npc;
  268.     npc = ch->GetQuestNPC();
  269.     if (NULL == npc)
  270.     {
  271.         if (test_server)
  272.             dev_log(LOG_DEB0, "acce_npc is NULL");
  273.        
  274.         return;
  275.     }
  276.    
  277.     if (FN_check_valid_npc(npc->GetRaceNum()) == false)
  278.     {
  279.         if ( test_server == true )
  280.         {
  281.             dev_log(LOG_DEB0, "Acce not valid NPC");
  282.         }
  283.        
  284.         return;
  285.     }
  286.    
  287.     if (ch->IsAcceOpen())
  288.     {
  289.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("The Acce creation window is already opened."));
  290.         return;
  291.     }
  292.    
  293.     if ( ch->GetExchange() || ch->GetMyShop() || ch->GetShopOwner() || ch->IsOpenSafebox() || ch->IsAcceOpen() )
  294.     {
  295.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("다른 거래중(창고,교환,상점)에는 사용할 수 없습니다."));
  296.         return;
  297.     }
  298.    
  299.     long distance = DISTANCE_APPROX(ch->GetX() - npc->GetX(), ch->GetY() - npc->GetY());
  300.     if (distance >= ACCE_MAX_DISTANCE)
  301.     {
  302.         sys_log(1, "Acce: TOO_FAR: %s distance %d", ch->GetName(), distance);
  303.         return;
  304.     }
  305.    
  306.     Acce_clean_item(ch);
  307.     ch->SetAcceNpc(npc);
  308.     ch->ChatPacket(CHAT_TYPE_COMMAND, "Acce open %d", npc->GetRaceNum());
  309. }
  310.  
  311. void Acce_absorption_open(LPCHARACTER ch)
  312. {
  313.     if (false == s_isInitializedAcceMaterialInformation)
  314.     {
  315.         Acce_InformationInitialize();
  316.     }
  317.    
  318.     if (NULL == ch)
  319.         return;
  320.    
  321.     LPCHARACTER npc;
  322.     npc = ch->GetQuestNPC();
  323.     if (NULL == npc)
  324.     {
  325.         if (test_server)
  326.             dev_log(LOG_DEB0, "acce_npc is NULL");
  327.        
  328.         return;
  329.     }
  330.    
  331.     if (FN_check_valid_npc(npc->GetRaceNum()) == false)
  332.     {
  333.         if ( test_server == true )
  334.         {
  335.             dev_log(LOG_DEB0, "Acce not valid NPC");
  336.         }
  337.        
  338.         return;
  339.     }
  340.    
  341.     if (ch->IsAcceOpen())
  342.     {
  343.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("The Acce creation window is already opened."));
  344.         return;
  345.     }
  346.    
  347.     if ( ch->GetExchange() || ch->GetMyShop() || ch->GetShopOwner() || ch->IsOpenSafebox() || ch->IsAcceOpen() )
  348.     {
  349.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("다른 거래중(창고,교환,상점)에는 사용할 수 없습니다."));
  350.         return;
  351.     }
  352.    
  353.     long distance = DISTANCE_APPROX(ch->GetX() - npc->GetX(), ch->GetY() - npc->GetY());
  354.     if (distance >= ACCE_MAX_DISTANCE)
  355.     {
  356.         sys_log(1, "Acce: TOO_FAR: %s distance %d", ch->GetName(), distance);
  357.         return;
  358.     }
  359.    
  360.     Acce_clean_item(ch);
  361.     ch->SetAcceNpc(npc);
  362.     ch->ChatPacket(CHAT_TYPE_COMMAND, "Acce open_absorption %d", npc->GetRaceNum());
  363. }
  364.  
  365. void Acce_close(LPCHARACTER ch)
  366. {
  367.     RETURN_IF_ACCE_IS_NOT_OPENED(ch);
  368.     Acce_clean_item(ch);
  369.     ch->SetAcceNpc(NULL);
  370.     ch->ChatPacket(CHAT_TYPE_COMMAND, "Acce close");
  371.     dev_log(LOG_DEB0, "<Acce> close (%s)", ch->GetName());
  372. }
  373.  
  374. void Acce_init()
  375. {
  376.     ACCE_DATA * p_acce = NULL;
  377.     std::vector<ACCE_DATA*>::iterator iter;
  378.     char file_name[256+1];
  379.    
  380.     snprintf(file_name, sizeof(file_name), "%s/acce.txt", LocaleService_GetBasePath().c_str());
  381.     sys_log(0, "Acce_Init %s", file_name);
  382.     for (iter = s_acce_proto.begin(); iter!=s_acce_proto.end(); iter++)
  383.     {
  384.         p_acce = *iter;
  385.         M2_DELETE(p_acce);
  386.     }
  387.    
  388.     s_acce_proto.clear();
  389.     if (false == Acce_load(file_name))
  390.         sys_err("Acce_Init failed");
  391. }
  392.  
  393. bool Acce_load(const char *file)
  394. {
  395.     FILE    *fp;
  396.     char    one_line[256];
  397.     int     value1, value2;
  398.     const char  *delim = " \t\r\n";
  399.     char    *v, *token_string;
  400.     ACCE_DATA   *acce_data = NULL;
  401.     ACCE_VALUE  acce_value = {0, 0};
  402.    
  403.     if (0 == file || 0 == file[0])
  404.         return false;
  405.    
  406.     if ((fp = fopen(file, "r")) == 0)
  407.         return false;
  408.    
  409.     while (fgets(one_line, 256, fp))
  410.     {
  411.         value1 = value2 = 0;
  412.         if (one_line[0] == '#')
  413.             continue;
  414.        
  415.         token_string = strtok(one_line, delim);
  416.         if (NULL == token_string)
  417.             continue;
  418.        
  419.         if ((v = strtok(NULL, delim)))
  420.             str_to_number(value1, v);
  421.        
  422.         if ((v = strtok(NULL, delim)))
  423.             str_to_number(value2, v);
  424.        
  425.         TOKEN("section")
  426.         {
  427.             acce_data = M2_NEW ACCE_DATA;
  428.         }
  429.         else TOKEN("npc")
  430.         {
  431.             acce_data->npc_vnum.push_back((WORD)value1);
  432.         }
  433.         else TOKEN("item")
  434.         {
  435.             acce_value.vnum = value1;
  436.             acce_value.count = value2;
  437.             acce_data->item.push_back(acce_value);
  438.         }
  439.         else TOKEN("reward")
  440.         {
  441.             acce_value.vnum = value1;
  442.             acce_value.count = value2;
  443.             acce_data->reward.push_back(acce_value);
  444.         }
  445.         else TOKEN("abs_chance_min")
  446.         {
  447.             acce_data->abs_chance_min = value1;
  448.         }
  449.         else TOKEN("abs_chance_max")
  450.         {
  451.             acce_data->abs_chance_max = value1;
  452.         }
  453.         else TOKEN("percent")
  454.         {
  455.             acce_data->percent = value1;
  456.         }
  457.         else TOKEN("gold")
  458.         {
  459.             acce_data->gold = value1;
  460.         }
  461.         else TOKEN("end")
  462.         {
  463.             if (false == FN_check_acce_data(acce_data))
  464.             {
  465.                 dev_log(LOG_DEB0, "something wrong");
  466.                 M2_DELETE(acce_data);
  467.                 continue;
  468.             }
  469.            
  470.             s_acce_proto.push_back(acce_data);
  471.         }
  472.     }
  473.    
  474.     fclose(fp);
  475.     return true;
  476. }
  477.  
  478. static void FN_acce_print(ACCE_DATA *data, DWORD index)
  479. {
  480.     DWORD   i;
  481.     dev_log(LOG_DEB0, "--------------------------------");
  482.     dev_log(LOG_DEB0, "ACCE_DATA[%d]", index);
  483.     for (i = 0; i < data->npc_vnum.size(); ++i)
  484.     {
  485.         dev_log(LOG_DEB0, "\tNPC_VNUM[%d] = %d", i, data->npc_vnum[i]);
  486.     }
  487.     for (i = 0; i < data->item.size(); ++i)
  488.     {
  489.         dev_log(LOG_DEB0, "\tITEM[%d]   = (%d, %d)", i, data->item[i].vnum, data->item[i].count);
  490.     }
  491.     for (i = 0; i < data->reward.size(); ++i)
  492.     {
  493.         dev_log(LOG_DEB0, "\tREWARD[%d] = (%d, %d)", i, data->reward[i].vnum, data->reward[i].count);
  494.     }
  495.    
  496.     dev_log(LOG_DEB0, "\tPERCENT = %d", data->percent);
  497.     dev_log(LOG_DEB0, "--------------------------------");
  498. }
  499.  
  500. void Acce_print ()
  501. {
  502.     for (DWORD i=0; i<s_acce_proto.size(); ++i)
  503.     {
  504.         FN_acce_print(s_acce_proto[i], i);
  505.     }
  506. }
  507.  
  508. static bool FN_update_acce_status(LPCHARACTER ch)
  509. {
  510.     if (NULL == ch)
  511.         return false;
  512.    
  513.     if (!ch->IsAcceOpen())
  514.         return false;
  515.    
  516.     LPCHARACTER npc = ch->GetQuestNPC();
  517.     if (NULL == npc)
  518.         return false;
  519.    
  520.     ACCE_DATA* Acce = FN_find_acce(ch->GetAcceItem(), npc->GetRaceNum());
  521.     if (NULL == Acce)
  522.     {
  523.         ch->ChatPacket(CHAT_TYPE_COMMAND, "Acce info 0 0 0 0 0");
  524.         return false;
  525.     }
  526.    
  527.     ch->ChatPacket(CHAT_TYPE_COMMAND, "Acce info %d %d %d %d %d", Acce->gold, 0, 0, Acce->reward[0], Acce->reward[1]);
  528.     return true;
  529. }
  530.  
  531. bool Acce_make(LPCHARACTER ch)
  532. {
  533.     LPCHARACTER npc;
  534.     int         percent_number = 0;
  535.     ACCE_DATA   *acce_proto;
  536.     LPITEM  *items;
  537.     LPITEM  new_item;
  538.     int    reward_vnum = 0;
  539.    
  540.     if (!(ch)->IsAcceOpen())
  541.     {
  542.         (ch)->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Kuak oluturma penceresi a汚k de?l."));
  543.         return false;
  544.     }
  545.    
  546.     npc = ch->GetQuestNPC();
  547.     if (NULL == npc)
  548.     {
  549.         return false;
  550.     }
  551.    
  552.     items = ch->GetAcceItem();
  553.     /*if (items[0] == NULL || items[1] == NULL || items[0]->GetVnum() != items[1]->GetVnum())
  554.     {
  555.         (ch)->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Slota kusagi yerlestirin."));
  556.         return false;
  557.     }*/
  558.    
  559.     if (items[0] == NULL || items[1] == NULL || items[0]->GetValue(0) != items[1]->GetValue(0))
  560.     {
  561.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Drag the items into the window."));
  562.         return false;
  563.     }
  564.    
  565.     acce_proto = FN_find_acce(items, npc->GetRaceNum());
  566.     if (NULL == acce_proto)
  567.     {
  568.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("제조 재료가 부족합니다"));
  569.         return false;
  570.     }
  571.    
  572.     if (ch->GetGold() < acce_proto->gold)
  573.     {
  574.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("돈이 부족하거나 아이템이 제자리에 없습니다."));
  575.         return false;
  576.     }
  577.    
  578.     reward_vnum = items[0]->GetValue(1);
  579.     if (reward_vnum == 0)
  580.     {
  581.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Drag the items into the window."));
  582.         return false;
  583.     }
  584.    
  585.     ACCE_VALUE  *reward_value = acce_proto->reward_value();
  586.     if (0 < acce_proto->gold)
  587.         ch->PointChange(POINT_GOLD, -(acce_proto->gold), false);
  588.    
  589.     percent_number = number(1, 100);
  590.     if (percent_number <= acce_proto->percent)
  591.     {
  592.         acce_proto->remove_material(ch, 1);
  593.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Basarili!"));
  594.         //ch->ChatPacket(CHAT_TYPE_COMMAND, "acce success %d %d", reward_value->vnum, reward_value->count);
  595.         ch->ChatPacket(CHAT_TYPE_COMMAND, "acce success %d %d", reward_vnum, reward_value->count);
  596.         ch->EffectPacket(SE_ACCE_SUCCEDED_1);
  597.         int abs_chance = 0;
  598.         if (acce_proto->abs_chance_min < 1 || acce_proto->abs_chance_max < 1)
  599.         {
  600.             abs_chance = 1;
  601.         }
  602.         else if (acce_proto->abs_chance_min > acce_proto->abs_chance_max)
  603.         {
  604.             abs_chance = 1;
  605.         }
  606.         else if (acce_proto->abs_chance_min == acce_proto->abs_chance_max)
  607.         {
  608.             abs_chance = acce_proto->abs_chance_min;
  609.         }
  610.         else
  611.         {
  612.             abs_chance = number(acce_proto->abs_chance_min, acce_proto->abs_chance_max);
  613.         }
  614.        
  615.         /*new_item = ch->AutoGiveAcce(reward_value->vnum, reward_value->count, abs_chance);
  616.         LogManager::instance().AcceLog(ch->GetPlayerID(), ch->GetX(), ch->GetY(), reward_value->vnum, new_item->GetID(), reward_value->count, abs_chance, 1);*/
  617.         new_item = ch->AutoGiveAcce(reward_vnum, reward_value->count, abs_chance);
  618.         LogManager::instance().AcceLog(ch->GetPlayerID(), ch->GetX(), ch->GetY(), reward_vnum, new_item->GetID(), reward_value->count, abs_chance, 1);
  619.         return true;
  620.     }
  621.     else
  622.     {
  623.         acce_proto->remove_material(ch, 0);
  624.         ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Basarisiz!"));
  625.         ch->ChatPacket(CHAT_TYPE_COMMAND, "Acce fail");
  626.         //LogManager::instance().AcceLog(ch->GetPlayerID(), ch->GetX(), ch->GetY(), reward_value->vnum, 0, 0, 0, 0);
  627.         LogManager::instance().AcceLog(ch->GetPlayerID(), ch->GetX(), ch->GetY(), reward_vnum, 0, 0, 0, 0);
  628.         return false;
  629.     }
  630.    
  631.     return false;
  632. }
  633.  
  634. bool Acce_absorption_make(LPCHARACTER ch)
  635. {
  636.     LPCHARACTER npc;
  637.     LPITEM  *items;
  638.     int absorption_chance = 0;
  639.     BYTE    type1 = 0, type2 = 0, type3 = 0, type4 = 0, type5 = 0, type6 = 0, type7 = 0, type8 = 0, type9 = 0, type10 = 0, type11 = 0, type12 = 0, type13 = 0, type14 = 0, type15 = 0;
  640.     float   value1 = 0, value2 = 0, value3 = 0, value4 = 0, value5 = 0, value6 = 0, value7 = 0, value8 = 0, value9 = 0, value10 = 0, value11 = 0, value12 = 0, value13 = 0, value14 = 0, value15 = 0;
  641.    
  642.     if (!(ch)->IsAcceOpen())
  643.     {
  644.         (ch)->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Kusak olusturma penceresi ac? degil."));
  645.         return false;
  646.     }
  647.    
  648.     npc = ch->GetQuestNPC();
  649.     if (NULL == npc)
  650.     {
  651.         return false;
  652.     }
  653.    
  654.     items = ch->GetAcceItem();
  655.     if (items[0] == NULL || items[1] == NULL)
  656.     {
  657.         (ch)->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Slota kusagi yerlestirin."));
  658.         return false;
  659.     }
  660.     else if (items[1]->GetType() != ITEM_WEAPON && items[1]->GetType() != ITEM_ARMOR)
  661.     {
  662.         (ch)->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You can use a sash to absorb the bonus just from weapons or armours."));
  663.         return false;
  664.     }
  665.     else if (items[0]->GetAcceAttributeCount() > 0)
  666.     {
  667.         (ch)->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You must remove the bonus from sash before continue."));
  668.         return false;
  669.     }
  670.    
  671.     absorption_chance = items[0]->GetSocket(1);
  672.     type1 = items[1]->GetAttributeType(0);
  673.     value1 = items[1]->GetAttributeValue(0) * absorption_chance / 100;
  674.     type2 = items[1]->GetAttributeType(1);
  675.     value2 = items[1]->GetAttributeValue(1) * absorption_chance / 100;
  676.     type3 = items[1]->GetAttributeType(2);
  677.     value3 = items[1]->GetAttributeValue(2) * absorption_chance / 100;
  678.     type4 = items[1]->GetAttributeType(3);
  679.     value4 = items[1]->GetAttributeValue(3) * absorption_chance / 100;
  680.     type5 = items[1]->GetAttributeType(4);
  681.     value5 = items[1]->GetAttributeValue(4) * absorption_chance / 100;
  682.     type6 = items[1]->GetAttributeType(5);
  683.     value6 = items[1]->GetAttributeValue(5) * absorption_chance / 100;
  684.     type7 = items[1]->GetAttributeType(6);
  685.     value7 = items[1]->GetAttributeValue(6) * absorption_chance / 100;
  686.    
  687.     if (items[1]->GetType() == ITEM_ARMOR)
  688.     {
  689.         type8 = 54;
  690.         value8 = (items[1]->GetValue(1) + items[1]->GetValue(5)) * absorption_chance / 100;
  691.     }
  692.     else
  693.     {
  694.         type8 = 0;
  695.         value8 = 0;
  696.     }
  697.    
  698.     if (items[1]->GetType() == ITEM_WEAPON)
  699.     {
  700.         type9 = 53;
  701.         value9 = (items[1]->GetValue(3) + items[1]->GetValue(5)) * absorption_chance / 100;
  702.         type10 = 53;
  703.         value10 = (items[1]->GetValue(4) + items[1]->GetValue(5)) * absorption_chance / 100;
  704.         value11 = (items[1]->GetValue(1) + items[1]->GetValue(5)) * absorption_chance / 100;
  705.         value12 = (items[1]->GetValue(2) + items[1]->GetValue(5)) * absorption_chance / 100;
  706.         if (items[1]->GetValue(1) <= 0)
  707.         {
  708.             type11 = 0;
  709.             value11 = 0;
  710.         }
  711.         else
  712.         {
  713.             type11 = 55;
  714.         }
  715.        
  716.         if (items[1]->GetValue(2) <= 0)
  717.         {
  718.             type12 = 0;
  719.             value12 = 0;
  720.         }
  721.         else
  722.         {
  723.             type12 = 55;
  724.         }
  725.     }
  726.     else
  727.     {
  728.         type9 = 0;
  729.         value9 = 0;
  730.         type10 = 0;
  731.         value10 = 0;
  732.         type11 = 0;
  733.         value11 = 0;
  734.         type12 = 0;
  735.         value12 = 0;
  736.     }
  737.    
  738.     type13 = items[1]->GetNewAttributeType(0);
  739.     value13 = items[1]->GetNewAttributeValue(0) * absorption_chance / 100;
  740.     type14 = items[1]->GetNewAttributeType(1);
  741.     value14 = items[1]->GetNewAttributeValue(1) * absorption_chance / 100;
  742.     type15 = items[1]->GetNewAttributeType(2);
  743.     value15 = items[1]->GetNewAttributeValue(2) * absorption_chance / 100;
  744.    
  745.     int value1_final = (value1 <= 0) ? (int)(1) : (int)(value1);
  746.     int value2_final = (value2 <= 0) ? (int)(1) : (int)(value2);
  747.     int value3_final = (value3 <= 0) ? (int)(1) : (int)(value3);
  748.     int value4_final = (value4 <= 0) ? (int)(1) : (int)(value4);
  749.     int value5_final = (value5 <= 0) ? (int)(1) : (int)(value5);
  750.     int value6_final = (value6 <= 0) ? (int)(1) : (int)(value6);
  751.     int value7_final = (value7 <= 0) ? (int)(1) : (int)(value7);
  752.     int value8_final = (value8 <= 0) ? (int)(1) : (int)(value8);
  753.     int value9_final = (value10 - value9 <= 0) ? (int)(1) : (int)(value10 - value9);
  754.     int value10_final = (value10 <= 0) ? (int)(1) : (int)(value10);
  755.     int value11_final = (value11 - value11 <= 0) ? (int)(1) : (int)(value12 - value11);
  756.     int value12_final = (value12 <= 0) ? (int)(1) : (int)(value12);
  757.     int value13_final = (value13 <= 0) ? (int)(1) : (int)(value13);
  758.     int value14_final = (value14 <= 0) ? (int)(1) : (int)(value14);
  759.     int value15_final = (value15 <= 0) ? (int)(1) : (int)(value15);
  760.    
  761.     items[0]->SetForceAttribute(0, type1, value1_final);
  762.     items[0]->SetForceAttribute(1, type2, value2_final);
  763.     items[0]->SetForceAttribute(2, type3, value3_final);
  764.     items[0]->SetForceAttribute(3, type4, value4_final);
  765.     items[0]->SetForceAttribute(4, type5, value5_final);
  766.     items[0]->SetForceAttribute(5, type6, value6_final);
  767.     items[0]->SetForceAttribute(6, type7, value7_final);
  768.     items[0]->SetForceAttribute(7, type8, value8_final);
  769.     items[0]->SetForceAttribute(8, type9, value9_final);
  770.     items[0]->SetForceAttribute(9, type10, value10_final);
  771.     items[0]->SetForceAttribute(10, type11, value11_final);
  772.     items[0]->SetForceAttribute(11, type12, value12_final);
  773.     items[0]->SetForceAttribute(12, type13, value13_final);
  774.     items[0]->SetForceAttribute(13, type14, value14_final);
  775.     items[0]->SetForceAttribute(14, type15, value15_final);
  776.    
  777.     ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("The absorption process had success!"));
  778.     ch->ChatPacket(CHAT_TYPE_COMMAND, "acce success_absorption");
  779.    
  780.     items[1]->SetCount(0);
  781.     items[1] = NULL;
  782.     return true;
  783. }
  784.  
  785. void Acce_show_list(LPCHARACTER ch)
  786. {
  787.     LPITEM  *acce_item;
  788.     LPITEM  item;
  789.    
  790.     RETURN_IF_ACCE_IS_NOT_OPENED(ch);
  791.    
  792.     acce_item = ch->GetAcceItem();
  793.     for (int i=0; i<ACCE_MAX_NUM; ++i)
  794.     {
  795.         item = acce_item[i];
  796.         if (item == NULL)
  797.             continue;
  798.        
  799.         ch->ChatPacket(CHAT_TYPE_INFO, "Acce[%d]: inventory[%d]: %s", i, item->GetCell(), item->GetName());
  800.     }
  801. }
  802.  
  803. void Acce_add_item(LPCHARACTER ch, int acce_index, int inven_index)
  804. {
  805.     LPITEM  item;
  806.     LPITEM  *acce_item;
  807.    
  808.     RETURN_IF_ACCE_IS_NOT_OPENED(ch);
  809.    
  810.     if (inven_index < 0 || INVENTORY_MAX_NUM <= inven_index)
  811.         return;
  812.    
  813.     if (acce_index<0 || ACCE_MAX_NUM <= acce_index)
  814.         return;
  815.    
  816.     item = ch->GetInventoryItem(inven_index);
  817.     if (item == NULL)
  818.         return;
  819.    
  820.     /*if (item->GetSubType() == COSTUME_ACCE)
  821.         item->SetSocket(0, 1);*/
  822.     if (item->GetType() == ITEM_COSTUME && item->GetSubType() == COSTUME_ACCE && item->GetType() != ITEM_WEAPON && item->GetType() != ITEM_ARMOR)
  823.         item->SetSocket(0, 1);
  824.    
  825.     acce_item = ch->GetAcceItem();
  826.     for (int i=0; i<ACCE_MAX_NUM; ++i)
  827.     {
  828.         if (item==acce_item[i])
  829.         {
  830.             acce_item[i] = NULL;
  831.             break;
  832.         }
  833.     }
  834.    
  835.     acce_item[acce_index] = item;
  836.     if (acce_index == 1)
  837.     {
  838.         if (item->GetType() == ITEM_WEAPON || item->GetType() == ITEM_ARMOR)
  839.         {
  840.             ch->ChatPacket(CHAT_TYPE_COMMAND, "AcceAbsMessage");
  841.         }
  842.         else
  843.         {
  844.             ch->ChatPacket(CHAT_TYPE_COMMAND, "AcceMessage");
  845.         }
  846.     }
  847.    
  848.     if (test_server)
  849.         ch->ChatPacket(CHAT_TYPE_INFO, "Acce[%d]: inventory[%d]: %s added", acce_index, inven_index, item->GetName());
  850.    
  851.     //FN_update_acce_status(ch);
  852.     if (acce_index == 0)
  853.     {
  854.         FN_update_acce_status(ch);
  855.     }
  856.     return;
  857. }
  858.  
  859. void Acce_delete_item(LPCHARACTER ch, int acce_index)
  860. {
  861.     LPITEM  item;
  862.     LPITEM  *acce_item;
  863.    
  864.     RETURN_IF_ACCE_IS_NOT_OPENED(ch);
  865.     if (acce_index < 0 || ACCE_MAX_NUM <= acce_index)
  866.         return;
  867.    
  868.     acce_item = ch->GetAcceItem();
  869.     if (acce_item[acce_index] == NULL)
  870.         return;
  871.    
  872.     item = acce_item[acce_index];
  873.     /*if (item->GetSubType() == COSTUME_ACCE)
  874.         item->SetSocket(0, 0);*/
  875.     if (item->GetType() == ITEM_COSTUME && item->GetSubType() == COSTUME_ACCE && item->GetType() != ITEM_WEAPON && item->GetType() != ITEM_ARMOR)
  876.         item->SetSocket(0, 0);
  877.    
  878.     acce_item[acce_index] = NULL;
  879.     if (test_server)
  880.         ch->ChatPacket(CHAT_TYPE_INFO, "Acce[%d]: Acce[%d]: %s deleted", acce_index, item->GetCell(), item->GetName());
  881.    
  882.     FN_update_acce_status(ch);
  883.     return;
  884. }
  885.  
  886. SItemNameAndLevel SplitItemNameAndLevelFromHName(const std::string& name)
  887. {
  888.     int level = 0;
  889.     SItemNameAndLevel info;
  890.     info.name = name;
  891.    
  892.     size_t pos = name.find("+");
  893.     if (std::string::npos != pos)
  894.     {
  895.         const std::string levelStr = name.substr(pos + 1, name.size() - pos - 1);
  896.         str_to_number(level, levelStr.c_str());
  897.  
  898.         info.name = name.substr(0, pos);
  899.     }
  900.    
  901.     info.level = level;
  902.     return info;
  903. };
  904.  
  905. bool FIsEqualAcceValue(const ACCE_VALUE& a, const ACCE_VALUE& b)
  906. {
  907.     return (a.vnum == b.vnum) && (a.count == b.count);
  908. }
  909.  
  910. bool FIsLessAcceValue(const ACCE_VALUE& a, const ACCE_VALUE& b)
  911. {
  912.     return a.vnum < b.vnum;
  913. }
  914.  
  915. void Acce_MakeAcceInformationText()
  916. {
  917.     for (TAcceMapByNPC::iterator iter = acce_info_map.begin(); acce_info_map.end() != iter; ++iter)
  918.     {
  919.         TAcceResultList& resultList = iter->second;
  920.         for (TAcceResultList::iterator resultIter = resultList.begin(); resultList.end() != resultIter; ++resultIter)
  921.         {
  922.             SAcceMaterialInfo& materialInfo = *resultIter;
  923.             std::string& infoText = materialInfo.infoText;
  924.             if (0 < materialInfo.complicateMaterial.size())
  925.             {
  926.                 std::sort(materialInfo.complicateMaterial.begin(), materialInfo.complicateMaterial.end(), FIsLessAcceValue);
  927.                 std::sort(materialInfo.material.begin(), materialInfo.material.end(), FIsLessAcceValue);
  928.                 for (TAcceValueVector::iterator iter = materialInfo.complicateMaterial.begin(); materialInfo.complicateMaterial.end() != iter; ++iter)
  929.                 {
  930.                     for (TAcceValueVector::iterator targetIter = materialInfo.material.begin(); materialInfo.material.end() != targetIter; ++targetIter)
  931.                     {
  932.                         if (*targetIter == *iter)
  933.                         {
  934.                             targetIter = materialInfo.material.erase(targetIter);
  935.                         }
  936.                     }
  937.                 }
  938.                
  939.                 for (TAcceValueVector::iterator iter = materialInfo.complicateMaterial.begin(); materialInfo.complicateMaterial.end() != iter; ++iter)
  940.                 {
  941.                     char tempBuffer[128];
  942.                     sprintf(tempBuffer, "%d,%d|", iter->vnum, iter->count);
  943.                    
  944.                     infoText += std::string(tempBuffer);
  945.                 }
  946.                
  947.                 infoText.erase(infoText.size() - 1);
  948.                 if (0 < materialInfo.material.size())
  949.                     infoText.push_back('&');
  950.             }
  951.            
  952.             for (TAcceValueVector::iterator iter = materialInfo.material.begin(); materialInfo.material.end() != iter; ++iter)
  953.             {
  954.                 char tempBuffer[128];
  955.                 sprintf(tempBuffer, "%d,%d&", iter->vnum, iter->count);
  956.                 infoText += std::string(tempBuffer);
  957.             }
  958.            
  959.             infoText.erase(infoText.size() - 1);
  960.             if (0 < materialInfo.gold)
  961.             {
  962.                 char temp[128];
  963.                 sprintf(temp, "%d", materialInfo.gold);
  964.                 infoText += std::string("/") + temp;
  965.             }
  966.         }
  967.     }
  968. }
  969.  
  970. bool Acce_InformationInitialize()
  971. {
  972.     for (int i = 0; i < s_acce_proto.size(); ++i)
  973.     {
  974.         ACCE_DATA* acceData = s_acce_proto[i];
  975.         const std::vector<ACCE_VALUE>& rewards = acceData->reward;
  976.         if (rewards.size() != 1)
  977.         {
  978.             sys_err("[AcceInfo] WARNING! Does not support multiple rewards (count: %d)", rewards.size());          
  979.             continue;
  980.         }
  981.        
  982.         const ACCE_VALUE& reward = rewards.at(0);
  983.         const WORD& npcVNUM = acceData->npc_vnum.at(0);
  984.         bool bComplicate = false;
  985.        
  986.         TAcceMapByNPC& acceMap = acce_info_map;
  987.         TAcceResultList& resultList = acceMap[npcVNUM];
  988.         SAcceMaterialInfo materialInfo;
  989.        
  990.         materialInfo.reward = reward;
  991.         materialInfo.gold = acceData->gold;
  992.         materialInfo.material = acceData->item;
  993.        
  994.         for (TAcceResultList::iterator iter = resultList.begin(); resultList.end() != iter; ++iter)
  995.         {
  996.             SAcceMaterialInfo& existInfo = *iter;
  997.             if (reward.vnum == existInfo.reward.vnum)
  998.             {
  999.                 for (TAcceValueVector::iterator existMaterialIter = existInfo.material.begin(); existInfo.material.end() != existMaterialIter; ++existMaterialIter)
  1000.                 {
  1001.                     TItemTable* existMaterialProto = ITEM_MANAGER::Instance().GetTable(existMaterialIter->vnum);
  1002.                     if (NULL == existMaterialProto)
  1003.                     {
  1004.                         sys_err("There is no item(%u)", existMaterialIter->vnum);
  1005.                         return false;
  1006.                     }
  1007.                    
  1008.                     SItemNameAndLevel existItemInfo = SplitItemNameAndLevelFromHName(existMaterialProto->szName);
  1009.                     if (0 < existItemInfo.level)
  1010.                     {
  1011.                         for (TAcceValueVector::iterator currentMaterialIter = materialInfo.material.begin(); materialInfo.material.end() != currentMaterialIter; ++currentMaterialIter)
  1012.                         {
  1013.                             TItemTable* currentMaterialProto = ITEM_MANAGER::Instance().GetTable(currentMaterialIter->vnum);
  1014.                             SItemNameAndLevel currentItemInfo = SplitItemNameAndLevelFromHName(currentMaterialProto->szName);
  1015.                             if (currentItemInfo.name == existItemInfo.name)
  1016.                             {
  1017.                                 bComplicate = true;
  1018.                                 existInfo.complicateMaterial.push_back(*currentMaterialIter);
  1019.                                 if (std::find(existInfo.complicateMaterial.begin(), existInfo.complicateMaterial.end(), *existMaterialIter) == existInfo.complicateMaterial.end())
  1020.                                     existInfo.complicateMaterial.push_back(*existMaterialIter);
  1021.                                
  1022.                                 break;
  1023.                             }
  1024.                         }
  1025.                     }
  1026.                 }
  1027.             }
  1028.         }
  1029.        
  1030.         if (false == bComplicate)
  1031.             resultList.push_back(materialInfo);
  1032.     }
  1033.    
  1034.     Acce_MakeAcceInformationText();
  1035.     s_isInitializedAcceMaterialInformation = true;
  1036.     return true;
  1037. }
  1038.  
  1039. void Acce_request_result_list(LPCHARACTER ch)
  1040. {
  1041.     RETURN_IF_ACCE_IS_NOT_OPENED(ch);
  1042.     LPCHARACTER npc = ch->GetQuestNPC();
  1043.     if (NULL == npc)
  1044.         return;
  1045.    
  1046.     DWORD npcVNUM = npc->GetRaceNum();
  1047.     size_t resultCount = 0;
  1048.     std::string& resultText = acce_result_info_map_by_npc[npcVNUM];
  1049.     if (resultText.length() == 0)
  1050.     {
  1051.         resultText.clear();
  1052.         const TAcceResultList& resultList = acce_info_map[npcVNUM];
  1053.         for (TAcceResultList::const_iterator iter = resultList.begin(); resultList.end() != iter; ++iter)
  1054.         {
  1055.             const SAcceMaterialInfo& materialInfo = *iter;
  1056.             char temp[128];
  1057.             sprintf(temp, "%d,%d", materialInfo.reward.vnum, materialInfo.reward.count);
  1058.            
  1059.             resultText += std::string(temp) + "/";
  1060.         }
  1061.        
  1062.         resultCount = resultList.size();
  1063.         if (resultCount == 0)
  1064.         {
  1065.             return;
  1066.         }
  1067.  
  1068.         resultText.erase(resultText.size() - 1);
  1069.         if (resultCount == 0)
  1070.         {
  1071.             return;
  1072.         }
  1073.        
  1074.         if (resultText.size() - 20 >= CHAT_MAX_LEN)
  1075.         {
  1076.             sys_err("[AcceInfo] Too long Acce result list text. (NPC: %d, length: %d)", npcVNUM, resultText.size());
  1077.             resultText.clear();
  1078.             resultCount = 0;
  1079.         }
  1080.     }
  1081.    
  1082.     ch->ChatPacket(CHAT_TYPE_COMMAND, "Acce r_list %d %d %s", npcVNUM, resultCount, resultText.c_str());
  1083. }
  1084.  
  1085. void Acce_request_material_info(LPCHARACTER ch, int requestStartIndex, int requestCount)
  1086. {
  1087.     RETURN_IF_ACCE_IS_NOT_OPENED(ch);
  1088.     LPCHARACTER npc = ch->GetQuestNPC();
  1089.     if (NULL == npc)
  1090.         return;
  1091.    
  1092.     DWORD npcVNUM = npc->GetRaceNum();
  1093.     std::string materialInfoText = "";
  1094.    
  1095.     int index = 0;
  1096.     bool bCatchInfo = false;
  1097.     const TAcceResultList& resultList = acce_info_map[npcVNUM];
  1098.    
  1099.     for (TAcceResultList::const_iterator iter = resultList.begin(); resultList.end() != iter; ++iter)
  1100.     {
  1101.         const SAcceMaterialInfo& materialInfo = *iter;
  1102.         if (index++ == requestStartIndex)
  1103.         {
  1104.             bCatchInfo = true;
  1105.         }
  1106.        
  1107.         if (bCatchInfo)
  1108.         {
  1109.             materialInfoText += materialInfo.infoText + "@";    //Rubas & Black-King
  1110.         }
  1111.        
  1112.         if (index >= requestStartIndex + requestCount)
  1113.             break;
  1114.     }
  1115.    
  1116.     if (!bCatchInfo || materialInfoText.size() == 0)
  1117.     {
  1118.         sys_err("[AcceInfo] Can't find matched material info (NPC: %d, index: %d, request count: %d)", npcVNUM, requestStartIndex, requestCount);
  1119.         return;
  1120.     }
  1121.    
  1122.     materialInfoText.erase(materialInfoText.size() - 1);
  1123.     if (materialInfoText.size() - 20 >= CHAT_MAX_LEN)
  1124.     {
  1125.         sys_err("[AcceInfo] Too long material info. (NPC: %d, requestStart: %d, requestCount: %d, length: %d)", npcVNUM, requestStartIndex, requestCount, materialInfoText.size());
  1126.     }
  1127.    
  1128.     ch->ChatPacket(CHAT_TYPE_COMMAND, "Acce m_info %d %d %s", requestStartIndex, requestCount, materialInfoText.c_str());
  1129. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement