Guest User

Untitled

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