Guest User

cmd_gm

a guest
Jul 12th, 2024
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 92.69 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "utils.h"
  3. #include "config.h"
  4. #include "desc_client.h"
  5. #include "desc_manager.h"
  6. #include "char.h"
  7. #include "char_manager.h"
  8. #include "item_manager.h"
  9. #include "sectree_manager.h"
  10. #include "mob_manager.h"
  11. #include "packet.h"
  12. #include "cmd.h"
  13. #include "regen.h"
  14. #include "guild.h"
  15. #include "guild_manager.h"
  16. #include "p2p.h"
  17. #include "buffer_manager.h"
  18. #include "fishing.h"
  19. #include "mining.h"
  20. #include "questmanager.h"
  21. #include "vector.h"
  22. #include "affect.h"
  23. #include "db.h"
  24. #include "priv_manager.h"
  25. #include "building.h"
  26. #include "battle.h"
  27. #include "arena.h"
  28. #include "start_position.h"
  29. #include "party.h"
  30. #include "BattleArena.h"
  31. #include "xmas_event.h"
  32. #include "log.h"
  33. #include "unique_item.h"
  34. #include "DragonSoul.h"
  35.  
  36. extern bool DropEvent_RefineBox_SetValue(const std::string& name, int value);
  37.  
  38. // ADD_COMMAND_SLOW_STUN
  39. enum
  40. {
  41.     COMMANDAFFECT_STUN,
  42.     COMMANDAFFECT_SLOW,
  43. };
  44.  
  45. void Command_ApplyAffect(LPCHARACTER ch, const char* argument, const char* affectName, int cmdAffect)
  46. {
  47.     char arg1[256];
  48.     one_argument(argument, arg1, sizeof(arg1));
  49.  
  50.     sys_log(0, arg1);
  51.  
  52.     if (!*arg1)
  53.     {
  54.         ch->ChatPacket(CHAT_TYPE_INFO, "Usage: %s <name>", affectName);
  55.         return;
  56.     }
  57.  
  58.     LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg1);
  59.     if (!tch)
  60.     {
  61.         ch->ChatPacket(CHAT_TYPE_INFO, "%s is not in same map", arg1);
  62.         return;
  63.     }
  64.  
  65.     switch (cmdAffect)
  66.     {
  67.         case COMMANDAFFECT_STUN:
  68.             SkillAttackAffect(tch, 1000, IMMUNE_STUN, AFFECT_STUN, POINT_NONE, 0, AFF_STUN, 30, "GM_STUN");
  69.             break;
  70.         case COMMANDAFFECT_SLOW:
  71.             SkillAttackAffect(tch, 1000, IMMUNE_SLOW, AFFECT_SLOW, POINT_MOV_SPEED, -30, AFF_SLOW, 30, "GM_SLOW");
  72.             break;
  73.     }
  74.  
  75.     sys_log(0, "%s %s", arg1, affectName);
  76.  
  77.     ch->ChatPacket(CHAT_TYPE_INFO, "%s %s", arg1, affectName);
  78. }
  79.  
  80. struct DropItem
  81. {
  82.     char szName[ITEM_NAME_MAX_LEN + 1];
  83.     DWORD count;
  84. };
  85.  
  86. ACMD(do_drop)
  87. {
  88.     if (!ch || !ch->GetDesc()) { return; }
  89.     char arg1[256], arg2[256];
  90.  
  91.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  92.  
  93.     if (!*arg1 || !*arg2)
  94.     {
  95.         ch->ChatPacket(CHAT_TYPE_INFO, "Syntax: drop_simul <mob vnum> <count>");
  96.         return;
  97.     }
  98.  
  99.     DWORD vnum = 0;
  100.     str_to_number(vnum, arg1);
  101.     DWORD loopCount = 0;
  102.     str_to_number(loopCount, arg2);
  103.  
  104.     if (vnum == 0 || loopCount == 0)
  105.     {
  106.         ch->ChatPacket(CHAT_TYPE_INFO, "Syntax: drop_simul <mob vnum> <count>");
  107.         return;
  108.     }
  109.  
  110.     auto* mob = CMobManager::instance().Get(vnum);
  111.     if (!mob)
  112.     {
  113.         ch->ChatPacket(CHAT_TYPE_INFO, "Mob vnum: %u not found", vnum);
  114.         return;
  115.     }
  116.  
  117.  
  118.     std::vector<LPITEM> dropVec;
  119.     std::unordered_map<DWORD/*vnum*/, DropItem> dropMap;
  120.  
  121.     if (ITEM_MANAGER::instance().CreateMobDropVec(vnum, dropVec))
  122.     {
  123.         for (const auto& item : dropVec)
  124.         {
  125.             if (!item) { continue; }
  126.            
  127.             const auto itemVnum = item->GetVnum();
  128.             const auto itemCount = item->GetCount();
  129.            
  130.             if (itemVnum == 0 || itemCount == 0) { continue; }
  131.        
  132.             const auto& it = dropMap.find(itemVnum);
  133.             if (it != dropMap.end())
  134.             {
  135.                 it->second.count += itemCount;
  136.             }
  137.             else
  138.             {
  139.                 DropItem dropItem{};
  140.                 dropItem.count = itemCount;
  141.                 strlcpy(dropItem.szName, item->GetName(), sizeof(dropItem.szName));
  142.                 dropMap[itemVnum] = dropItem;
  143.             }
  144.  
  145.             M2_DESTROY_ITEM(item);
  146.         }
  147.  
  148.         ch->ChatPacket(CHAT_TYPE_PARTY, "############### |cFF6d8cf2|H|h(%d)x %s|h|r DROP SIMULATION ###############", loopCount, mob->m_table.szLocaleName);
  149.  
  150.         const auto& func = [&](auto& pair)
  151.         {
  152.             auto& [vnum, dropItem] = pair;
  153.             dropItem.count *= loopCount;
  154.             ch->ChatPacket(CHAT_TYPE_PARTY, "Item: %s - Count: %u", dropItem.szName, dropItem.count);
  155.         };
  156.  
  157.         std::for_each(dropMap.begin(), dropMap.end(), func);
  158.     }
  159. }
  160.  
  161. ACMD(do_stun)
  162. {
  163.     Command_ApplyAffect(ch, argument, "stun", COMMANDAFFECT_STUN);
  164. }
  165.  
  166. ACMD(do_slow)
  167. {
  168.     Command_ApplyAffect(ch, argument, "slow", COMMANDAFFECT_SLOW);
  169. }
  170.  
  171. ACMD(do_transfer)
  172. {
  173.     char arg1[256];
  174.     one_argument(argument, arg1, sizeof(arg1));
  175.  
  176.     if (!*arg1)
  177.     {
  178.         ch->ChatPacket(CHAT_TYPE_INFO, "Usage: transfer <name>");
  179.         return;
  180.     }
  181.  
  182.     LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg1);
  183.     if (!tch)
  184.     {
  185.         CCI * pkCCI = P2P_MANAGER::instance().Find(arg1);
  186.  
  187.         if (pkCCI)
  188.         {
  189.             if (pkCCI->bChannel != g_bChannel)
  190.             {
  191.                 ch->ChatPacket(CHAT_TYPE_INFO, "Target is in %d channel (my channel %d)", pkCCI->bChannel, g_bChannel);
  192.                 return;
  193.             }
  194.  
  195.             TPacketGGTransfer pgg;
  196.  
  197.             pgg.bHeader = HEADER_GG_TRANSFER;
  198.             strlcpy(pgg.szName, arg1, sizeof(pgg.szName));
  199.             pgg.lX = ch->GetX();
  200.             pgg.lY = ch->GetY();
  201.  
  202.             P2P_MANAGER::instance().Send(&pgg, sizeof(TPacketGGTransfer));
  203.             ch->ChatPacket(CHAT_TYPE_INFO, "Transfer requested.");
  204.         }
  205.         else
  206.         {
  207.             ch->ChatPacket(CHAT_TYPE_INFO, "There is no character(%s) by that name", arg1);
  208.             sys_log(0, "There is no character(%s) by that name", arg1);
  209.         }
  210.  
  211.         return;
  212.     }
  213.  
  214.     if (ch == tch)
  215.     {
  216.         ch->ChatPacket(CHAT_TYPE_INFO, "Transfer me?");
  217.         return;
  218.     }
  219.  
  220.     //tch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY(), ch->GetZ());
  221.     tch->WarpSet(ch->GetX(), ch->GetY(), ch->GetMapIndex());
  222. }
  223.  
  224. // LUA_ADD_GOTO_INFO
  225. struct GotoInfo
  226. {
  227.     std::string     st_name;
  228.  
  229.     BYTE    empire;
  230.     int     mapIndex;
  231.     DWORD   x, y;
  232.  
  233.     GotoInfo()
  234.     {
  235.         st_name     = "";
  236.         empire      = 0;
  237.         mapIndex    = 0;
  238.  
  239.         x = 0;
  240.         y = 0;
  241.     }
  242.     GotoInfo(const GotoInfo& c_src)
  243.     {
  244.         __copy__(c_src);
  245.     }
  246.     void operator = (const GotoInfo& c_src)
  247.     {
  248.         __copy__(c_src);
  249.     }
  250.     void __copy__(const GotoInfo& c_src)
  251.     {
  252.         st_name     = c_src.st_name;
  253.         empire      = c_src.empire;
  254.         mapIndex    = c_src.mapIndex;
  255.  
  256.         x = c_src.x;
  257.         y = c_src.y;
  258.     }
  259. };
  260.  
  261. static std::vector<GotoInfo> gs_vec_gotoInfo;
  262.  
  263. void CHARACTER_AddGotoInfo(const std::string& c_st_name, BYTE empire, int mapIndex, DWORD x, DWORD y)
  264. {
  265.     GotoInfo newGotoInfo;
  266.     newGotoInfo.st_name = c_st_name;
  267.     newGotoInfo.empire = empire;
  268.     newGotoInfo.mapIndex = mapIndex;
  269.     newGotoInfo.x = x;
  270.     newGotoInfo.y = y;
  271.     gs_vec_gotoInfo.push_back(newGotoInfo);
  272.  
  273.     sys_log(0, "AddGotoInfo(name=%s, empire=%d, mapIndex=%d, pos=(%d, %d))", c_st_name.c_str(), empire, mapIndex, x, y);
  274. }
  275.  
  276. bool FindInString(const char * c_pszFind, const char * c_pszIn)
  277. {
  278.     const char * c = c_pszIn;
  279.     const char * p;
  280.  
  281.     p = strchr(c, '|');
  282.  
  283.     if (!p)
  284.         return (0 == strncasecmp(c_pszFind, c_pszIn, strlen(c_pszFind)));
  285.     else
  286.     {
  287.         char sz[64 + 1];
  288.  
  289.         do
  290.         {
  291.             strlcpy(sz, c, MIN(sizeof(sz), (p - c) + 1));
  292.  
  293.             if (!strncasecmp(c_pszFind, sz, strlen(c_pszFind)))
  294.                 return true;
  295.  
  296.             c = p + 1;
  297.         } while ((p = strchr(c, '|')));
  298.  
  299.         strlcpy(sz, c, sizeof(sz));
  300.  
  301.         if (!strncasecmp(c_pszFind, sz, strlen(c_pszFind)))
  302.             return true;
  303.     }
  304.  
  305.     return false;
  306. }
  307.  
  308. bool CHARACTER_GoToName(LPCHARACTER ch, BYTE empire, int mapIndex, const char* gotoName)
  309. {
  310.     std::vector<GotoInfo>::iterator i;
  311.     for (i = gs_vec_gotoInfo.begin(); i != gs_vec_gotoInfo.end(); ++i)
  312.     {
  313.         const GotoInfo& c_eachGotoInfo = *i;
  314.  
  315.         if (mapIndex != 0)
  316.         {
  317.             if (mapIndex != c_eachGotoInfo.mapIndex)
  318.                 continue;
  319.         }
  320.         else if (!FindInString(gotoName, c_eachGotoInfo.st_name.c_str()))
  321.             continue;
  322.  
  323.         if (c_eachGotoInfo.empire == 0 || c_eachGotoInfo.empire == empire)
  324.         {
  325.             int x = c_eachGotoInfo.x * 100;
  326.             int y = c_eachGotoInfo.y * 100;
  327.  
  328.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;440;%d;%d]", x, y);
  329.             ch->WarpSet(x, y);
  330.             ch->Stop();
  331.             return true;
  332.         }
  333.     }
  334.     return false;
  335. }
  336.  
  337. // END_OF_LUA_ADD_GOTO_INFO
  338.  
  339. /*
  340.    = {
  341.    { "A1|영안읍성",     0, 1,  4693, 9642 },
  342.    { "A3|자양현",        0, 3,  3608, 8776 },
  343.  
  344.    { "B1|조안읍성",     0, 21,  557, 1579 },
  345.    { "B3|복정현",        0, 23, 1385, 2349 },
  346.  
  347.    { "C1|평무읍성",     0, 41, 9696, 2784 },
  348.    { "C3|박라현",        0, 43, 8731, 2426 },
  349.  
  350. // Snow
  351. { "Snow|서한산",     1, 61, 4342, 2906 },
  352. { "Snow|서한산",     2, 61, 3752, 1749 },
  353. { "Snow|서한산",     3, 61, 4918, 1736 },
  354.  
  355. // Flame
  356. { "Flame|도염화지|화염",  1, 62, 5994, 7563 },
  357. { "Flame|도염화지|화염",  2, 62, 5978, 6222 },
  358. { "Flame|도염화지|화염",  3, 62, 7307, 6898 },
  359.  
  360. // Desert
  361. { "Desert|영비사막|사막", 1, 63, 2178, 6272 },
  362. { "Desert|영비사막|사막", 2, 63, 2219, 5027 },
  363. { "Desert|영비사막|사막", 3, 63, 3440, 5025 },
  364.  
  365. // Threeway
  366. { "Three|승룡곡",        1, 64, 4021, 6739 },
  367. { "Three|승룡곡",        2, 64, 2704, 7399 },
  368. { "Three|승룡곡",        3, 64, 3213, 8080 },
  369.  
  370. // 밀교사원
  371. { "Milgyo|밀교사원",    1, 65, 5536, 1436 },
  372. { "Milgyo|밀교사원",    2, 65, 5536, 1436 },
  373. { "Milgyo|밀교사원",    3, 65, 5536, 1436 },
  374.  
  375. // 사귀타워입구
  376. { "사귀타워입구",     1, 65, 5905, 1108 },
  377. { "사귀타워입구",     2, 65, 5905, 1108 },
  378. { "사귀타워입구",     3, 65, 5905, 1108 },
  379.  
  380. { NULL,         0,  0,    0,    0 },
  381. };
  382.  */
  383.  
  384.  
  385. ACMD(do_goto)
  386. {
  387.     char arg1[256], arg2[256];
  388.     int x = 0, y = 0, z = 0;
  389.  
  390.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  391.  
  392.     if (!*arg1 && !*arg2)
  393.     {
  394.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;441]");
  395.         return;
  396.     }
  397.  
  398.     if (isnhdigit(*arg1) && isnhdigit(*arg2))
  399.     {
  400.         str_to_number(x, arg1);
  401.         str_to_number(y, arg2);
  402.  
  403.         PIXEL_POSITION p;
  404.  
  405.         if (SECTREE_MANAGER::instance().GetMapBasePosition(ch->GetX(), ch->GetY(), p))
  406.         {
  407.             x += p.x / 100;
  408.             y += p.y / 100;
  409.         }
  410.  
  411.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;442;%d;%d]", x, y);
  412.     }
  413.     else
  414.     {
  415.         int mapIndex = 0;
  416.         BYTE empire = 0;
  417.  
  418.         if (*arg1 == '#')
  419.             str_to_number(mapIndex,  (arg1 + 1));
  420.  
  421.         if (*arg2 && isnhdigit(*arg2))
  422.         {
  423.             str_to_number(empire, arg2);
  424.             empire = MINMAX(1, empire, 3);
  425.         }
  426.         else
  427.             empire = ch->GetEmpire();
  428.  
  429.         if (CHARACTER_GoToName(ch, empire, mapIndex, arg1))
  430.         {
  431.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;443]");
  432.             return;
  433.         }
  434.  
  435.         return;
  436.     }
  437.  
  438.     x *= 100;
  439.     y *= 100;
  440.  
  441.     ch->Show(ch->GetMapIndex(), x, y, z);
  442.     ch->Stop();
  443. }
  444.  
  445. ACMD(do_warp)
  446. {
  447.     char arg1[256], arg2[256];
  448.  
  449.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  450.  
  451.     if (!*arg1)
  452.     {
  453.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;444]");
  454.         return;
  455.     }
  456.  
  457.     int x = 0, y = 0;
  458.  
  459.     if (isnhdigit(*arg1) && isnhdigit(*arg2))
  460.     {
  461.         str_to_number(x, arg1);
  462.         str_to_number(y, arg2);
  463.     }
  464.     else
  465.     {
  466.         LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg1);
  467.  
  468.         if (NULL == tch)
  469.         {
  470.             const CCI* pkCCI = P2P_MANAGER::instance().Find(arg1);
  471.  
  472.             if (NULL != pkCCI)
  473.             {
  474.                 if (pkCCI->bChannel != g_bChannel)
  475.                 {
  476.                     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;445;%d;%d]", pkCCI->bChannel, g_bChannel);
  477.                     return;
  478.                 }
  479.  
  480.                 ch->WarpToPID( pkCCI->dwPID );
  481.             }
  482.             else
  483.             {
  484.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;446]");
  485.             }
  486.  
  487.             return;
  488.         }
  489.         else
  490.         {
  491.             x = tch->GetX() / 100;
  492.             y = tch->GetY() / 100;
  493.         }
  494.     }
  495.  
  496.     x *= 100;
  497.     y *= 100;
  498.  
  499.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;447;%d;%d]", x, y);
  500.     ch->WarpSet(x, y);
  501.     ch->Stop();
  502. }
  503.  
  504. ACMD(do_item)
  505. {
  506.     char arg1[256], arg2[256];
  507.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  508.  
  509.     if (!*arg1)
  510.     {
  511.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;448]");
  512.         return;
  513.     }
  514.  
  515.     int iCount = 1;
  516.  
  517.     if (*arg2)
  518.     {
  519.         str_to_number(iCount, arg2);
  520.         iCount = MINMAX(1, iCount, ITEM_MAX_COUNT);
  521.     }
  522.  
  523.     DWORD dwVnum;
  524.  
  525.     if (isnhdigit(*arg1))
  526.         str_to_number(dwVnum, arg1);
  527.     else
  528.     {
  529.         if (!ITEM_MANAGER::instance().GetVnum(arg1, dwVnum))
  530.         {
  531.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;449;%d]", dwVnum);
  532.             return;
  533.         }
  534.     }
  535.  
  536.     LPITEM item = ITEM_MANAGER::instance().CreateItem(dwVnum, iCount, 0, true);
  537.  
  538.     if (item)
  539.     {
  540.         if (item->IsDragonSoul())
  541.         {
  542.             int iEmptyPos = ch->GetEmptyDragonSoulInventory(item);
  543.  
  544.             if (iEmptyPos != -1)
  545.             {
  546.                 item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
  547.                 LogManager::instance().ItemLog(ch, item, "GM", item->GetName());
  548.             }
  549.             else
  550.             {
  551.                 M2_DESTROY_ITEM(item);
  552.                 if (!ch->DragonSoul_IsQualified())
  553.                 {
  554.                     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;450]");
  555.                 }
  556.                 else
  557.                     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;314]");
  558.             }
  559.         }
  560.         else
  561.         {
  562.             int iEmptyPos = ch->GetEmptyInventory(item->GetSize());
  563.  
  564.             if (iEmptyPos != -1)
  565.             {
  566.                 item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
  567.                 LogManager::instance().ItemLog(ch, item, "GM", item->GetName());
  568.             }
  569.             else
  570.             {
  571.                 M2_DESTROY_ITEM(item);
  572.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;314]");
  573.             }
  574.         }
  575.     }
  576.     else
  577.     {
  578.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;449;%d]", dwVnum);
  579.     }
  580. }
  581.  
  582. ACMD(do_group_random)
  583. {
  584.     char arg1[256];
  585.     one_argument(argument, arg1, sizeof(arg1));
  586.  
  587.     if (!*arg1)
  588.     {
  589.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;451]");
  590.         return;
  591.     }
  592.  
  593.     DWORD dwVnum = 0;
  594.     str_to_number(dwVnum, arg1);
  595.     CHARACTER_MANAGER::instance().SpawnGroupGroup(dwVnum, ch->GetMapIndex(), ch->GetX() - 500, ch->GetY() - 500, ch->GetX() + 500, ch->GetY() + 500);
  596. }
  597.  
  598. ACMD(do_group)
  599. {
  600.     char arg1[256];
  601.     one_argument(argument, arg1, sizeof(arg1));
  602.  
  603.     if (!*arg1)
  604.     {
  605.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;452]");
  606.         return;
  607.     }
  608.  
  609.     DWORD dwVnum = 0;
  610.     str_to_number(dwVnum, arg1);
  611.  
  612.     if (test_server)
  613.         sys_log(0, "COMMAND GROUP SPAWN %u at %u %u %u", dwVnum, ch->GetMapIndex(), ch->GetX(), ch->GetY());
  614.  
  615.     CHARACTER_MANAGER::instance().SpawnGroup(dwVnum, ch->GetMapIndex(), ch->GetX() - 500, ch->GetY() - 500, ch->GetX() + 500, ch->GetY() + 500);
  616. }
  617.  
  618. ACMD(do_mob_coward)
  619. {
  620.     char    arg1[256], arg2[256];
  621.     DWORD   vnum = 0;
  622.     LPCHARACTER tch;
  623.  
  624.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  625.  
  626.     if (!*arg1)
  627.     {
  628.         ch->ChatPacket(CHAT_TYPE_INFO, "Usage: mc <vnum>");
  629.         return;
  630.     }
  631.  
  632.     const CMob * pkMob;
  633.  
  634.     if (isdigit(*arg1))
  635.     {
  636.         str_to_number(vnum, arg1);
  637.  
  638.         if ((pkMob = CMobManager::instance().Get(vnum)) == NULL)
  639.             vnum = 0;
  640.     }
  641.     else
  642.     {
  643.         pkMob = CMobManager::Instance().Get(arg1, true);
  644.  
  645.         if (pkMob)
  646.             vnum = pkMob->m_table.dwVnum;
  647.     }
  648.  
  649.     if (vnum == 0)
  650.     {
  651.         ch->ChatPacket(CHAT_TYPE_INFO, "No such mob by that vnum");
  652.         return;
  653.     }
  654.  
  655.     int iCount = 0;
  656.  
  657.     if (*arg2)
  658.         str_to_number(iCount, arg2);
  659.     else
  660.         iCount = 1;
  661.  
  662.     if (iCount < 0)
  663.     {
  664.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;782]");
  665.         return;
  666.     }  
  667.  
  668.     iCount = MIN(20, iCount);
  669.  
  670.     while (iCount--)
  671.     {
  672.         tch = CHARACTER_MANAGER::instance().SpawnMobRange(vnum,
  673.                 ch->GetMapIndex(),
  674.                 ch->GetX() - number(200, 750),
  675.                 ch->GetY() - number(200, 750),
  676.                 ch->GetX() + number(200, 750),
  677.                 ch->GetY() + number(200, 750),
  678.                 true,
  679.                 pkMob->m_table.bType == CHAR_TYPE_STONE);
  680.         if (tch)
  681.             tch->SetCoward();
  682.     }
  683. }
  684.  
  685. ACMD(do_mob_map)
  686. {
  687.     char arg1[256];
  688.     one_argument(argument, arg1, sizeof(arg1));
  689.  
  690.     if (!*arg1)
  691.     {
  692.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;453]");
  693.         return;
  694.     }
  695.  
  696.     DWORD vnum = 0;
  697.     str_to_number(vnum, arg1);
  698.     LPCHARACTER tch = CHARACTER_MANAGER::instance().SpawnMobRandomPosition(vnum, ch->GetMapIndex());
  699.  
  700.     if (tch)
  701.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;454;%s;%d;%d]", tch->GetName(), tch->GetX(), tch->GetY());
  702.     else
  703.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;455]");
  704. }
  705.  
  706. ACMD(do_mob_aggresive)
  707. {
  708.     char    arg1[256], arg2[256];
  709.     DWORD   vnum = 0;
  710.     LPCHARACTER tch;
  711.  
  712.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  713.  
  714.     if (!*arg1)
  715.     {
  716.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;456]");
  717.         return;
  718.     }
  719.  
  720.     const CMob * pkMob;
  721.  
  722.     if (isdigit(*arg1))
  723.     {
  724.         str_to_number(vnum, arg1);
  725.  
  726.         if ((pkMob = CMobManager::instance().Get(vnum)) == NULL)
  727.             vnum = 0;
  728.     }
  729.     else
  730.     {
  731.         pkMob = CMobManager::Instance().Get(arg1, true);
  732.  
  733.         if (pkMob)
  734.             vnum = pkMob->m_table.dwVnum;
  735.     }
  736.  
  737.     if (vnum == 0)
  738.     {
  739.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;457]");
  740.         return;
  741.     }
  742.  
  743.     int iCount = 0;
  744.  
  745.     if (*arg2)
  746.         str_to_number(iCount, arg2);
  747.     else
  748.         iCount = 1;
  749.    
  750.     if (iCount < 0)
  751.     {
  752.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;782]");
  753.         return;
  754.     }
  755.  
  756.     iCount = MIN(20, iCount);
  757.  
  758.     while (iCount--)
  759.     {
  760.         tch = CHARACTER_MANAGER::instance().SpawnMobRange(vnum,
  761.                 ch->GetMapIndex(),
  762.                 ch->GetX() - number(200, 750),
  763.                 ch->GetY() - number(200, 750),
  764.                 ch->GetX() + number(200, 750),
  765.                 ch->GetY() + number(200, 750),
  766.                 true,
  767.                 pkMob->m_table.bType == CHAR_TYPE_STONE);
  768.         if (tch)
  769.             tch->SetAggressive();
  770.     }
  771. }
  772.  
  773. ACMD(do_mob)
  774. {
  775.     char arg1[256], arg2[256];
  776.     DWORD vnum = 0;
  777.  
  778.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  779.  
  780.     if (!*arg1)
  781.     {
  782.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;456]");
  783.         return;
  784.     }
  785.  
  786.     const CMob* pkMob = NULL;
  787.  
  788.     if (isnhdigit(*arg1))
  789.     {
  790.         str_to_number(vnum, arg1);
  791.  
  792.         if ((pkMob = CMobManager::instance().Get(vnum)) == NULL)
  793.             vnum = 0;
  794.     }
  795.     else
  796.     {
  797.         pkMob = CMobManager::Instance().Get(arg1, true);
  798.  
  799.         if (pkMob)
  800.             vnum = pkMob->m_table.dwVnum;
  801.     }
  802.  
  803.     if (vnum == 0)
  804.     {
  805.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;457]");
  806.         return;
  807.     }
  808.  
  809.     int iCount = 0;
  810.  
  811.     if (*arg2)
  812.     {
  813.         str_to_number(iCount, arg2);
  814.     }
  815.     else
  816.     {
  817.         iCount = 1;
  818.     }
  819.    
  820.     if (iCount < 0)
  821.     {
  822.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;782]");
  823.         return;
  824.     }
  825.    
  826.     if (test_server)
  827.         iCount = MIN(40, iCount);
  828.     else
  829.         iCount = MIN(20, iCount);
  830.  
  831.     while (iCount--)
  832.     {
  833.         CHARACTER_MANAGER::instance().SpawnMobRange(vnum,
  834.                 ch->GetMapIndex(),
  835.                 ch->GetX() - number(200, 750),
  836.                 ch->GetY() - number(200, 750),
  837.                 ch->GetX() + number(200, 750),
  838.                 ch->GetY() + number(200, 750),
  839.                 true,
  840.                 pkMob->m_table.bType == CHAR_TYPE_STONE);
  841.     }
  842. }
  843.  
  844. ACMD(do_mob_ld)
  845. {
  846.     char    arg1[256], arg2[256], arg3[256], arg4[256];
  847.     DWORD   vnum = 0;
  848.  
  849.     two_arguments(two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2)), arg3, sizeof(arg3), arg4, sizeof(arg4));
  850.  
  851.     if (!*arg1)
  852.     {
  853.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;456]");
  854.         return;
  855.     }
  856.  
  857.     const CMob* pkMob = NULL;
  858.  
  859.     if (isnhdigit(*arg1))
  860.     {
  861.         str_to_number(vnum, arg1);
  862.  
  863.         if ((pkMob = CMobManager::instance().Get(vnum)) == NULL)
  864.             vnum = 0;
  865.     }
  866.     else
  867.     {
  868.         pkMob = CMobManager::Instance().Get(arg1, true);
  869.  
  870.         if (pkMob)
  871.             vnum = pkMob->m_table.dwVnum;
  872.     }
  873.  
  874.     if (vnum == 0)
  875.     {
  876.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;457]");
  877.         return;
  878.     }
  879.  
  880.     int dir = 1;
  881.     long x, y;
  882.  
  883.     if (*arg2)
  884.         str_to_number(x, arg2);
  885.     if (*arg3)
  886.         str_to_number(y, arg3);
  887.     if (*arg4)
  888.         str_to_number(dir, arg4);
  889.  
  890.  
  891.     CHARACTER_MANAGER::instance().SpawnMob(vnum,
  892.         ch->GetMapIndex(),
  893.         x*100,
  894.         y*100,
  895.         ch->GetZ(),
  896.         pkMob->m_table.bType == CHAR_TYPE_STONE,
  897.         dir);
  898. }
  899.  
  900. struct FuncPurge
  901. {
  902.     LPCHARACTER m_pkGM;
  903.     bool    m_bAll;
  904.  
  905.     FuncPurge(LPCHARACTER ch) : m_pkGM(ch), m_bAll(false)
  906.     {
  907.     }
  908.  
  909.     void operator () (LPENTITY ent)
  910.     {
  911.         if (!ent->IsType(ENTITY_CHARACTER))
  912.             return;
  913.  
  914.         LPCHARACTER pkChr = (LPCHARACTER) ent;
  915.  
  916.         int iDist = DISTANCE_APPROX(pkChr->GetX() - m_pkGM->GetX(), pkChr->GetY() - m_pkGM->GetY());
  917.  
  918.         if (!m_bAll && iDist >= 1000)   // 10미터 이상에 있는 것들은 purge 하지 않는다.
  919.             return;
  920.  
  921.         sys_log(0, "PURGE: %s %d", pkChr->GetName(), iDist);
  922.  
  923.         if (pkChr->IsNPC() && !pkChr->GetRider() && !pkChr->IsPet())
  924.         {
  925.             M2_DESTROY_CHARACTER(pkChr);
  926.         }
  927.     }
  928. };
  929.  
  930. ACMD(do_purge)
  931. {
  932.     char arg1[256];
  933.     one_argument(argument, arg1, sizeof(arg1));
  934.  
  935.     FuncPurge func(ch);
  936.  
  937.     if (*arg1 && !strcmp(arg1, "all"))
  938.         func.m_bAll = true;
  939.  
  940.     LPSECTREE sectree = ch->GetSectree();
  941.     if (sectree) // #431
  942.         sectree->ForEachAround(func);
  943.     else
  944.         sys_err("PURGE_ERROR.NULL_SECTREE(mapIndex=%d, pos=(%d, %d)", ch->GetMapIndex(), ch->GetX(), ch->GetY());
  945. }
  946.  
  947. ACMD(do_item_purge)
  948. {
  949.     int         i;
  950.     LPITEM      item;
  951.  
  952.     for (i = 0; i < INVENTORY_AND_EQUIP_SLOT_MAX; ++i)
  953.     {
  954.         if ((item = ch->GetInventoryItem(i)))
  955.         {
  956.             ITEM_MANAGER::instance().RemoveItem(item, "PURGE");
  957.             ch->SyncQuickslot(QUICKSLOT_TYPE_ITEM, i, 255);
  958.         }
  959.     }  
  960.     for (i = 0; i < DRAGON_SOUL_INVENTORY_MAX_NUM; ++i)
  961.     {
  962.         if ((item = ch->GetItem(TItemPos(DRAGON_SOUL_INVENTORY, i ))))
  963.         {
  964.             ITEM_MANAGER::instance().RemoveItem(item, "PURGE");
  965.         }
  966.     }  
  967. }
  968.  
  969. ACMD(do_state)
  970. {
  971.     char arg1[256];
  972.     LPCHARACTER tch;
  973.  
  974.     one_argument(argument, arg1, sizeof(arg1));
  975.  
  976.     if (*arg1)
  977.     {
  978.         if (arg1[0] == '#')
  979.         {
  980.             tch = CHARACTER_MANAGER::instance().Find(strtoul(arg1+1, NULL, 10));
  981.         }
  982.         else
  983.         {
  984.             LPDESC d = DESC_MANAGER::instance().FindByCharacterName(arg1);
  985.  
  986.             if (!d)
  987.                 tch = NULL;
  988.             else
  989.                 tch = d->GetCharacter();
  990.         }
  991.     }
  992.     else
  993.         tch = ch;
  994.  
  995.     if (!tch)
  996.         return;
  997.  
  998.     char buf[256];
  999.  
  1000.     snprintf(buf, sizeof(buf), "%s's State: ", tch->GetName());
  1001.  
  1002.     if (tch->IsPosition(POS_FIGHTING))
  1003.         strlcat(buf, "Battle", sizeof(buf));
  1004.     else if (tch->IsPosition(POS_DEAD))
  1005.         strlcat(buf, "Dead", sizeof(buf));
  1006.     else
  1007.         strlcat(buf, "Standing", sizeof(buf));
  1008.  
  1009.     if (ch->GetShop())
  1010.         strlcat(buf, ", Shop", sizeof(buf));
  1011.  
  1012.     if (ch->GetExchange())
  1013.         strlcat(buf, ", Exchange", sizeof(buf));
  1014.  
  1015.     ch->ChatPacket(CHAT_TYPE_INFO, "%s", buf);
  1016.  
  1017.     int len;
  1018.     len = snprintf(buf, sizeof(buf), "Coordinate %ldx%ld (%ldx%ld)",
  1019.             tch->GetX(), tch->GetY(), tch->GetX() / 100, tch->GetY() / 100);
  1020.  
  1021.     if (len < 0 || len >= (int) sizeof(buf))
  1022.         len = sizeof(buf) - 1;
  1023.  
  1024.     LPSECTREE pSec = SECTREE_MANAGER::instance().Get(tch->GetMapIndex(), tch->GetX(), tch->GetY());
  1025.  
  1026.     if (pSec)
  1027.     {
  1028.         TMapSetting& map_setting = SECTREE_MANAGER::instance().GetMap(tch->GetMapIndex())->m_setting;
  1029.         snprintf(buf + len, sizeof(buf) - len, " MapIndex %ld Attribute %08X Local Position (%ld x %ld)",
  1030.             tch->GetMapIndex(), pSec->GetAttribute(tch->GetX(), tch->GetY()), (tch->GetX() - map_setting.iBaseX)/100, (tch->GetY() - map_setting.iBaseY)/100);
  1031.     }
  1032.  
  1033.     ch->ChatPacket(CHAT_TYPE_INFO, "%s", buf);
  1034.  
  1035.     ch->ChatPacket(CHAT_TYPE_INFO, "LEV %d", tch->GetLevel());
  1036.     ch->ChatPacket(CHAT_TYPE_INFO, "HP %d/%d", tch->GetHP(), tch->GetMaxHP());
  1037.     ch->ChatPacket(CHAT_TYPE_INFO, "SP %d/%d", tch->GetSP(), tch->GetMaxSP());
  1038.     ch->ChatPacket(CHAT_TYPE_INFO, "ATT %d MAGIC_ATT %d SPD %d CRIT %d%% PENE %d%% ATT_BONUS %d%%",
  1039.             tch->GetPoint(POINT_ATT_GRADE),
  1040.             tch->GetPoint(POINT_MAGIC_ATT_GRADE),
  1041.             tch->GetPoint(POINT_ATT_SPEED),
  1042.             tch->GetPoint(POINT_CRITICAL_PCT),
  1043.             tch->GetPoint(POINT_PENETRATE_PCT),
  1044.             tch->GetPoint(POINT_ATT_BONUS));
  1045.     ch->ChatPacket(CHAT_TYPE_INFO, "DEF %d MAGIC_DEF %d BLOCK %d%% DODGE %d%% DEF_BONUS %d%%",
  1046.             tch->GetPoint(POINT_DEF_GRADE),
  1047.             tch->GetPoint(POINT_MAGIC_DEF_GRADE),
  1048.             tch->GetPoint(POINT_BLOCK),
  1049.             tch->GetPoint(POINT_DODGE),
  1050.             tch->GetPoint(POINT_DEF_BONUS));
  1051.     ch->ChatPacket(CHAT_TYPE_INFO, "RESISTANCES:");
  1052.     ch->ChatPacket(CHAT_TYPE_INFO, "   WARR:%3d%% ASAS:%3d%% SURA:%3d%% SHAM:%3d%%",
  1053.             tch->GetPoint(POINT_RESIST_WARRIOR),
  1054.             tch->GetPoint(POINT_RESIST_ASSASSIN),
  1055.             tch->GetPoint(POINT_RESIST_SURA),
  1056.             tch->GetPoint(POINT_RESIST_SHAMAN));
  1057.     ch->ChatPacket(CHAT_TYPE_INFO, "   SWORD:%3d%% THSWORD:%3d%% DAGGER:%3d%% BELL:%3d%% FAN:%3d%% BOW:%3d%%",
  1058.             tch->GetPoint(POINT_RESIST_SWORD),
  1059.             tch->GetPoint(POINT_RESIST_TWOHAND),
  1060.             tch->GetPoint(POINT_RESIST_DAGGER),
  1061.             tch->GetPoint(POINT_RESIST_BELL),
  1062.             tch->GetPoint(POINT_RESIST_FAN),
  1063.             tch->GetPoint(POINT_RESIST_BOW));
  1064.     ch->ChatPacket(CHAT_TYPE_INFO, "   FIRE:%3d%% ELEC:%3d%% MAGIC:%3d%% WIND:%3d%% CRIT:%3d%% PENE:%3d%%",
  1065.             tch->GetPoint(POINT_RESIST_FIRE),
  1066.             tch->GetPoint(POINT_RESIST_ELEC),
  1067.             tch->GetPoint(POINT_RESIST_MAGIC),
  1068.             tch->GetPoint(POINT_RESIST_WIND),
  1069.             tch->GetPoint(POINT_RESIST_CRITICAL),
  1070.             tch->GetPoint(POINT_RESIST_PENETRATE));
  1071.     ch->ChatPacket(CHAT_TYPE_INFO, "   ICE:%3d%% EARTH:%3d%% DARK:%3d%%",
  1072.             tch->GetPoint(POINT_RESIST_ICE),
  1073.             tch->GetPoint(POINT_RESIST_EARTH),
  1074.             tch->GetPoint(POINT_RESIST_DARK));
  1075.  
  1076.     ch->ChatPacket(CHAT_TYPE_INFO, "MALL:");
  1077.     ch->ChatPacket(CHAT_TYPE_INFO, "   ATT:%3d%% DEF:%3d%% EXP:%3d%% ITEMx%d GOLDx%d",
  1078.             tch->GetPoint(POINT_MALL_ATTBONUS),
  1079.             tch->GetPoint(POINT_MALL_DEFBONUS),
  1080.             tch->GetPoint(POINT_MALL_EXPBONUS),
  1081.             tch->GetPoint(POINT_MALL_ITEMBONUS) / 10,
  1082.             tch->GetPoint(POINT_MALL_GOLDBONUS) / 10);
  1083.  
  1084.     ch->ChatPacket(CHAT_TYPE_INFO, "BONUS:");
  1085.     ch->ChatPacket(CHAT_TYPE_INFO, "   SKILL:%3d%% NORMAL:%3d%% SKILL_DEF:%3d%% NORMAL_DEF:%3d%%",
  1086.             tch->GetPoint(POINT_SKILL_DAMAGE_BONUS),
  1087.             tch->GetPoint(POINT_NORMAL_HIT_DAMAGE_BONUS),
  1088.             tch->GetPoint(POINT_SKILL_DEFEND_BONUS),
  1089.             tch->GetPoint(POINT_NORMAL_HIT_DEFEND_BONUS));
  1090.  
  1091.     ch->ChatPacket(CHAT_TYPE_INFO, "   HUMAN:%3d%% ANIMAL:%3d%% ORC:%3d%% MILGYO:%3d%% UNDEAD:%3d%%",
  1092.             tch->GetPoint(POINT_ATTBONUS_HUMAN),
  1093.             tch->GetPoint(POINT_ATTBONUS_ANIMAL),
  1094.             tch->GetPoint(POINT_ATTBONUS_ORC),
  1095.             tch->GetPoint(POINT_ATTBONUS_MILGYO),
  1096.             tch->GetPoint(POINT_ATTBONUS_UNDEAD));
  1097.  
  1098.     ch->ChatPacket(CHAT_TYPE_INFO, "   DEVIL:%3d%% INSECT:%3d%% FIRE:%3d%% ICE:%3d%% DESERT:%3d%%",
  1099.             tch->GetPoint(POINT_ATTBONUS_DEVIL),
  1100.             tch->GetPoint(POINT_ATTBONUS_INSECT),
  1101.             tch->GetPoint(POINT_ATTBONUS_FIRE),
  1102.             tch->GetPoint(POINT_ATTBONUS_ICE),
  1103.             tch->GetPoint(POINT_ATTBONUS_DESERT));
  1104.  
  1105.     ch->ChatPacket(CHAT_TYPE_INFO, "   TREE:%3d%% MONSTER:%3d%%",
  1106.             tch->GetPoint(POINT_ATTBONUS_TREE),
  1107.             tch->GetPoint(POINT_ATTBONUS_MONSTER));
  1108.  
  1109.     ch->ChatPacket(CHAT_TYPE_INFO, "   WARR:%3d%% ASAS:%3d%% SURA:%3d%% SHAM:%3d%%",
  1110.             tch->GetPoint(POINT_ATTBONUS_WARRIOR),
  1111.             tch->GetPoint(POINT_ATTBONUS_ASSASSIN),
  1112.             tch->GetPoint(POINT_ATTBONUS_SURA),
  1113.             tch->GetPoint(POINT_ATTBONUS_SHAMAN));
  1114.  
  1115.     for (int i = 0; i < MAX_PRIV_NUM; ++i)
  1116.         if (CPrivManager::instance().GetPriv(tch, i))
  1117.         {
  1118.             int iByEmpire = CPrivManager::instance().GetPrivByEmpire(tch->GetEmpire(), i);
  1119.             int iByGuild = 0;
  1120.  
  1121.             if (tch->GetGuild())
  1122.                 iByGuild = CPrivManager::instance().GetPrivByGuild(tch->GetGuild()->GetID(), i);
  1123.  
  1124.             int iByPlayer = CPrivManager::instance().GetPrivByCharacter(tch->GetPlayerID(), i);
  1125.  
  1126.             if (iByEmpire)
  1127.                 ch->ChatPacket(CHAT_TYPE_INFO, "%s for empire : %d", LC_TEXT(c_apszPrivNames[i]), iByEmpire);
  1128.  
  1129.             if (iByGuild)
  1130.                 ch->ChatPacket(CHAT_TYPE_INFO, "%s for guild : %d", LC_TEXT(c_apszPrivNames[i]), iByGuild);
  1131.  
  1132.             if (iByPlayer)
  1133.                 ch->ChatPacket(CHAT_TYPE_INFO, "%s for player : %d", LC_TEXT(c_apszPrivNames[i]), iByPlayer);
  1134.         }
  1135. }
  1136.  
  1137. struct notice_packet_func
  1138. {
  1139.     const char * m_str;
  1140.  
  1141.     notice_packet_func(const char * str) : m_str(str)
  1142.     {
  1143.     }
  1144.  
  1145.     void operator () (LPDESC d)
  1146.     {
  1147.         if (!d->GetCharacter())
  1148.             return;
  1149.  
  1150.         d->GetCharacter()->ChatPacket(CHAT_TYPE_NOTICE, "%s", m_str);
  1151.     }
  1152. };
  1153.  
  1154. void SendNotice(const char * c_pszBuf)
  1155. {
  1156.     const DESC_MANAGER::DESC_SET & c_ref_set = DESC_MANAGER::instance().GetClientSet();
  1157.     std::for_each(c_ref_set.begin(), c_ref_set.end(), notice_packet_func(c_pszBuf));
  1158. }
  1159.  
  1160. struct notice_map_packet_func
  1161. {
  1162.     const char* m_str;
  1163.     int m_mapIndex;
  1164.     bool m_bBigFont;
  1165.  
  1166.     notice_map_packet_func(const char* str, int idx, bool bBigFont) : m_str(str), m_mapIndex(idx), m_bBigFont(bBigFont)
  1167.     {
  1168.     }
  1169.  
  1170.     void operator() (LPDESC d)
  1171.     {
  1172.         if (d->GetCharacter() == NULL) return;
  1173.         if (d->GetCharacter()->GetMapIndex() != m_mapIndex) return;
  1174.  
  1175.         d->GetCharacter()->ChatPacket(m_bBigFont == true ? CHAT_TYPE_BIG_NOTICE : CHAT_TYPE_NOTICE, "%s", m_str);
  1176.     }
  1177. };
  1178.  
  1179. void SendNoticeMap(const char* c_pszBuf, int nMapIndex, bool bBigFont)
  1180. {
  1181.     const DESC_MANAGER::DESC_SET & c_ref_set = DESC_MANAGER::instance().GetClientSet();
  1182.     std::for_each(c_ref_set.begin(), c_ref_set.end(), notice_map_packet_func(c_pszBuf, nMapIndex, bBigFont));
  1183. }
  1184.  
  1185. struct log_packet_func
  1186. {
  1187.     const char * m_str;
  1188.  
  1189.     log_packet_func(const char * str) : m_str(str)
  1190.     {
  1191.     }
  1192.  
  1193.     void operator () (LPDESC d)
  1194.     {
  1195.         if (!d->GetCharacter())
  1196.             return;
  1197.  
  1198.         if (d->GetCharacter()->GetGMLevel() > GM_PLAYER)
  1199.             d->GetCharacter()->ChatPacket(CHAT_TYPE_NOTICE, "%s", m_str);
  1200.     }
  1201. };
  1202.  
  1203.  
  1204. void SendLog(const char * c_pszBuf)
  1205. {
  1206.     const DESC_MANAGER::DESC_SET & c_ref_set = DESC_MANAGER::instance().GetClientSet();
  1207.     std::for_each(c_ref_set.begin(), c_ref_set.end(), log_packet_func(c_pszBuf));
  1208. }
  1209.  
  1210. void BroadcastNotice(const char * c_pszBuf)
  1211. {
  1212.     TPacketGGNotice p;
  1213.     p.bHeader = HEADER_GG_NOTICE;
  1214.     p.lSize = strlen(c_pszBuf) + 1;
  1215.  
  1216.     TEMP_BUFFER buf;
  1217.     buf.write(&p, sizeof(p));
  1218.     buf.write(c_pszBuf, p.lSize);
  1219.  
  1220.     P2P_MANAGER::instance().Send(buf.read_peek(), buf.size()); // HEADER_GG_NOTICE
  1221.  
  1222.     SendNotice(c_pszBuf);
  1223. }
  1224.  
  1225. ACMD(do_notice)
  1226. {
  1227.     BroadcastNotice(argument);
  1228. }
  1229.  
  1230. ACMD(do_map_notice)
  1231. {
  1232.     SendNoticeMap(argument, ch->GetMapIndex(), false);
  1233. }
  1234.  
  1235. ACMD(do_big_notice)
  1236. {
  1237.     ch->ChatPacket(CHAT_TYPE_BIG_NOTICE, "%s", argument);
  1238. }
  1239.  
  1240. ACMD(do_who)
  1241. {
  1242.     int iTotal;
  1243.     int * paiEmpireUserCount;
  1244.     int iLocal;
  1245.  
  1246.     DESC_MANAGER::instance().GetUserCount(iTotal, &paiEmpireUserCount, iLocal);
  1247.  
  1248.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;458;%d;%d;%d;%d;%d]",
  1249.             iTotal, paiEmpireUserCount[1], paiEmpireUserCount[2], paiEmpireUserCount[3], iLocal);
  1250. }
  1251.  
  1252. class user_func
  1253. {
  1254.     public:
  1255.         LPCHARACTER m_ch;
  1256.         static int count;
  1257.         static char str[128];
  1258.         static int str_len;
  1259.  
  1260.         user_func()
  1261.             : m_ch(NULL)
  1262.         {}
  1263.  
  1264.         void initialize(LPCHARACTER ch)
  1265.         {
  1266.             m_ch = ch;
  1267.             str_len = 0;
  1268.             count = 0;
  1269.             str[0] = '\0';
  1270.         }
  1271.  
  1272.         void operator () (LPDESC d)
  1273.         {
  1274.             if (!d->GetCharacter())
  1275.                 return;
  1276.  
  1277.             int len = snprintf(str + str_len, sizeof(str) - str_len, "%-16s ", d->GetCharacter()->GetName());
  1278.  
  1279.             if (len < 0 || len >= (int) sizeof(str) - str_len)
  1280.                 len = (sizeof(str) - str_len) - 1;
  1281.  
  1282.             str_len += len;
  1283.             ++count;
  1284.  
  1285.             if (!(count % 4))
  1286.             {
  1287.                 m_ch->ChatPacket(CHAT_TYPE_INFO, str);
  1288.  
  1289.                 str[0] = '\0';
  1290.                 str_len = 0;
  1291.             }
  1292.         }
  1293. };
  1294.  
  1295. int user_func::count = 0;
  1296. char user_func::str[128] = { 0, };
  1297. int user_func::str_len = 0;
  1298.  
  1299. ACMD(do_user)
  1300. {
  1301.     const DESC_MANAGER::DESC_SET & c_ref_set = DESC_MANAGER::instance().GetClientSet();
  1302.     user_func func;
  1303.  
  1304.     func.initialize(ch);
  1305.     std::for_each(c_ref_set.begin(), c_ref_set.end(), func);
  1306.  
  1307.     if (func.count % 4)
  1308.         ch->ChatPacket(CHAT_TYPE_INFO, func.str);
  1309.  
  1310.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;459;%d]", func.count);
  1311. }
  1312.  
  1313. ACMD(do_disconnect)
  1314. {
  1315.     char arg1[256];
  1316.     one_argument(argument, arg1, sizeof(arg1));
  1317.  
  1318.     if (!*arg1)
  1319.     {
  1320.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;460]");
  1321.         return;
  1322.     }
  1323.  
  1324.     LPDESC d = DESC_MANAGER::instance().FindByCharacterName(arg1);
  1325.     LPCHARACTER tch = d ? d->GetCharacter() : NULL;
  1326.  
  1327.     if (!tch)
  1328.     {
  1329.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;461;%s]", arg1);
  1330.         return;
  1331.     }
  1332.  
  1333.     if (tch == ch)
  1334.     {
  1335.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;462]");
  1336.         return;
  1337.     }
  1338.    
  1339.     DESC_MANAGER::instance().DestroyDesc(d);
  1340. }
  1341.  
  1342. ACMD(do_kill)
  1343. {
  1344.     char arg1[256];
  1345.     one_argument(argument, arg1, sizeof(arg1));
  1346.  
  1347.     if (!*arg1)
  1348.     {
  1349.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;463]");
  1350.         return;
  1351.     }
  1352.  
  1353.     LPDESC  d = DESC_MANAGER::instance().FindByCharacterName(arg1);
  1354.     LPCHARACTER tch = d ? d->GetCharacter() : NULL;
  1355.  
  1356.     if (!tch)
  1357.     {
  1358.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;461;%s]", arg1);
  1359.         return;
  1360.     }
  1361.  
  1362.     tch->Dead();
  1363. }
  1364.  
  1365. #define MISC    0
  1366. #define BINARY  1
  1367. #define NUMBER  2
  1368.  
  1369. const struct set_struct
  1370. {
  1371.     const char *cmd;
  1372.     const char type;
  1373. } set_fields[] = {
  1374.     { "gold",       NUMBER  },
  1375.     { "race",       BINARY  },
  1376.     { "sex",        BINARY  },
  1377.     { "exp",        NUMBER  },
  1378.     { "max_hp",     NUMBER  },
  1379.     { "max_sp",     NUMBER  },
  1380.     { "skill",      NUMBER  },
  1381.     { "alignment",  NUMBER  },
  1382.     { "align",      NUMBER  },
  1383.     { "\n",     MISC    }
  1384. };
  1385.  
  1386. ACMD(do_set)
  1387. {
  1388.     char arg1[256], arg2[256], arg3[256];
  1389.  
  1390.     LPCHARACTER tch = NULL;
  1391.  
  1392.     int i, len;
  1393.     const char* line;
  1394.  
  1395.     line = two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  1396.     one_argument(line, arg3, sizeof(arg3));
  1397.  
  1398.     if (!*arg1 || !*arg2 || !*arg3)
  1399.     {
  1400.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;464]");
  1401.         return;
  1402.     }
  1403.  
  1404.     tch = CHARACTER_MANAGER::instance().FindPC(arg1);
  1405.  
  1406.     if (!tch)
  1407.     {
  1408.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;465;%s]", arg1);
  1409.         return;
  1410.     }
  1411.  
  1412.     len = strlen(arg2);
  1413.  
  1414.     for (i = 0; *(set_fields[i].cmd) != '\n'; i++)
  1415.         if (!strncmp(arg2, set_fields[i].cmd, len))
  1416.             break;
  1417.  
  1418.     switch (i)
  1419.     {
  1420.         case 0: // gold
  1421.             {
  1422.                 int gold = 0;
  1423.                 str_to_number(gold, arg3);
  1424.                 DBManager::instance().SendMoneyLog(MONEY_LOG_MISC, 3, gold);
  1425.                 int before_gold = tch->GetGold();
  1426.                 tch->PointChange(POINT_GOLD, gold, true);
  1427.                 int after_gold = tch->GetGold();
  1428.                 if (0 == after_gold && 0 != before_gold)
  1429.                 {
  1430.                     LogManager::instance().CharLog(tch, gold, "ZERO_GOLD", "GM");
  1431.                 }
  1432.             }
  1433.             break;
  1434.  
  1435.         case 1: // race
  1436.             break;
  1437.  
  1438.         case 2: // sex
  1439.             break;
  1440.  
  1441.         case 3: // exp
  1442.             {
  1443.                 int amount = 0;
  1444.                 str_to_number(amount, arg3);
  1445.                 tch->PointChange(POINT_EXP, amount, true);
  1446.             }
  1447.             break;
  1448.  
  1449.         case 4: // max_hp
  1450.             {
  1451.                 int amount = 0;
  1452.                 str_to_number(amount, arg3);
  1453.                 tch->PointChange(POINT_MAX_HP, amount, true);
  1454.             }
  1455.             break;
  1456.  
  1457.         case 5: // max_sp
  1458.             {
  1459.                 int amount = 0;
  1460.                 str_to_number(amount, arg3);
  1461.                 tch->PointChange(POINT_MAX_SP, amount, true);
  1462.             }
  1463.             break;
  1464.  
  1465.         case 6: // active skill point
  1466.             {
  1467.                 int amount = 0;
  1468.                 str_to_number(amount, arg3);
  1469.                 tch->PointChange(POINT_SKILL, amount, true);
  1470.             }
  1471.             break;
  1472.  
  1473.         case 7: // alignment
  1474.         case 8: // alignment
  1475.         {
  1476.             int amount = 0;
  1477.             str_to_number(amount, arg3);
  1478.             tch->UpdateAlignment(amount);
  1479.         }
  1480.         break;
  1481.     }
  1482.  
  1483.     if (set_fields[i].type == NUMBER)
  1484.     {
  1485.         int amount = 0;
  1486.         str_to_number(amount, arg3);
  1487.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;466;%s;%s;%d]", tch->GetName(), set_fields[i].cmd, amount);
  1488.     }
  1489. }
  1490.  
  1491. ACMD(do_reset)
  1492. {
  1493.     ch->PointChange(POINT_HP, ch->GetMaxHP() - ch->GetHP());
  1494.     ch->PointChange(POINT_SP, ch->GetMaxSP() - ch->GetSP());
  1495.     ch->Save();
  1496. }
  1497.  
  1498. ACMD(do_advance)
  1499. {
  1500.     char arg1[256], arg2[256];
  1501.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  1502.  
  1503.     if (!*arg1 || !*arg2)
  1504.     {
  1505.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;467]");
  1506.         return;
  1507.     }
  1508.  
  1509.     LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg1);
  1510.  
  1511.     if (!tch)
  1512.     {
  1513.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;465;%s]", arg1);
  1514.         return;
  1515.     }
  1516.  
  1517.     int level = 0;
  1518.     str_to_number(level, arg2);
  1519.  
  1520.     tch->ResetPoint(MINMAX(0, level, PLAYER_MAX_LEVEL_CONST));
  1521. }
  1522.  
  1523. ACMD(do_respawn)
  1524. {
  1525.     char arg1[256];
  1526.     one_argument(argument, arg1, sizeof(arg1));
  1527.  
  1528.     if (*arg1 && !strcasecmp(arg1, "all"))
  1529.     {
  1530.         ch->ChatPacket(CHAT_TYPE_INFO, "Respaw everywhere");
  1531.         regen_reset(0, 0);
  1532.     }
  1533.     else
  1534.     {
  1535.         ch->ChatPacket(CHAT_TYPE_INFO, "Respaw around");
  1536.         regen_reset(ch->GetX(), ch->GetY());
  1537.     }
  1538. }
  1539.  
  1540. ACMD(do_safebox_size)
  1541. {
  1542.  
  1543.     char arg1[256];
  1544.     one_argument(argument, arg1, sizeof(arg1));
  1545.  
  1546.     int size = 0;
  1547.  
  1548.     if (*arg1)
  1549.         str_to_number(size, arg1);
  1550.  
  1551.     if (size > 3 || size < 0)
  1552.         size = 0;
  1553.  
  1554.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;468;%d]", size);
  1555.     ch->ChangeSafeboxSize(size);
  1556. }
  1557.  
  1558. ACMD(do_makeguild)
  1559. {
  1560.     if (ch->GetGuild())
  1561.         return;
  1562.  
  1563.     CGuildManager& gm = CGuildManager::instance();
  1564.  
  1565.     char arg1[256];
  1566.     one_argument(argument, arg1, sizeof(arg1));
  1567.  
  1568.     TGuildCreateParameter cp;
  1569.     memset(&cp, 0, sizeof(cp));
  1570.  
  1571.     cp.master = ch;
  1572.     strlcpy(cp.name, arg1, sizeof(cp.name));
  1573.  
  1574.     if (!check_name(cp.name))
  1575.     {
  1576.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;89]");
  1577.         return;
  1578.     }
  1579.  
  1580.     gm.CreateGuild(cp);
  1581.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;469;%s]", cp.name);
  1582. }
  1583.  
  1584. ACMD(do_deleteguild)
  1585. {
  1586.     if (ch->GetGuild())
  1587.         ch->GetGuild()->RequestDisband(ch->GetPlayerID());
  1588. }
  1589.  
  1590. ACMD(do_greset)
  1591. {
  1592.     if (ch->GetGuild())
  1593.         ch->GetGuild()->Reset();
  1594. }
  1595.  
  1596. // REFINE_ROD_HACK_BUG_FIX
  1597. ACMD(do_refine_rod)
  1598. {
  1599.     char arg1[256];
  1600.     one_argument(argument, arg1, sizeof(arg1));
  1601.  
  1602.     BYTE cell = 0;
  1603.     str_to_number(cell, arg1);
  1604.     LPITEM item = ch->GetInventoryItem(cell);
  1605.     if (item)
  1606.         fishing::RealRefineRod(ch, item);
  1607. }
  1608. // END_OF_REFINE_ROD_HACK_BUG_FIX
  1609.  
  1610. // REFINE_PICK
  1611. ACMD(do_refine_pick)
  1612. {
  1613.     char arg1[256];
  1614.     one_argument(argument, arg1, sizeof(arg1));
  1615.  
  1616.     BYTE cell = 0;
  1617.     str_to_number(cell, arg1);
  1618.     LPITEM item = ch->GetInventoryItem(cell);
  1619.     if (item)
  1620.     {
  1621.         mining::CHEAT_MAX_PICK(ch, item);
  1622.         mining::RealRefinePick(ch, item);
  1623.     }
  1624. }
  1625.  
  1626. ACMD(do_max_pick)
  1627. {
  1628.     char arg1[256];
  1629.     one_argument(argument, arg1, sizeof(arg1));
  1630.  
  1631.     BYTE cell = 0;
  1632.     str_to_number(cell, arg1);
  1633.     LPITEM item = ch->GetInventoryItem(cell);
  1634.     if (item)
  1635.     {
  1636.         mining::CHEAT_MAX_PICK(ch, item);
  1637.     }
  1638. }
  1639. // END_OF_REFINE_PICK
  1640.  
  1641.  
  1642. ACMD(do_fishing_simul)
  1643. {
  1644.     char arg1[256];
  1645.     char arg2[256];
  1646.     char arg3[256];
  1647.     argument = one_argument(argument, arg1, sizeof(arg1));
  1648.     two_arguments(argument, arg2, sizeof(arg2), arg3, sizeof(arg3));
  1649.  
  1650.     int count = 1000;
  1651.     int prob_idx = 0;
  1652.     int level = 100;
  1653.  
  1654.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;470]");
  1655.  
  1656.     if (*arg1)
  1657.         str_to_number(level, arg1);
  1658.  
  1659.     if (*arg2)
  1660.         str_to_number(prob_idx, arg2);
  1661.  
  1662.     if (*arg3)
  1663.         str_to_number(count, arg3);
  1664.  
  1665.     fishing::Simulation(level, count, prob_idx, ch);
  1666. }
  1667.  
  1668. ACMD(do_invisibility)
  1669. {
  1670.     if (ch->IsAffectFlag(AFF_INVISIBILITY))
  1671.     {
  1672.         ch->RemoveAffect(AFFECT_INVISIBILITY);
  1673.     }
  1674.     else
  1675.     {
  1676.         ch->AddAffect(AFFECT_INVISIBILITY, POINT_NONE, 0, AFF_INVISIBILITY, INFINITE_AFFECT_DURATION, 0, true);
  1677.         ch->ForgetMyAttacker(false);
  1678.     }
  1679. }
  1680.  
  1681. ACMD(do_event_flag)
  1682. {
  1683.     char arg1[256];
  1684.     char arg2[256];
  1685.  
  1686.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  1687.  
  1688.     if (!(*arg1) || !(*arg2))
  1689.         return;
  1690.  
  1691.     int value = 0;
  1692.     str_to_number(value, arg2);
  1693.  
  1694.     if (!strcmp(arg1, "mob_item") ||
  1695.             !strcmp(arg1, "mob_exp") ||
  1696.             !strcmp(arg1, "mob_gold") ||
  1697.             !strcmp(arg1, "mob_dam") ||
  1698.             !strcmp(arg1, "mob_gold_pct") ||
  1699.             !strcmp(arg1, "mob_item_buyer") ||
  1700.             !strcmp(arg1, "mob_exp_buyer") ||
  1701.             !strcmp(arg1, "mob_gold_buyer") ||
  1702.             !strcmp(arg1, "mob_gold_pct_buyer")
  1703.        )
  1704.         value = MINMAX(0, value, 1000);
  1705.  
  1706.     //quest::CQuestManager::instance().SetEventFlag(arg1, atoi(arg2));
  1707.     quest::CQuestManager::instance().RequestSetEventFlag(arg1, value);
  1708.     ch->ChatPacket(CHAT_TYPE_INFO, "RequestSetEventFlag %s %d", arg1, value);
  1709.     sys_log(0, "RequestSetEventFlag %s %d", arg1, value);
  1710. }
  1711.  
  1712. ACMD(do_get_event_flag)
  1713. {
  1714.     quest::CQuestManager::instance().SendEventFlagList(ch);
  1715. }
  1716.  
  1717. ACMD(do_private)
  1718. {
  1719.     char arg1[256];
  1720.     one_argument(argument, arg1, sizeof(arg1));
  1721.  
  1722.     if (!*arg1)
  1723.     {
  1724.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;471]");
  1725.         return;
  1726.     }
  1727.  
  1728.     long lMapIndex;
  1729.     long map_index = 0;
  1730.     str_to_number(map_index, arg1);
  1731.     if ((lMapIndex = SECTREE_MANAGER::instance().CreatePrivateMap(map_index)))
  1732.     {
  1733.         ch->SaveExitLocation();
  1734.  
  1735.         LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(lMapIndex);
  1736.         ch->WarpSet(pkSectreeMap->m_setting.posSpawn.x, pkSectreeMap->m_setting.posSpawn.y, lMapIndex);
  1737.     }
  1738.     else
  1739.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;472;%d]", map_index);
  1740. }
  1741.  
  1742. ACMD(do_qf)
  1743. {
  1744.     char arg1[256];
  1745.  
  1746.     one_argument(argument, arg1, sizeof(arg1));
  1747.  
  1748.     if (!*arg1)
  1749.         return;
  1750.  
  1751.     quest::PC* pPC = quest::CQuestManager::instance().GetPCForce(ch->GetPlayerID());
  1752.     std::string questname = pPC->GetCurrentQuestName();
  1753.  
  1754.     if (!questname.empty())
  1755.     {
  1756.         int value = quest::CQuestManager::Instance().GetQuestStateIndex(questname, arg1);
  1757.  
  1758.         pPC->SetFlag(questname + ".__status", value);
  1759.         pPC->ClearTimer();
  1760.  
  1761.         quest::PC::QuestInfoIterator it = pPC->quest_begin();
  1762.         unsigned int questindex = quest::CQuestManager::instance().GetQuestIndexByName(questname);
  1763.  
  1764.         while (it!= pPC->quest_end())
  1765.         {
  1766.             if (it->first == questindex)
  1767.             {
  1768.                 it->second.st = value;
  1769.                 break;
  1770.             }
  1771.  
  1772.             ++it;
  1773.         }
  1774.  
  1775.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;473;%s;%s;%d]", questname.c_str(), arg1, value);
  1776.     }
  1777.     else
  1778.     {
  1779.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;474]");
  1780.     }
  1781. }
  1782.  
  1783. LPCHARACTER chHori, chForge, chLib, chTemple, chTraining, chTree, chPortal, chBall;
  1784.  
  1785. ACMD(do_b1)
  1786. {
  1787.     //호리병 478 579
  1788.     chHori = CHARACTER_MANAGER::instance().SpawnMobRange(14017, ch->GetMapIndex(), 304222, 742858, 304222, 742858, true, false);
  1789.     chHori->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_BUILDING_CONSTRUCTION_SMALL, 65535, 0, true);
  1790.     chHori->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
  1791.  
  1792.     for (int i = 0; i < 30; ++i)
  1793.     {
  1794.         int rot = number(0, 359);
  1795.         float fx, fy;
  1796.         GetDeltaByDegree(rot, 800, &fx, &fy);
  1797.  
  1798.         LPCHARACTER tch = CHARACTER_MANAGER::instance().SpawnMobRange(number(701, 706),
  1799.                 ch->GetMapIndex(),
  1800.                 304222 + (int)fx,
  1801.                 742858 + (int)fy,
  1802.                 304222 + (int)fx,
  1803.                 742858 + (int)fy,
  1804.                 true,
  1805.                 false);
  1806.         tch->SetAggressive();
  1807.     }
  1808.  
  1809.     for (int i = 0; i < 5; ++i)
  1810.     {
  1811.         int rot = number(0, 359);
  1812.         float fx, fy;
  1813.         GetDeltaByDegree(rot, 800, &fx, &fy);
  1814.  
  1815.         LPCHARACTER tch = CHARACTER_MANAGER::instance().SpawnMobRange(8009,
  1816.                 ch->GetMapIndex(),
  1817.                 304222 + (int)fx,
  1818.                 742858 + (int)fy,
  1819.                 304222 + (int)fx,
  1820.                 742858 + (int)fy,
  1821.                 true,
  1822.                 false);
  1823.         tch->SetAggressive();
  1824.     }
  1825. }
  1826.  
  1827. ACMD(do_b2)
  1828. {
  1829.     chHori->RemoveAffect(AFFECT_DUNGEON_UNIQUE);
  1830. }
  1831.  
  1832. ACMD(do_b3)
  1833. {
  1834.     // 포지 492 547
  1835.     chForge = CHARACTER_MANAGER::instance().SpawnMobRange(14003, ch->GetMapIndex(), 307500, 746300, 307500, 746300, true, false);
  1836.     chForge->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
  1837.     //높은탑 509 589 -> 도서관
  1838.     chLib = CHARACTER_MANAGER::instance().SpawnMobRange(14007, ch->GetMapIndex(), 307900, 744500, 307900, 744500, true, false);
  1839.     chLib->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
  1840.     //욕조 513 606 -> 힘의신전
  1841.     chTemple = CHARACTER_MANAGER::instance().SpawnMobRange(14004, ch->GetMapIndex(), 307700, 741600, 307700, 741600, true, false);
  1842.     chTemple->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
  1843.     //권투장 490 625
  1844.     chTraining= CHARACTER_MANAGER::instance().SpawnMobRange(14010, ch->GetMapIndex(), 307100, 739500, 307100, 739500, true, false);
  1845.     chTraining->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
  1846.     //나무 466 614
  1847.     chTree= CHARACTER_MANAGER::instance().SpawnMobRange(14013, ch->GetMapIndex(), 300800, 741600, 300800, 741600, true, false);
  1848.     chTree->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
  1849.     //포탈 439 615
  1850.     chPortal= CHARACTER_MANAGER::instance().SpawnMobRange(14001, ch->GetMapIndex(), 300900, 744500, 300900, 744500, true, false);
  1851.     chPortal->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
  1852.     // 구슬 436 600
  1853.     chBall = CHARACTER_MANAGER::instance().SpawnMobRange(14012, ch->GetMapIndex(), 302500, 746600, 302500, 746600, true, false);
  1854.     chBall->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
  1855. }
  1856.  
  1857. ACMD(do_b4)
  1858. {
  1859.     chLib->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_BUILDING_UPGRADE, 65535, 0, true);
  1860.  
  1861.     for (int i = 0; i < 30; ++i)
  1862.     {
  1863.         int rot = number(0, 359);
  1864.         float fx, fy;
  1865.         GetDeltaByDegree(rot, 1200, &fx, &fy);
  1866.  
  1867.         LPCHARACTER tch = CHARACTER_MANAGER::instance().SpawnMobRange(number(701, 706),
  1868.                 ch->GetMapIndex(),
  1869.                 307900 + (int)fx,
  1870.                 744500 + (int)fy,
  1871.                 307900 + (int)fx,
  1872.                 744500 + (int)fy,
  1873.                 true,
  1874.                 false);
  1875.         tch->SetAggressive();
  1876.     }
  1877.  
  1878.     for (int i = 0; i < 5; ++i)
  1879.     {
  1880.         int rot = number(0, 359);
  1881.         float fx, fy;
  1882.         GetDeltaByDegree(rot, 1200, &fx, &fy);
  1883.  
  1884.         LPCHARACTER tch = CHARACTER_MANAGER::instance().SpawnMobRange(8009,
  1885.                 ch->GetMapIndex(),
  1886.                 307900 + (int)fx,
  1887.                 744500 + (int)fy,
  1888.                 307900 + (int)fx,
  1889.                 744500 + (int)fy,
  1890.                 true,
  1891.                 false);
  1892.         tch->SetAggressive();
  1893.     }
  1894.  
  1895. }
  1896.  
  1897. ACMD(do_b5)
  1898. {
  1899.     M2_DESTROY_CHARACTER(chLib);
  1900.     //chHori->RemoveAffect(AFFECT_DUNGEON_UNIQUE);
  1901.     chLib = CHARACTER_MANAGER::instance().SpawnMobRange(14008, ch->GetMapIndex(), 307900, 744500, 307900, 744500, true, false);
  1902.     chLib->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
  1903. }
  1904.  
  1905. ACMD(do_b6)
  1906. {
  1907.     chLib->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_BUILDING_UPGRADE, 65535, 0, true);
  1908. }
  1909. ACMD(do_b7)
  1910. {
  1911.     M2_DESTROY_CHARACTER(chLib);
  1912.     //chHori->RemoveAffect(AFFECT_DUNGEON_UNIQUE);
  1913.     chLib = CHARACTER_MANAGER::instance().SpawnMobRange(14009, ch->GetMapIndex(), 307900, 744500, 307900, 744500, true, false);
  1914.     chLib->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
  1915. }
  1916.  
  1917. ACMD(do_book)
  1918. {
  1919.     char arg1[256];
  1920.  
  1921.     one_argument(argument, arg1, sizeof(arg1));
  1922.  
  1923.     CSkillProto * pkProto;
  1924.  
  1925.     if (isnhdigit(*arg1))
  1926.     {
  1927.         DWORD vnum = 0;
  1928.         str_to_number(vnum, arg1);
  1929.         pkProto = CSkillManager::instance().Get(vnum);
  1930.     }
  1931.     else
  1932.         pkProto = CSkillManager::instance().Get(arg1);
  1933.  
  1934.     if (!pkProto)
  1935.     {
  1936.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS:475]");
  1937.         return;
  1938.     }
  1939.  
  1940.     LPITEM item = ch->AutoGiveItem(50300);
  1941.     item->SetSocket(0, pkProto->dwVnum);
  1942. }
  1943.  
  1944. ACMD(do_setskillother)
  1945. {
  1946.     char arg1[256], arg2[256], arg3[256];
  1947.     argument = two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  1948.     one_argument(argument, arg3, sizeof(arg3));
  1949.  
  1950.     if (!*arg1 || !*arg2 || !*arg3 || !isdigit(*arg3))
  1951.     {
  1952.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS:476]");
  1953.         return;
  1954.     }
  1955.  
  1956.     LPCHARACTER tch;
  1957.  
  1958.     tch = CHARACTER_MANAGER::instance().FindPC(arg1);
  1959.  
  1960.     if (!tch)
  1961.     {
  1962.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;477]");
  1963.         return;
  1964.     }
  1965.  
  1966.     CSkillProto * pk;
  1967.  
  1968.     if (isdigit(*arg2))
  1969.     {
  1970.         DWORD vnum = 0;
  1971.         str_to_number(vnum, arg2);
  1972.         pk = CSkillManager::instance().Get(vnum);
  1973.     }
  1974.     else
  1975.         pk = CSkillManager::instance().Get(arg2);
  1976.  
  1977.     if (!pk)
  1978.     {
  1979.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;478]");
  1980.         return;
  1981.     }
  1982.  
  1983.     BYTE level = 0;
  1984.     str_to_number(level, arg3);
  1985.     tch->SetSkillLevel(pk->dwVnum, level);
  1986.     tch->ComputePoints();
  1987.     tch->SkillLevelPacket();
  1988. }
  1989.  
  1990. ACMD(do_setskill)
  1991. {
  1992.     char arg1[256], arg2[256];
  1993.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  1994.  
  1995.     if (!*arg1 || !*arg2 || !isdigit(*arg2))
  1996.     {
  1997.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;479]");
  1998.         return;
  1999.     }
  2000.  
  2001.     CSkillProto * pk;
  2002.  
  2003.     if (isdigit(*arg1))
  2004.     {
  2005.         DWORD vnum = 0;
  2006.         str_to_number(vnum, arg1);
  2007.         pk = CSkillManager::instance().Get(vnum);
  2008.     }
  2009.  
  2010.     else
  2011.         pk = CSkillManager::instance().Get(arg1);
  2012.  
  2013.     if (!pk)
  2014.     {
  2015.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;478]");
  2016.         return;
  2017.     }
  2018.  
  2019.     BYTE level = 0;
  2020.     str_to_number(level, arg2);
  2021.     ch->SetSkillLevel(pk->dwVnum, level);
  2022.     ch->ComputePoints();
  2023.     ch->SkillLevelPacket();
  2024. }
  2025.  
  2026. ACMD(do_set_skill_point)
  2027. {
  2028.     char arg1[256];
  2029.     one_argument(argument, arg1, sizeof(arg1));
  2030.  
  2031.     int skill_point = 0;
  2032.     if (*arg1)
  2033.         str_to_number(skill_point, arg1);
  2034.  
  2035.     ch->SetRealPoint(POINT_SKILL, skill_point);
  2036.     ch->SetPoint(POINT_SKILL, ch->GetRealPoint(POINT_SKILL));
  2037.     ch->PointChange(POINT_SKILL, 0);
  2038. }
  2039.  
  2040. ACMD(do_set_skill_group)
  2041. {
  2042.     char arg1[256];
  2043.     one_argument(argument, arg1, sizeof(arg1));
  2044.  
  2045.     int skill_group = 0;
  2046.     if (*arg1)
  2047.         str_to_number(skill_group, arg1);
  2048.  
  2049.     ch->SetSkillGroup(skill_group);
  2050.    
  2051.     ch->ClearSkill();
  2052.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;480;%d]", skill_group);
  2053. }
  2054.  
  2055. ACMD(do_reload)
  2056. {
  2057.     char arg1[256];
  2058.     one_argument(argument, arg1, sizeof(arg1));
  2059.  
  2060.     if (*arg1)
  2061.     {
  2062.         switch (LOWER(*arg1))
  2063.         {
  2064.             case 'u':
  2065.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;481]");
  2066.                 LoadStateUserCount();
  2067.                 break;
  2068.  
  2069.             case 'p':
  2070.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;482]");
  2071.                 db_clientdesc->DBPacket(HEADER_GD_RELOAD_PROTO, 0, NULL, 0);
  2072.                 break;
  2073.  
  2074.             case 'q':
  2075.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;483]");
  2076.                 quest::CQuestManager::instance().Reload();
  2077.                 break;
  2078.  
  2079.             case 'f':
  2080.                 fishing::Initialize();
  2081.                 break;
  2082.  
  2083.                 //RELOAD_ADMIN
  2084.             case 'a':
  2085.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;484]");
  2086.                 db_clientdesc->DBPacket(HEADER_GD_RELOAD_ADMIN, 0, NULL, 0);
  2087.                 sys_log(0, "Reloading admin infomation.");
  2088.                 break;
  2089.                 //END_RELOAD_ADMIN
  2090.             case 'c':   // cube
  2091.                 // 로컬 프로세스만 갱산한다.
  2092.                 Cube_init ();
  2093.                 break;
  2094.         }
  2095.     }
  2096.     else
  2097.     {
  2098.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;481]");
  2099.         LoadStateUserCount();
  2100.  
  2101.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;482]");
  2102.         db_clientdesc->DBPacket(HEADER_GD_RELOAD_PROTO, 0, NULL, 0);
  2103.     }
  2104. }
  2105.  
  2106. ACMD(do_cooltime)
  2107. {
  2108.     ch->DisableCooltime();
  2109. }
  2110.  
  2111. ACMD(do_level)
  2112. {
  2113.     char arg2[256];
  2114.     one_argument(argument, arg2, sizeof(arg2));
  2115.  
  2116.     if (!*arg2)
  2117.     {
  2118.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;486]");
  2119.         return;
  2120.     }
  2121.  
  2122.     int level = 0;
  2123.     str_to_number(level, arg2);
  2124.     ch->ResetPoint(MINMAX(1, level, PLAYER_MAX_LEVEL_CONST));
  2125. }
  2126.  
  2127. ACMD(do_gwlist)
  2128. {
  2129.     ch->ChatPacket(CHAT_TYPE_NOTICE, "[LS;487]");
  2130.     CGuildManager::instance().ShowGuildWarList(ch);
  2131. }
  2132.  
  2133. ACMD(do_stop_guild_war)
  2134. {
  2135.     char arg1[256], arg2[256];
  2136.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2137.  
  2138.     if (!*arg1 || !*arg2)
  2139.         return;
  2140.  
  2141.     int id1 = 0, id2 = 0;
  2142.  
  2143.     str_to_number(id1, arg1);
  2144.     str_to_number(id2, arg2);
  2145.    
  2146.     if (!id1 || !id2)
  2147.         return;
  2148.  
  2149.     if (id1 > id2)
  2150.     {
  2151.         std::swap(id1, id2);
  2152.     }
  2153.  
  2154.     ch->ChatPacket(CHAT_TYPE_TALKING, "%d %d", id1, id2);
  2155.     CGuildManager::instance().RequestEndWar(id1, id2);
  2156. }
  2157.  
  2158. ACMD(do_cancel_guild_war)
  2159. {
  2160.     char arg1[256], arg2[256];
  2161.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2162.  
  2163.     int id1 = 0, id2 = 0;
  2164.     str_to_number(id1, arg1);
  2165.     str_to_number(id2, arg2);
  2166.  
  2167.     if (id1 > id2)
  2168.         std::swap(id1, id2);
  2169.  
  2170.     CGuildManager::instance().RequestCancelWar(id1, id2);
  2171. }
  2172.  
  2173. ACMD(do_guild_state)
  2174. {
  2175.     char arg1[256];
  2176.     one_argument(argument, arg1, sizeof(arg1));
  2177.  
  2178.     CGuild* pGuild = CGuildManager::instance().FindGuildByName(arg1);
  2179.     if (pGuild != NULL)
  2180.     {
  2181.         ch->ChatPacket(CHAT_TYPE_INFO, "GuildID: %d", pGuild->GetID());
  2182.         ch->ChatPacket(CHAT_TYPE_INFO, "GuildMasterPID: %d", pGuild->GetMasterPID());
  2183.         ch->ChatPacket(CHAT_TYPE_INFO, "IsInWar: %d", pGuild->UnderAnyWar());
  2184.     }
  2185.     else
  2186.     {
  2187.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;488;%s]", arg1);
  2188.     }
  2189. }
  2190.  
  2191. struct FuncWeaken
  2192. {
  2193.     LPCHARACTER m_pkGM;
  2194.     bool    m_bAll;
  2195.  
  2196.     FuncWeaken(LPCHARACTER ch) : m_pkGM(ch), m_bAll(false)
  2197.     {
  2198.     }
  2199.  
  2200.     void operator () (LPENTITY ent)
  2201.     {
  2202.         if (!ent->IsType(ENTITY_CHARACTER))
  2203.             return;
  2204.  
  2205.         LPCHARACTER pkChr = (LPCHARACTER) ent;
  2206.  
  2207.         int iDist = DISTANCE_APPROX(pkChr->GetX() - m_pkGM->GetX(), pkChr->GetY() - m_pkGM->GetY());
  2208.  
  2209.         if (!m_bAll && iDist >= 1000)   // 10미터 이상에 있는 것들은 purge 하지 않는다.
  2210.             return;
  2211.  
  2212.         if (pkChr->IsNPC())
  2213.             pkChr->PointChange(POINT_HP, (10 - pkChr->GetHP()));
  2214.     }
  2215. };
  2216.  
  2217. ACMD(do_weaken)
  2218. {
  2219.     char arg1[256];
  2220.     one_argument(argument, arg1, sizeof(arg1));
  2221.  
  2222.     FuncWeaken func(ch);
  2223.  
  2224.     if (*arg1 && !strcmp(arg1, "all"))
  2225.         func.m_bAll = true;
  2226.  
  2227.     ch->GetSectree()->ForEachAround(func);
  2228. }
  2229.  
  2230. ACMD(do_getqf)
  2231. {
  2232.     char arg1[256];
  2233.  
  2234.     one_argument(argument, arg1, sizeof(arg1));
  2235.  
  2236.     LPCHARACTER tch;
  2237.  
  2238.     if (!*arg1)
  2239.         tch = ch;
  2240.     else
  2241.     {
  2242.         tch = CHARACTER_MANAGER::instance().FindPC(arg1);
  2243.  
  2244.         if (!tch)
  2245.         {
  2246.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;489]");
  2247.             return;
  2248.         }
  2249.     }
  2250.  
  2251.     quest::PC* pPC = quest::CQuestManager::instance().GetPC(tch->GetPlayerID());
  2252.  
  2253.     if (pPC)
  2254.         pPC->SendFlagList(ch);
  2255. }
  2256.  
  2257. ACMD(do_set_state)
  2258. {
  2259.     char arg1[256];
  2260.     char arg2[256];
  2261.  
  2262.     //argument = one_argument(argument, arg1, sizeof(arg1));
  2263.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2264.  
  2265.     if (!*arg1 || !*arg2)
  2266.         return;
  2267.  
  2268.     quest::PC* pPC = quest::CQuestManager::instance().GetPCForce(ch->GetPlayerID());
  2269.     std::string questname = arg1;
  2270.     std::string statename = arg2;
  2271.  
  2272.     if (!questname.empty())
  2273.     {
  2274.         int value = quest::CQuestManager::Instance().GetQuestStateIndex(questname, statename);
  2275.  
  2276.         pPC->SetFlag(questname + ".__status", value);
  2277.         pPC->ClearTimer();
  2278.  
  2279.         quest::PC::QuestInfoIterator it = pPC->quest_begin();
  2280.         unsigned int questindex = quest::CQuestManager::instance().GetQuestIndexByName(questname);
  2281.  
  2282.         while (it!= pPC->quest_end())
  2283.         {
  2284.             if (it->first == questindex)
  2285.             {
  2286.                 it->second.st = value;
  2287.                 break;
  2288.             }
  2289.  
  2290.             ++it;
  2291.         }
  2292.  
  2293.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;473;%s;%s;%d]", questname.c_str(), arg1, value);
  2294.     }
  2295.     else
  2296.     {
  2297.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;474]");
  2298.     }
  2299. }
  2300.  
  2301. ACMD(do_setqf)
  2302. {
  2303.     char arg1[256];
  2304.     char arg2[256];
  2305.     char arg3[256];
  2306.  
  2307.     one_argument(two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2)), arg3, sizeof(arg3));
  2308.  
  2309.     if (!*arg1)
  2310.     {
  2311.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;490]");
  2312.         return;
  2313.     }
  2314.  
  2315.     LPCHARACTER tch = ch;
  2316.  
  2317.     if (*arg3)
  2318.         tch = CHARACTER_MANAGER::instance().FindPC(arg3);
  2319.  
  2320.     if (!tch)
  2321.     {
  2322.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;489]");
  2323.         return;
  2324.     }
  2325.  
  2326.     quest::PC* pPC = quest::CQuestManager::instance().GetPC(tch->GetPlayerID());
  2327.  
  2328.     if (pPC)
  2329.     {
  2330.         int value = 0;
  2331.         str_to_number(value, arg2);
  2332.         pPC->SetFlag(arg1, value);
  2333.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;491;%s;%d]", arg1, value);
  2334.     }
  2335. }
  2336.  
  2337. ACMD(do_delqf)
  2338. {
  2339.     char arg1[256];
  2340.     char arg2[256];
  2341.  
  2342.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2343.  
  2344.     if (!*arg1)
  2345.     {
  2346.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;492]");
  2347.         return;
  2348.     }
  2349.  
  2350.     LPCHARACTER tch = ch;
  2351.  
  2352.     if (*arg2)
  2353.         tch = CHARACTER_MANAGER::instance().FindPC(arg2);
  2354.  
  2355.     if (!tch)
  2356.     {
  2357.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;489]");
  2358.         return;
  2359.     }
  2360.  
  2361.     quest::PC* pPC = quest::CQuestManager::instance().GetPC(tch->GetPlayerID());
  2362.  
  2363.     if (pPC)
  2364.     {
  2365.         if (pPC->DeleteFlag(arg1))
  2366.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;493]");
  2367.         else
  2368.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;494]");
  2369.     }
  2370. }
  2371.  
  2372. ACMD(do_forgetme)
  2373. {
  2374.     ch->ForgetMyAttacker();
  2375. }
  2376.  
  2377. ACMD(do_aggregate)
  2378. {
  2379.     ch->AggregateMonster();
  2380. }
  2381.  
  2382. ACMD(do_attract_ranger)
  2383. {
  2384.     ch->AttractRanger();
  2385. }
  2386.  
  2387. ACMD(do_pull_monster)
  2388. {
  2389.     ch->PullMonster();
  2390. }
  2391.  
  2392. ACMD(do_polymorph)
  2393. {
  2394.     char arg1[256], arg2[256];
  2395.  
  2396.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2397.     if (*arg1)
  2398.     {
  2399.         DWORD dwVnum = 0;
  2400.         str_to_number(dwVnum, arg1);
  2401.         bool bMaintainStat = false;
  2402.         if (*arg2)
  2403.         {
  2404.             int value = 0;
  2405.             str_to_number(value, arg2);
  2406.             bMaintainStat = (value>0);
  2407.         }
  2408.  
  2409.         ch->SetPolymorph(dwVnum, bMaintainStat);
  2410.     }
  2411. }
  2412.  
  2413. ACMD(do_polymorph_item)
  2414. {
  2415.     char arg1[256];
  2416.  
  2417.     one_argument(argument, arg1, sizeof(arg1));
  2418.  
  2419.     if (*arg1)
  2420.     {
  2421.         DWORD dwVnum = 0;
  2422.         str_to_number(dwVnum, arg1);
  2423.  
  2424.         LPITEM item = ITEM_MANAGER::instance().CreateItem(70104, 1, 0, true);
  2425.         if (item)
  2426.         {
  2427.             item->SetSocket(0, dwVnum);
  2428.             int iEmptyPos = ch->GetEmptyInventory(item->GetSize());
  2429.  
  2430.             if (iEmptyPos != -1)
  2431.             {
  2432.                 item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
  2433.                 LogManager::instance().ItemLog(ch, item, "GM", item->GetName());
  2434.             }
  2435.             else
  2436.             {
  2437.                 M2_DESTROY_ITEM(item);
  2438.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;314]");
  2439.             }
  2440.         }
  2441.         else
  2442.         {
  2443.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;495;%d]", 70103);
  2444.         }
  2445.         //ch->SetPolymorph(dwVnum, bMaintainStat);
  2446.     }
  2447. }
  2448.  
  2449. ACMD(do_priv_empire)
  2450. {
  2451.     char arg1[256] = {0};
  2452.     char arg2[256] = {0};
  2453.     char arg3[256] = {0};
  2454.     char arg4[256] = {0};
  2455.     int empire = 0;
  2456.     int type = 0;
  2457.     int value = 0;
  2458.     int duration = 0;
  2459.  
  2460.     const char* line = two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2461.  
  2462.     if (!*arg1 || !*arg2)
  2463.         goto USAGE;
  2464.  
  2465.     if (!line)
  2466.         goto USAGE;
  2467.  
  2468.     two_arguments(line, arg3, sizeof(arg3), arg4, sizeof(arg4));
  2469.  
  2470.     if (!*arg3 || !*arg4)
  2471.         goto USAGE;
  2472.  
  2473.     str_to_number(empire, arg1);
  2474.     str_to_number(type, arg2);
  2475.     str_to_number(value,    arg3);
  2476.     value = MINMAX(0, value, 1000);
  2477.     str_to_number(duration, arg4);
  2478.  
  2479.     if (empire < 0 || 3 < empire)
  2480.         goto USAGE;
  2481.  
  2482.     if (type < 1 || 4 < type)
  2483.         goto USAGE;
  2484.  
  2485.     if (value < 0)
  2486.         goto USAGE;
  2487.  
  2488.     if (duration < 0)
  2489.         goto USAGE;
  2490.  
  2491.     // 시간 단위로 변경
  2492.     duration = duration * (60*60);
  2493.  
  2494.     sys_log(0, "_give_empire_privileage(empire=%d, type=%d, value=%d, duration=%d) by command",
  2495.             empire, type, value, duration);
  2496.     CPrivManager::instance().RequestGiveEmpirePriv(empire, type, value, duration);
  2497.     return;
  2498.  
  2499. USAGE:
  2500.     ch->ChatPacket(CHAT_TYPE_INFO, "usage : priv_empire <empire> <type> <value> <duration>");
  2501.     ch->ChatPacket(CHAT_TYPE_INFO, "  <empire>    0 - 3 (0==all)");
  2502.     ch->ChatPacket(CHAT_TYPE_INFO, "  <type>      1:item_drop, 2:gold_drop, 3:gold10_drop, 4:exp");
  2503.     ch->ChatPacket(CHAT_TYPE_INFO, "  <value>     percent");
  2504.     ch->ChatPacket(CHAT_TYPE_INFO, "  <duration>  hour");
  2505. }
  2506.  
  2507. ACMD(do_priv_guild)
  2508. {
  2509.     static const char msg[] = { '\0' };
  2510.  
  2511.     char arg1[256];
  2512.     one_argument(argument, arg1, sizeof(arg1));
  2513.  
  2514.     if (*arg1)
  2515.     {
  2516.         CGuild * g = CGuildManager::instance().FindGuildByName(arg1);
  2517.  
  2518.         if (!g)
  2519.         {
  2520.             DWORD guild_id = 0;
  2521.             str_to_number(guild_id, arg1);
  2522.             g = CGuildManager::instance().FindGuild(guild_id);
  2523.         }
  2524.  
  2525.         if (!g)
  2526.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;496]");
  2527.         else
  2528.         {
  2529.             char buf[1024+1];
  2530.             snprintf(buf, sizeof(buf), msg, g->GetID());
  2531.  
  2532.             using namespace quest;
  2533.             PC * pc = CQuestManager::instance().GetPC(ch->GetPlayerID());
  2534.             QuestState qs = CQuestManager::instance().OpenState("ADMIN_QUEST", QUEST_FISH_REFINE_STATE_INDEX);
  2535.             luaL_loadbuffer(qs.co, buf, strlen(buf), "ADMIN_QUEST");
  2536.             pc->SetQuest("ADMIN_QUEST", qs);
  2537.  
  2538.             QuestState & rqs = *pc->GetRunningQuestState();
  2539.  
  2540.             if (!CQuestManager::instance().RunState(rqs))
  2541.             {
  2542.                 CQuestManager::instance().CloseState(rqs);
  2543.                 pc->EndRunning();
  2544.                 return;
  2545.             }
  2546.         }
  2547.     }
  2548. }
  2549.  
  2550. ACMD(do_mount_test)
  2551. {
  2552.     char arg1[256];
  2553.  
  2554.     one_argument(argument, arg1, sizeof(arg1));
  2555.  
  2556.     if (*arg1)
  2557.     {
  2558.         DWORD vnum = 0;
  2559.         str_to_number(vnum, arg1);
  2560.         ch->MountVnum(vnum);
  2561.     }
  2562. }
  2563.  
  2564. ACMD(do_observer)
  2565. {
  2566.     ch->SetObserverMode(!ch->IsObserverMode());
  2567. }
  2568.  
  2569. ACMD(do_socket_item)
  2570. {
  2571.     char arg1[256], arg2[256];
  2572.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2573.  
  2574.     if (*arg1)
  2575.     {
  2576.         DWORD dwVnum = 0;
  2577.         str_to_number(dwVnum, arg1);
  2578.    
  2579.         int iSocketCount = 0;
  2580.         str_to_number(iSocketCount, arg2);
  2581.    
  2582.         if (!iSocketCount || iSocketCount >= ITEM_SOCKET_MAX_NUM)
  2583.             iSocketCount = 3;
  2584.    
  2585.         if (!dwVnum)
  2586.         {
  2587.             if (!ITEM_MANAGER::instance().GetVnum(arg1, dwVnum))
  2588.             {
  2589.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;495;%d]", dwVnum);
  2590.                 return;
  2591.             }
  2592.         }
  2593.  
  2594.         LPITEM item = ch->AutoGiveItem(dwVnum);
  2595.    
  2596.         if (item)
  2597.         {
  2598.             for (int i = 0; i < iSocketCount; ++i)
  2599.                 item->SetSocket(i, 1);
  2600.         }
  2601.         else
  2602.         {
  2603.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;497;%d]", dwVnum);
  2604.         }
  2605.     }
  2606. }
  2607.  
  2608. ACMD(do_xmas)
  2609. {
  2610.     char arg1[256];
  2611.     one_argument(argument, arg1, sizeof(arg1));
  2612.  
  2613.     int flag = 0;
  2614.  
  2615.     if (*arg1)
  2616.         str_to_number(flag, arg1);
  2617.  
  2618.     switch (subcmd)
  2619.     {
  2620.         case SCMD_XMAS_SNOW:
  2621.             quest::CQuestManager::instance().RequestSetEventFlag("xmas_snow", flag);
  2622.             break;
  2623.  
  2624.         case SCMD_XMAS_BOOM:
  2625.             quest::CQuestManager::instance().RequestSetEventFlag("xmas_boom", flag);
  2626.             break;
  2627.  
  2628.         case SCMD_XMAS_SANTA:
  2629.             quest::CQuestManager::instance().RequestSetEventFlag("xmas_santa", flag);
  2630.             break;
  2631.     }
  2632. }
  2633.  
  2634.  
  2635. // BLOCK_CHAT
  2636. ACMD(do_block_chat_list)
  2637. {
  2638.     // GM이 아니거나 block_chat_privilege가 없는 사람은 명령어 사용 불가
  2639.     if (!ch || (ch->GetGMLevel() < GM_HIGH_WIZARD && ch->GetQuestFlag("chat_privilege.block") <= 0))
  2640.     {
  2641.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS:498]");
  2642.         return;
  2643.     }
  2644.  
  2645.     DBManager::instance().ReturnQuery(QID_BLOCK_CHAT_LIST, ch->GetPlayerID(), NULL,
  2646.             "SELECT p.name, a.lDuration FROM affect%s as a, player%s as p WHERE a.bType = %d AND a.dwPID = p.id",
  2647.             get_table_postfix(), get_table_postfix(), AFFECT_BLOCK_CHAT);
  2648. }
  2649.  
  2650. ACMD(do_vote_block_chat)
  2651. {
  2652.     return;
  2653.  
  2654.     char arg1[256];
  2655.     argument = one_argument(argument, arg1, sizeof(arg1));
  2656.  
  2657.     if (!*arg1)
  2658.     {
  2659.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;499]");
  2660.         return;
  2661.     }
  2662.  
  2663.     const char* name = arg1;
  2664.     long lBlockDuration = 10;
  2665.     sys_log(0, "vote_block_chat %s %d", name, lBlockDuration);
  2666.  
  2667.     LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(name);
  2668.  
  2669.     if (!tch)
  2670.     {
  2671.         CCI * pkCCI = P2P_MANAGER::instance().Find(name);
  2672.  
  2673.         if (pkCCI)
  2674.         {
  2675.             TPacketGGBlockChat p;
  2676.  
  2677.             p.bHeader = HEADER_GG_BLOCK_CHAT;
  2678.             strlcpy(p.szName, name, sizeof(p.szName));
  2679.             p.lBlockDuration = lBlockDuration;
  2680.             P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGBlockChat));
  2681.         }
  2682.         else
  2683.         {
  2684.             TPacketBlockChat p;
  2685.  
  2686.             strlcpy(p.szName, name, sizeof(p.szName));
  2687.             p.lDuration = lBlockDuration;
  2688.             db_clientdesc->DBPacket(HEADER_GD_BLOCK_CHAT, ch ? ch->GetDesc()->GetHandle() : 0, &p, sizeof(p));
  2689.  
  2690.         }
  2691.  
  2692.         if (ch)
  2693.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;500]");
  2694.  
  2695.         return;
  2696.     }
  2697.  
  2698.     if (tch && ch != tch)
  2699.         tch->AddAffect(AFFECT_BLOCK_CHAT, POINT_NONE, 0, AFF_NONE, lBlockDuration, 0, true);
  2700. }
  2701.  
  2702. ACMD(do_block_chat)
  2703. {
  2704.     // GM이 아니거나 block_chat_privilege가 없는 사람은 명령어 사용 불가
  2705.     if (ch && (ch->GetGMLevel() < GM_HIGH_WIZARD && ch->GetQuestFlag("chat_privilege.block") <= 0))
  2706.     {
  2707.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS:498]");
  2708.         return;
  2709.     }
  2710.  
  2711.     char arg1[256];
  2712.     argument = one_argument(argument, arg1, sizeof(arg1));
  2713.  
  2714.     if (!*arg1)
  2715.     {
  2716.         if (ch)
  2717.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;501]");
  2718.  
  2719.         return;
  2720.     }
  2721.  
  2722.     const char* name = arg1;
  2723.     long lBlockDuration = parse_time_str(argument);
  2724.  
  2725.     if (lBlockDuration < 0)
  2726.     {
  2727.         if (ch)
  2728.         {
  2729.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;502]");
  2730.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;503]");
  2731.         }
  2732.         return;
  2733.     }
  2734.  
  2735.     sys_log(0, "BLOCK CHAT %s %d", name, lBlockDuration);
  2736.  
  2737.     LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(name);
  2738.  
  2739.     if (!tch)
  2740.     {
  2741.         CCI * pkCCI = P2P_MANAGER::instance().Find(name);
  2742.  
  2743.         if (pkCCI)
  2744.         {
  2745.             TPacketGGBlockChat p;
  2746.  
  2747.             p.bHeader = HEADER_GG_BLOCK_CHAT;
  2748.             strlcpy(p.szName, name, sizeof(p.szName));
  2749.             p.lBlockDuration = lBlockDuration;
  2750.             P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGBlockChat));
  2751.         }
  2752.         else
  2753.         {
  2754.             TPacketBlockChat p;
  2755.  
  2756.             strlcpy(p.szName, name, sizeof(p.szName));
  2757.             p.lDuration = lBlockDuration;
  2758.             db_clientdesc->DBPacket(HEADER_GD_BLOCK_CHAT, ch ? ch->GetDesc()->GetHandle() : 0, &p, sizeof(p));
  2759.         }
  2760.  
  2761.         if (ch)
  2762.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;500]");
  2763.  
  2764.         return;
  2765.     }
  2766.  
  2767.     if (tch && ch != tch)
  2768.         tch->AddAffect(AFFECT_BLOCK_CHAT, POINT_NONE, 0, AFF_NONE, lBlockDuration, 0, true);
  2769. }
  2770. // END_OF_BLOCK_CHAT
  2771.  
  2772. // BUILD_BUILDING
  2773. ACMD(do_build)
  2774. {
  2775.     using namespace building;
  2776.  
  2777.     char arg1[256], arg2[256], arg3[256], arg4[256];
  2778.     const char * line = one_argument(argument, arg1, sizeof(arg1));
  2779.     BYTE GMLevel = ch->GetGMLevel();
  2780.  
  2781.     CLand * pkLand = CManager::instance().FindLand(ch->GetMapIndex(), ch->GetX(), ch->GetY());
  2782.  
  2783.     // NOTE: 조건 체크들은 클라이언트와 서버가 함께 하기 때문에 문제가 있을 때는
  2784.     //       메세지를 전송하지 않고 에러를 출력한다.
  2785.     if (!pkLand)
  2786.     {
  2787.         sys_err("%s trying to build on not buildable area.", ch->GetName());
  2788.         return;
  2789.     }
  2790.  
  2791.     if (!*arg1)
  2792.     {
  2793.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;504]");
  2794.         return;
  2795.     }
  2796.  
  2797.     // 건설 권한 체크
  2798.     if (GMLevel == GM_PLAYER)
  2799.     {
  2800.         // 플레이어가 집을 지을 때는 땅이 내껀지 확인해야 한다.
  2801.         if ((!ch->GetGuild() || ch->GetGuild()->GetID() != pkLand->GetOwner()))
  2802.         {
  2803.             sys_err("%s trying to build on not owned land.", ch->GetName());
  2804.             return;
  2805.         }
  2806.  
  2807.         // 내가 길마인가?
  2808.         if (ch->GetGuild()->GetMasterPID() != ch->GetPlayerID())
  2809.         {
  2810.             sys_err("%s trying to build while not the guild master.", ch->GetName());
  2811.             return;
  2812.         }
  2813.     }
  2814.  
  2815.     switch (LOWER(*arg1))
  2816.     {
  2817.         case 'c':
  2818.             {
  2819.                 // /build c vnum x y x_rot y_rot z_rot
  2820.                 char arg5[256], arg6[256];
  2821.                 line = one_argument(two_arguments(line, arg1, sizeof(arg1), arg2, sizeof(arg2)), arg3, sizeof(arg3)); // vnum x y
  2822.                 one_argument(two_arguments(line, arg4, sizeof(arg4), arg5, sizeof(arg5)), arg6, sizeof(arg6)); // x_rot y_rot z_rot
  2823.  
  2824.                 if (!*arg1 || !*arg2 || !*arg3 || !*arg4 || !*arg5 || !*arg6)
  2825.                 {
  2826.                     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;505]");
  2827.                     return;
  2828.                 }
  2829.  
  2830.                 DWORD dwVnum = 0;
  2831.                 str_to_number(dwVnum,  arg1);
  2832.  
  2833.                 using namespace building;
  2834.  
  2835.                 const TObjectProto * t = CManager::instance().GetObjectProto(dwVnum);
  2836.                 if (!t)
  2837.                 {
  2838.                     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;506]");
  2839.                     return;
  2840.                 }
  2841.  
  2842.                 const DWORD BUILDING_MAX_PRICE = 100000000;
  2843.  
  2844.                 if (t->dwGroupVnum)
  2845.                 {
  2846.                     if (pkLand->FindObjectByGroup(t->dwGroupVnum))
  2847.                     {
  2848.                         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;507]");
  2849.                         return;
  2850.                     }
  2851.                 }
  2852.  
  2853.                 // 건물 종속성 체크 (이 건물이 지어져 있어야함)
  2854.                 if (t->dwDependOnGroupVnum)
  2855.                 {
  2856.                     //      const TObjectProto * dependent = CManager::instance().GetObjectProto(dwVnum);
  2857.                     //      if (dependent)
  2858.                     {
  2859.                         // 지어져있는가?
  2860.                         if (!pkLand->FindObjectByGroup(t->dwDependOnGroupVnum))
  2861.                         {
  2862.                             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;508]");
  2863.                             return;
  2864.                         }
  2865.                     }
  2866.                 }
  2867.  
  2868.                 if (test_server || GMLevel == GM_PLAYER)
  2869.                 {
  2870.                     // GM이 아닐경우만 (테섭에서는 GM도 소모)
  2871.                     // 건설 비용 체크
  2872.                     if (t->dwPrice > BUILDING_MAX_PRICE)
  2873.                     {
  2874.                         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;509]");
  2875.                         return;
  2876.                     }
  2877.  
  2878.                     if (ch->GetGold() < (int)t->dwPrice)
  2879.                     {
  2880.                         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;510]");
  2881.                         return;
  2882.                     }
  2883.  
  2884.                     // 아이템 자재 개수 체크
  2885.  
  2886.                     int i;
  2887.                     for (i = 0; i < OBJECT_MATERIAL_MAX_NUM; ++i)
  2888.                     {
  2889.                         DWORD dwItemVnum = t->kMaterials[i].dwItemVnum;
  2890.                         DWORD dwItemCount = t->kMaterials[i].dwCount;
  2891.  
  2892.                         if (dwItemVnum == 0)
  2893.                             break;
  2894.  
  2895.                         if ((int) dwItemCount > ch->CountSpecifyItem(dwItemVnum))
  2896.                         {
  2897.                             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;511]");
  2898.                             return;
  2899.                         }
  2900.                     }
  2901.                 }
  2902.  
  2903.                 float x_rot = atof(arg4);
  2904.                 float y_rot = atof(arg5);
  2905.                 float z_rot = atof(arg6);
  2906.                 // 20050811.myevan.건물 회전 기능 봉인 해제
  2907.                 /*
  2908.                    if (x_rot != 0.0f || y_rot != 0.0f || z_rot != 0.0f)
  2909.                    {
  2910.                    ch->ChatPacket(CHAT_TYPE_INFO, "건물 회전 기능은 아직 제공되지 않습니다");
  2911.                    return;
  2912.                    }
  2913.                  */
  2914.  
  2915.                 long map_x = 0;
  2916.                 str_to_number(map_x, arg2);
  2917.                 long map_y = 0;
  2918.                 str_to_number(map_y, arg3);
  2919.  
  2920.                 bool isSuccess = pkLand->RequestCreateObject(dwVnum,
  2921.                         ch->GetMapIndex(),
  2922.                         map_x,
  2923.                         map_y,
  2924.                         x_rot,
  2925.                         y_rot,
  2926.                         z_rot, true);
  2927.  
  2928.                 if (!isSuccess)
  2929.                 {
  2930.                     if (test_server)
  2931.                         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;512]");
  2932.                     return;
  2933.                 }
  2934.  
  2935.                 if (test_server || GMLevel == GM_PLAYER)
  2936.                     // 건설 재료 소모하기 (테섭에서는 GM도 소모)
  2937.                 {
  2938.                     // 건설 비용 소모
  2939.                     ch->PointChange(POINT_GOLD, -t->dwPrice);
  2940.  
  2941.                     // 아이템 자재 사용하기
  2942.                     {
  2943.                         int i;
  2944.                         for (i = 0; i < OBJECT_MATERIAL_MAX_NUM; ++i)
  2945.                         {
  2946.                             DWORD dwItemVnum = t->kMaterials[i].dwItemVnum;
  2947.                             DWORD dwItemCount = t->kMaterials[i].dwCount;
  2948.  
  2949.                             if (dwItemVnum == 0)
  2950.                                 break;
  2951.  
  2952.                             sys_log(0, "BUILD: material %d %u %u", i, dwItemVnum, dwItemCount);
  2953.                             ch->RemoveSpecifyItem(dwItemVnum, dwItemCount);
  2954.                         }
  2955.                     }
  2956.                 }
  2957.             }
  2958.             break;
  2959.  
  2960.         case 'd' :
  2961.             // build (d)elete ObjectID
  2962.             {
  2963.                 one_argument(line, arg1, sizeof(arg1));
  2964.  
  2965.                 if (!*arg1)
  2966.                 {
  2967.                     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;505]");
  2968.                     return;
  2969.                 }
  2970.  
  2971.                 DWORD vid = 0;
  2972.                 str_to_number(vid, arg1);
  2973.                 pkLand->RequestDeleteObjectByVID(vid);
  2974.             }
  2975.             break;
  2976.  
  2977.             // BUILD_WALL  
  2978.  
  2979.             // build w n/e/w/s
  2980.         case 'w' :
  2981.             if (GMLevel > GM_PLAYER)
  2982.             {
  2983.                 int mapIndex = ch->GetMapIndex();
  2984.  
  2985.                 one_argument(line, arg1, sizeof(arg1));
  2986.                
  2987.                 sys_log(0, "guild.wall.build map[%d] direction[%s]", mapIndex, arg1);
  2988.  
  2989.                 switch (arg1[0])
  2990.                 {
  2991.                     case 's':
  2992.                         pkLand->RequestCreateWall(mapIndex,   0.0f);
  2993.                         break;
  2994.                     case 'n':
  2995.                         pkLand->RequestCreateWall(mapIndex, 180.0f);
  2996.                         break;
  2997.                     case 'e':
  2998.                         pkLand->RequestCreateWall(mapIndex,  90.0f);
  2999.                         break;
  3000.                     case 'w':
  3001.                         pkLand->RequestCreateWall(mapIndex, 270.0f);
  3002.                         break;
  3003.                     default:
  3004.                         ch->ChatPacket(CHAT_TYPE_INFO, "guild.wall.build unknown_direction[%s]", arg1);
  3005.                         sys_err("guild.wall.build unknown_direction[%s]", arg1);
  3006.                         break;
  3007.                 }
  3008.  
  3009.             }
  3010.             break;
  3011.  
  3012.         case 'e':
  3013.             if (GMLevel > GM_PLAYER)
  3014.             {
  3015.                 pkLand->RequestDeleteWall();
  3016.             }
  3017.             break;
  3018.  
  3019.         case 'W' :
  3020.             // 담장 세우기
  3021.             // build (w)all 담장번호 담장크기 대문동 대문서 대문남 대문북
  3022.  
  3023.             if (GMLevel >  GM_PLAYER)
  3024.             {
  3025.                 int setID = 0, wallSize = 0;
  3026.                 char arg5[256], arg6[256];
  3027.                 line = two_arguments(line, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3028.                 line = two_arguments(line, arg3, sizeof(arg3), arg4, sizeof(arg4));
  3029.                 two_arguments(line, arg5, sizeof(arg5), arg6, sizeof(arg6));
  3030.  
  3031.                 str_to_number(setID, arg1);
  3032.                 str_to_number(wallSize, arg2);
  3033.  
  3034.                 if (setID != 14105 && setID != 14115 && setID != 14125)
  3035.                 {
  3036.                     sys_log(0, "BUILD_WALL: wrong wall set id %d", setID);
  3037.                     break;
  3038.                 }
  3039.                 else
  3040.                 {
  3041.                     bool door_east = false;
  3042.                     str_to_number(door_east, arg3);
  3043.                     bool door_west = false;
  3044.                     str_to_number(door_west, arg4);
  3045.                     bool door_south = false;
  3046.                     str_to_number(door_south, arg5);
  3047.                     bool door_north = false;
  3048.                     str_to_number(door_north, arg6);
  3049.                     pkLand->RequestCreateWallBlocks(setID, ch->GetMapIndex(), wallSize, door_east, door_west, door_south, door_north);
  3050.                 }
  3051.             }
  3052.             break;
  3053.  
  3054.         case 'E' :
  3055.             // 담장 지우기
  3056.             // build (e)rase 담장셋ID
  3057.             if (GMLevel > GM_PLAYER)
  3058.             {
  3059.                 one_argument(line, arg1, sizeof(arg1));
  3060.                 DWORD id = 0;
  3061.                 str_to_number(id, arg1);
  3062.                 pkLand->RequestDeleteWallBlocks(id);
  3063.             }
  3064.             break;
  3065.  
  3066.         default:
  3067.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;513;%s]", arg1);
  3068.             break;
  3069.     }
  3070. }
  3071. // END_OF_BUILD_BUILDING
  3072.  
  3073. ACMD(do_clear_quest)
  3074. {
  3075.     char arg1[256];
  3076.  
  3077.     one_argument(argument, arg1, sizeof(arg1));
  3078.  
  3079.     if (!*arg1)
  3080.         return;
  3081.  
  3082.     quest::PC* pPC = quest::CQuestManager::instance().GetPCForce(ch->GetPlayerID());
  3083.     pPC->ClearQuest(arg1);
  3084. }
  3085.  
  3086. ACMD(do_horse_state)
  3087. {
  3088.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;514]");
  3089.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;515]", ch->GetHorseLevel());
  3090.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;516]", ch->GetHorseHealth(), ch->GetHorseMaxHealth(), ch->GetHorseHealth() * 100 / ch->GetHorseMaxHealth());
  3091.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;517]", ch->GetHorseStamina(), ch->GetHorseMaxStamina(), ch->GetHorseStamina() * 100 / ch->GetHorseMaxStamina());
  3092. }
  3093.  
  3094. ACMD(do_horse_level)
  3095. {
  3096.     char arg1[256] = {0};
  3097.     char arg2[256] = {0};
  3098.     LPCHARACTER victim;
  3099.     int level = 0;
  3100.  
  3101.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3102.  
  3103.     if (!*arg1 || !*arg2)
  3104.     {
  3105.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;518]");
  3106.         return;
  3107.     }
  3108.  
  3109.     victim = CHARACTER_MANAGER::instance().FindPC(arg1);
  3110.  
  3111.     if (NULL == victim)
  3112.     {
  3113.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;418]");
  3114.         return;
  3115.     }
  3116.  
  3117.     str_to_number(level, arg2);
  3118.     level = MINMAX(0, level, HORSE_MAX_LEVEL);
  3119.  
  3120.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;519;%s;%d]", victim->GetName(), level);
  3121.  
  3122.     victim->SetHorseLevel(level);
  3123.     victim->ComputePoints();
  3124.     victim->SkillLevelPacket();
  3125.     return;
  3126. }
  3127.  
  3128. ACMD(do_horse_ride)
  3129. {
  3130.     if (ch->IsHorseRiding())
  3131.     {
  3132.         ch->StopRiding();
  3133.     }
  3134.     else
  3135.     {
  3136.         ch->StartRiding();
  3137.     }
  3138. }
  3139.  
  3140. ACMD(do_horse_summon)
  3141. {
  3142.     ch->HorseSummon(true, true);
  3143. }
  3144.  
  3145. ACMD(do_horse_unsummon)
  3146. {
  3147.     ch->HorseSummon(false, true);
  3148. }
  3149.  
  3150. ACMD(do_horse_set_stat)
  3151. {
  3152.     char arg1[256], arg2[256];
  3153.  
  3154.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3155.  
  3156.     if (*arg1 && *arg2)
  3157.     {
  3158.         int hp = 0;
  3159.         str_to_number(hp, arg1);
  3160.         int stam = 0;
  3161.         str_to_number(stam, arg2);
  3162.         ch->UpdateHorseHealth(hp - ch->GetHorseHealth());
  3163.         ch->UpdateHorseStamina(stam - ch->GetHorseStamina());
  3164.     }
  3165.     else
  3166.     {
  3167.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;520]");
  3168.     }
  3169. }
  3170.  
  3171. ACMD(do_save_attribute_to_image) // command "/saveati" for alias
  3172. {
  3173.     char szFileName[256];
  3174.     char szMapIndex[256];
  3175.  
  3176.     two_arguments(argument, szMapIndex, sizeof(szMapIndex), szFileName, sizeof(szFileName));
  3177.  
  3178.     if (!*szMapIndex || !*szFileName)
  3179.     {
  3180.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;521]");
  3181.         return;
  3182.     }
  3183.  
  3184.     long lMapIndex = 0;
  3185.     str_to_number(lMapIndex, szMapIndex);
  3186.  
  3187.     if (SECTREE_MANAGER::instance().SaveAttributeToImage(lMapIndex, szFileName))
  3188.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;522]");
  3189.     else
  3190.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;523]");
  3191. }
  3192.  
  3193. ACMD(do_affect_remove)
  3194. {
  3195.     char arg1[256];
  3196.     char arg2[256];
  3197.  
  3198.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3199.  
  3200.     if (!*arg1 || !*arg2)
  3201.     {
  3202.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;524]");
  3203.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;525]");
  3204.  
  3205.         LPCHARACTER tch = ch;
  3206.  
  3207.         if (*arg1)
  3208.             if (!(tch = CHARACTER_MANAGER::instance().FindPC(arg1)))
  3209.                 tch = ch;
  3210.  
  3211.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;526;%s]", tch->GetName());
  3212.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS:527]");
  3213.  
  3214.         const std::list<CAffect *> & cont = tch->GetAffectContainer();
  3215.  
  3216.         itertype(cont) it = cont.begin();
  3217.  
  3218.         while (it != cont.end())
  3219.         {
  3220.             CAffect * pkAff = *it++;
  3221.  
  3222.             ch->ChatPacket(CHAT_TYPE_INFO, "%4d %5d %5d %8d %u", pkAff->type, pkAff->applyOn, pkAff->applyValue, pkAff->duration, pkAff->flag);
  3223.         }
  3224.         return;
  3225.     }
  3226.  
  3227.     bool removed = false;
  3228.  
  3229.     CAffect * af;
  3230.  
  3231.     DWORD   type = 0;
  3232.     str_to_number(type, arg1);
  3233.     BYTE    point = 0;
  3234.     str_to_number(point, arg2);
  3235.     while ((af = ch->FindAffect(type, point)))
  3236.     {
  3237.         ch->RemoveAffect(af);
  3238.         removed = true;
  3239.     }
  3240.  
  3241.     if (removed)
  3242.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;528]");
  3243.     else
  3244.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;529]");
  3245. }
  3246.  
  3247. ACMD(do_change_attr)
  3248. {
  3249.     LPITEM weapon = ch->GetWear(WEAR_WEAPON);
  3250.     if (weapon)
  3251.         weapon->ChangeAttribute();
  3252. }
  3253.  
  3254. ACMD(do_add_attr)
  3255. {
  3256.     LPITEM weapon = ch->GetWear(WEAR_WEAPON);
  3257.     if (weapon)
  3258.         weapon->AddAttribute();
  3259. }
  3260.  
  3261. ACMD(do_add_socket)
  3262. {
  3263.     LPITEM weapon = ch->GetWear(WEAR_WEAPON);
  3264.     if (weapon)
  3265.         weapon->AddSocket();
  3266. }
  3267.  
  3268. ACMD(do_show_arena_list)
  3269. {
  3270.     CArenaManager::instance().SendArenaMapListTo(ch);
  3271. }
  3272.  
  3273. ACMD(do_end_all_duel)
  3274. {
  3275.     CArenaManager::instance().EndAllDuel();
  3276. }
  3277.  
  3278. ACMD(do_end_duel)
  3279. {
  3280.     char szName[256];
  3281.  
  3282.     one_argument(argument, szName, sizeof(szName));
  3283.  
  3284.     LPCHARACTER pChar = CHARACTER_MANAGER::instance().FindPC(szName);
  3285.     if (pChar == NULL)
  3286.     {
  3287.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;418]");
  3288.         return;
  3289.     }
  3290.  
  3291.     if (CArenaManager::instance().EndDuel(pChar->GetPlayerID()) == false)
  3292.     {
  3293.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;530]");
  3294.     }
  3295.     else
  3296.     {
  3297.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;531]");
  3298.     }
  3299. }
  3300.  
  3301. ACMD(do_duel)
  3302. {
  3303.     char szName1[256];
  3304.     char szName2[256];
  3305.     char szSet[256];
  3306.     char szMinute[256];
  3307.     int set = 0;
  3308.     int minute = 0;
  3309.  
  3310.     argument = two_arguments(argument, szName1, sizeof(szName1), szName2, sizeof(szName2));
  3311.     two_arguments(argument, szSet, sizeof(szSet), szMinute, sizeof(szMinute));
  3312.  
  3313.     str_to_number(set, szSet);
  3314.    
  3315.     if (set < 0) set = 1;
  3316.     if (set > 5) set = 5;
  3317.  
  3318.     if (!str_to_number(minute, szMinute))
  3319.     {
  3320.         // 캐나다는 기본 10분.
  3321.         if (LC_IsCanada() == true)
  3322.         {
  3323.             minute = 10;
  3324.         }
  3325.         else
  3326.         {
  3327.             minute = 5;
  3328.         }
  3329.     }
  3330.     if (minute < 5)
  3331.         minute = 5;
  3332.  
  3333.     LPCHARACTER pChar1 = CHARACTER_MANAGER::instance().FindPC(szName1);
  3334.     LPCHARACTER pChar2 = CHARACTER_MANAGER::instance().FindPC(szName2);
  3335.  
  3336.     if (pChar1 != NULL && pChar2 != NULL)
  3337.     {
  3338.         pChar1->RemoveGoodAffect();
  3339.         pChar2->RemoveGoodAffect();
  3340.  
  3341.         pChar1->RemoveBadAffect();
  3342.         pChar2->RemoveBadAffect();
  3343.  
  3344.         LPPARTY pParty = pChar1->GetParty();
  3345.         if (pParty != NULL)
  3346.         {
  3347.             if (pParty->GetMemberCount() == 2)
  3348.             {
  3349.                 CPartyManager::instance().DeleteParty(pParty);
  3350.             }
  3351.             else
  3352.             {
  3353.                 pChar1->ChatPacket(CHAT_TYPE_INFO, "[LS;532]");
  3354.                 pParty->Quit(pChar1->GetPlayerID());
  3355.             }
  3356.         }
  3357.    
  3358.         pParty = pChar2->GetParty();
  3359.         if (pParty != NULL)
  3360.         {
  3361.             if (pParty->GetMemberCount() == 2)
  3362.             {
  3363.                 CPartyManager::instance().DeleteParty(pParty);
  3364.             }
  3365.             else
  3366.             {
  3367.                 pChar2->ChatPacket(CHAT_TYPE_INFO, "[LS;532]");
  3368.                 pParty->Quit(pChar2->GetPlayerID());
  3369.             }
  3370.         }
  3371.        
  3372.         if (CArenaManager::instance().StartDuel(pChar1, pChar2, set, minute) == true)
  3373.         {
  3374.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;533]");
  3375.         }
  3376.         else
  3377.         {
  3378.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;534]");
  3379.         }
  3380.     }
  3381.     else
  3382.     {
  3383.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;535]");
  3384.     }
  3385. }
  3386.  
  3387. ACMD(do_stat_plus_amount)
  3388. {
  3389.     char szPoint[256];
  3390.  
  3391.     one_argument(argument, szPoint, sizeof(szPoint));
  3392.  
  3393.     if (*szPoint == '\0')
  3394.         return;
  3395.  
  3396.     if (ch->IsPolymorphed())
  3397.     {
  3398.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;426]");
  3399.         return;
  3400.     }
  3401.  
  3402.     int nRemainPoint = ch->GetPoint(POINT_STAT);
  3403.  
  3404.     if (nRemainPoint <= 0)
  3405.     {
  3406.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;537]");
  3407.         return;
  3408.     }
  3409.  
  3410.     int nPoint = 0;
  3411.     str_to_number(nPoint, szPoint);
  3412.  
  3413.     if (nRemainPoint < nPoint)
  3414.     {
  3415.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;538]");
  3416.         return;
  3417.     }
  3418.  
  3419.     if (nPoint < 0)
  3420.     {
  3421.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;539]");
  3422.         return;
  3423.     }
  3424.    
  3425.     switch (subcmd)
  3426.     {
  3427.         case POINT_HT : // 체력
  3428.             if (nPoint + ch->GetPoint(POINT_HT) > 90)
  3429.             {
  3430.                 nPoint = 90 - ch->GetPoint(POINT_HT);
  3431.             }
  3432.             break;
  3433.  
  3434.         case POINT_IQ : // 지능
  3435.             if (nPoint + ch->GetPoint(POINT_IQ) > 90)
  3436.             {
  3437.                 nPoint = 90 - ch->GetPoint(POINT_IQ);
  3438.             }
  3439.             break;
  3440.            
  3441.         case POINT_ST : // 근력
  3442.             if (nPoint + ch->GetPoint(POINT_ST) > 90)
  3443.             {
  3444.                 nPoint = 90 - ch->GetPoint(POINT_ST);
  3445.             }
  3446.             break;
  3447.            
  3448.         case POINT_DX : // 민첩
  3449.             if (nPoint + ch->GetPoint(POINT_DX) > 90)
  3450.             {
  3451.                 nPoint = 90 - ch->GetPoint(POINT_DX);
  3452.             }
  3453.             break;
  3454.  
  3455.         default :
  3456.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;540]");
  3457.             return;
  3458.             break;
  3459.     }
  3460.  
  3461.     if (nPoint != 0)
  3462.     {
  3463.         ch->SetRealPoint(subcmd, ch->GetRealPoint(subcmd) + nPoint);
  3464.         ch->SetPoint(subcmd, ch->GetPoint(subcmd) + nPoint);
  3465.         ch->ComputePoints();
  3466.         ch->PointChange(subcmd, 0);
  3467.  
  3468.         ch->PointChange(POINT_STAT, -nPoint);
  3469.         ch->ComputePoints();
  3470.     }
  3471. }
  3472.  
  3473. struct tTwoPID
  3474. {
  3475.     int pid1;
  3476.     int pid2;
  3477. };
  3478.  
  3479. ACMD(do_break_marriage)
  3480. {
  3481.     char arg1[256], arg2[256];
  3482.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  3483.  
  3484.     tTwoPID pids = { 0, 0 };
  3485.  
  3486.     str_to_number(pids.pid1, arg1);
  3487.     str_to_number(pids.pid2, arg2);
  3488.    
  3489.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;541;%d;%d]", pids.pid1, pids.pid2);
  3490.     db_clientdesc->DBPacket(HEADER_GD_BREAK_MARRIAGE, 0, &pids, sizeof(pids));
  3491. }
  3492.  
  3493. ACMD(do_effect)
  3494. {
  3495.     char arg1[256];
  3496.  
  3497.     one_argument(argument, arg1, sizeof(arg1));
  3498.  
  3499.     int effect_type = 0;
  3500.     str_to_number(effect_type, arg1);
  3501.     ch->EffectPacket(effect_type);
  3502. }
  3503.  
  3504. struct FCountInMap
  3505. {
  3506.     int m_Count[4];
  3507.     FCountInMap() { memset(m_Count, 0, sizeof(int) * 4); }
  3508.     void operator()(LPENTITY ent)
  3509.     {
  3510.         if (ent->IsType(ENTITY_CHARACTER))
  3511.         {
  3512.             LPCHARACTER ch = (LPCHARACTER) ent;
  3513.             if (ch && ch->IsPC())
  3514.                 ++m_Count[ch->GetEmpire()];
  3515.         }
  3516.     }
  3517.     int GetCount(BYTE bEmpire) { return m_Count[bEmpire]; }
  3518. };
  3519.  
  3520. ACMD(do_reset_subskill)
  3521. {
  3522.     char arg1[256];
  3523.  
  3524.     one_argument(argument, arg1, sizeof(arg1));
  3525.    
  3526.     if (!*arg1)
  3527.     {
  3528.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;556]");
  3529.         return;
  3530.     }
  3531.    
  3532.     LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg1);
  3533.    
  3534.     if (tch == NULL)
  3535.         return;
  3536.  
  3537.     tch->ClearSubSkill();
  3538.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;557;%s]", tch->GetName());
  3539. }
  3540.  
  3541. ACMD(do_flush)
  3542. {
  3543.     char arg1[256];
  3544.     one_argument(argument, arg1, sizeof(arg1));
  3545.  
  3546.     if (0 == arg1[0])
  3547.     {
  3548.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;555]");
  3549.         return;
  3550.     }
  3551.  
  3552.     DWORD pid = (DWORD) strtoul(arg1, NULL, 10);
  3553.  
  3554.     db_clientdesc->DBPacketHeader(HEADER_GD_FLUSH_CACHE, 0, sizeof(DWORD));
  3555.     db_clientdesc->Packet(&pid, sizeof(DWORD));
  3556. }
  3557.  
  3558. ACMD(do_eclipse)
  3559. {
  3560.     char arg1[256];
  3561.     one_argument(argument, arg1, sizeof(arg1));
  3562.  
  3563.     if (strtol(arg1, NULL, 10) == 1)
  3564.     {
  3565.         quest::CQuestManager::instance().RequestSetEventFlag("eclipse", 1);
  3566.     }
  3567.     else
  3568.     {
  3569.         quest::CQuestManager::instance().RequestSetEventFlag("eclipse", 0);
  3570.     }
  3571. }
  3572.  
  3573. ACMD(do_weeklyevent)
  3574. {
  3575.     char arg1[256];
  3576.     int empire = 0;
  3577.    
  3578.     if (CBattleArena::instance().IsRunning() == false)
  3579.     {
  3580.         one_argument(argument, arg1, sizeof(arg1));
  3581.  
  3582.         empire = strtol(arg1, NULL, 10);
  3583.  
  3584.         if (empire == 1 || empire == 2 || empire == 3)
  3585.         {
  3586.             CBattleArena::instance().Start(empire);
  3587.         }
  3588.         else
  3589.         {
  3590.             CBattleArena::instance().Start(rand()%3 + 1);
  3591.         }
  3592.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;553]");
  3593.     }
  3594.     else
  3595.     {
  3596.         CBattleArena::instance().ForceEnd();
  3597.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;554]");
  3598.     }
  3599. }
  3600.  
  3601. ACMD(do_event_helper)
  3602. {
  3603.     char arg1[256];
  3604.     int mode = 0;
  3605.  
  3606.     one_argument(argument, arg1, sizeof(arg1));
  3607.     str_to_number(mode, arg1);
  3608.  
  3609.     if (mode == 1)
  3610.     {
  3611.         xmas::SpawnEventHelper(true);
  3612.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;551]");
  3613.     }
  3614.     else
  3615.     {
  3616.         xmas::SpawnEventHelper(false);
  3617.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;552]");
  3618.     }
  3619. }
  3620.  
  3621. struct FMobCounter
  3622. {
  3623.     int nCount;
  3624.  
  3625.     void operator () (LPENTITY ent)
  3626.     {
  3627.         if (ent->IsType(ENTITY_CHARACTER))
  3628.         {
  3629.             LPCHARACTER pChar = static_cast<LPCHARACTER>(ent);
  3630.  
  3631.             if (pChar->IsMonster() == true || pChar->IsStone())
  3632.             {
  3633.                 nCount++;
  3634.             }
  3635.         }
  3636.     }
  3637. };
  3638.  
  3639. ACMD(do_get_mob_count)
  3640. {
  3641.     LPSECTREE_MAP pSectree = SECTREE_MANAGER::instance().GetMap(ch->GetMapIndex());
  3642.  
  3643.     if (pSectree == NULL)
  3644.         return;
  3645.  
  3646.     FMobCounter f;
  3647.     f.nCount = 0;
  3648.  
  3649.     pSectree->for_each(f);
  3650.  
  3651.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;550;%d;%d]", ch->GetMapIndex(), f.nCount);
  3652. }
  3653.  
  3654. ACMD(do_clear_land)
  3655. {
  3656.     const building::CLand* pLand = building::CManager::instance().FindLand(ch->GetMapIndex(), ch->GetX(), ch->GetY());
  3657.  
  3658.     if( NULL == pLand )
  3659.     {
  3660.         return;
  3661.     }
  3662.  
  3663.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;549;%d]", pLand->GetID());
  3664.  
  3665.     building::CManager::instance().ClearLand(pLand->GetID());
  3666. }
  3667.  
  3668. ACMD(do_special_item)
  3669. {
  3670.     ITEM_MANAGER::instance().ConvSpecialDropItemFile();
  3671. }
  3672.  
  3673. ACMD(do_set_stat)
  3674. {
  3675.     char szName [256];
  3676.     char szChangeAmount[256];
  3677.  
  3678.     two_arguments (argument, szName, sizeof (szName), szChangeAmount, sizeof(szChangeAmount));
  3679.  
  3680.     if (*szName == 0 || *szChangeAmount == '\0')
  3681.     {
  3682.         ch->ChatPacket (CHAT_TYPE_INFO, "[LS;543]");
  3683.         return;
  3684.     }
  3685.  
  3686.     LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(szName);
  3687.  
  3688.     if (!tch)
  3689.     {
  3690.         CCI * pkCCI = P2P_MANAGER::instance().Find(szName);
  3691.  
  3692.         if (pkCCI)
  3693.         {
  3694.             ch->ChatPacket (CHAT_TYPE_INFO, "[LS;544;%s;%s]", szName, szName);
  3695.             return;
  3696.         }
  3697.         else
  3698.         {
  3699.             ch->ChatPacket (CHAT_TYPE_INFO, "[LS;545;%s;%s]", szName, szName);
  3700.             return;
  3701.         }
  3702.     }
  3703.     else
  3704.     {
  3705.         if (tch->IsPolymorphed())
  3706.         {
  3707.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;426]");
  3708.             return;
  3709.         }
  3710.  
  3711.         if (subcmd != POINT_HT && subcmd != POINT_IQ && subcmd != POINT_ST && subcmd != POINT_DX)
  3712.         {
  3713.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;540]");
  3714.             return;
  3715.         }
  3716.         int nRemainPoint = tch->GetPoint(POINT_STAT);
  3717.         int nCurPoint = tch->GetRealPoint(subcmd);
  3718.         int nChangeAmount = 0;
  3719.         str_to_number(nChangeAmount, szChangeAmount);
  3720.         int nPoint = nCurPoint + nChangeAmount;
  3721.        
  3722.         int n;
  3723.         switch (subcmd)
  3724.         {
  3725.         case POINT_HT:
  3726.             if (nPoint < JobInitialPoints[tch->GetJob()].ht)
  3727.             {
  3728.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;546]");
  3729.                 return;
  3730.             }
  3731.             n = 0;
  3732.             break;
  3733.         case POINT_IQ:
  3734.             if (nPoint < JobInitialPoints[tch->GetJob()].iq)
  3735.             {
  3736.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;546]");
  3737.                 return;
  3738.             }
  3739.             n = 1;
  3740.             break;
  3741.         case POINT_ST:
  3742.             if (nPoint < JobInitialPoints[tch->GetJob()].st)
  3743.             {
  3744.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;546]");
  3745.                 return;
  3746.             }
  3747.             n = 2;
  3748.             break;
  3749.         case POINT_DX:
  3750.             if (nPoint < JobInitialPoints[tch->GetJob()].dx)
  3751.             {
  3752.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;546]");
  3753.                 return;
  3754.             }
  3755.             n = 3;
  3756.             break;
  3757.         }
  3758.  
  3759.         if (nPoint > 90)
  3760.         {
  3761.             nChangeAmount -= nPoint - 90;
  3762.             nPoint = 90;
  3763.         }
  3764.  
  3765.         if (nRemainPoint < nChangeAmount)
  3766.         {
  3767.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;538]");
  3768.             return;
  3769.         }
  3770.  
  3771.         tch->SetRealPoint(subcmd, nPoint);
  3772.         tch->SetPoint(subcmd, tch->GetPoint(subcmd) + nChangeAmount);
  3773.         tch->ComputePoints();
  3774.         tch->PointChange(subcmd, 0);
  3775.  
  3776.         tch->PointChange(POINT_STAT, -nChangeAmount);
  3777.         tch->ComputePoints();
  3778.  
  3779.         const char* stat_name[4] = {"con", "int", "str", "dex"};
  3780.  
  3781.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;547;%s;%s;%d;%d]", szName, stat_name[n], nCurPoint, nPoint);
  3782.     }
  3783. }
  3784.  
  3785. ACMD(do_get_item_id_list)
  3786. {
  3787.     for (int i = 0; i < INVENTORY_AND_EQUIP_SLOT_MAX; i++)
  3788.     {
  3789.         LPITEM item = ch->GetInventoryItem(i);
  3790.         if (item != NULL)
  3791.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;548;%d;%s;%d]", item->GetCell(), item->GetName(), item->GetID());
  3792.     }
  3793. }
  3794.  
  3795. ACMD(do_set_socket)
  3796. {
  3797.     char arg1 [256];
  3798.     char arg2 [256];
  3799.     char arg3 [256];
  3800.  
  3801.     one_argument (two_arguments (argument, arg1, sizeof (arg1), arg2, sizeof(arg2)), arg3, sizeof (arg3));
  3802.    
  3803.     int item_id, socket_num, value;
  3804.     if (!str_to_number (item_id, arg1) || !str_to_number (socket_num, arg2) || !str_to_number (value, arg3))
  3805.         return;
  3806.    
  3807.     LPITEM item = ITEM_MANAGER::instance().Find (item_id);
  3808.     if (item)
  3809.         item->SetSocket (socket_num, value);
  3810. }
  3811.  
  3812. ACMD (do_can_dead)
  3813. {
  3814.     if (subcmd)
  3815.         ch->SetArmada();
  3816.     else
  3817.         ch->ResetArmada();
  3818. }
  3819.  
  3820. ACMD (do_full_set)
  3821. {
  3822.     extern void do_all_skill_master(LPCHARACTER ch, const char *argument, int cmd, int subcmd);
  3823.     do_all_skill_master(ch, NULL, 0, 0);
  3824.     extern void do_item_full_set(LPCHARACTER ch, const char *argument, int cmd, int subcmd);
  3825.     do_item_full_set(ch, NULL, 0, 0);
  3826.     extern void do_attr_full_set(LPCHARACTER ch, const char *argument, int cmd, int subcmd);
  3827.     do_attr_full_set(ch, NULL, 0, 0);
  3828.  
  3829. }
  3830.  
  3831. ACMD (do_all_skill_master)
  3832. {
  3833.     ch->SetHorseLevel(SKILL_MAX_LEVEL);
  3834.     for (int i = 0; i < SKILL_MAX_NUM; i++)
  3835.     {
  3836.         if (true == ch->CanUseSkill(i))
  3837.         {
  3838.             ch->SetSkillLevel(i, SKILL_MAX_LEVEL);
  3839.         }
  3840.         else
  3841.         {
  3842.             switch(i)
  3843.             {
  3844.             case SKILL_HORSE_WILDATTACK:
  3845.             case SKILL_HORSE_CHARGE:
  3846.             case SKILL_HORSE_ESCAPE:
  3847.             case SKILL_HORSE_WILDATTACK_RANGE:
  3848.                 ch->SetSkillLevel(i, SKILL_MAX_LEVEL);
  3849.                 break;
  3850.             }
  3851.         }
  3852.     }
  3853.     ch->ComputePoints();
  3854.     ch->SkillLevelPacket();
  3855. }
  3856.  
  3857. ACMD (do_item_full_set)
  3858. {
  3859.     BYTE job = ch->GetJob();
  3860.     LPITEM item;
  3861.     for (int i = 0; i < 6; i++)
  3862.     {
  3863.         item = ch->GetWear(i);
  3864.         if (item != NULL)
  3865.             ch->UnequipItem(item);
  3866.     }
  3867.     item = ch->GetWear(WEAR_SHIELD);
  3868.     if (item != NULL)
  3869.         ch->UnequipItem(item);
  3870.  
  3871.     switch (job)
  3872.     {
  3873.     case JOB_SURA:
  3874.         {
  3875.            
  3876.             item = ITEM_MANAGER::instance().CreateItem(11699);
  3877.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3878.                 M2_DESTROY_ITEM(item);
  3879.             item = ITEM_MANAGER::instance().CreateItem(13049);
  3880.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3881.                 M2_DESTROY_ITEM(item);
  3882.             item = ITEM_MANAGER::instance().CreateItem(15189 );
  3883.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3884.                 M2_DESTROY_ITEM(item);
  3885.             item = ITEM_MANAGER::instance().CreateItem(189 );
  3886.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3887.                 M2_DESTROY_ITEM(item);
  3888.             item = ITEM_MANAGER::instance().CreateItem(12529 );
  3889.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3890.                 M2_DESTROY_ITEM(item);
  3891.             item = ITEM_MANAGER::instance().CreateItem(14109 );
  3892.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3893.                 M2_DESTROY_ITEM(item);
  3894.             item = ITEM_MANAGER::instance().CreateItem(17209 );
  3895.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3896.                 M2_DESTROY_ITEM(item);
  3897.             item = ITEM_MANAGER::instance().CreateItem(16209 );
  3898.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3899.                 M2_DESTROY_ITEM(item);
  3900.         }
  3901.         break;
  3902.     case JOB_WARRIOR:
  3903.         {
  3904.            
  3905.             item = ITEM_MANAGER::instance().CreateItem(11299);
  3906.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3907.                 M2_DESTROY_ITEM(item);
  3908.             item = ITEM_MANAGER::instance().CreateItem(13049);
  3909.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3910.                 M2_DESTROY_ITEM(item);
  3911.             item = ITEM_MANAGER::instance().CreateItem(15189 );
  3912.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3913.                 M2_DESTROY_ITEM(item);
  3914.             item = ITEM_MANAGER::instance().CreateItem(3159 );
  3915.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3916.                 M2_DESTROY_ITEM(item);
  3917.             item = ITEM_MANAGER::instance().CreateItem(12249 );
  3918.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3919.                 M2_DESTROY_ITEM(item);
  3920.             item = ITEM_MANAGER::instance().CreateItem(14109 );
  3921.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3922.                 M2_DESTROY_ITEM(item);
  3923.             item = ITEM_MANAGER::instance().CreateItem(17109 );
  3924.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3925.                 M2_DESTROY_ITEM(item);
  3926.             item = ITEM_MANAGER::instance().CreateItem(16109 );
  3927.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3928.                 M2_DESTROY_ITEM(item);
  3929.         }
  3930.         break;
  3931.     case JOB_SHAMAN:
  3932.         {
  3933.            
  3934.             item = ITEM_MANAGER::instance().CreateItem(11899);
  3935.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3936.                 M2_DESTROY_ITEM(item);
  3937.             item = ITEM_MANAGER::instance().CreateItem(13049);
  3938.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3939.                 M2_DESTROY_ITEM(item);
  3940.             item = ITEM_MANAGER::instance().CreateItem(15189 );
  3941.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3942.                 M2_DESTROY_ITEM(item);
  3943.             item = ITEM_MANAGER::instance().CreateItem(7159 );
  3944.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3945.                 M2_DESTROY_ITEM(item);
  3946.             item = ITEM_MANAGER::instance().CreateItem(12669 );
  3947.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3948.                 M2_DESTROY_ITEM(item);
  3949.             item = ITEM_MANAGER::instance().CreateItem(14109 );
  3950.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3951.                 M2_DESTROY_ITEM(item);
  3952.             item = ITEM_MANAGER::instance().CreateItem(17209 );
  3953.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3954.                 M2_DESTROY_ITEM(item);
  3955.             item = ITEM_MANAGER::instance().CreateItem(16209 );
  3956.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3957.                 M2_DESTROY_ITEM(item);
  3958.         }
  3959.         break;
  3960.     case JOB_ASSASSIN:
  3961.         {
  3962.            
  3963.             item = ITEM_MANAGER::instance().CreateItem(11499);
  3964.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3965.                 M2_DESTROY_ITEM(item);
  3966.             item = ITEM_MANAGER::instance().CreateItem(13049);
  3967.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3968.                 M2_DESTROY_ITEM(item);
  3969.             item = ITEM_MANAGER::instance().CreateItem(15189 );
  3970.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3971.                 M2_DESTROY_ITEM(item);
  3972.             item = ITEM_MANAGER::instance().CreateItem(1139 );
  3973.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3974.                 M2_DESTROY_ITEM(item);
  3975.             item = ITEM_MANAGER::instance().CreateItem(12389 );
  3976.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3977.                 M2_DESTROY_ITEM(item);
  3978.             item = ITEM_MANAGER::instance().CreateItem(14109 );
  3979.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3980.                 M2_DESTROY_ITEM(item);
  3981.             item = ITEM_MANAGER::instance().CreateItem(17189 );
  3982.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3983.                 M2_DESTROY_ITEM(item);
  3984.             item = ITEM_MANAGER::instance().CreateItem(16189 );
  3985.             if (!item || !item->EquipTo(ch, item->FindEquipCell(ch)))
  3986.                 M2_DESTROY_ITEM(item);
  3987.         }
  3988.         break;
  3989.     }
  3990. }
  3991.  
  3992. ACMD (do_attr_full_set)
  3993. {
  3994.     BYTE job = ch->GetJob();
  3995.     LPITEM item;
  3996.  
  3997.     switch (job)
  3998.     {
  3999.     case JOB_WARRIOR:
  4000.     case JOB_ASSASSIN:
  4001.     case JOB_SURA:
  4002.     case JOB_SHAMAN:
  4003.         {
  4004.             // 무사 몸빵 셋팅.
  4005.             // 이것만 나와 있어서 임시로 모든 직군 다 이런 속성 따름.
  4006.             item = ch->GetWear(WEAR_HEAD);
  4007.             if (item != NULL)
  4008.             {
  4009.                 item->ClearAttribute();
  4010.                 item->SetForceAttribute( 0, APPLY_ATT_SPEED, 8);
  4011.                 item->SetForceAttribute( 1, APPLY_HP_REGEN, 30);
  4012.                 item->SetForceAttribute( 2, APPLY_SP_REGEN, 30);
  4013.                 item->SetForceAttribute( 3, APPLY_DODGE, 15);
  4014.                 item->SetForceAttribute( 4, APPLY_STEAL_SP, 10);
  4015.             }
  4016.  
  4017.             item = ch->GetWear(WEAR_WEAPON);
  4018.             if (item != NULL)
  4019.             {
  4020.                 item->ClearAttribute();
  4021.                 item->SetForceAttribute( 0, APPLY_CAST_SPEED, 20);
  4022.                 item->SetForceAttribute( 1, APPLY_CRITICAL_PCT, 10);
  4023.                 item->SetForceAttribute( 2, APPLY_PENETRATE_PCT, 10);
  4024.                 item->SetForceAttribute( 3, APPLY_ATTBONUS_DEVIL, 20);
  4025.                 item->SetForceAttribute( 4, APPLY_STR, 12);
  4026.             }
  4027.  
  4028.             item = ch->GetWear(WEAR_SHIELD);
  4029.             if (item != NULL)
  4030.             {
  4031.                 item->ClearAttribute();
  4032.                 item->SetForceAttribute( 0, APPLY_CON, 12);
  4033.                 item->SetForceAttribute( 1, APPLY_BLOCK, 15);
  4034.                 item->SetForceAttribute( 2, APPLY_REFLECT_MELEE, 10);
  4035.                 item->SetForceAttribute( 3, APPLY_IMMUNE_STUN, 1);
  4036.                 item->SetForceAttribute( 4, APPLY_IMMUNE_SLOW, 1);
  4037.             }
  4038.  
  4039.             item = ch->GetWear(WEAR_BODY);
  4040.             if (item != NULL)
  4041.             {
  4042.                 item->ClearAttribute();
  4043.                 item->SetForceAttribute( 0, APPLY_MAX_HP, 2000);
  4044.                 item->SetForceAttribute( 1, APPLY_CAST_SPEED, 20);
  4045.                 item->SetForceAttribute( 2, APPLY_STEAL_HP, 10);
  4046.                 item->SetForceAttribute( 3, APPLY_REFLECT_MELEE, 10);
  4047.                 item->SetForceAttribute( 4, APPLY_ATT_GRADE_BONUS, 50);
  4048.             }
  4049.  
  4050.             item = ch->GetWear(WEAR_FOOTS);
  4051.             if (item != NULL)
  4052.             {
  4053.                 item->ClearAttribute();
  4054.                 item->SetForceAttribute( 0, APPLY_MAX_HP, 2000);
  4055.                 item->SetForceAttribute( 1, APPLY_MAX_SP, 80);
  4056.                 item->SetForceAttribute( 2, APPLY_MOV_SPEED, 8);
  4057.                 item->SetForceAttribute( 3, APPLY_ATT_SPEED, 8);
  4058.                 item->SetForceAttribute( 4, APPLY_CRITICAL_PCT, 10);
  4059.             }
  4060.  
  4061.             item = ch->GetWear(WEAR_WRIST);
  4062.             if (item != NULL)
  4063.             {
  4064.                 item->ClearAttribute();
  4065.                 item->SetForceAttribute( 0, APPLY_MAX_HP, 2000);
  4066.                 item->SetForceAttribute( 1, APPLY_MAX_SP, 80);
  4067.                 item->SetForceAttribute( 2, APPLY_PENETRATE_PCT, 10);
  4068.                 item->SetForceAttribute( 3, APPLY_STEAL_HP, 10);
  4069.                 item->SetForceAttribute( 4, APPLY_MANA_BURN_PCT, 10);
  4070.             }
  4071.             item = ch->GetWear(WEAR_NECK);
  4072.             if (item != NULL)
  4073.             {
  4074.                 item->ClearAttribute();
  4075.                 item->SetForceAttribute( 0, APPLY_MAX_HP, 2000);
  4076.                 item->SetForceAttribute( 1, APPLY_MAX_SP, 80);
  4077.                 item->SetForceAttribute( 2, APPLY_CRITICAL_PCT, 10);
  4078.                 item->SetForceAttribute( 3, APPLY_PENETRATE_PCT, 10);
  4079.                 item->SetForceAttribute( 4, APPLY_STEAL_SP, 10);
  4080.             }
  4081.             item = ch->GetWear(WEAR_EAR);
  4082.             if (item != NULL)
  4083.             {
  4084.                 item->ClearAttribute();
  4085.                 item->SetForceAttribute( 0, APPLY_MOV_SPEED, 20);
  4086.                 item->SetForceAttribute( 1, APPLY_MANA_BURN_PCT, 10);
  4087.                 item->SetForceAttribute( 2, APPLY_POISON_REDUCE, 5);
  4088.                 item->SetForceAttribute( 3, APPLY_ATTBONUS_DEVIL, 20);
  4089.                 item->SetForceAttribute( 4, APPLY_ATTBONUS_UNDEAD, 20);
  4090.             }
  4091.         }
  4092.         break;
  4093.     }
  4094. }
  4095.  
  4096. ACMD (do_use_item)
  4097. {
  4098.     char arg1 [256];
  4099.  
  4100.     one_argument (argument, arg1, sizeof (arg1));
  4101.  
  4102.     int cell;
  4103.     str_to_number(cell, arg1);
  4104.    
  4105.     LPITEM item = ch->GetInventoryItem(cell);
  4106.     if (item)
  4107.     {
  4108.         ch->UseItem(TItemPos (INVENTORY, cell));
  4109.     }
  4110.     else
  4111.     {
  4112.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;542]");
  4113.     }
  4114. }
  4115.  
  4116. ACMD (do_clear_affect)
  4117. {
  4118.     ch->ClearAffect(true);
  4119. }
  4120.  
  4121. ACMD (do_dragon_soul)
  4122. {
  4123.     char arg1[512];
  4124.     const char* rest = one_argument (argument, arg1, sizeof(arg1));
  4125.     switch (arg1[0])
  4126.     {
  4127.     case 'a':
  4128.         {
  4129.             one_argument (rest, arg1, sizeof(arg1));
  4130.             int deck_idx;
  4131.             if (str_to_number(deck_idx, arg1) == false)
  4132.             {
  4133.                 return;
  4134.             }
  4135.             ch->DragonSoul_ActivateDeck(deck_idx);
  4136.         }
  4137.         break;
  4138.     case 'd':
  4139.         {
  4140.             ch->DragonSoul_DeactivateAll();
  4141.         }
  4142.         break;
  4143.     }
  4144. }
  4145.  
  4146. ACMD (do_ds_list)
  4147. {
  4148.     for (int i = 0; i < DRAGON_SOUL_INVENTORY_MAX_NUM; i++)
  4149.     {
  4150.         TItemPos cell(DRAGON_SOUL_INVENTORY, i);
  4151.        
  4152.         LPITEM item = ch->GetItem(cell);
  4153.         if (item != NULL)
  4154.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;548;%d;%s;%d]", item->GetCell(), item->GetName(), item->GetID());
  4155.     }
  4156. }
  4157.  
  4158. ACMD(do_test) {
  4159.     BOOST_ASSERT_MSG(ch, "Character nullptr.");
  4160.    
  4161.     auto args = ParseArguments(argument);
  4162.     if (args.size() < 1) return;
  4163.  
  4164.     try {
  4165.         switch (static_cast<uint8_t>(std::stoi(args[0]))) {
  4166.             case 0: {
  4167.                 ch->ChatPacket(CHAT_TYPE_COMMAND, "RecvControllPacket 0");
  4168.             } break;
  4169.  
  4170.             default:
  4171.                 break;
  4172.         }
  4173.     } catch (...) {
  4174.         return;
  4175.     }
  4176. }
  4177.  
Advertisement
Add Comment
Please, Sign In to add comment