Guest User

cmd_general

a guest
Jul 12th, 2024
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 41.03 KB | None | 0 0
  1. #include "stdafx.h"
  2. #ifdef __FreeBSD__
  3. #include <md5.h>
  4. #else
  5. #include "../../libthecore/include/xmd5.h"
  6. #endif
  7.  
  8. #include "utils.h"
  9. #include "config.h"
  10. #include "desc_client.h"
  11. #include "desc_manager.h"
  12. #include "char.h"
  13. #include "char_manager.h"
  14. #include "motion.h"
  15. #include "packet.h"
  16. #include "affect.h"
  17. #include "pvp.h"
  18. #include "start_position.h"
  19. #include "party.h"
  20. #include "guild_manager.h"
  21. #include "p2p.h"
  22. #include "dungeon.h"
  23. #include "messenger_manager.h"
  24. #include "war_map.h"
  25. #include "questmanager.h"
  26. #include "item_manager.h"
  27. #include "mob_manager.h"
  28. #include "item.h"
  29. #include "arena.h"
  30. #include "buffer_manager.h"
  31. #include "unique_item.h"
  32. #include "log.h"
  33. #include "../../common/VnumHelper.h"
  34.  
  35. extern int g_server_id;
  36. extern int g_nPortalLimitTime;
  37.  
  38. ACMD(do_user_horse_ride)
  39. {
  40.     static std::chrono::steady_clock::time_point lastCallTime;
  41.  
  42.     auto now = std::chrono::steady_clock::now();
  43.     auto timeElapsed = std::chrono::duration_cast<std::chrono::seconds>(now - lastCallTime);
  44.  
  45.     if (timeElapsed < COOLDOWN_HORSE_RIDE)
  46.     {
  47.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;1;%d]", static_cast<int32_t>(COOLDOWN_HORSE_RIDE.count() - timeElapsed.count()));
  48.         return;
  49.     }
  50.  
  51.     lastCallTime = now;
  52.    
  53.     if (ch->IsObserverMode() || ch->IsDead() || ch->IsStun())
  54.     {
  55.         return;
  56.     }
  57.  
  58.     auto isRiding = ch->IsHorseRiding();
  59.     auto hasMount = ch->GetMountVnum() != 0;
  60.     auto hasHorse = ch->GetHorse() != nullptr;
  61.  
  62.     if (!isRiding)
  63.     {
  64.         if (hasMount)
  65.         {
  66.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;2]");
  67.             return;
  68.         }
  69.  
  70.         if (!hasHorse)
  71.         {
  72.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;3]");
  73.             return;
  74.         }
  75.     }
  76.    
  77.     ch->ToggleRiding();
  78. }
  79.  
  80. ACMD(do_drop)
  81. {
  82.     if (!ch || !ch->GetDesc()) { return; }
  83.     char arg1[256], arg2[256];
  84.  
  85.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  86.  
  87.     if (!*arg1 || !*arg2)
  88.     {
  89.         ch->ChatPacket(CHAT_TYPE_INFO, "Syntax: drop_simul <mob vnum> <count>");
  90.         return;
  91.     }
  92.  
  93.     DWORD vnum = 0;
  94.     str_to_number(vnum, arg1);
  95.     DWORD loopCount = 0;
  96.     str_to_number(loopCount, arg2);
  97.  
  98.     if (vnum == 0 || loopCount == 0)
  99.     {
  100.         ch->ChatPacket(CHAT_TYPE_INFO, "Syntax: drop_simul <mob vnum> <count>");
  101.         return;
  102.     }
  103.  
  104.     auto* mob = CMobManager::instance().Get(vnum);
  105.     if (!mob)
  106.     {
  107.         ch->ChatPacket(CHAT_TYPE_INFO, "Mob vnum: %u not found", vnum);
  108.         return;
  109.     }
  110.  
  111.  
  112.     std::vector<LPITEM> dropVec;
  113.     std::unordered_map<DWORD/*vnum*/, DropItem> dropMap;
  114.  
  115.     if (ITEM_MANAGER::instance().CreateMobDropVec(vnum, dropVec))
  116.     {
  117.         for (const auto& item : dropVec)
  118.         {
  119.             if (!item) { continue; }
  120.            
  121.             const auto itemVnum = item->GetVnum();
  122.             const auto itemCount = item->GetCount();
  123.            
  124.             if (itemVnum == 0 || itemCount == 0) { continue; }
  125.        
  126.             const auto& it = dropMap.find(itemVnum);
  127.             if (it != dropMap.end())
  128.             {
  129.                 it->second.count += itemCount;
  130.             }
  131.             else
  132.             {
  133.                 DropItem dropItem{};
  134.                 dropItem.count = itemCount;
  135.                 strlcpy(dropItem.szName, item->GetName(), sizeof(dropItem.szName));
  136.                 dropMap[itemVnum] = dropItem;
  137.             }
  138.  
  139.             M2_DESTROY_ITEM(item);
  140.         }
  141.  
  142.         ch->ChatPacket(CHAT_TYPE_PARTY, "############### |cFF6d8cf2|H|h(%d)x %s|h|r DROP SIMULATION ###############", loopCount, mob->m_table.szLocaleName);
  143.  
  144.         const auto& func = [&](auto& pair)
  145.         {
  146.             auto& [vnum, dropItem] = pair;
  147.             dropItem.count *= loopCount;
  148.             ch->ChatPacket(CHAT_TYPE_PARTY, "Item: %s - Count: %u", dropItem.szName, dropItem.count);
  149.         };
  150.  
  151.         std::for_each(dropMap.begin(), dropMap.end(), func);
  152.     }
  153. }
  154.  
  155. ACMD(do_user_horse_back)
  156. {
  157.     auto horse = ch->GetHorse();
  158.    
  159.     if (horse != nullptr)
  160.     {
  161.         ch->HorseSummon(false);
  162.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;4]");
  163.     }
  164.     else if (ch->IsHorseRiding())
  165.     {
  166.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;5]");
  167.     }
  168.     else
  169.     {
  170.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;3]");
  171.     }
  172. }
  173.  
  174. ACMD(do_user_horse_feed)
  175. {
  176.     if (ch->GetMyShop())
  177.     {
  178.         return;
  179.     }
  180.  
  181.     auto horse = ch->GetHorse();
  182.  
  183.     if (!horse)
  184.     {
  185.         auto message = ch->IsHorseRiding() ? "[LS;6]" : "[LS;3]";
  186.         ch->ChatPacket(CHAT_TYPE_INFO, message);
  187.         return;
  188.     }
  189.    
  190.     if (ch->IsHorseDead())
  191.     {
  192.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;9]");
  193.         return;
  194.     }
  195.  
  196.     auto foodItemId = static_cast<uint32_t>(ch->GetHorseGrade() + 50054 - 1);
  197.     auto itemTable = ITEM_MANAGER::instance().GetTable(foodItemId);
  198.     auto itemName = itemTable->szLocaleName;
  199.  
  200.     if (ch->CountSpecifyItem(foodItemId) > 0)
  201.     {
  202.         ch->RemoveSpecifyItem(foodItemId, 1);
  203.         ch->FeedHorse();
  204.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;7;%s]", itemName);
  205.     }
  206.     else
  207.     {
  208.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;8;%s]", itemName);
  209.     }
  210. }
  211.  
  212. struct DropItem
  213. {
  214.     char szName[ITEM_NAME_MAX_LEN + 1];
  215.     DWORD count;
  216. };
  217.  
  218. #define MAX_REASON_LEN      128
  219.  
  220. EVENTINFO(TimedEventInfo)
  221. {
  222.     DynamicCharacterPtr ch;
  223.     int     subcmd;
  224.     int             left_second;
  225.     char        szReason[MAX_REASON_LEN];
  226.  
  227.     TimedEventInfo()
  228.     : ch()
  229.     , subcmd( 0 )
  230.     , left_second( 0 )
  231.     {
  232.         ::memset( szReason, 0, MAX_REASON_LEN );
  233.     }
  234. };
  235.  
  236. struct SendDisconnectFunc
  237. {
  238.     void operator () (LPDESC d)
  239.     {
  240.         if (d->GetCharacter())
  241.         {
  242.             if (d->GetCharacter()->GetGMLevel() == GM_PLAYER)
  243.                 d->GetCharacter()->ChatPacket(CHAT_TYPE_COMMAND, "quit Shutdown(SendDisconnectFunc)");
  244.         }
  245.     }
  246. };
  247.  
  248. struct DisconnectFunc
  249. {
  250.     void operator () (LPDESC d)
  251.     {
  252.         if (d->GetType() == DESC_TYPE_CONNECTOR)
  253.             return;
  254.  
  255.         if (d->IsPhase(PHASE_P2P))
  256.             return;
  257.  
  258.         if (d->GetCharacter())
  259.             d->GetCharacter()->Disconnect("Shutdown(DisconnectFunc)");
  260.  
  261.         d->SetPhase(PHASE_CLOSE);
  262.     }
  263. };
  264.  
  265. EVENTINFO(shutdown_event_data)
  266. {
  267.     int seconds;
  268.  
  269.     shutdown_event_data()
  270.     : seconds( 0 )
  271.     {
  272.     }
  273. };
  274.  
  275. EVENTFUNC(shutdown_event)
  276. {
  277.     shutdown_event_data* info = dynamic_cast<shutdown_event_data*>( event->info );
  278.  
  279.     if ( info == NULL )
  280.     {
  281.         sys_err( "shutdown_event> <Factor> Null pointer" );
  282.         return 0;
  283.     }
  284.  
  285.     int * pSec = & (info->seconds);
  286.  
  287.     if (*pSec < 0)
  288.     {
  289.         sys_log(0, "shutdown_event sec %d", *pSec);
  290.  
  291.         if (--*pSec == -10)
  292.         {
  293.             const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
  294.             std::for_each(c_set_desc.begin(), c_set_desc.end(), DisconnectFunc());
  295.             return passes_per_sec;
  296.         }
  297.         else if (*pSec < -10)
  298.             return 0;
  299.  
  300.         return passes_per_sec;
  301.     }
  302.     else if (*pSec == 0)
  303.     {
  304.         const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
  305.         std::for_each(c_set_desc.begin(), c_set_desc.end(), SendDisconnectFunc());
  306.         g_bNoMoreClient = true;
  307.         --*pSec;
  308.         return passes_per_sec;
  309.     }
  310.     else
  311.     {
  312.         char buf[64];
  313.         snprintf(buf, sizeof(buf),"[LS;83;%d]", *pSec);
  314.         SendNotice(buf);
  315.  
  316.         --*pSec;
  317.         return passes_per_sec;
  318.     }
  319. }
  320.  
  321. void Shutdown(int iSec)
  322. {
  323.     if (g_bNoMoreClient)
  324.     {
  325.         thecore_shutdown();
  326.         return;
  327.     }
  328.  
  329.     CWarMapManager::instance().OnShutdown();
  330.  
  331.     char buf[64];
  332.     snprintf(buf, sizeof(buf), "[LS;82;%d]", iSec);
  333.  
  334.     SendNotice(buf);
  335.  
  336.     shutdown_event_data* info = AllocEventInfo<shutdown_event_data>();
  337.     info->seconds = iSec;
  338.  
  339.     event_create(shutdown_event, info, 1);
  340. }
  341.  
  342. ACMD(do_shutdown)
  343. {
  344.     if (ch == nullptr)
  345.     {
  346.         sys_err("Attempt to shutdown with null character pointer.");
  347.         return;
  348.     }
  349.  
  350.     if (!ch->IsGM())
  351.     {
  352.         sys_err("Unauthorized attempt to shutdown by %s.", ch->GetName());
  353.         return;
  354.     }
  355.  
  356.     TPacketGGShutdown p;
  357.     p.bHeader = HEADER_GG_SHUTDOWN;
  358.     P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGShutdown));
  359.  
  360.     Shutdown(10);
  361. }
  362.  
  363. EVENTFUNC(timed_event)
  364. {
  365.     TimedEventInfo * info = dynamic_cast<TimedEventInfo *>( event->info );
  366.    
  367.     if ( info == NULL )
  368.     {
  369.         sys_err( "timed_event> <Factor> Null pointer" );
  370.         return 0;
  371.     }
  372.  
  373.     LPCHARACTER ch = info->ch;
  374.     if (ch == NULL) { // <Factor>
  375.         return 0;
  376.     }
  377.     LPDESC d = ch->GetDesc();
  378.  
  379.     if (info->left_second <= 0)
  380.     {
  381.         ch->m_pkTimedEvent = NULL;
  382.  
  383.         if (true == LC_IsEurope() || true == LC_IsYMIR() || true == LC_IsKorea())
  384.         {
  385.             switch (info->subcmd)
  386.             {
  387.                 case SCMD_LOGOUT:
  388.                 case SCMD_QUIT:
  389.                 case SCMD_PHASE_SELECT:
  390.                     {
  391.                         TPacketNeedLoginLogInfo acc_info;
  392.                         acc_info.dwPlayerID = ch->GetDesc()->GetAccountTable().id;
  393.  
  394.                         db_clientdesc->DBPacket( HEADER_GD_VALID_LOGOUT, 0, &acc_info, sizeof(acc_info) );
  395.  
  396.                         LogManager::instance().DetailLoginLog( false, ch );
  397.                     }
  398.                     break;
  399.             }
  400.         }
  401.  
  402.         switch (info->subcmd)
  403.         {
  404.             case SCMD_LOGOUT:
  405.             {
  406.                 if (d)
  407.                 {
  408.                     d->SetPhase(PHASE_CLOSE);
  409.                 }
  410.                
  411.                 break;
  412.             }
  413.  
  414.         case SCMD_QUIT:
  415.         {
  416.             if (d)
  417.             {
  418.                 ch->ChatPacket(CHAT_TYPE_COMMAND, "quit");
  419.                 d->DelayedDisconnect(2);
  420.             }
  421.  
  422.             break;
  423.         }
  424.  
  425.             case SCMD_PHASE_SELECT:
  426.             {
  427.                 ch->Disconnect("timed_event - SCMD_PHASE_SELECT");
  428.  
  429.                 if (d)
  430.                 {
  431.                     d->SetPhase(PHASE_SELECT);
  432.                 }
  433.                
  434.                 break;
  435.             }
  436.         }
  437.  
  438.         return 0;
  439.     }
  440.     else
  441.     {
  442.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;81;%d]", info->left_second);
  443.  
  444.         --info->left_second;
  445.     }
  446.  
  447.     return PASSES_PER_SEC(1);
  448. }
  449.  
  450. ACMD(do_cmd)
  451. {
  452.     if (ch->m_pkTimedEvent)
  453.     {
  454.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;80]");
  455.         event_cancel(&ch->m_pkTimedEvent);
  456.         return;
  457.     }
  458.  
  459.     switch (subcmd)
  460.     {
  461.         case SCMD_LOGOUT:
  462.             break;
  463.  
  464.         case SCMD_QUIT:
  465.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;78]");
  466.             break;
  467.  
  468.         case SCMD_PHASE_SELECT:
  469.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;79]");
  470.             break;
  471.     }
  472.  
  473.     int nExitLimitTime = 10;
  474.  
  475.     if (ch->IsHack (false, true, nExitLimitTime) && (!ch->GetWarMap() || ch->GetWarMap()->GetType() == GUILD_WAR_TYPE_FLAG))
  476.     {
  477.         return;
  478.     }
  479.    
  480.     switch (subcmd)
  481.     {
  482.         case SCMD_LOGOUT:
  483.         case SCMD_QUIT:
  484.         case SCMD_PHASE_SELECT:
  485.             {
  486.                 TimedEventInfo* info = AllocEventInfo<TimedEventInfo>();
  487.  
  488.                 {
  489.                     if (ch->IsPosition(POS_FIGHTING))
  490.                         info->left_second = 10;
  491.                     else
  492.                         info->left_second = 3;
  493.                 }
  494.  
  495.                 info->ch        = ch;
  496.                 info->subcmd        = subcmd;
  497.                 strlcpy(info->szReason, argument, sizeof(info->szReason));
  498.  
  499.                 ch->m_pkTimedEvent  = event_create(timed_event, info, 1);
  500.             }
  501.             break;
  502.     }
  503. }
  504.  
  505. ACMD(do_mount)
  506. {
  507. }
  508.  
  509. ACMD(do_fishing)
  510. {
  511.     char arg1[256];
  512.     one_argument(argument, arg1, sizeof(arg1));
  513.  
  514.     if (!*arg1)
  515.         return;
  516.  
  517.     ch->SetRotation(atof(arg1));
  518.     ch->fishing();
  519. }
  520.  
  521. ACMD(do_console)
  522. {
  523.     ch->ChatPacket(CHAT_TYPE_COMMAND, "ConsoleEnable");
  524. }
  525.  
  526. ACMD(do_restart)
  527. {
  528.     if (false == ch->IsDead())
  529.     {
  530.         ch->ChatPacket(CHAT_TYPE_COMMAND, "CloseRestartWindow");
  531.         ch->StartRecoveryEvent();
  532.         return;
  533.     }
  534.  
  535.     if (NULL == ch->m_pkDeadEvent)
  536.         return;
  537.  
  538.     int iTimeToDead = (event_time(ch->m_pkDeadEvent) / passes_per_sec);
  539.  
  540.     if (subcmd != SCMD_RESTART_TOWN && (!ch->GetWarMap() || ch->GetWarMap()->GetType() == GUILD_WAR_TYPE_FLAG))
  541.     {
  542.         if (!test_server)
  543.         {
  544.             if (iTimeToDead > 170)
  545.             {
  546.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;74;%d]", iTimeToDead - 170);
  547.                 return;
  548.             }
  549.         }
  550.     }
  551.  
  552.     //PREVENT_HACK
  553.     //DESC : 창고, 교환 창 후 포탈을 사용하는 버그에 이용될수 있어서
  554.     //      쿨타임을 추가
  555.     if (subcmd == SCMD_RESTART_TOWN)
  556.     {
  557.         if (ch->IsHack())
  558.         {
  559.             if ((!ch->GetWarMap() || ch->GetWarMap()->GetType() == GUILD_WAR_TYPE_FLAG))
  560.             {
  561.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;75;%d]", iTimeToDead - (180 - g_nPortalLimitTime));
  562.                 return;
  563.             }
  564.         }
  565.  
  566.         if (iTimeToDead > 173)
  567.         {
  568.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;76;%d]", iTimeToDead - 173);
  569.             return;
  570.         }
  571.     }
  572.     //END_PREVENT_HACK
  573.  
  574.     ch->ChatPacket(CHAT_TYPE_COMMAND, "CloseRestartWindow");
  575.  
  576.     ch->GetDesc()->SetPhase(PHASE_GAME);
  577.     ch->SetPosition(POS_STANDING);
  578.     ch->StartRecoveryEvent();
  579.  
  580.     if (ch->GetDungeon())
  581.         ch->GetDungeon()->UseRevive(ch);
  582.  
  583.     if (ch->GetWarMap() && !ch->IsObserverMode())
  584.     {
  585.         CWarMap * pMap = ch->GetWarMap();
  586.         DWORD dwGuildOpponent = pMap ? pMap->GetGuildOpponent(ch) : 0;
  587.  
  588.         if (dwGuildOpponent)
  589.         {
  590.             switch (subcmd)
  591.             {
  592.                 case SCMD_RESTART_TOWN:
  593.                     sys_log(0, "do_restart: restart town");
  594.                     PIXEL_POSITION pos;
  595.  
  596.                     if (CWarMapManager::instance().GetStartPosition(ch->GetMapIndex(), ch->GetGuild()->GetID() < dwGuildOpponent ? 0 : 1, pos))
  597.                         ch->Show(ch->GetMapIndex(), pos.x, pos.y);
  598.                     else
  599.                         ch->ExitToSavedLocation();
  600.  
  601.                     ch->PointChange(POINT_HP, ch->GetMaxHP() - ch->GetHP());
  602.                     ch->PointChange(POINT_SP, ch->GetMaxSP() - ch->GetSP());
  603.                     ch->ReviveInvisible(5);
  604.                     break;
  605.  
  606.                 case SCMD_RESTART_HERE:
  607.                     sys_log(0, "do_restart: restart here");
  608.                     ch->RestartAtSamePos();
  609.                     ch->PointChange(POINT_HP, ch->GetMaxHP() - ch->GetHP());
  610.                     ch->PointChange(POINT_SP, ch->GetMaxSP() - ch->GetSP());
  611.                     ch->ReviveInvisible(5);
  612.                     break;
  613.             }
  614.  
  615.             return;
  616.         }
  617.     }
  618.  
  619.     switch (subcmd)
  620.     {
  621.         case SCMD_RESTART_TOWN:
  622.             sys_log(0, "do_restart: restart town");
  623.             PIXEL_POSITION pos;
  624.  
  625.             if (SECTREE_MANAGER::instance().GetRecallPositionByEmpire(ch->GetMapIndex(), ch->GetEmpire(), pos))
  626.                 ch->WarpSet(pos.x, pos.y);
  627.             else
  628.                 ch->WarpSet(EMPIRE_START_X(ch->GetEmpire()), EMPIRE_START_Y(ch->GetEmpire()));
  629.  
  630.             ch->PointChange(POINT_HP, 50 - ch->GetHP());
  631.             ch->DeathPenalty(1);
  632.             break;
  633.  
  634.         case SCMD_RESTART_HERE:
  635.             sys_log(0, "do_restart: restart here");
  636.             ch->RestartAtSamePos();
  637.             ch->PointChange(POINT_HP, 50 - ch->GetHP());
  638.             ch->DeathPenalty(0);
  639.             ch->ReviveInvisible(5);
  640.             break;
  641.     }
  642. }
  643.  
  644. #define MAX_STAT 90
  645.  
  646. ACMD(do_stat_reset)
  647. {
  648.     ch->PointChange(POINT_STAT_RESET_COUNT, 12 - ch->GetPoint(POINT_STAT_RESET_COUNT));
  649. }
  650.  
  651. ACMD(do_stat_minus)
  652. {
  653.     char arg1[256];
  654.     one_argument(argument, arg1, sizeof(arg1));
  655.  
  656.     if (!*arg1)
  657.         return;
  658.  
  659.     if (ch->IsPolymorphed())
  660.     {
  661.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;425]");
  662.         return;
  663.     }
  664.  
  665.     if (ch->GetPoint(POINT_STAT_RESET_COUNT) <= 0)
  666.         return;
  667.  
  668.     if (!strcmp(arg1, "st"))
  669.     {
  670.         if (ch->GetRealPoint(POINT_ST) <= JobInitialPoints[ch->GetJob()].st)
  671.             return;
  672.  
  673.         ch->SetRealPoint(POINT_ST, ch->GetRealPoint(POINT_ST) - 1);
  674.         ch->SetPoint(POINT_ST, ch->GetPoint(POINT_ST) - 1);
  675.         ch->ComputePoints();
  676.         ch->PointChange(POINT_ST, 0);
  677.     }
  678.     else if (!strcmp(arg1, "dx"))
  679.     {
  680.         if (ch->GetRealPoint(POINT_DX) <= JobInitialPoints[ch->GetJob()].dx)
  681.             return;
  682.  
  683.         ch->SetRealPoint(POINT_DX, ch->GetRealPoint(POINT_DX) - 1);
  684.         ch->SetPoint(POINT_DX, ch->GetPoint(POINT_DX) - 1);
  685.         ch->ComputePoints();
  686.         ch->PointChange(POINT_DX, 0);
  687.     }
  688.     else if (!strcmp(arg1, "ht"))
  689.     {
  690.         if (ch->GetRealPoint(POINT_HT) <= JobInitialPoints[ch->GetJob()].ht)
  691.             return;
  692.  
  693.         ch->SetRealPoint(POINT_HT, ch->GetRealPoint(POINT_HT) - 1);
  694.         ch->SetPoint(POINT_HT, ch->GetPoint(POINT_HT) - 1);
  695.         ch->ComputePoints();
  696.         ch->PointChange(POINT_HT, 0);
  697.         ch->PointChange(POINT_MAX_HP, 0);
  698.     }
  699.     else if (!strcmp(arg1, "iq"))
  700.     {
  701.         if (ch->GetRealPoint(POINT_IQ) <= JobInitialPoints[ch->GetJob()].iq)
  702.             return;
  703.  
  704.         ch->SetRealPoint(POINT_IQ, ch->GetRealPoint(POINT_IQ) - 1);
  705.         ch->SetPoint(POINT_IQ, ch->GetPoint(POINT_IQ) - 1);
  706.         ch->ComputePoints();
  707.         ch->PointChange(POINT_IQ, 0);
  708.         ch->PointChange(POINT_MAX_SP, 0);
  709.     }
  710.     else
  711.         return;
  712.  
  713.     ch->PointChange(POINT_STAT, +1);
  714.     ch->PointChange(POINT_STAT_RESET_COUNT, -1);
  715.     ch->ComputePoints();
  716. }
  717.  
  718. ACMD(do_stat)
  719. {
  720.     char arg1[256];
  721.     one_argument(argument, arg1, sizeof(arg1));
  722.  
  723.     if (!*arg1)
  724.         return;
  725.  
  726.     if (ch->IsPolymorphed())
  727.     {
  728.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;426]");
  729.         return;
  730.     }
  731.  
  732.     if (ch->GetPoint(POINT_STAT) <= 0)
  733.         return;
  734.  
  735.     BYTE idx = 0;
  736.    
  737.     if (!strcmp(arg1, "st"))
  738.         idx = POINT_ST;
  739.     else if (!strcmp(arg1, "dx"))
  740.         idx = POINT_DX;
  741.     else if (!strcmp(arg1, "ht"))
  742.         idx = POINT_HT;
  743.     else if (!strcmp(arg1, "iq"))
  744.         idx = POINT_IQ;
  745.     else
  746.         return;
  747.  
  748.     if (ch->GetRealPoint(idx) >= MAX_STAT)
  749.         return;
  750.  
  751.     ch->SetRealPoint(idx, ch->GetRealPoint(idx) + 1);
  752.     ch->SetPoint(idx, ch->GetPoint(idx) + 1);
  753.     ch->ComputePoints();
  754.     ch->PointChange(idx, 0);
  755.  
  756.     if (idx == POINT_IQ)
  757.     {
  758.         ch->PointChange(POINT_MAX_HP, 0);
  759.     }
  760.     else if (idx == POINT_HT)
  761.     {
  762.         ch->PointChange(POINT_MAX_SP, 0);
  763.     }
  764.  
  765.     ch->PointChange(POINT_STAT, -1);
  766.     ch->ComputePoints();
  767. }
  768.  
  769. ACMD(do_pvp)
  770. {  
  771.     if (ch->GetArena() != NULL || CArenaManager::instance().IsArenaMap(ch->GetMapIndex()) == true)
  772.     {
  773.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;427]");
  774.         return;
  775.     }
  776.  
  777.     char arg1[256];
  778.     one_argument(argument, arg1, sizeof(arg1));
  779.  
  780.     DWORD vid = 0;
  781.     str_to_number(vid, arg1);
  782.     LPCHARACTER pkVictim = CHARACTER_MANAGER::instance().Find(vid);
  783.  
  784.     if (!pkVictim)
  785.         return;
  786.  
  787.     if (pkVictim->IsNPC())
  788.         return;
  789.  
  790.     if (pkVictim->GetArena() != NULL)
  791.     {
  792.         pkVictim->ChatPacket(CHAT_TYPE_INFO, "[LS;428]");
  793.         return;
  794.     }      
  795.    
  796.     if (pkVictim->GetLevel() < 15)
  797.     {
  798.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;307]");
  799.         return;
  800.     }      
  801.  
  802.     CPVPManager::instance().Insert(ch, pkVictim);
  803. }
  804.  
  805. ACMD(do_guildskillup)
  806. {
  807.     char arg1[256];
  808.     one_argument(argument, arg1, sizeof(arg1));
  809.  
  810.     if (!*arg1)
  811.         return;
  812.  
  813.     if (!ch->GetGuild())
  814.     {
  815.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;430]");
  816.         return;
  817.     }
  818.  
  819.     CGuild* g = ch->GetGuild();
  820.     TGuildMember* gm = g->GetMember(ch->GetPlayerID());
  821.     if (gm->grade == GUILD_LEADER_GRADE)
  822.     {
  823.         DWORD vnum = 0;
  824.         str_to_number(vnum, arg1);
  825.         g->SkillLevelUp(vnum);
  826.     }
  827.     else
  828.     {
  829.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;429]");
  830.     }
  831. }
  832.  
  833. ACMD(do_skillup)
  834. {
  835.     char arg1[256];
  836.     one_argument(argument, arg1, sizeof(arg1));
  837.  
  838.     if (!*arg1)
  839.         return;
  840.  
  841.     DWORD vnum = 0;
  842.     str_to_number(vnum, arg1);
  843.  
  844.     if (true == ch->CanUseSkill(vnum))
  845.     {
  846.         ch->SkillLevelUp(vnum);
  847.     }
  848.     else
  849.     {
  850.         switch(vnum)
  851.         {
  852.             case SKILL_HORSE_WILDATTACK:
  853.             case SKILL_HORSE_CHARGE:
  854.             case SKILL_HORSE_ESCAPE:
  855.             case SKILL_HORSE_WILDATTACK_RANGE:
  856.  
  857.             case SKILL_7_A_ANTI_TANHWAN:
  858.             case SKILL_7_B_ANTI_AMSEOP:
  859.             case SKILL_7_C_ANTI_SWAERYUNG:
  860.             case SKILL_7_D_ANTI_YONGBI:
  861.  
  862.             case SKILL_8_A_ANTI_GIGONGCHAM:
  863.             case SKILL_8_B_ANTI_YEONSA:
  864.             case SKILL_8_C_ANTI_MAHWAN:
  865.             case SKILL_8_D_ANTI_BYEURAK:
  866.  
  867.             case SKILL_ADD_HP:
  868.             case SKILL_RESIST_PENETRATE:
  869.                 ch->SkillLevelUp(vnum);
  870.                 break;
  871.         }
  872.     }
  873. }
  874.  
  875. ACMD(do_safebox_close)
  876. {
  877.     ch->CloseSafebox();
  878. }
  879.  
  880. ACMD(do_safebox_password)
  881. {
  882.     char arg1[256];
  883.     one_argument(argument, arg1, sizeof(arg1));
  884.     ch->ReqSafeboxLoad(arg1);
  885. }
  886.  
  887. ACMD(do_safebox_change_password)
  888. {
  889.     char arg1[256];
  890.     char arg2[256];
  891.  
  892.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  893.  
  894.     if (!*arg1 || strlen(arg1)>6)
  895.     {
  896.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;84]");
  897.         return;
  898.     }
  899.  
  900.     if (!*arg2 || strlen(arg2)>6)
  901.     {
  902.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;84]");
  903.         return;
  904.     }
  905.  
  906.     TSafeboxChangePasswordPacket p;
  907.  
  908.     p.dwID = ch->GetDesc()->GetAccountTable().id;
  909.     strlcpy(p.szOldPassword, arg1, sizeof(p.szOldPassword));
  910.     strlcpy(p.szNewPassword, arg2, sizeof(p.szNewPassword));
  911.  
  912.     db_clientdesc->DBPacket(HEADER_GD_SAFEBOX_CHANGE_PASSWORD, ch->GetDesc()->GetHandle(), &p, sizeof(p));
  913. }
  914.  
  915. ACMD(do_mall_password)
  916. {
  917.     char arg1[256];
  918.     one_argument(argument, arg1, sizeof(arg1));
  919.  
  920.     if (!*arg1 || strlen(arg1) > 6)
  921.     {
  922.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;84]");
  923.         return;
  924.     }
  925.  
  926.     int iPulse = thecore_pulse();
  927.  
  928.     if (ch->GetMall())
  929.     {
  930.         ch->ChatPacket(CHAT_TYPE_INFO,"[LS;59]");
  931.         return;
  932.     }
  933.  
  934.     if (iPulse - ch->GetMallLoadTime() < passes_per_sec * 10) // 10초에 한번만 요청 가능
  935.     {
  936.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;60]");
  937.         return;
  938.     }
  939.  
  940.     ch->SetMallLoadTime(iPulse);
  941.  
  942.     TSafeboxLoadPacket p;
  943.     p.dwID = ch->GetDesc()->GetAccountTable().id;
  944.     strlcpy(p.szLogin, ch->GetDesc()->GetAccountTable().login, sizeof(p.szLogin));
  945.     strlcpy(p.szPassword, arg1, sizeof(p.szPassword));
  946.  
  947.     db_clientdesc->DBPacket(HEADER_GD_MALL_LOAD, ch->GetDesc()->GetHandle(), &p, sizeof(p));
  948. }
  949.  
  950. ACMD(do_mall_close)
  951. {
  952.     if (ch->GetMall())
  953.     {
  954.         ch->SetMallLoadTime(thecore_pulse());
  955.         ch->CloseMall();
  956.         ch->Save();
  957.     }
  958. }
  959.  
  960. ACMD(do_ungroup)
  961. {
  962.     if (!ch->GetParty())
  963.         return;
  964.  
  965.     if (!CPartyManager::instance().IsEnablePCParty())
  966.     {
  967.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;43]");
  968.         return;
  969.     }
  970.  
  971.     if (ch->GetDungeon())
  972.     {
  973.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;85]");
  974.         return;
  975.     }
  976.  
  977.     LPPARTY pParty = ch->GetParty();
  978.  
  979.     if (pParty->GetMemberCount() == 2)
  980.     {
  981.         CPartyManager::instance().DeleteParty(pParty);
  982.     }
  983.     else
  984.     {
  985.         ch->ChatPacket(CHAT_TYPE_INFO,  "[LS;86]");
  986.         pParty->Quit(ch->GetPlayerID());
  987.     }
  988. }
  989.  
  990. ACMD(do_close_shop)
  991. {
  992.     if (ch->GetMyShop())
  993.     {
  994.         ch->CloseMyShop();
  995.         return;
  996.     }
  997. }
  998.  
  999. ACMD(do_set_walk_mode)
  1000. {
  1001.     ch->SetNowWalking(true);
  1002.     ch->SetWalking(true);
  1003. }
  1004.  
  1005. ACMD(do_set_run_mode)
  1006. {
  1007.     ch->SetNowWalking(false);
  1008.     ch->SetWalking(false);
  1009. }
  1010.  
  1011. ACMD(do_war)
  1012. {
  1013.     auto playerGuild = ch->GetGuild();
  1014.  
  1015.     if (!playerGuild)
  1016.     {
  1017.         return;
  1018.     }
  1019.  
  1020.     if (playerGuild->UnderAnyWar())
  1021.     {
  1022.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;87]");
  1023.         return;
  1024.     }
  1025.  
  1026.     char arg1[256], arg2[256];
  1027.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  1028.  
  1029.     uint8_t type = GUILD_WAR_TYPE_FIELD;
  1030.  
  1031.     if (!*arg1)
  1032.     {
  1033.         return;
  1034.     }
  1035.  
  1036.     if (*arg2)
  1037.     {
  1038.         str_to_number(type, arg2);
  1039.  
  1040.         if (type >= GUILD_WAR_TYPE_MAX_NUM)
  1041.         {
  1042.             type = GUILD_WAR_TYPE_FIELD;
  1043.         }
  1044.     }
  1045.  
  1046.     if (playerGuild->GetMasterPID() != ch->GetPlayerID())
  1047.     {
  1048.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;88]");
  1049.         return;
  1050.     }
  1051.  
  1052.     auto opponentGuild  = CGuildManager::instance().FindGuildByName(arg1);
  1053.  
  1054.     if (!opponentGuild)
  1055.     {
  1056.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;89]");
  1057.         return;
  1058.     }
  1059.  
  1060.     switch (playerGuild->GetGuildWarState(opponentGuild ->GetID()))
  1061.     {
  1062.         case GUILD_WAR_NONE:
  1063.         {
  1064.             if (opponentGuild->UnderAnyWar())
  1065.             {
  1066.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;90]");
  1067.                 return;
  1068.             }
  1069.  
  1070.             int32_t iWarPrice = KOR_aGuildWarInfo[type].iWarPrice;
  1071.  
  1072.             if (playerGuild->GetGuildMoney() < iWarPrice)
  1073.             {
  1074.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;91]");
  1075.                 return;
  1076.             }
  1077.  
  1078.             if (opponentGuild->GetGuildMoney() < iWarPrice)
  1079.             {
  1080.                 ch->ChatPacket(CHAT_TYPE_INFO,  "[LS;92]");
  1081.                 return;
  1082.             }
  1083.         }
  1084.         break;
  1085.  
  1086.         case GUILD_WAR_SEND_DECLARE:
  1087.         {
  1088.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;93]");
  1089.             return;
  1090.         }
  1091.         break;
  1092.  
  1093.         case GUILD_WAR_RECV_DECLARE:
  1094.         {
  1095.             if (opponentGuild->UnderAnyWar())
  1096.             {
  1097.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;87]");
  1098.                 playerGuild->RequestRefuseWar(opponentGuild ->GetID());
  1099.                 return;
  1100.             }
  1101.         }
  1102.         break;
  1103.  
  1104.         case GUILD_WAR_RESERVE:
  1105.         {
  1106.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;93]");
  1107.             return;
  1108.         }
  1109.         break;
  1110.  
  1111.         case GUILD_WAR_END:
  1112.         {
  1113.             return;
  1114.         }
  1115.  
  1116.         default:
  1117.         {
  1118.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;90]");
  1119.             playerGuild->RequestRefuseWar(opponentGuild ->GetID());
  1120.             return;
  1121.         }
  1122.     }
  1123.  
  1124.     if (!playerGuild->CanStartWar(type))
  1125.     {
  1126.         if (playerGuild->GetLadderPoint() == 0)
  1127.         {
  1128.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;94]");
  1129.             sys_log(0, "GuildWar.StartError.NEED_LADDER_POINT");
  1130.         }
  1131.         else if (playerGuild->GetMemberCount() < GUILD_WAR_MIN_MEMBER_COUNT)
  1132.         {
  1133.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;95;%d]", GUILD_WAR_MIN_MEMBER_COUNT);
  1134.             sys_log(0, "GuildWar.StartError.NEED_MINIMUM_MEMBER[%d]", GUILD_WAR_MIN_MEMBER_COUNT);
  1135.         }
  1136.         else
  1137.         {
  1138.             sys_log(0, "GuildWar.StartError.UNKNOWN_ERROR");
  1139.         }
  1140.        
  1141.         return;
  1142.     }
  1143.  
  1144.     if (!opponentGuild ->CanStartWar(GUILD_WAR_TYPE_FIELD))
  1145.     {
  1146.         if (opponentGuild ->GetLadderPoint() == 0)
  1147.         {
  1148.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;94]");
  1149.         }
  1150.         else if (opponentGuild ->GetMemberCount() < GUILD_WAR_MIN_MEMBER_COUNT)
  1151.         {
  1152.             ch->ChatPacket(CHAT_TYPE_INFO, "[LS;96]");
  1153.         }
  1154.        
  1155.         return;
  1156.     }
  1157.  
  1158.     do
  1159.     {
  1160.         if (playerGuild->GetMasterCharacter() != nullptr)
  1161.         {
  1162.             break;
  1163.         }
  1164.  
  1165.         CCI *pCCI = P2P_MANAGER::instance().FindByPID(playerGuild->GetMasterPID());
  1166.  
  1167.         if (pCCI != nullptr)
  1168.         {
  1169.             break;
  1170.         }
  1171.  
  1172.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;97]");
  1173.         playerGuild->RequestRefuseWar(opponentGuild ->GetID());
  1174.         return;
  1175.  
  1176.     } while (false);
  1177.  
  1178.     do
  1179.     {
  1180.         if (opponentGuild ->GetMasterCharacter() != nullptr)
  1181.         {
  1182.             break;
  1183.         }
  1184.        
  1185.         CCI *pCCI = P2P_MANAGER::instance().FindByPID(opponentGuild ->GetMasterPID());
  1186.        
  1187.         if (pCCI != nullptr)
  1188.         {
  1189.             break;
  1190.         }
  1191.  
  1192.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;98]");
  1193.         playerGuild->RequestRefuseWar(opponentGuild ->GetID());
  1194.         return;
  1195.  
  1196.     } while (false);
  1197.  
  1198.     playerGuild->RequestDeclareWar(opponentGuild ->GetID(), type);
  1199. }
  1200.  
  1201. ACMD(do_nowar)
  1202. {
  1203.     CGuild* g = ch->GetGuild();
  1204.     if (!g)
  1205.         return;
  1206.  
  1207.     char arg1[256];
  1208.     one_argument(argument, arg1, sizeof(arg1));
  1209.  
  1210.     if (!*arg1)
  1211.         return;
  1212.  
  1213.     DWORD gm_pid = g->GetMasterPID();
  1214.  
  1215.     if (gm_pid != ch->GetPlayerID())
  1216.     {
  1217.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;431]");
  1218.         return;
  1219.     }
  1220.  
  1221.     CGuild* opp_g = CGuildManager::instance().FindGuildByName(arg1);
  1222.  
  1223.     if (!opp_g)
  1224.     {
  1225.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;89]");
  1226.         return;
  1227.     }
  1228.  
  1229.     g->RequestRefuseWar(opp_g->GetID());
  1230. }
  1231.  
  1232. ACMD(do_detaillog)
  1233. {
  1234.     ch->DetailLog();
  1235. }
  1236.  
  1237. ACMD(do_monsterlog)
  1238. {
  1239.     ch->ToggleMonsterLog();
  1240. }
  1241.  
  1242. ACMD(do_pkmode)
  1243. {
  1244.     char arg1[256];
  1245.     one_argument(argument, arg1, sizeof(arg1));
  1246.  
  1247.     if (!*arg1)
  1248.         return;
  1249.  
  1250.     BYTE mode = 0;
  1251.     str_to_number(mode, arg1);
  1252.  
  1253.     if (mode == PK_MODE_PROTECT)
  1254.         return;
  1255.  
  1256.     if (ch->GetLevel() < PK_PROTECT_LEVEL && mode != 0)
  1257.         return;
  1258.  
  1259.     ch->SetPKMode(mode);
  1260. }
  1261.  
  1262. ACMD(do_messenger_auth)
  1263. {
  1264.     if (ch->GetArena())
  1265.     {
  1266.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;101]");
  1267.         return;
  1268.     }
  1269.  
  1270.     char firstArgument[256], secondArgument[256];
  1271.     two_arguments(argument, firstArgument, sizeof(firstArgument), secondArgument, sizeof(secondArgument));
  1272.  
  1273.     if (!*firstArgument || !*secondArgument)
  1274.     {
  1275.         return;
  1276.     }
  1277.  
  1278.     const bool isFriendRequestDenied = std::tolower(firstArgument[0]) != 'y';
  1279.     const bool isFriendRequestProcessed = MessengerManager::instance().AuthToAdd(ch->GetName(), secondArgument, isFriendRequestDenied) != 0;
  1280.  
  1281.     if (isFriendRequestProcessed && isFriendRequestDenied)
  1282.     {
  1283.         if (auto targetCharacter = CHARACTER_MANAGER::instance().FindPC(secondArgument); targetCharacter)
  1284.         {
  1285.             targetCharacter->ChatPacket(CHAT_TYPE_INFO,"[LS;99;%s]", ch->GetName());
  1286.         }
  1287.     }
  1288. }
  1289.  
  1290. ACMD(do_setblockmode)
  1291. {
  1292.     char arg1[256];
  1293.     one_argument(argument, arg1, sizeof(arg1));
  1294.  
  1295.     if (*arg1)
  1296.     {
  1297.         BYTE flag = 0;
  1298.         str_to_number(flag, arg1);
  1299.         ch->SetBlockMode(flag);
  1300.     }
  1301. }
  1302.  
  1303. ACMD(do_unmount)
  1304. {
  1305.     auto mount = ch->GetWear(WEAR_COSTUME_MOUNT);
  1306.  
  1307.     auto unequipRideItem = [&](LPITEM item)
  1308.     {
  1309.         if (item && item->IsRideItem())
  1310.         {
  1311.             ch->UnequipItem(item);
  1312.         }
  1313.     };
  1314.  
  1315.     unequipRideItem(ch->GetWear(WEAR_UNIQUE1));
  1316.     unequipRideItem(ch->GetWear(WEAR_UNIQUE2));
  1317.     unequipRideItem(mount);
  1318.  
  1319.     if (ch->UnEquipSpecialRideUniqueItem())
  1320.     {
  1321.         ch->RemoveAffect(AFFECT_MOUNT);
  1322.         ch->RemoveAffect(AFFECT_MOUNT_BONUS);
  1323.        
  1324.         if (ch->IsHorseRiding())
  1325.         {
  1326.             ch->StopRiding();
  1327.         }
  1328.     }
  1329.     else
  1330.     {
  1331.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;432]");
  1332.     }
  1333. }
  1334.  
  1335.  
  1336. ACMD(do_observer_exit)
  1337. {
  1338.     if (ch->IsObserverMode())
  1339.     {
  1340.         if (ch->GetWarMap())
  1341.             ch->SetWarMap(NULL);
  1342.  
  1343.         if (ch->GetArena() != NULL || ch->GetArenaObserverMode() == true)
  1344.         {
  1345.             ch->SetArenaObserverMode(false);
  1346.  
  1347.             if (ch->GetArena() != NULL)
  1348.                 ch->GetArena()->RemoveObserver(ch->GetPlayerID());
  1349.  
  1350.             ch->SetArena(NULL);
  1351.             ch->WarpSet(ARENA_RETURN_POINT_X(ch->GetEmpire()), ARENA_RETURN_POINT_Y(ch->GetEmpire()));
  1352.         }
  1353.         else
  1354.         {
  1355.             ch->ExitToSavedLocation();
  1356.         }
  1357.         ch->SetObserverMode(false);
  1358.     }
  1359. }
  1360.  
  1361. ACMD(do_view_equip)
  1362. {
  1363.     if (ch->GetGMLevel() <= GM_PLAYER)
  1364.         return;
  1365.  
  1366.     char arg1[256];
  1367.     one_argument(argument, arg1, sizeof(arg1));
  1368.  
  1369.     if (*arg1)
  1370.     {
  1371.         DWORD vid = 0;
  1372.         str_to_number(vid, arg1);
  1373.         LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
  1374.  
  1375.         if (!tch)
  1376.             return;
  1377.  
  1378.         if (!tch->IsPC())
  1379.             return;
  1380.  
  1381.         tch->SendEquipment(ch);
  1382.     }
  1383. }
  1384.  
  1385. ACMD(do_party_request)
  1386. {
  1387.     if (ch->GetArena())
  1388.     {
  1389.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;101]");
  1390.         return;
  1391.     }
  1392.  
  1393.     if (ch->GetParty())
  1394.     {
  1395.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;102]");
  1396.         return;
  1397.     }
  1398.  
  1399.     char arg1[256];
  1400.     one_argument(argument, arg1, sizeof(arg1));
  1401.  
  1402.     if (!*arg1)
  1403.         return;
  1404.  
  1405.     DWORD vid = 0;
  1406.     str_to_number(vid, arg1);
  1407.     LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
  1408.  
  1409.     if (tch)
  1410.         if (!ch->RequestToParty(tch))
  1411.             ch->ChatPacket(CHAT_TYPE_COMMAND, "PartyRequestDenied");
  1412. }
  1413.  
  1414. ACMD(do_party_request_accept)
  1415. {
  1416.     char arg1[256];
  1417.     one_argument(argument, arg1, sizeof(arg1));
  1418.  
  1419.     if (!*arg1)
  1420.         return;
  1421.  
  1422.     DWORD vid = 0;
  1423.     str_to_number(vid, arg1);
  1424.     LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
  1425.  
  1426.     if (tch)
  1427.         ch->AcceptToParty(tch);
  1428. }
  1429.  
  1430. ACMD(do_party_request_deny)
  1431. {
  1432.     char arg1[256];
  1433.     one_argument(argument, arg1, sizeof(arg1));
  1434.  
  1435.     if (!*arg1)
  1436.         return;
  1437.  
  1438.     DWORD vid = 0;
  1439.     str_to_number(vid, arg1);
  1440.     LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
  1441.  
  1442.     if (tch)
  1443.         ch->DenyToParty(tch);
  1444. }
  1445.  
  1446. // LUA_ADD_GOTO_INFO
  1447. struct GotoInfo
  1448. {
  1449.     std::string     st_name;
  1450.  
  1451.     BYTE    empire;
  1452.     int     mapIndex;
  1453.     DWORD   x, y;
  1454.  
  1455.     GotoInfo()
  1456.     {
  1457.         st_name     = "";
  1458.         empire      = 0;
  1459.         mapIndex    = 0;
  1460.  
  1461.         x = 0;
  1462.         y = 0;
  1463.     }
  1464.  
  1465.     GotoInfo(const GotoInfo& c_src)
  1466.     {
  1467.         __copy__(c_src);
  1468.     }
  1469.  
  1470.     void operator = (const GotoInfo& c_src)
  1471.     {
  1472.         __copy__(c_src);
  1473.     }
  1474.  
  1475.     void __copy__(const GotoInfo& c_src)
  1476.     {
  1477.         st_name     = c_src.st_name;
  1478.         empire      = c_src.empire;
  1479.         mapIndex    = c_src.mapIndex;
  1480.  
  1481.         x = c_src.x;
  1482.         y = c_src.y;
  1483.     }
  1484. };
  1485.  
  1486. extern void BroadcastNotice(const char * c_pszBuf);
  1487.  
  1488. static std::string FN_point_string(int apply_number)
  1489. {
  1490.     switch (apply_number)
  1491.     {
  1492.         case POINT_MAX_HP:
  1493.         {
  1494.             return "[LS;103;" + std::to_string(apply_number) + "]";
  1495.         }
  1496.        
  1497.         case POINT_MAX_SP:
  1498.         {
  1499.             return "[LS;104;%d]";
  1500.         }
  1501.        
  1502.         case POINT_HT:
  1503.         {
  1504.             return "[LS;105;" + std::to_string(apply_number) + "]";
  1505.         }
  1506.        
  1507.         case POINT_IQ:
  1508.         {
  1509.             return "[LS;106;%d]";
  1510.         }
  1511.        
  1512.         case POINT_ST:
  1513.         {
  1514.             return "[LS;107;%d]";
  1515.         }
  1516.        
  1517.         case POINT_DX:
  1518.         {  
  1519.             return "[LS;108;%d]";
  1520.         }
  1521.        
  1522.         case POINT_ATT_SPEED:
  1523.         {
  1524.             return "[LS;109;%d]";
  1525.         }
  1526.        
  1527.         case POINT_MOV_SPEED:
  1528.         {
  1529.             return "[LS;110;%d]";
  1530.         }
  1531.        
  1532.         case POINT_CASTING_SPEED:
  1533.         {
  1534.             return "[LS;111;%d]";
  1535.         }
  1536.        
  1537.         case POINT_HP_REGEN:
  1538.         {
  1539.             return "[LS;112;%d]";
  1540.         }
  1541.        
  1542.         case POINT_SP_REGEN:
  1543.         {
  1544.             return "[LS;113;%d]";
  1545.         }
  1546.        
  1547.         case POINT_POISON_PCT:
  1548.         {
  1549.             return "[LS;114;%d]";
  1550.         }
  1551.        
  1552.         case POINT_STUN_PCT:
  1553.         {
  1554.             return "[LS;115;%d]";
  1555.         }
  1556.        
  1557.         case POINT_SLOW_PCT:
  1558.         {
  1559.             return "[LS;116;%d]";
  1560.         }
  1561.        
  1562.         case POINT_CRITICAL_PCT:
  1563.         {
  1564.             return "[LS;117;%d%%]";
  1565.         }
  1566.        
  1567.         case POINT_RESIST_CRITICAL:
  1568.         {
  1569.             return "[LS;119;%d%%]";
  1570.         }
  1571.        
  1572.         case POINT_PENETRATE_PCT:
  1573.         {
  1574.             return "[LS;118;%d%%]";
  1575.         }
  1576.        
  1577.         case POINT_RESIST_PENETRATE:
  1578.         {
  1579.             return "[LS;120;%d%%]";
  1580.         }
  1581.        
  1582.         case POINT_ATTBONUS_HUMAN:
  1583.         {
  1584.             return "[LS;121;%d%%]";
  1585.         }
  1586.        
  1587.         case POINT_ATTBONUS_ANIMAL:
  1588.         {
  1589.             return "[LS;122;%d%%]";
  1590.         }
  1591.        
  1592.         case POINT_ATTBONUS_ORC:   
  1593.         {
  1594.             return "[LS;123;%d%%]";
  1595.         }
  1596.        
  1597.         case POINT_ATTBONUS_MILGYO:
  1598.         {
  1599.             return "[LS;124;%d%%]";
  1600.         }
  1601.        
  1602.         case POINT_ATTBONUS_UNDEAD:
  1603.         {
  1604.             return "[LS;125;%d%%]";
  1605.         }
  1606.        
  1607.         case POINT_ATTBONUS_DEVIL: 
  1608.         {
  1609.             return "[LS;126;%d%%]";
  1610.         }
  1611.        
  1612.         case POINT_STEAL_HP:
  1613.         {
  1614.             return "[LS;127;%d%%]";
  1615.         }
  1616.        
  1617.         case POINT_STEAL_SP:   
  1618.         {      
  1619.             return "[LS;128;%d%%]";
  1620.         }
  1621.        
  1622.         case POINT_MANA_BURN_PCT:  
  1623.         {
  1624.             return "[LS;129;%d%%]";
  1625.         }
  1626.        
  1627.         case POINT_DAMAGE_SP_RECOVER:
  1628.         {
  1629.             return "[LS;130;%d%%]";
  1630.         }
  1631.        
  1632.         case POINT_BLOCK:          
  1633.         {
  1634.             return "[LS;131;%d%%]";
  1635.         }
  1636.        
  1637.         case POINT_DODGE:
  1638.         {
  1639.             return "[LS;132;%d%%]";
  1640.         }
  1641.        
  1642.         case POINT_RESIST_SWORD:
  1643.         {
  1644.             return "[LS;133;%d%%]";
  1645.         }
  1646.        
  1647.         case POINT_RESIST_TWOHAND:
  1648.         {
  1649.             return "[LS;134;%d%%]";
  1650.         }
  1651.        
  1652.         case POINT_RESIST_DAGGER:
  1653.         {
  1654.             return "[LS;135;%d%%]";
  1655.         }
  1656.        
  1657.         case POINT_RESIST_BELL:
  1658.         {      
  1659.             return "[LS;136;%d%%]";
  1660.         }
  1661.        
  1662.         case POINT_RESIST_FAN:     
  1663.         {
  1664.             return "[LS;137;%d%%]";
  1665.         }
  1666.        
  1667.         case POINT_RESIST_BOW: 
  1668.         {      
  1669.             return "[LS;138;%d%%]";
  1670.         }
  1671.        
  1672.         case POINT_RESIST_FIRE:
  1673.         {
  1674.             return "[LS;139;%d%%]";
  1675.         }
  1676.        
  1677.         case POINT_RESIST_ELEC:
  1678.         {
  1679.             return "[LS;140;%d%%]";
  1680.         }
  1681.        
  1682.         case POINT_RESIST_MAGIC:   
  1683.         {
  1684.             return "[LS;141;%d%%]";
  1685.         }
  1686.        
  1687.         case POINT_RESIST_WIND:
  1688.         {
  1689.             return "[LS;142;%d%%]";
  1690.         }
  1691.        
  1692.         case POINT_RESIST_ICE:
  1693.         {
  1694.             return "[LS;143;%d%%]";
  1695.         }
  1696.        
  1697.         case POINT_RESIST_EARTH:
  1698.         {
  1699.             return "[LS;144;%d%%]";
  1700.         }
  1701.        
  1702.         case POINT_RESIST_DARK:
  1703.         {
  1704.             return "[LS;145;%d%%]";
  1705.         }
  1706.        
  1707.         case POINT_REFLECT_MELEE:
  1708.         {
  1709.             return "[LS;146;%d%%]";
  1710.         }
  1711.        
  1712.         case POINT_REFLECT_CURSE:
  1713.         {
  1714.             return "[LS;147;%d%%]";
  1715.         }
  1716.        
  1717.         case POINT_POISON_REDUCE:
  1718.         {
  1719.             return "[LS;148;%d%%]";
  1720.         }
  1721.        
  1722.         case POINT_KILL_SP_RECOVER:
  1723.         {
  1724.             return "[LS;149;%d%%]";
  1725.         }
  1726.        
  1727.         case POINT_EXP_DOUBLE_BONUS:
  1728.         {
  1729.             return "[LS;150;%d%%]";
  1730.         }
  1731.        
  1732.         case POINT_GOLD_DOUBLE_BONUS:
  1733.         {
  1734.             return "[LS;151;%d%%]";
  1735.         }
  1736.        
  1737.         case POINT_ITEM_DROP_BONUS:
  1738.         {
  1739.             return "[LS;152;%d%%]";
  1740.         }
  1741.        
  1742.         case POINT_POTION_BONUS:
  1743.         {
  1744.             return "[LS;153;%d%%]";
  1745.         }
  1746.        
  1747.         case POINT_KILL_HP_RECOVERY:
  1748.         {
  1749.             return "[LS;154;%d%%]";
  1750.         }
  1751.        
  1752.         case POINT_ATT_GRADE_BONUS:
  1753.         {
  1754.             return "[LS;155;%d%]";
  1755.         }
  1756.        
  1757.         case POINT_DEF_GRADE_BONUS:
  1758.         {
  1759.             return "[LS;156;%d%]";
  1760.         }
  1761.        
  1762.         case POINT_MAGIC_ATT_GRADE:
  1763.         {
  1764.             return "[LS;157;%d%]";
  1765.         }
  1766.        
  1767.         case POINT_MAGIC_DEF_GRADE:
  1768.         {
  1769.             return "[LS;158;%d%]";
  1770.         }
  1771.        
  1772.         case POINT_MAX_STAMINA:
  1773.         {
  1774.             return "[LS;159;%d%]";
  1775.         }
  1776.        
  1777.         case POINT_ATTBONUS_WARRIOR:
  1778.         {
  1779.             return "[LS;160;%d%%]";
  1780.         }
  1781.        
  1782.         case POINT_ATTBONUS_ASSASSIN:
  1783.         {
  1784.             return "[LS;161;%d%%]";
  1785.         }
  1786.        
  1787.         case POINT_ATTBONUS_SURA:
  1788.         {
  1789.             return "[LS;162;%d%%]";
  1790.         }
  1791.        
  1792.         case POINT_ATTBONUS_SHAMAN:
  1793.         {
  1794.             return "[LS;163;%d%%]";
  1795.         }
  1796.        
  1797.         case POINT_ATTBONUS_MONSTER:
  1798.         {
  1799.             return "[LS;164;%d%%]";
  1800.         }
  1801.        
  1802.         case POINT_MALL_ATTBONUS:
  1803.         {
  1804.             return "[LS;165;%d%%]";
  1805.         }
  1806.        
  1807.         case POINT_MALL_DEFBONUS:
  1808.         {
  1809.             return "[LS;166;%d%%]";
  1810.         }
  1811.        
  1812.         case POINT_MALL_EXPBONUS:
  1813.         {
  1814.             return "[LS;167;%d%%]";
  1815.         }
  1816.  
  1817.         case POINT_MALL_ITEMBONUS:
  1818.         {
  1819.             return "[LS;168;%d]";
  1820.         }
  1821.        
  1822.         case POINT_MALL_GOLDBONUS:
  1823.         {
  1824.             return "[LS;169;%d]";
  1825.         }
  1826.        
  1827.         case POINT_MAX_HP_PCT:
  1828.         {
  1829.             return "[LS;170;%d%%]";
  1830.         }
  1831.        
  1832.         case POINT_MAX_SP_PCT:
  1833.         {
  1834.             return "[LS;171;%d%%]";
  1835.         }
  1836.        
  1837.         case POINT_SKILL_DAMAGE_BONUS:
  1838.         {
  1839.             return "[LS;172;%d%%]";
  1840.         }
  1841.        
  1842.         case POINT_NORMAL_HIT_DAMAGE_BONUS:
  1843.         {
  1844.             return "[LS;173;%d%%]";
  1845.         }
  1846.        
  1847.         case POINT_SKILL_DEFEND_BONUS:
  1848.         {
  1849.             return "[LS;174;%d%%]";
  1850.         }
  1851.        
  1852.         case POINT_NORMAL_HIT_DEFEND_BONUS:
  1853.         {
  1854.             return "[LS;175;%d%%]";
  1855.         }
  1856.        
  1857.         case POINT_RESIST_WARRIOR:
  1858.         {
  1859.             return "[LS;176;%d%%]";
  1860.         }
  1861.        
  1862.         case POINT_RESIST_ASSASSIN:
  1863.         {
  1864.             return "[LS;177;%d%%]";
  1865.         }
  1866.        
  1867.         case POINT_RESIST_SURA:
  1868.         {
  1869.             return "[LS;178;%d%%]";
  1870.         }
  1871.        
  1872.         case POINT_RESIST_SHAMAN:
  1873.         {
  1874.             return "[LS;179;%d%%]";
  1875.         }
  1876.        
  1877.         default:
  1878.         {
  1879.             return "error %d";
  1880.         }
  1881.     }
  1882. }
  1883.  
  1884. static bool FN_hair_affect_string(LPCHARACTER ch, char *buf, size_t bufsiz)
  1885. {
  1886.     if (NULL == ch || NULL == buf)
  1887.         return false;
  1888.  
  1889.     CAffect* aff = NULL;
  1890.     time_t expire = 0;
  1891.     struct tm ltm;
  1892.     int year, mon, day;
  1893.     int offset = 0;
  1894.  
  1895.     aff = ch->FindAffect(AFFECT_HAIR);
  1896.  
  1897.     if (NULL == aff)
  1898.         return false;
  1899.  
  1900.     expire = ch->GetQuestFlag("hair.limit_time");
  1901.  
  1902.     if (expire < get_global_time())
  1903.         return false;
  1904.  
  1905.     const std::string pointString = FN_point_string(aff->applyOn);
  1906.    
  1907.     if (pointString.empty())
  1908.     {
  1909.         return false;
  1910.     }
  1911.  
  1912.     offset = snprintf(buf, bufsiz, pointString.c_str(), aff->applyValue);
  1913.    
  1914.     if (offset < 0 || offset >= (int) bufsiz)
  1915.         offset = bufsiz - 1;
  1916.  
  1917.     localtime_r(&expire, &ltm);
  1918.  
  1919.     year    = ltm.tm_year + 1900;
  1920.     mon     = ltm.tm_mon + 1;
  1921.     day     = ltm.tm_mday;
  1922.  
  1923.     snprintf(buf + offset, bufsiz - offset, "[LS;180;%d;%d;%d]", year, mon, day);
  1924.  
  1925.     return true;
  1926. }
  1927.  
  1928. ACMD(do_costume)
  1929. {
  1930.     char buf[512];
  1931.     const size_t bufferSize = sizeof(buf);
  1932.  
  1933.     char arg1[256];
  1934.     one_argument(argument, arg1, sizeof(arg1));
  1935.  
  1936.     CItem* pBody = ch->GetWear(WEAR_COSTUME_BODY);
  1937.     CItem* pHair = ch->GetWear(WEAR_COSTUME_HAIR);
  1938.     CItem* pMount = ch->GetWear(WEAR_COSTUME_MOUNT);
  1939.  
  1940.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;435]");
  1941.  
  1942.     if (pHair)
  1943.     {
  1944.         const char* itemName = pHair->GetName();
  1945.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;436]", itemName);
  1946.  
  1947.         for (int i = 0; i < pHair->GetAttributeCount(); ++i)
  1948.         {
  1949.             const TPlayerItemAttribute& attr = pHair->GetAttribute(i);
  1950.             if (0 < attr.bType)
  1951.             {
  1952.                 const std::string& pointString = FN_point_string(attr.bType);
  1953.                
  1954.                 if (pointString.empty())
  1955.                 {
  1956.                     continue;
  1957.                 }
  1958.            
  1959.                 snprintf(buf, bufferSize, pointString.c_str(), attr.sValue);
  1960.                 ch->ChatPacket(CHAT_TYPE_INFO, "[LS;436]", buf);
  1961.             }
  1962.         }
  1963.  
  1964.         if (pHair->IsEquipped() && arg1[0] == 'h')
  1965.             ch->UnequipItem(pHair);
  1966.     }
  1967.  
  1968.     if (pBody)
  1969.     {
  1970.         const char* itemName = pBody->GetName();
  1971.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;438]", itemName);
  1972.  
  1973.         if (pBody->IsEquipped() && arg1[0] == 'b')
  1974.             ch->UnequipItem(pBody);
  1975.     }
  1976.    
  1977.     if (pMount)
  1978.     {
  1979.         const char* itemName = pMount->GetName();
  1980.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;439]", itemName);
  1981.  
  1982.         if (pMount->IsEquipped() && arg1[0] == 'm')
  1983.             ch->UnequipItem(pMount);
  1984.     }
  1985. }
  1986.  
  1987. ACMD(do_hair)
  1988. {
  1989.     char buf[256];
  1990.  
  1991.     if (false == FN_hair_affect_string(ch, buf, sizeof(buf)))
  1992.         return;
  1993.  
  1994.     ch->ChatPacket(CHAT_TYPE_INFO, buf);
  1995. }
  1996.  
  1997. ACMD(do_inventory)
  1998. {
  1999.     int index = 0;
  2000.     int count       = 1;
  2001.  
  2002.     char arg1[256];
  2003.     char arg2[256];
  2004.  
  2005.     LPITEM  item;
  2006.  
  2007.     two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2008.  
  2009.     if (!*arg1)
  2010.     {
  2011.         ch->ChatPacket(CHAT_TYPE_INFO, "Usage: inventory <start_index> <count>");
  2012.         return;
  2013.     }
  2014.  
  2015.     if (!*arg2)
  2016.     {
  2017.         index = 0;
  2018.         str_to_number(count, arg1);
  2019.     }
  2020.     else
  2021.     {
  2022.         str_to_number(index, arg1); index = MIN(index, INVENTORY_MAX_NUM);
  2023.         str_to_number(count, arg2); count = MIN(count, INVENTORY_MAX_NUM);
  2024.     }
  2025.  
  2026.     for (int i = 0; i < count; ++i)
  2027.     {
  2028.         if (index >= INVENTORY_MAX_NUM)
  2029.             break;
  2030.  
  2031.         item = ch->GetInventoryItem(index);
  2032.  
  2033.         ch->ChatPacket(CHAT_TYPE_INFO, "ekwipunek [%d] = %s", index, item ? item->GetName() : "<NONE>");
  2034.         ++index;
  2035.     }
  2036. }
  2037.  
  2038. //gift notify quest command
  2039. ACMD(do_gift)
  2040. {
  2041.     ch->ChatPacket(CHAT_TYPE_COMMAND, "gift");
  2042. }
  2043.  
  2044. ACMD(do_cube)
  2045. {
  2046.     if (!ch->CanDoCube())
  2047.         return;
  2048.  
  2049.     int cube_index = 0, inven_index = 0;
  2050.     const char *line;
  2051.  
  2052.     char arg1[256], arg2[256], arg3[256];
  2053.  
  2054.     line = two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
  2055.     one_argument(line, arg3, sizeof(arg3));
  2056.  
  2057.     if (0 == arg1[0])
  2058.     {
  2059.         // print usage
  2060.         ch->ChatPacket(CHAT_TYPE_INFO, "Usage: cube open");
  2061.         ch->ChatPacket(CHAT_TYPE_INFO, "       cube close");
  2062.         ch->ChatPacket(CHAT_TYPE_INFO, "       cube add <inveltory_index>");
  2063.         ch->ChatPacket(CHAT_TYPE_INFO, "       cube delete <cube_index>");
  2064.         ch->ChatPacket(CHAT_TYPE_INFO, "       cube list");
  2065.         ch->ChatPacket(CHAT_TYPE_INFO, "       cube cancel");
  2066.         ch->ChatPacket(CHAT_TYPE_INFO, "       cube make [all]");
  2067.         return;
  2068.     }
  2069.  
  2070.     const std::string& strArg1 = std::string(arg1);
  2071.  
  2072.     // r_info (request information)
  2073.     // /cube r_info     ==> (Client -> Server) 현재 NPC가 만들 수 있는 레시피 요청
  2074.     //                      (Server -> Client) /cube r_list npcVNUM resultCOUNT 123,1/125,1/128,1/130,5
  2075.     //
  2076.     // /cube r_info 3   ==> (Client -> Server) 현재 NPC가 만들수 있는 레시피 중 3번째 아이템을 만드는 데 필요한 정보를 요청
  2077.     // /cube r_info 3 5 ==> (Client -> Server) 현재 NPC가 만들수 있는 레시피 중 3번째 아이템부터 이후 5개의 아이템을 만드는 데 필요한 재료 정보를 요청
  2078.     //                     (Server -> Client) /cube m_info startIndex count 125,1|126,2|127,2|123,5&555,5&555,4/120000@125,1|126,2|127,2|123,5&555,5&555,4/120000
  2079.     //
  2080.     if (strArg1 == "r_info")
  2081.     {
  2082.         if (0 == arg2[0])
  2083.             Cube_request_result_list(ch);
  2084.         else
  2085.         {
  2086.             if (isdigit(*arg2))
  2087.             {
  2088.                 int listIndex = 0, requestCount = 1;
  2089.                 str_to_number(listIndex, arg2);
  2090.  
  2091.                 if (0 != arg3[0] && isdigit(*arg3))
  2092.                     str_to_number(requestCount, arg3);
  2093.  
  2094.                 Cube_request_material_info(ch, listIndex, requestCount);
  2095.             }
  2096.         }
  2097.  
  2098.         return;
  2099.     }
  2100.  
  2101.     switch (LOWER(arg1[0]))
  2102.     {
  2103.         case 'o':   // open
  2104.             Cube_open(ch);
  2105.             break;
  2106.  
  2107.         case 'c':   // close
  2108.             Cube_close(ch);
  2109.             break;
  2110.  
  2111.         case 'l':   // list
  2112.             Cube_show_list(ch);
  2113.             break;
  2114.  
  2115.         case 'a':   // add cue_index inven_index
  2116.             {
  2117.                 if (0 == arg2[0] || !isdigit(*arg2) ||
  2118.                     0 == arg3[0] || !isdigit(*arg3))
  2119.                     return;
  2120.  
  2121.                 str_to_number(cube_index, arg2);
  2122.                 str_to_number(inven_index, arg3);
  2123.                 Cube_add_item (ch, cube_index, inven_index);
  2124.             }
  2125.             break;
  2126.  
  2127.         case 'd':   // delete
  2128.             {
  2129.                 if (0 == arg2[0] || !isdigit(*arg2))
  2130.                     return;
  2131.  
  2132.                 str_to_number(cube_index, arg2);
  2133.                 Cube_delete_item (ch, cube_index);
  2134.             }
  2135.             break;
  2136.  
  2137.         case 'm':
  2138.             Cube_make (ch);
  2139.             break;
  2140.  
  2141.         default:
  2142.             return;
  2143.     }
  2144. }
  2145.  
  2146. ACMD(do_in_game_mall)
  2147. {
  2148. }
  2149.  
  2150. ACMD(do_dice)
  2151. {
  2152.     int start = 1, end = 100;
  2153.     int n = number(start, end);
  2154.  
  2155.     if (ch->GetParty())
  2156.     {
  2157.         ch->GetParty()->ChatPacketToAllMember(CHAT_TYPE_INFO, "[LS;433;%s;%d;%d;%d]", ch->GetName(), n, start, end);
  2158.     }
  2159.     else
  2160.     {
  2161.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;434;%d;%d;%d]", n, start, end);
  2162.     }
  2163. }
  2164.  
  2165. ACMD(do_click_mall)
  2166. {
  2167.     ch->ChatPacket(CHAT_TYPE_COMMAND, "ShowMeMallPassword");
  2168. }
  2169.  
  2170. ACMD(do_ride)
  2171. {
  2172.     const auto jazdaTime = static_cast<int>((get_dword_time() - ch->GetLastMountTime()) / 1000 + 0.5);
  2173.  
  2174.     if (jazdaTime < 1 || ch->IsDead() || ch->IsStun() || ch->GetMapIndex() == 113 || ch->IsPolymorphed())
  2175.     {
  2176.         return;
  2177.     }
  2178.  
  2179.     if(ch->IsPolymorphed())
  2180.     {
  2181.         ch->ChatPacket(CHAT_TYPE_INFO, "[LS;11]");
  2182.         return;
  2183.     }
  2184.    
  2185.     if (ch->IsHorseRiding())
  2186.     {
  2187.         ch->StopRiding();
  2188.         return;
  2189.     }
  2190.  
  2191.     if (ch->GetHorse())
  2192.     {
  2193.         ch->StartRiding();
  2194.         return;
  2195.     }
  2196.  
  2197.     for (BYTE i = 0; i < INVENTORY_MAX_NUM; ++i)
  2198.     {
  2199.         auto item = ch->GetInventoryItem(i);
  2200.        
  2201.         if (item && item->IsRideItem() && !ch->GetWear(WEAR_UNIQUE1) && !ch->GetWear(WEAR_UNIQUE2) && !ch->GetWear(WEAR_COSTUME_MOUNT))
  2202.         {
  2203.             ch->UseItem(TItemPos(INVENTORY, i));
  2204.             return;
  2205.         }
  2206.     }
  2207.  
  2208.     ch->ChatPacket(CHAT_TYPE_INFO, "[LS;3]");
  2209. }
Advertisement
Add Comment
Please, Sign In to add comment