Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 8th, 2012  |  syntax: C++  |  size: 365.63 KB  |  hits: 19  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3.  
  4. #include "../common/cbasetypes.h"
  5. #include "../common/mmo.h"
  6. #include "../common/timer.h"
  7. #include "../common/nullpo.h"
  8. #include "../common/core.h"
  9. #include "../common/showmsg.h"
  10. #include "../common/malloc.h"
  11. #include "../common/socket.h"
  12. #include "../common/strlib.h"
  13. #include "../common/utils.h"
  14.  
  15. #include "atcommand.h"
  16. #include "battle.h"
  17. #include "battleground.h"
  18. #include "chat.h"
  19. #include "channel.h"
  20. #include "clif.h"
  21. #include "chrif.h"
  22. #include "duel.h"
  23. #include "intif.h"
  24. #include "itemdb.h"
  25. #include "log.h"
  26. #include "map.h"
  27. #include "pc.h"
  28. #include "status.h"
  29. #include "skill.h"
  30. #include "mob.h"
  31. #include "npc.h"
  32. #include "pet.h"
  33. #include "homunculus.h"
  34. #include "mercenary.h"
  35. #include "elemental.h"
  36. #include "party.h"
  37. #include "guild.h"
  38. #include "script.h"
  39. #include "storage.h"
  40. #include "trade.h"
  41. #include "unit.h"
  42. #include "achievement.h"
  43.  
  44. #ifndef TXT_ONLY
  45. #include "mail.h"
  46. #endif
  47.  
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include <string.h>
  51. #include <math.h>
  52.  
  53. // extern variables
  54. char atcommand_symbol = '@'; // first char of the commands
  55. char charcommand_symbol = '#';
  56. char* msg_table[MAX_MSG]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
  57.  
  58. // local declarations
  59. #define ACMD_FUNC(x) int atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message)
  60.  
  61. typedef struct AtCommandInfo
  62. {
  63.         const char* command;
  64.         int level;
  65.         int level2;
  66.         int premium;
  67.         AtCommandFunc func;
  68. } AtCommandInfo;
  69.  
  70. static AtCommandInfo* get_atcommandinfo_byname(const char* name);
  71. static AtCommandInfo* get_atcommandinfo_byfunc(const AtCommandFunc func);
  72. static bool premium_usage = false;
  73.  
  74. ACMD_FUNC(commands);
  75.  
  76.  
  77. /*=========================================
  78.  * Generic variables
  79.  *-----------------------------------------*/
  80. char atcmd_output[CHAT_SIZE_MAX];
  81. char atcmd_player_name[NAME_LENGTH];
  82. char atcmd_temp[100];
  83.  
  84. // compare function for sorting high to lowest
  85. int hightolow_compare (const void * a, const void * b)
  86. {
  87.         return ( *(int*)b - *(int*)a );
  88. }
  89.  
  90. // compare function for sorting lowest to highest
  91. int lowtohigh_compare (const void * a, const void * b)
  92. {
  93.         return ( *(int*)a - *(int*)b );
  94. }
  95.  
  96. //-----------------------------------------------------------
  97. // Return the message string of the specified number by [Yor]
  98. //-----------------------------------------------------------
  99. const char* msg_txt(int msg_number)
  100. {
  101.         if (msg_number >= 0 && msg_number < MAX_MSG &&
  102.             msg_table[msg_number] != NULL && msg_table[msg_number][0] != '\0')
  103.                 return msg_table[msg_number];
  104.  
  105.         return "??";
  106. }
  107.  
  108. //-----------------------------------------------------------
  109. // Returns Players title (from msg_athena.conf) [Lupus]
  110. //-----------------------------------------------------------
  111. static char* player_title_txt(int level)
  112. {
  113.         const char* format;
  114.         format = (level >= battle_config.title_lvl8) ? msg_txt(332)
  115.                : (level >= battle_config.title_lvl7) ? msg_txt(331)
  116.                : (level >= battle_config.title_lvl6) ? msg_txt(330)
  117.                : (level >= battle_config.title_lvl5) ? msg_txt(329)
  118.                : (level >= battle_config.title_lvl4) ? msg_txt(328)
  119.                : (level >= battle_config.title_lvl3) ? msg_txt(327)
  120.                : (level >= battle_config.title_lvl2) ? msg_txt(326)
  121.                : (level >= battle_config.title_lvl1) ? msg_txt(325)
  122.                : "";
  123.         sprintf(atcmd_temp, format, level);
  124.         return atcmd_temp;
  125. }
  126.  
  127.  
  128. /*==========================================
  129.  * Read Message Data
  130.  *------------------------------------------*/
  131. int msg_config_read(const char* cfgName)
  132. {
  133.         int msg_number;
  134.         char line[1024], w1[1024], w2[1024];
  135.         FILE *fp;
  136.         static int called = 1;
  137.  
  138.         if ((fp = fopen(cfgName, "r")) == NULL) {
  139.                 ShowError("Messages file not found: %s\n", cfgName);
  140.                 return 1;
  141.         }
  142.  
  143.         if ((--called) == 0)
  144.                 memset(msg_table, 0, sizeof(msg_table[0]) * MAX_MSG);
  145.  
  146.         while(fgets(line, sizeof(line), fp))
  147.         {
  148.                 if (line[0] == '/' && line[1] == '/')
  149.                         continue;
  150.                 if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
  151.                         continue;
  152.  
  153.                 if (strcmpi(w1, "import") == 0)
  154.                         msg_config_read(w2);
  155.                 else
  156.                 {
  157.                         msg_number = atoi(w1);
  158.                         if (msg_number >= 0 && msg_number < MAX_MSG)
  159.                         {
  160.                                 if (msg_table[msg_number] != NULL)
  161.                                         aFree(msg_table[msg_number]);
  162.                                 msg_table[msg_number] = (char *)aMalloc((strlen(w2) + 1)*sizeof (char));
  163.                                 strcpy(msg_table[msg_number],w2);
  164.                         }
  165.                 }
  166.         }
  167.  
  168.         fclose(fp);
  169.  
  170.         return 0;
  171. }
  172.  
  173. /*==========================================
  174.  * Cleanup Message Data
  175.  *------------------------------------------*/
  176. void do_final_msg(void)
  177. {
  178.         int i;
  179.         for (i = 0; i < MAX_MSG; i++)
  180.                 aFree(msg_table[i]);
  181. }
  182.  
  183.  
  184. /*==========================================
  185.  * @send (used for testing packet sends from the client)
  186.  *------------------------------------------*/
  187. ACMD_FUNC(send)
  188. {
  189.         int len=0,off,end,type;
  190.         long num;
  191.         (void)command; // not used
  192.  
  193.         // read message type as hex number (without the 0x)
  194.         if(!message || !*message ||
  195.                         !((sscanf(message, "len %x", &type)==1 && (len=1))
  196.                         || sscanf(message, "%x", &type)==1) )
  197.         {
  198.                 clif_displaymessage(fd, "Usage:");
  199.                 clif_displaymessage(fd, "       @send len <packet hex number>");
  200.                 clif_displaymessage(fd, "       @send <packet hex number> {<value>}*");
  201.                 clif_displaymessage(fd, "       Value: <type=B(default),W,L><number> or S<length>\"<string>\"");
  202.                 return -1;
  203.         }
  204.  
  205. #define PARSE_ERROR(error,p) \
  206.         {\
  207.                 clif_displaymessage(fd, (error));\
  208.                 sprintf(atcmd_output, ">%s", (p));\
  209.                 clif_displaymessage(fd, atcmd_output);\
  210.         }
  211. //define PARSE_ERROR
  212.  
  213. #define CHECK_EOS(p) \
  214.         if(*(p) == 0){\
  215.                 clif_displaymessage(fd, "Unexpected end of string");\
  216.                 return -1;\
  217.         }
  218. //define CHECK_EOS
  219.  
  220. #define SKIP_VALUE(p) \
  221.         {\
  222.                 while(*(p) && !ISSPACE(*(p))) ++(p); /* non-space */\
  223.                 while(*(p) && ISSPACE(*(p)))  ++(p); /* space */\
  224.         }
  225. //define SKIP_VALUE
  226.  
  227. #define GET_VALUE(p,num) \
  228.         {\
  229.                 if(sscanf((p), "x%lx", &(num)) < 1 && sscanf((p), "%ld ", &(num)) < 1){\
  230.                         PARSE_ERROR("Invalid number in:",(p));\
  231.                         return -1;\
  232.                 }\
  233.         }
  234. //define GET_VALUE
  235.  
  236.         if (type > 0 && type < MAX_PACKET_DB) {
  237.  
  238.                 if(len)
  239.                 {// show packet length
  240.                         sprintf(atcmd_output, "Packet 0x%x length: %d", type, packet_db[sd->packet_ver][type].len);
  241.                         clif_displaymessage(fd, atcmd_output);
  242.                         return 0;
  243.                 }
  244.  
  245.                 len=packet_db[sd->packet_ver][type].len;
  246.                 off=2;
  247.                 if(len == 0)
  248.                 {// unknown packet - ERROR
  249.                         sprintf(atcmd_output, "Unknown packet: 0x%x", type);
  250.                         clif_displaymessage(fd, atcmd_output);
  251.                         return -1;
  252.                 } else if(len == -1)
  253.                 {// dynamic packet
  254.                         len=SHRT_MAX-4; // maximum length
  255.                         off=4;
  256.                 }
  257.                 WFIFOHEAD(fd, len);
  258.                 WFIFOW(fd,0)=TOW(type);
  259.  
  260.                 // parse packet contents
  261.                 SKIP_VALUE(message);
  262.                 while(*message != 0 && off < len){
  263.                         if(ISDIGIT(*message) || *message == '-' || *message == '+')
  264.                         {// default (byte)
  265.                                 GET_VALUE(message,num);
  266.                                 WFIFOB(fd,off)=TOB(num);
  267.                                 ++off;
  268.                         } else if(TOUPPER(*message) == 'B')
  269.                         {// byte
  270.                                 ++message;
  271.                                 GET_VALUE(message,num);
  272.                                 WFIFOB(fd,off)=TOB(num);
  273.                                 ++off;
  274.                         } else if(TOUPPER(*message) == 'W')
  275.                         {// word (2 bytes)
  276.                                 ++message;
  277.                                 GET_VALUE(message,num);
  278.                                 WFIFOW(fd,off)=TOW(num);
  279.                                 off+=2;
  280.                         } else if(TOUPPER(*message) == 'L')
  281.                         {// long word (4 bytes)
  282.                                 ++message;
  283.                                 GET_VALUE(message,num);
  284.                                 WFIFOL(fd,off)=TOL(num);
  285.                                 off+=4;
  286.                         } else if(TOUPPER(*message) == 'S')
  287.                         {// string - escapes are valid
  288.                                 // get string length - num <= 0 means not fixed length (default)
  289.                                 ++message;
  290.                                 if(*message == '"'){
  291.                                         num=0;
  292.                                 } else {
  293.                                         GET_VALUE(message,num);
  294.                                         while(*message != '"')
  295.                                         {// find start of string
  296.                                                 if(*message == 0 || ISSPACE(*message)){
  297.                                                         PARSE_ERROR("Not a string:",message);
  298.                                                         return -1;
  299.                                                 }
  300.                                                 ++message;
  301.                                         }
  302.                                 }
  303.  
  304.                                 // parse string
  305.                                 ++message;
  306.                                 CHECK_EOS(message);
  307.                                 end=(num<=0? 0: min(off+((int)num),len));
  308.                                 for(; *message != '"' && (off < end || end == 0); ++off){
  309.                                         if(*message == '\\'){
  310.                                                 ++message;
  311.                                                 CHECK_EOS(message);
  312.                                                 switch(*message){
  313.                                                         case 'a': num=0x07; break; // Bell
  314.                                                         case 'b': num=0x08; break; // Backspace
  315.                                                         case 't': num=0x09; break; // Horizontal tab
  316.                                                         case 'n': num=0x0A; break; // Line feed
  317.                                                         case 'v': num=0x0B; break; // Vertical tab
  318.                                                         case 'f': num=0x0C; break; // Form feed
  319.                                                         case 'r': num=0x0D; break; // Carriage return
  320.                                                         case 'e': num=0x1B; break; // Escape
  321.                                                         default:  num=*message; break;
  322.                                                         case 'x': // Hexadecimal
  323.                                                         {
  324.                                                                 ++message;
  325.                                                                 CHECK_EOS(message);
  326.                                                                 if(!ISXDIGIT(*message)){
  327.                                                                         PARSE_ERROR("Not a hexadecimal digit:",message);
  328.                                                                         return -1;
  329.                                                                 }
  330.                                                                 num=(ISDIGIT(*message)?*message-'0':TOLOWER(*message)-'a'+10);
  331.                                                                 if(ISXDIGIT(*message)){
  332.                                                                         ++message;
  333.                                                                         CHECK_EOS(message);
  334.                                                                         num<<=8;
  335.                                                                         num+=(ISDIGIT(*message)?*message-'0':TOLOWER(*message)-'a'+10);
  336.                                                                 }
  337.                                                                 WFIFOB(fd,off)=TOB(num);
  338.                                                                 ++message;
  339.                                                                 CHECK_EOS(message);
  340.                                                                 continue;
  341.                                                         }
  342.                                                         case '0':
  343.                                                         case '1':
  344.                                                         case '2':
  345.                                                         case '3':
  346.                                                         case '4':
  347.                                                         case '5':
  348.                                                         case '6':
  349.                                                         case '7': // Octal
  350.                                                         {
  351.                                                                 num=*message-'0'; // 1st octal digit
  352.                                                                 ++message;
  353.                                                                 CHECK_EOS(message);
  354.                                                                 if(ISDIGIT(*message) && *message < '8'){
  355.                                                                         num<<=3;
  356.                                                                         num+=*message-'0'; // 2nd octal digit
  357.                                                                         ++message;
  358.                                                                         CHECK_EOS(message);
  359.                                                                         if(ISDIGIT(*message) && *message < '8'){
  360.                                                                                 num<<=3;
  361.                                                                                 num+=*message-'0'; // 3rd octal digit
  362.                                                                                 ++message;
  363.                                                                                 CHECK_EOS(message);
  364.                                                                         }
  365.                                                                 }
  366.                                                                 WFIFOB(fd,off)=TOB(num);
  367.                                                                 continue;
  368.                                                         }
  369.                                                 }
  370.                                         } else
  371.                                                 num=*message;
  372.                                         WFIFOB(fd,off)=TOB(num);
  373.                                         ++message;
  374.                                         CHECK_EOS(message);
  375.                                 }//for
  376.                                 while(*message != '"')
  377.                                 {// ignore extra characters
  378.                                         ++message;
  379.                                         CHECK_EOS(message);
  380.                                 }
  381.  
  382.                                 // terminate the string
  383.                                 if(off < end)
  384.                                 {// fill the rest with 0's
  385.                                         memset(WFIFOP(fd,off),0,end-off);
  386.                                         off=end;
  387.                                 }
  388.                         } else
  389.                         {// unknown
  390.                                 PARSE_ERROR("Unknown type of value in:",message);
  391.                                 return -1;
  392.                         }
  393.                         SKIP_VALUE(message);
  394.                 }
  395.  
  396.                 if(packet_db[sd->packet_ver][type].len == -1)
  397.                 {// send dynamic packet
  398.                         WFIFOW(fd,2)=TOW(off);
  399.                         WFIFOSET(fd,off);
  400.                 } else
  401.                 {// send static packet
  402.                         if(off < len)
  403.                                 memset(WFIFOP(fd,off),0,len-off);
  404.                         WFIFOSET(fd,len);
  405.                 }
  406.         } else {
  407.                 clif_displaymessage(fd, msg_txt(259)); // Invalid packet
  408.                 return -1;
  409.         }
  410.         sprintf (atcmd_output, msg_txt(258), type, type); // Sent packet 0x%x (%d)
  411.         clif_displaymessage(fd, atcmd_output);
  412.         return 0;
  413. #undef PARSE_ERROR
  414. #undef CHECK_EOS
  415. #undef SKIP_VALUE
  416. #undef GET_VALUE
  417. }
  418.  
  419. /*==========================================
  420.  * @rura, @warp, @mapmove
  421.  *------------------------------------------*/
  422. ACMD_FUNC(mapmove)
  423. {
  424.         char map_name[MAP_NAME_LENGTH_EXT];
  425.         unsigned short mapindex;
  426.         short x = 0, y = 0;
  427.         int m = -1;
  428.  
  429.         nullpo_retr(-1, sd);
  430.  
  431.         memset(map_name, '\0', sizeof(map_name));
  432.  
  433.         if (!message || !*message ||
  434.                 (sscanf(message, "%15s %hd %hd", map_name, &x, &y) < 3 &&
  435.                  sscanf(message, "%15[^,],%hd,%hd", map_name, &x, &y) < 1)) {
  436.                  
  437.                         clif_displaymessage(fd, "Please, enter a map (usage: @warp/@rura/@mapmove <mapname> <x> <y>).");
  438.                         return -1;
  439.         }
  440.  
  441.         if( battle_config.pvpmode_nowarp_cmd && sd->state.pvpmode )
  442.         {
  443.                 clif_displaymessage(sd->fd,"You can not use @go while on PVP Mode.");
  444.                 return -1;
  445.         }
  446.  
  447.         mapindex = mapindex_name2id(map_name);
  448.         if (mapindex)
  449.                 m = map_mapindex2mapid(mapindex);
  450.        
  451.         if (!mapindex) { // m < 0 means on different server! [Kevin]
  452.                 clif_displaymessage(fd, msg_txt(1)); // Map not found.
  453.                 return -1;
  454.         }
  455.  
  456.         if ((x || y) && map_getcell(m, x, y, CELL_CHKNOPASS))
  457.         {       //This is to prevent the pc_setpos call from printing an error.
  458.                 clif_displaymessage(fd, msg_txt(2));
  459.                 if (!map_search_freecell(NULL, m, &x, &y, 10, 10, 1))
  460.                         x = y = 0; //Invalid cell, use random spot.
  461.         }
  462.         if (map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
  463.                 clif_displaymessage(fd, msg_txt(247));
  464.                 return -1;
  465.         }
  466.         if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
  467.                 clif_displaymessage(fd, msg_txt(248));
  468.                 return -1;
  469.         }
  470.         if (pc_setpos(sd, mapindex, x, y, CLR_TELEPORT) != 0) {
  471.                 clif_displaymessage(fd, msg_txt(1)); // Map not found.
  472.                 return -1;
  473.         }
  474.  
  475.         clif_displaymessage(fd, msg_txt(0)); // Warped.
  476.         return 0;
  477. }
  478.  
  479. /*==========================================
  480.  * Displays where a character is. Corrected version by Silent. [Skotlex]
  481.  *------------------------------------------*/
  482. ACMD_FUNC(where)
  483. {
  484.         struct map_session_data* pl_sd;
  485.  
  486.         nullpo_retr(-1, sd);
  487.         memset(atcmd_player_name, '\0', sizeof atcmd_player_name);
  488.  
  489.         if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
  490.                 clif_displaymessage(fd, "Please, enter a player name (usage: @where <char name>).");
  491.                 return -1;
  492.         }
  493.  
  494.         pl_sd = map_nick2sd(atcmd_player_name);
  495.         if( pl_sd == NULL
  496.         ||  strncmp(pl_sd->status.name,atcmd_player_name,NAME_LENGTH) != 0
  497.         ||  (battle_config.hide_GM_session && pc_isGM(sd) < pc_isGM(pl_sd) && !(battle_config.who_display_aid && pc_isGM(sd) >= battle_config.who_display_aid))
  498.         ) {
  499.                 clif_displaymessage(fd, msg_txt(3)); // Character not found.
  500.                 return -1;
  501.         }
  502.  
  503.         snprintf(atcmd_output, sizeof atcmd_output, "%s %s %d %d", pl_sd->status.name, mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y);
  504.         clif_displaymessage(fd, atcmd_output);
  505.  
  506.         return 0;
  507. }
  508.  
  509. /*==========================================
  510.  *
  511.  *------------------------------------------*/
  512. ACMD_FUNC(jumpto)
  513. {
  514.         struct map_session_data *pl_sd = NULL;
  515.  
  516.         nullpo_retr(-1, sd);
  517.  
  518.         if (!message || !*message) {
  519.                 clif_displaymessage(fd, "Please, enter a player name (usage: @jumpto/@warpto/@goto <player name/id>).");
  520.                 return -1;
  521.         }
  522.  
  523.         if((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL)
  524.         {
  525.                 clif_displaymessage(fd, msg_txt(3)); // Character not found.
  526.                 return -1;
  527.         }
  528.        
  529.         if (pl_sd == sd)
  530.         {
  531.                 clif_displaymessage(fd, "But you are already where you are...");
  532.                 return -1;
  533.         }
  534.        
  535.         if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd))
  536.         {
  537.                 clif_displaymessage(fd, msg_txt(247));  // You are not authorized to warp to this map.
  538.                 return -1;
  539.         }
  540.        
  541.         if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd))
  542.         {
  543.                 clif_displaymessage(fd, msg_txt(248));  // You are not authorized to warp from your current map.
  544.                 return -1;
  545.         }
  546.  
  547.         if( pc_isdead(sd) )
  548.         {
  549.                 clif_displaymessage(fd, "You cannot use this command when dead.");
  550.                 return -1;
  551.         }
  552.  
  553.         pc_setpos(sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT);
  554.         sprintf(atcmd_output, msg_txt(4), pl_sd->status.name); // Jumped to %s
  555.         clif_displaymessage(fd, atcmd_output);
  556.  
  557.         return 0;
  558. }
  559.  
  560. /*==========================================
  561.  *
  562.  *------------------------------------------*/
  563. ACMD_FUNC(jump)
  564. {
  565.         short x = 0, y = 0;
  566.  
  567.         nullpo_retr(-1, sd);
  568.  
  569.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  570.  
  571.         sscanf(message, "%hd %hd", &x, &y);
  572.  
  573.         if (map[sd->bl.m].flag.noteleport && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
  574.                 clif_displaymessage(fd, msg_txt(248));  // You are not authorized to warp from your current map.
  575.                 return -1;
  576.         }
  577.  
  578.         if( pc_isdead(sd) )
  579.         {
  580.                 clif_displaymessage(fd, "You cannot use this command when dead.");
  581.                 return -1;
  582.         }
  583.  
  584.         if ((x || y) && map_getcell(sd->bl.m, x, y, CELL_CHKNOPASS))
  585.         {       //This is to prevent the pc_setpos call from printing an error.
  586.                 clif_displaymessage(fd, msg_txt(2));
  587.                 if (!map_search_freecell(NULL, sd->bl.m, &x, &y, 10, 10, 1))
  588.                         x = y = 0; //Invalid cell, use random spot.
  589.         }
  590.  
  591.         pc_setpos(sd, sd->mapindex, x, y, CLR_TELEPORT);
  592.         sprintf(atcmd_output, msg_txt(5), sd->bl.x, sd->bl.y); // Jumped to %d %d
  593.         clif_displaymessage(fd, atcmd_output);
  594.         return 0;
  595. }
  596.  
  597. /*==========================================
  598.  * @who3 = Player name, his location
  599.  *------------------------------------------*/
  600. ACMD_FUNC(who3)
  601. {
  602.         char temp0[100];
  603.         struct map_session_data *pl_sd;
  604.         struct s_mapiterator* iter;
  605.         int j, count;
  606.         int pl_GM_level, GM_level;
  607.         char match_text[100];
  608.         char player_name[NAME_LENGTH];
  609.  
  610.         nullpo_retr(-1, sd);
  611.  
  612.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  613.         memset(match_text, '\0', sizeof(match_text));
  614.         memset(player_name, '\0', sizeof(player_name));
  615.  
  616.         if (sscanf(message, "%99[^\n]", match_text) < 1)
  617.                 strcpy(match_text, "");
  618.         for (j = 0; match_text[j]; j++)
  619.                 match_text[j] = TOLOWER(match_text[j]);
  620.  
  621.         count = 0;
  622.         GM_level = pc_isGM(sd);
  623.  
  624.         iter = mapit_getallusers();
  625.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  626.         {
  627.                 pl_GM_level = pc_isGM(pl_sd);
  628.                 if(!( (battle_config.hide_GM_session || (pl_sd->sc.option & OPTION_INVISIBLE)) && pl_GM_level > GM_level ))
  629.                 {// you can look only lower or same level
  630.                         memcpy(player_name, pl_sd->status.name, NAME_LENGTH);
  631.                         for (j = 0; player_name[j]; j++)
  632.                                 player_name[j] = TOLOWER(player_name[j]);
  633.                         if (strstr(player_name, match_text) != NULL) { // search with no case sensitive
  634.  
  635.                                 if (battle_config.who_display_aid > 0 && pc_isGM(sd) >= battle_config.who_display_aid) {
  636.                                         sprintf(atcmd_output, "(CID:%d/AID:%d) ", pl_sd->status.char_id, pl_sd->status.account_id);
  637.                                 } else {
  638.                                         atcmd_output[0]=0;
  639.                                 }
  640.                                 //Player name
  641.                                 sprintf(temp0, msg_txt(333), pl_sd->status.name);
  642.                                 strcat(atcmd_output,temp0);
  643.                                 //Player title, if exists
  644.                                 if (pl_GM_level > 0) {
  645.                                         //sprintf(temp0, "(%s) ", player_title_txt(pl_GM_level) );
  646.                                         sprintf(temp0, msg_txt(334), player_title_txt(pl_GM_level) );
  647.                                         strcat(atcmd_output,temp0);
  648.                                 }
  649.                                 //Players Location: map x y
  650.                                 sprintf(temp0, msg_txt(338), mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y);
  651.                                 strcat(atcmd_output,temp0);
  652.  
  653.                                 clif_displaymessage(fd, atcmd_output);
  654.                                 count++;
  655.                         }
  656.                 }
  657.         }
  658.         mapit_free(iter);
  659.  
  660.         if (count == 0)
  661.                 clif_displaymessage(fd, msg_txt(28)); // No player found.
  662.         else if (count == 1)
  663.                 clif_displaymessage(fd, msg_txt(29)); // 1 player found.
  664.         else {
  665.                 sprintf(atcmd_output, msg_txt(30), count); // %d players found.
  666.                 clif_displaymessage(fd, atcmd_output);
  667.         }
  668.  
  669.         return 0;
  670. }
  671.  
  672. /*==========================================
  673.  * Player name, BLevel, Job,
  674.  *------------------------------------------*/
  675. ACMD_FUNC(who2)
  676. {
  677.         char temp0[100];
  678.         struct map_session_data *pl_sd;
  679.         struct s_mapiterator* iter;
  680.         int j, count;
  681.         int pl_GM_level, GM_level;
  682.         char match_text[100];
  683.         char player_name[NAME_LENGTH];
  684.  
  685.         nullpo_retr(-1, sd);
  686.  
  687.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  688.         memset(match_text, '\0', sizeof(match_text));
  689.         memset(player_name, '\0', sizeof(player_name));
  690.  
  691.         if (sscanf(message, "%99[^\n]", match_text) < 1)
  692.                 strcpy(match_text, "");
  693.         for (j = 0; match_text[j]; j++)
  694.                 match_text[j] = TOLOWER(match_text[j]);
  695.  
  696.         count = 0;
  697.         GM_level = pc_isGM(sd);
  698.  
  699.         iter = mapit_getallusers();
  700.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  701.         {
  702.                 pl_GM_level = pc_isGM(pl_sd);
  703.                 if(!( (battle_config.hide_GM_session || (pl_sd->sc.option & OPTION_INVISIBLE)) && (pl_GM_level > GM_level) ))
  704.                 {// you can look only lower or same level
  705.                         memcpy(player_name, pl_sd->status.name, NAME_LENGTH);
  706.                         for (j = 0; player_name[j]; j++)
  707.                                 player_name[j] = TOLOWER(player_name[j]);
  708.                         if (strstr(player_name, match_text) != NULL) { // search with no case sensitive
  709.                                 //Players Name
  710.                                 //sprintf(atcmd_output, "Name: %s ", pl_sd->status.name);
  711.                                 sprintf(atcmd_output, msg_txt(333), pl_sd->status.name);
  712.                                 //Player title, if exists
  713.                                 if (pl_GM_level > 0) {
  714.                                         //sprintf(temp0, "(%s) ", player_title_txt(pl_GM_level) );
  715.                                         sprintf(temp0, msg_txt(334), player_title_txt(pl_GM_level) );
  716.                                         strcat(atcmd_output,temp0);
  717.                                 }
  718.                                 //Players Base Level / Job name
  719.                                 //sprintf(temp0, "| L:%d/%d | Job: %s", pl_sd->status.base_level, pl_sd->status.job_level, job_name(pl_sd->status.class_) );
  720.                                 sprintf(temp0, msg_txt(337), pl_sd->status.base_level, pl_sd->status.job_level, job_name(pl_sd->status.class_) );
  721.                                 strcat(atcmd_output,temp0);
  722.  
  723.                                 clif_displaymessage(fd, atcmd_output);
  724.                                 count++;
  725.                         }
  726.                 }
  727.         }
  728.         mapit_free(iter);
  729.        
  730.         if (count == 0)
  731.                 clif_displaymessage(fd, msg_txt(28)); // No player found.
  732.         else if (count == 1)
  733.                 clif_displaymessage(fd, msg_txt(29)); // 1 player found.
  734.         else {
  735.                 sprintf(atcmd_output, msg_txt(30), count); // %d players found.
  736.                 clif_displaymessage(fd, atcmd_output);
  737.         }
  738.  
  739.         return 0;
  740. }
  741.  
  742. /*==========================================
  743.  * Player name, Playrs Party / Guild name
  744.  *------------------------------------------*/
  745. ACMD_FUNC(who)
  746. {
  747.         char temp0[100];
  748.         struct map_session_data *pl_sd;
  749.         struct s_mapiterator* iter;
  750.         int j, count;
  751.         int pl_GM_level, GM_level;
  752.         char match_text[100];
  753.         char player_name[NAME_LENGTH];
  754.         struct guild *g;
  755.         struct party_data *p;
  756.  
  757.         nullpo_retr(-1, sd);
  758.  
  759.         memset(temp0, '\0', sizeof(temp0));
  760.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  761.         memset(match_text, '\0', sizeof(match_text));
  762.         memset(player_name, '\0', sizeof(player_name));
  763.  
  764.         if (sscanf(message, "%99[^\n]", match_text) < 1)
  765.                 strcpy(match_text, "");
  766.         for (j = 0; match_text[j]; j++)
  767.                 match_text[j] = TOLOWER(match_text[j]);
  768.  
  769.         count = 0;
  770.         GM_level = pc_isGM(sd);
  771.  
  772.         iter = mapit_getallusers();
  773.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  774.         {
  775.                 pl_GM_level = pc_isGM(pl_sd);
  776.                 if(!( (battle_config.hide_GM_session || (pl_sd->sc.option & OPTION_INVISIBLE)) && pl_GM_level > GM_level ))
  777.                 {// you can look only lower or same level
  778.                         memcpy(player_name, pl_sd->status.name, NAME_LENGTH);
  779.                         for (j = 0; player_name[j]; j++)
  780.                                 player_name[j] = TOLOWER(player_name[j]);
  781.                         if (strstr(player_name, match_text) != NULL) { // search with no case sensitive
  782.                                 g = guild_search(pl_sd->status.guild_id);
  783.                                 p = party_search(pl_sd->status.party_id);
  784.                                 //Players Name
  785.                                 sprintf(atcmd_output, msg_txt(333), pl_sd->status.name);
  786.                                 //Player title, if exists
  787.                                 if (pl_GM_level > 0) {
  788.                                         sprintf(temp0, msg_txt(334), player_title_txt(pl_GM_level) );
  789.                                         strcat(atcmd_output,temp0);
  790.                                 }
  791.                                 //Players Party if exists
  792.                                 if (p != NULL) {
  793.                                         //sprintf(temp0," | Party: '%s'", p->name);
  794.                                         sprintf(temp0, msg_txt(335), p->party.name);
  795.                                         strcat(atcmd_output,temp0);
  796.                                 }
  797.                                 //Players Guild if exists
  798.                                 if (g != NULL) {
  799.                                         //sprintf(temp0," | Guild: '%s'", g->name);
  800.                                         sprintf(temp0, msg_txt(336), g->name);
  801.                                         strcat(atcmd_output,temp0);
  802.                                 }
  803.                                 clif_displaymessage(fd, atcmd_output);
  804.                                 count++;
  805.                         }
  806.                 }
  807.         }
  808.         mapit_free(iter);
  809.  
  810.         if (count == 0)
  811.                 clif_displaymessage(fd, msg_txt(28)); // No player found.
  812.         else if (count == 1)
  813.                 clif_displaymessage(fd, msg_txt(29)); // 1 player found.
  814.         else {
  815.                 sprintf(atcmd_output, msg_txt(30), count); // %d players found.
  816.                 clif_displaymessage(fd, atcmd_output);
  817.         }
  818.  
  819.         return 0;
  820. }
  821.  
  822. /*==========================================
  823.  *
  824.  *------------------------------------------*/
  825. ACMD_FUNC(whomap3)
  826. {
  827.         struct map_session_data *pl_sd;
  828.         struct s_mapiterator* iter;
  829.         int count;
  830.         int pl_GM_level, GM_level;
  831.         int map_id;
  832.         char map_name[MAP_NAME_LENGTH_EXT];
  833.  
  834.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  835.         memset(map_name, '\0', sizeof(map_name));
  836.  
  837.         if (!message || !*message)
  838.                 map_id = sd->bl.m;
  839.         else {
  840.                 sscanf(message, "%15s", map_name);
  841.                 if ((map_id = map_mapname2mapid(map_name)) < 0)
  842.                         map_id = sd->bl.m;
  843.         }
  844.  
  845.         count = 0;
  846.         GM_level = pc_isGM(sd);
  847.  
  848.         iter = mapit_getallusers();
  849.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  850.         {
  851.                 pl_GM_level = pc_isGM(pl_sd);
  852.                 if( pl_sd->bl.m != map_id )
  853.                         continue;
  854.                 if( (battle_config.hide_GM_session || (pl_sd->sc.option & OPTION_INVISIBLE)) && (pl_GM_level > GM_level) )
  855.                         continue;
  856.  
  857.                 if (pl_GM_level > 0)
  858.                         sprintf(atcmd_output, "Name: %s (GM:%d) | Location: %s %d %d", pl_sd->status.name, pl_GM_level, mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y);
  859.                 else
  860.                         sprintf(atcmd_output, "Name: %s | Location: %s %d %d", pl_sd->status.name, mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y);
  861.                 clif_displaymessage(fd, atcmd_output);
  862.                 count++;
  863.         }
  864.         mapit_free(iter);
  865.  
  866.         if (count == 0)
  867.                 sprintf(atcmd_output, msg_txt(54), map[map_id].name); // No player found in map '%s'.
  868.         else if (count == 1)
  869.                 sprintf(atcmd_output, msg_txt(55), map[map_id].name); // 1 player found in map '%s'.
  870.         else {
  871.                 sprintf(atcmd_output, msg_txt(56), count, map[map_id].name); // %d players found in map '%s'.
  872.         }
  873.         clif_displaymessage(fd, atcmd_output);
  874.  
  875.         return 0;
  876. }
  877.  
  878. /*==========================================
  879.  *
  880.  *------------------------------------------*/
  881. ACMD_FUNC(whomap2)
  882. {
  883.         struct map_session_data *pl_sd;
  884.         struct s_mapiterator* iter;
  885.         int count;
  886.         int pl_GM_level, GM_level;
  887.         int map_id = 0;
  888.         char map_name[MAP_NAME_LENGTH_EXT];
  889.  
  890.         nullpo_retr(-1, sd);
  891.  
  892.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  893.         memset(map_name, '\0', sizeof(map_name));
  894.  
  895.         if (!message || !*message)
  896.                 map_id = sd->bl.m;
  897.         else {
  898.                 sscanf(message, "%15s", map_name);
  899.                 if ((map_id = map_mapname2mapid(map_name)) < 0)
  900.                         map_id = sd->bl.m;
  901.         }
  902.  
  903.         count = 0;
  904.         GM_level = pc_isGM(sd);
  905.  
  906.         iter = mapit_getallusers();
  907.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  908.         {
  909.                 pl_GM_level = pc_isGM(pl_sd);
  910.                 if( pl_sd->bl.m != map_id )
  911.                         continue;
  912.                 if( (battle_config.hide_GM_session || (pl_sd->sc.option & OPTION_INVISIBLE)) && (pl_GM_level > GM_level) )
  913.                         continue;
  914.  
  915.                 if (pl_GM_level > 0)
  916.                         sprintf(atcmd_output, "Name: %s (GM:%d) | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_GM_level, pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level);
  917.                 else
  918.                         sprintf(atcmd_output, "Name: %s | BLvl: %d | Job: %s (Lvl: %d)", pl_sd->status.name, pl_sd->status.base_level, job_name(pl_sd->status.class_), pl_sd->status.job_level);
  919.                 clif_displaymessage(fd, atcmd_output);
  920.                 count++;
  921.         }
  922.         mapit_free(iter);
  923.  
  924.         if (count == 0)
  925.                 sprintf(atcmd_output, msg_txt(54), map[map_id].name); // No player found in map '%s'.
  926.         else if (count == 1)
  927.                 sprintf(atcmd_output, msg_txt(55), map[map_id].name); // 1 player found in map '%s'.
  928.         else {
  929.                 sprintf(atcmd_output, msg_txt(56), count, map[map_id].name); // %d players found in map '%s'.
  930.         }
  931.         clif_displaymessage(fd, atcmd_output);
  932.  
  933.         return 0;
  934. }
  935.  
  936. /*==========================================
  937.  *
  938.  *------------------------------------------*/
  939. ACMD_FUNC(whomap)
  940. {
  941.         char temp0[100];
  942.         char temp1[100];
  943.         struct map_session_data *pl_sd;
  944.         struct s_mapiterator* iter;
  945.         int count;
  946.         int pl_GM_level, GM_level;
  947.         int map_id = 0;
  948.         char map_name[MAP_NAME_LENGTH_EXT];
  949.         struct guild *g;
  950.         struct party_data *p;
  951.  
  952.         nullpo_retr(-1, sd);
  953.  
  954.         memset(temp0, '\0', sizeof(temp0));
  955.         memset(temp1, '\0', sizeof(temp1));
  956.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  957.         memset(map_name, '\0', sizeof(map_name));
  958.  
  959.         if (!message || !*message)
  960.                 map_id = sd->bl.m;
  961.         else {
  962.                 sscanf(message, "%15s", map_name);
  963.                 if ((map_id = map_mapname2mapid(map_name)) < 0)
  964.                         map_id = sd->bl.m;
  965.         }
  966.  
  967.         count = 0;
  968.         GM_level = pc_isGM(sd);
  969.  
  970.         iter = mapit_getallusers();
  971.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  972.         {
  973.                 pl_GM_level = pc_isGM(pl_sd);
  974.                 if( pl_sd->bl.m != map_id )
  975.                         continue;
  976.                 if( (battle_config.hide_GM_session || (pl_sd->sc.option & OPTION_INVISIBLE)) && (pl_GM_level > GM_level) )
  977.                         continue;
  978.  
  979.                 g = guild_search(pl_sd->status.guild_id);
  980.                 if (g == NULL)
  981.                         sprintf(temp1, "None");
  982.                 else
  983.                         sprintf(temp1, "%s", g->name);
  984.                 p = party_search(pl_sd->status.party_id);
  985.                 if (p == NULL)
  986.                         sprintf(temp0, "None");
  987.                 else
  988.                         sprintf(temp0, "%s", p->party.name);
  989.                 if (pl_GM_level > 0)
  990.                         sprintf(atcmd_output, "Name: %s (GM:%d) | Party: '%s' | Guild: '%s'", pl_sd->status.name, pl_GM_level, temp0, temp1);
  991.                 else
  992.                         sprintf(atcmd_output, "Name: %s | Party: '%s' | Guild: '%s'", pl_sd->status.name, temp0, temp1);
  993.                 clif_displaymessage(fd, atcmd_output);
  994.                 count++;
  995.         }
  996.         mapit_free(iter);
  997.  
  998.         if (count == 0)
  999.                 sprintf(atcmd_output, msg_txt(54), map[map_id].name); // No player found in map '%s'.
  1000.         else if (count == 1)
  1001.                 sprintf(atcmd_output, msg_txt(55), map[map_id].name); // 1 player found in map '%s'.
  1002.         else {
  1003.                 sprintf(atcmd_output, msg_txt(56), count, map[map_id].name); // %d players found in map '%s'.
  1004.         }
  1005.         clif_displaymessage(fd, atcmd_output);
  1006.  
  1007.         return 0;
  1008. }
  1009.  
  1010. /*==========================================
  1011.  *
  1012.  *------------------------------------------*/
  1013. ACMD_FUNC(whogm)
  1014. {
  1015.         struct map_session_data* pl_sd;
  1016.         struct s_mapiterator* iter;
  1017.         int j, count;
  1018.         int pl_GM_level, GM_level;
  1019.         char match_text[CHAT_SIZE_MAX];
  1020.         char player_name[NAME_LENGTH];
  1021.         struct guild *g;
  1022.         struct party_data *p;
  1023.  
  1024.         nullpo_retr(-1, sd);
  1025.  
  1026.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  1027.         memset(match_text, '\0', sizeof(match_text));
  1028.         memset(player_name, '\0', sizeof(player_name));
  1029.  
  1030.         if (sscanf(message, "%199[^\n]", match_text) < 1)
  1031.                 strcpy(match_text, "");
  1032.         for (j = 0; match_text[j]; j++)
  1033.                 match_text[j] = TOLOWER(match_text[j]);
  1034.  
  1035.         count = 0;
  1036.         GM_level = pc_isGM(sd);
  1037.  
  1038.         iter = mapit_getallusers();
  1039.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  1040.         {
  1041.                 pl_GM_level = pc_isGM(pl_sd);
  1042.                 if (!pl_GM_level)
  1043.                         continue;
  1044.  
  1045.                 if (match_text[0])
  1046.                 {
  1047.                         memcpy(player_name, pl_sd->status.name, NAME_LENGTH);
  1048.                         for (j = 0; player_name[j]; j++)
  1049.                                 player_name[j] = TOLOWER(player_name[j]);
  1050.                         // search with no case sensitive
  1051.                         if (strstr(player_name, match_text) == NULL)
  1052.                                 continue;
  1053.                 }
  1054.                 if (pl_GM_level > GM_level) {
  1055.                         if (pl_sd->sc.option & OPTION_INVISIBLE)
  1056.                                 continue;
  1057.                         sprintf(atcmd_output, "Name: %s (GM)", pl_sd->status.name);
  1058.                         clif_displaymessage(fd, atcmd_output);
  1059.                         count++;
  1060.                         continue;
  1061.                 }
  1062.  
  1063.                 sprintf(atcmd_output, "Name: %s (GM:%d) | Location: %s %d %d",
  1064.                         pl_sd->status.name, pl_GM_level,
  1065.                         mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y);
  1066.                 clif_displaymessage(fd, atcmd_output);
  1067.  
  1068.                 sprintf(atcmd_output, "       BLvl: %d | Job: %s (Lvl: %d)",
  1069.                         pl_sd->status.base_level,
  1070.                         job_name(pl_sd->status.class_), pl_sd->status.job_level);
  1071.                 clif_displaymessage(fd, atcmd_output);
  1072.                
  1073.                 p = party_search(pl_sd->status.party_id);
  1074.                 g = guild_search(pl_sd->status.guild_id);
  1075.        
  1076.                 sprintf(atcmd_output,"       Party: '%s' | Guild: '%s'",
  1077.                         p?p->party.name:"None", g?g->name:"None");
  1078.  
  1079.                 clif_displaymessage(fd, atcmd_output);
  1080.                 count++;
  1081.         }
  1082.         mapit_free(iter);
  1083.  
  1084.         if (count == 0)
  1085.                 clif_displaymessage(fd, msg_txt(150)); // No GM found.
  1086.         else if (count == 1)
  1087.                 clif_displaymessage(fd, msg_txt(151)); // 1 GM found.
  1088.         else {
  1089.                 sprintf(atcmd_output, msg_txt(152), count); // %d GMs found.
  1090.                 clif_displaymessage(fd, atcmd_output);
  1091.         }
  1092.  
  1093.         return 0;
  1094. }
  1095.  
  1096. /*==========================================
  1097.  *
  1098.  *------------------------------------------*/
  1099. ACMD_FUNC(save)
  1100. {
  1101.         nullpo_retr(-1, sd);
  1102.  
  1103.         pc_setsavepoint(sd, sd->mapindex, sd->bl.x, sd->bl.y);
  1104.         if (sd->status.pet_id > 0 && sd->pd)
  1105.                 intif_save_petdata(sd->status.account_id, &sd->pd->pet);
  1106.  
  1107.         chrif_save(sd,0);
  1108.        
  1109.         clif_displaymessage(fd, msg_txt(6)); // Your save point has been changed.
  1110.  
  1111.         return 0;
  1112. }
  1113.  
  1114. /*==========================================
  1115.  *
  1116.  *------------------------------------------*/
  1117. ACMD_FUNC(load)
  1118. {
  1119.         int m;
  1120.  
  1121.         nullpo_retr(-1, sd);
  1122.  
  1123.         m = map_mapindex2mapid(sd->status.save_point.map);
  1124.         if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
  1125.                 clif_displaymessage(fd, msg_txt(249));  // You are not authorized to warp to your save map.
  1126.                 return -1;
  1127.         }
  1128.         if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
  1129.                 clif_displaymessage(fd, msg_txt(248));  // You are not authorized to warp from your current map.
  1130.                 return -1;
  1131.         }
  1132.  
  1133.         pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT);
  1134.         clif_displaymessage(fd, msg_txt(7)); // Warping to save point..
  1135.  
  1136.         return 0;
  1137. }
  1138.  
  1139. /*==========================================
  1140.  *
  1141.  *------------------------------------------*/
  1142. ACMD_FUNC(speed)
  1143. {
  1144.         int speed;
  1145.  
  1146.         nullpo_retr(-1, sd);
  1147.  
  1148.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  1149.  
  1150.         if (!message || !*message || sscanf(message, "%d", &speed) < 1) {
  1151.                 sprintf(atcmd_output, "Please, enter a speed value (usage: @speed <%d-%d>).", MIN_WALK_SPEED, MAX_WALK_SPEED);
  1152.                 clif_displaymessage(fd, atcmd_output);
  1153.                 return -1;
  1154.         }
  1155.  
  1156.         sd->base_status.speed = cap_value(speed, MIN_WALK_SPEED, MAX_WALK_SPEED);
  1157.         status_calc_bl(&sd->bl, SCB_SPEED);
  1158.         clif_displaymessage(fd, msg_txt(8)); // Speed changed.
  1159.         return 0;
  1160. }
  1161.  
  1162. /*==========================================
  1163.  *
  1164.  *------------------------------------------*/
  1165. ACMD_FUNC(storage)
  1166. {
  1167.         nullpo_retr(-1, sd);
  1168.  
  1169.         if( sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading || sd->state.storage_flag )
  1170.                 return -1;
  1171.  
  1172.         if( premium_usage && map_flag_gvg(sd->bl.m) )
  1173.                 return -1;
  1174.  
  1175.         if (storage_storageopen(sd) == 1)
  1176.         {       //Already open.
  1177.                 clif_displaymessage(fd, msg_txt(250));
  1178.                 return -1;
  1179.         }
  1180.        
  1181.         clif_displaymessage(fd, "Storage opened.");
  1182.        
  1183.         return 0;
  1184. }
  1185.  
  1186.  
  1187. /*==========================================
  1188.  *
  1189.  *------------------------------------------*/
  1190. ACMD_FUNC(guildstorage)
  1191. {
  1192.         nullpo_retr(-1, sd);
  1193.  
  1194.         if (!sd->status.guild_id) {
  1195.                 clif_displaymessage(fd, msg_txt(252));
  1196.                 return -1;
  1197.         }
  1198.  
  1199.         if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading)
  1200.                 return -1;
  1201.  
  1202.         if (sd->state.storage_flag == 1 || sd->state.storage_flag == 3) {
  1203.                 clif_displaymessage(fd, msg_txt(250));
  1204.                 return -1;
  1205.         }
  1206.  
  1207.         if (sd->state.storage_flag == 2) {
  1208.                 clif_displaymessage(fd, msg_txt(251));
  1209.                 return -1;
  1210.         }
  1211.  
  1212.         storage_guild_storageopen(sd);
  1213.         clif_displaymessage(fd, "Guild storage opened.");
  1214.         return 0;
  1215. }
  1216.  
  1217. /*==========================================
  1218.  *
  1219.  *------------------------------------------*/
  1220. ACMD_FUNC(option)
  1221. {
  1222.         int param1 = 0, param2 = 0, param3 = 0;
  1223.         nullpo_retr(-1, sd);
  1224.  
  1225.         if (!message || !*message || sscanf(message, "%d %d %d", &param1, &param2, &param3) < 1 || param1 < 0 || param2 < 0 || param3 < 0) {
  1226.                 clif_displaymessage(fd, "Please, enter at least a option (usage: @option <param1:0+> <param2:0+> <param3:0+>).");
  1227.                 return -1;
  1228.         }
  1229.  
  1230.         sd->sc.opt1 = param1;
  1231.         sd->sc.opt2 = param2;
  1232.         pc_setoption(sd, param3);
  1233.        
  1234.         clif_displaymessage(fd, msg_txt(9)); // Options changed.
  1235.  
  1236.         return 0;
  1237. }
  1238.  
  1239. /*==========================================
  1240.  *
  1241.  *------------------------------------------*/
  1242. ACMD_FUNC(hide)
  1243. {
  1244.         nullpo_retr(-1, sd);
  1245.         if (sd->sc.option & OPTION_INVISIBLE) {
  1246.                 sd->sc.option &= ~OPTION_INVISIBLE;
  1247.                 if (sd->disguise)
  1248.                         status_set_viewdata(&sd->bl, sd->disguise);
  1249.                 else
  1250.                         status_set_viewdata(&sd->bl, sd->status.class_);
  1251.                 clif_displaymessage(fd, msg_txt(10)); // Invisible: Off
  1252.         } else {
  1253.                 sd->sc.option |= OPTION_INVISIBLE;
  1254.                 sd->vd.class_ = INVISIBLE_CLASS;
  1255.                 clif_displaymessage(fd, msg_txt(11)); // Invisible: On
  1256.         }
  1257.         clif_changeoption(&sd->bl);
  1258.  
  1259.         return 0;
  1260. }
  1261.  
  1262. /*==========================================
  1263.  * Changes a character's class
  1264.  *------------------------------------------*/
  1265. ACMD_FUNC(jobchange)
  1266. {
  1267.         //FIXME: redundancy, potentially wrong code, should use job_name() or similar instead of hardcoding the table [ultramage]
  1268.         int job = 0, upper = 0;
  1269.         nullpo_retr(-1, sd);
  1270.  
  1271.         if (!message || !*message || sscanf(message, "%d %d", &job, &upper) < 1)
  1272.         {
  1273.                 int i, found = 0;
  1274.                 const struct { char name[16]; int id; } jobs[] = {
  1275.                         { "novice",             0 },
  1276.                         { "swordsman"1 },
  1277.                         { "mage",               2 },
  1278.                         { "archer",             3 },
  1279.                         { "acolyte",    4 },
  1280.                         { "merchant",   5 },
  1281.                         { "thief",              6 },
  1282.                         { "knight",             7 },
  1283.                         { "priest",             8 },
  1284.                         { "priestess"8 },
  1285.                         { "wizard",             9 },
  1286.                         { "blacksmith", 10 },
  1287.                         { "hunter",             11 },
  1288.                         { "assassin",   12 },
  1289.                         { "crusader",   14 },
  1290.                         { "monk",               15 },
  1291.                         { "sage",               16 },
  1292.                         { "rogue",              17 },
  1293.                         { "alchemist"18 },
  1294.                         { "bard",               19 },
  1295.                         { "dancer",             20 },
  1296.                         { "super novice",       23 },
  1297.                         { "supernovice",        23 },
  1298.                         { "gunslinger", 24 },
  1299.                         { "gunner",     24 },
  1300.                         { "ninja",      25 },
  1301.                         { "high novice",        4001 },
  1302.                         { "swordsman high",     4002 },
  1303.                         { "mage high",          4003 },
  1304.                         { "archer high",        4004 },
  1305.                         { "acolyte high",       4005 },
  1306.                         { "merchant high",      4006 },
  1307.                         { "thief high",         4007 },
  1308.                         { "lord knight",        4008 },
  1309.                         { "high priest",        4009 },
  1310.                         { "high priestess",     4009 },
  1311.                         { "high wizard",        4010 },
  1312.                         { "whitesmith",         4011 },
  1313.                         { "sniper",             4012 },
  1314.                         { "assassin cross",     4013 },
  1315.                         { "paladin",    4015 },
  1316.                         { "champion",   4016 },
  1317.                         { "professor"4017 },
  1318.                         { "stalker",    4018 },
  1319.                         { "creator",    4019 },
  1320.                         { "clown",              4020 },
  1321.                         { "gypsy",              4021 },
  1322.                         { "baby novice",        4023 },
  1323.                         { "baby swordsman",     4024 },
  1324.                         { "baby mage",          4025 },
  1325.                         { "baby archer",        4026 },
  1326.                         { "baby acolyte",       4027 },
  1327.                         { "baby merchant",      4028 },
  1328.                         { "baby thief",         4029 },
  1329.                         { "baby knight",        4030 },
  1330.                         { "baby priest",        4031 },
  1331.                         { "baby priestess",     4031 },
  1332.                         { "baby wizard",        4032 },
  1333.                         { "baby blacksmith",4033 },
  1334.                         { "baby hunter",        4034 },
  1335.                         { "baby assassin",      4035 },
  1336.                         { "baby crusader",      4037 },
  1337.                         { "baby monk",          4038 },
  1338.                         { "baby sage",          4039 },
  1339.                         { "baby rogue",         4040 },
  1340.                         { "baby alchemist",     4041 },
  1341.                         { "baby bard",          4042 },
  1342.                         { "baby dancer",        4043 },
  1343.                         { "super baby",         4045 },
  1344.                         { "taekwon",            4046 },
  1345.                         { "taekwon boy",        4046 },
  1346.                         { "taekwon girl",       4046 },
  1347.                         { "star gladiator",     4047 },
  1348.                         { "soul linker",        4049 },
  1349.                         { "gangsi",             4050 },
  1350.                         { "bongun",             4050 },
  1351.                         { "munak",              4050 },
  1352.                         { "death knight",       4051 },
  1353.                         { "dark collector",     4052 },
  1354.                         { "rune knight",        4054 },
  1355.                         { "warlock",            4055 },
  1356.                         { "ranger",             4056 },
  1357.                         { "arch bishop",        4057 },
  1358.                         { "mechanic",           4058 },
  1359.                         { "guillotine",         4059 },
  1360.                         { "rune knight2",       4060 },
  1361.                         { "warlock2",           4061 },
  1362.                         { "ranger2",            4062 },
  1363.                         { "arch bishop2",       4063 },
  1364.                         { "mechanic2",          4064 },
  1365.                         { "guillotine2",        4065 },
  1366.                         { "royal guard",        4066 },
  1367.                         { "sorcerer",           4067 },
  1368.                         { "minstrel",           4068 },
  1369.                         { "wanderer",           4069 },
  1370.                         { "sura",               4070 },
  1371.                         { "genetic",            4071 },
  1372.                         { "shadow chaser",      4072 },
  1373.                         { "royal guard2",       4073 },
  1374.                         { "sorcerer2",          4074 },
  1375.                         { "minstrel2",          4075 },
  1376.                         { "wanderer2",          4076 },
  1377.                         { "sura2",              4077 },
  1378.                         { "genetic2",           4078 },
  1379.                         { "shadow chaser2",     4079 },
  1380.                         { "baby rune",          4096 },
  1381.                         { "baby warlock",       4097 },
  1382.                         { "baby ranger",        4098 },
  1383.                         { "baby bishop",        4099 },
  1384.                         { "baby mechanic",      4100 },
  1385.                         { "baby cross",         4101 },
  1386.                         { "baby guard",         4102 },
  1387.                         { "baby sorcerer",      4103 },
  1388.                         { "baby minstrel",      4104 },
  1389.                         { "baby wanderer",      4105 },
  1390.                         { "baby sura",          4106 },
  1391.                         { "baby genetic",       4107 },
  1392.                         { "baby chaser",        4108 },
  1393.                         { "super novice e",     4190 },
  1394.                         { "super baby e",       4191 },
  1395.                         { "kagerou",            4211 },
  1396.                         { "oboro",              4212 },
  1397.                 };
  1398.  
  1399.                 for (i=0; i < ARRAYLENGTH(jobs); i++) {
  1400.                         if (strncmpi(message, jobs[i].name, 16) == 0) {
  1401.                                 job = jobs[i].id;
  1402.                                 upper = 0;
  1403.                                 found = 1;
  1404.                                 break;
  1405.                         }
  1406.                 }
  1407.  
  1408.                 if (!found) {
  1409.                         clif_displaymessage(fd, "Please, enter job ID (usage: @job/@jobchange <job name/ID>).");
  1410.                         clif_displaymessage(fd, "----- Novice / 1st Class -----");
  1411.                         clif_displaymessage(fd, "   0 Novice            1 Swordman          2 Mage              3 Archer");
  1412.                         clif_displaymessage(fd, "   4 Acolyte           5 Merchant          6 Thief");
  1413.                         clif_displaymessage(fd, "----- 2nd Class -----");
  1414.                         clif_displaymessage(fd, "   7 Knight            8 Priest            9 Wizard           10 Blacksmith");
  1415.                         clif_displaymessage(fd, "  11 Hunter           12 Assassin         14 Crusader         15 Monk");
  1416.                         clif_displaymessage(fd, "  16 Sage             17 Rogue            18 Alchemist        19 Bard");
  1417.                         clif_displaymessage(fd, "  20 Dancer");
  1418.                         clif_displaymessage(fd, "----- High Novice / High 1st Class -----");
  1419.                         clif_displaymessage(fd, "4001 Novice High    4002 Swordman High  4003 Mage High      4004 Archer High");
  1420.                         clif_displaymessage(fd, "4005 Acolyte High   4006 Merchant High  4007 Thief High");
  1421.                         clif_displaymessage(fd, "----- Transcendent 2nd Class -----");
  1422.                         clif_displaymessage(fd, "4008 Lord Knight    4009 High Priest    4010 High Wizard    4011 Whitesmith");
  1423.                         clif_displaymessage(fd, "4012 Sniper         4013 Assassin Cross 4015 Paladin        4016 Champion");
  1424.                         clif_displaymessage(fd, "4017 Professor      4018 Stalker        4019 Creator        4020 Clown");
  1425.                         clif_displaymessage(fd, "4021 Gypsy");
  1426.                         clif_displaymessage(fd, "----- 3rd Class (Regular to 3rd) -----");
  1427.                         clif_displaymessage(fd, "4054 Rune Knight    4055 Warlock        4056 Ranger         4057 Arch Bishop");
  1428.                         clif_displaymessage(fd, "4058 Mechanic       4059 Guillotine Cross 4066 Royal Guard  4067 Sorcerer");
  1429.                         clif_displaymessage(fd, "4068 Minstrel       4069 Wanderer       4070 Sura           4071 Genetic");
  1430.                         clif_displaymessage(fd, "4072 Shadow Chaser");
  1431.                         clif_displaymessage(fd, "----- 3rd Class (Transcendent to 3rd) -----");
  1432.                         clif_displaymessage(fd, "4060 Rune Knight    4061 Warlock        4062 Ranger         4063 Arch Bishop");
  1433.                         clif_displaymessage(fd, "4064 Mechanic       4065 Guillotine Cross 4073 Royal Guard  4074 Sorcerer");
  1434.                         clif_displaymessage(fd, "4075 Minstrel       4076 Wanderer       4077 Sura           4078 Genetic");
  1435.                         clif_displaymessage(fd, "4079 Shadow Chaser");
  1436.                         clif_displaymessage(fd, "----- Expanded Class -----");
  1437.                         clif_displaymessage(fd, "  23 Super Novice     24 Gunslinger       25 Ninja          4046 Taekwon");
  1438.                         clif_displaymessage(fd, "4047 Star Gladiator 4049 Soul Linker    4050 Gangsi         4051 Death Knight");
  1439.                         clif_displaymessage(fd, "4052 Dark Collector 4190 Extended Super Novice  4191 Extended Super Baby");
  1440.                         clif_displaymessage(fd, "4211 Kagerou        4212 Oboro");
  1441.                         clif_displaymessage(fd, "---- 1st And 2nd Baby Class ----");
  1442.                         clif_displaymessage(fd, "4023 Baby Novice    4024 Baby Swordsman 4025 Baby Mage      4026 Baby Archer");
  1443.                         clif_displaymessage(fd, "4027 Baby Acolyte   4028 Baby Merchant  4029 Baby Thief     4030 Baby Knight");
  1444.                         clif_displaymessage(fd, "4031 Baby Priest    4032 Baby Wizard    4033 Baby Blacksmith 4034 Baby Hunter");
  1445.                         clif_displaymessage(fd, "4035 Baby Assassin  4037 Baby Crusader  4038 Baby Monk      4039 Baby Sage");
  1446.                         clif_displaymessage(fd, "4040 Baby Rogue     4041 Baby Alchemist 4042 Baby Bard      4043 Baby Dancer");
  1447.                         clif_displaymessage(fd, "4045 Super Baby");
  1448.                         clif_displaymessage(fd, "---- 3rd Baby Class ----");
  1449.                         clif_displaymessage(fd, "4096 Baby Rune Knight    4097 Baby Warlock        4098 Baby Ranger");
  1450.                         clif_displaymessage(fd, "4099 Baby Arch Bishop    4100 Baby Mechanic       4101 Baby Guillotine Cross");
  1451.                         clif_displaymessage(fd, "4102 Baby Royal Guard    4103 Baby Sorcerer       4104 Baby Minstrel");
  1452.                         clif_displaymessage(fd, "4105 Baby Wanderer       4106 Baby Sura           4107 Baby Genetic");
  1453.                         clif_displaymessage(fd, "4108 Baby Shadow Chaser");
  1454.                         clif_displaymessage(fd, "---- Modes, And Others ----");
  1455.                         clif_displaymessage(fd, "  22 Wedding          26 Christmas");
  1456.                         clif_displaymessage(fd, "  27 Summer         4048 Star Gladiator (Union)");
  1457.                         clif_displaymessage(fd, "---- Mounts (Not Allowed) ----");
  1458.                         clif_displaymessage(fd, "  13 Knight (Peco)          21 Crusader (Peco)");
  1459.                         clif_displaymessage(fd, "4014 Lord Knight (Peco)   4022 Paladin (Peco)       4036 Baby Knight (Peco)");
  1460.                         clif_displaymessage(fd, "4044 Baby Crusader (Peco) 4080 Rune Knight (Dragon)");
  1461.                         clif_displaymessage(fd, "4081 Rune Knight Trans (Dragon)  4082 Royal Guard (Gryphon)");
  1462.                         clif_displaymessage(fd, "4083 Royal Guard Trans (Gryphon) 4084 Ranger (Warg) 4085 Ranger Trans (Warg)");
  1463.                         clif_displaymessage(fd, "4086 Mechanic (Mado)      4087 Mechanic Trans (Mado)");
  1464.                         return -1;
  1465.                 }
  1466.         }
  1467.  
  1468.         switch( job )
  1469.         {
  1470.                 case   13: case   21: case 4014: case 4022: case 4036:
  1471.                 case 4044: case 4080: case 4081: case 4082: case 4083:
  1472.                 case 4084: case 4085: case 4086: case 4087: case 4109:
  1473.                 case 4110: case 4111: case 4112:
  1474.                         return 0; // Deny direct transformation into dummy jobs
  1475.         }
  1476.  
  1477.         if (pcdb_checkid(job))
  1478.         {
  1479.                 if (pc_jobchange(sd, job, upper) == 0)
  1480.                         clif_displaymessage(fd, msg_txt(12)); // Your job has been changed.
  1481.                 else {
  1482.                         clif_displaymessage(fd, msg_txt(155)); // You are unable to change your job.
  1483.                         return -1;
  1484.                 }
  1485.         } else {
  1486.                 clif_displaymessage(fd, "Please, enter a valid job ID (usage: @job/@jobchange <job name/ID>).");
  1487.                 clif_displaymessage(fd, "   0 Novice            1 Swordman          2 Mage              3 Archer");
  1488.                 clif_displaymessage(fd, "   4 Acolyte           5 Merchant          6 Thief");
  1489.                 clif_displaymessage(fd, "----- 2nd Class -----");
  1490.                 clif_displaymessage(fd, "   7 Knight            8 Priest            9 Wizard           10 Blacksmith");
  1491.                 clif_displaymessage(fd, "  11 Hunter           12 Assassin         14 Crusader         15 Monk");
  1492.                 clif_displaymessage(fd, "  16 Sage             17 Rogue            18 Alchemist        19 Bard");
  1493.                 clif_displaymessage(fd, "  20 Dancer");
  1494.                 clif_displaymessage(fd, "----- High Novice / High 1st Class -----");
  1495.                 clif_displaymessage(fd, "4001 Novice High    4002 Swordman High  4003 Mage High      4004 Archer High");
  1496.                 clif_displaymessage(fd, "4005 Acolyte High   4006 Merchant High  4007 Thief High");
  1497.                 clif_displaymessage(fd, "----- Transcendent 2nd Class -----");
  1498.                 clif_displaymessage(fd, "4008 Lord Knight    4009 High Priest    4010 High Wizard    4011 Whitesmith");
  1499.                 clif_displaymessage(fd, "4012 Sniper         4013 Assassin Cross 4015 Paladin        4016 Champion");
  1500.                 clif_displaymessage(fd, "4017 Professor      4018 Stalker        4019 Creator        4020 Clown");
  1501.                 clif_displaymessage(fd, "4021 Gypsy");
  1502.                 clif_displaymessage(fd, "----- 3rd Class (Regular to 3rd) -----");
  1503.                 clif_displaymessage(fd, "4054 Rune Knight    4055 Warlock        4056 Ranger         4057 Arch Bishop");
  1504.                 clif_displaymessage(fd, "4058 Mechanic       4059 Guillotine Cross 4066 Royal Guard  4067 Sorcerer");
  1505.                 clif_displaymessage(fd, "4068 Minstrel       4069 Wanderer       4070 Sura           4071 Genetic");
  1506.                 clif_displaymessage(fd, "4072 Shadow Chaser");
  1507.                 clif_displaymessage(fd, "----- 3rd Class (Transcendent to 3rd) -----");
  1508.                 clif_displaymessage(fd, "4060 Rune Knight    4061 Warlock        4062 Ranger         4063 Arch Bishop");
  1509.                 clif_displaymessage(fd, "4064 Mechanic       4065 Guillotine Cross 4073 Royal Guard  4074 Sorcerer");
  1510.                 clif_displaymessage(fd, "4075 Minstrel       4076 Wanderer       4077 Sura           4078 Genetic");
  1511.                 clif_displaymessage(fd, "4079 Shadow Chaser");
  1512.                 clif_displaymessage(fd, "----- Expanded Class -----");
  1513.                 clif_displaymessage(fd, "  23 Super Novice     24 Gunslinger       25 Ninja          4046 Taekwon");
  1514.                 clif_displaymessage(fd, "4047 Star Gladiator 4049 Soul Linker    4050 Gangsi         4051 Death Knight");
  1515.                 clif_displaymessage(fd, "4052 Dark Collector 4190 Extended Super Novice  4191 Extended Super Baby");
  1516.                 clif_displaymessage(fd, "4211 Kagerou        4212 Oboro");
  1517.                 clif_displaymessage(fd, "---- 1st And 2nd Baby Class ----");
  1518.                 clif_displaymessage(fd, "4023 Baby Novice    4024 Baby Swordsman 4025 Baby Mage      4026 Baby Archer");
  1519.                 clif_displaymessage(fd, "4027 Baby Acolyte   4028 Baby Merchant  4029 Baby Thief     4030 Baby Knight");
  1520.                 clif_displaymessage(fd, "4031 Baby Priest    4032 Baby Wizard    4033 Baby Blacksmith 4034 Baby Hunter");
  1521.                 clif_displaymessage(fd, "4035 Baby Assassin  4037 Baby Crusader  4038 Baby Monk      4039 Baby Sage");
  1522.                 clif_displaymessage(fd, "4040 Baby Rogue     4041 Baby Alchemist 4042 Baby Bard      4043 Baby Dancer");
  1523.                 clif_displaymessage(fd, "4045 Super Baby");
  1524.                 clif_displaymessage(fd, "---- 3rd Baby Class ----");
  1525.                 clif_displaymessage(fd, "4096 Baby Rune Knight    4097 Baby Warlock        4098 Baby Ranger");
  1526.                 clif_displaymessage(fd, "4099 Baby Arch Bishop    4100 Baby Mechanic       4101 Baby Guillotine Cross");
  1527.                 clif_displaymessage(fd, "4102 Baby Royal Guard    4103 Baby Sorcerer       4104 Baby Minstrel");
  1528.                 clif_displaymessage(fd, "4105 Baby Wanderer       4106 Baby Sura           4107 Baby Genetic");
  1529.                 clif_displaymessage(fd, "4108 Baby Shadow Chaser");
  1530.                 clif_displaymessage(fd, "---- Modes, And Others ----");
  1531.                 clif_displaymessage(fd, "  22 Wedding          26 Christmas");
  1532.                 clif_displaymessage(fd, "  27 Summer         4048 Star Gladiator (Union)");
  1533.                 clif_displaymessage(fd, "---- Mounts (Not Allowed) ----");
  1534.                 clif_displaymessage(fd, "  13 Knight (Peco)          21 Crusader (Peco)");
  1535.                 clif_displaymessage(fd, "4014 Lord Knight (Peco)   4022 Paladin (Peco)       4036 Baby Knight (Peco)");
  1536.                 clif_displaymessage(fd, "4044 Baby Crusader (Peco) 4080 Rune Knight (Dragon)");
  1537.                 clif_displaymessage(fd, "4081 Rune Knight Trans (Dragon)  4082 Royal Guard (Gryphon)");
  1538.                 clif_displaymessage(fd, "4083 Royal Guard Trans (Gryphon) 4084 Ranger (Warg) 4085 Ranger Trans (Warg)");
  1539.                 clif_displaymessage(fd, "4086 Mechanic (Mado)      4087 Mechanic Trans (Mado)");
  1540.                 return -1;
  1541.         }
  1542.  
  1543.         return 0;
  1544. }
  1545.  
  1546. /*==========================================
  1547.  *
  1548.  *------------------------------------------*/
  1549. ACMD_FUNC(die)
  1550. {
  1551.         nullpo_retr(-1, sd);
  1552.         clif_specialeffect(&sd->bl,450,SELF);
  1553.         status_kill(&sd->bl);
  1554.         clif_displaymessage(fd, msg_txt(13)); // A pity! You've died.
  1555.  
  1556.         return 0;
  1557. }
  1558.  
  1559. /*==========================================
  1560.  *
  1561.  *------------------------------------------*/
  1562. ACMD_FUNC(kill)
  1563. {
  1564.         struct map_session_data *pl_sd;
  1565.         nullpo_retr(-1, sd);
  1566.  
  1567.         memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
  1568.  
  1569.         if (!message || !*message) {
  1570.                 clif_displaymessage(fd, "Please, enter a player name (usage: @kill <player name/id>).");
  1571.                 return -1;
  1572.         }
  1573.  
  1574.         if((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL)
  1575.         {
  1576.                 clif_displaymessage(fd, msg_txt(3)); // Character not found.
  1577.                 return -1;
  1578.         }
  1579.        
  1580.         if (pc_isGM(sd) < pc_isGM(pl_sd))
  1581.         { // you can kill only lower or same level
  1582.                 clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
  1583.                 return -1;
  1584.         }
  1585.        
  1586.         status_kill(&pl_sd->bl);
  1587.         clif_displaymessage(pl_sd->fd, msg_txt(13)); // A pity! You've died.
  1588.         if (fd != pl_sd->fd)
  1589.                 clif_displaymessage(fd, msg_txt(14)); // Character killed.
  1590.  
  1591.         return 0;
  1592. }
  1593.  
  1594. /*==========================================
  1595.  *
  1596.  *------------------------------------------*/
  1597. ACMD_FUNC(alive)
  1598. {
  1599.         nullpo_retr(-1, sd);
  1600.         if (!status_revive(&sd->bl, 100, 100))
  1601.         {
  1602.                 clif_displaymessage(fd, "You're not dead.");
  1603.                 return -1;
  1604.         }
  1605.         clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1);
  1606.         clif_displaymessage(fd, msg_txt(16)); // You've been revived! It's a miracle!
  1607.         return 0;
  1608. }
  1609.  
  1610. /*==========================================
  1611.  * +kamic [LuzZza]
  1612.  *------------------------------------------*/
  1613. ACMD_FUNC(kami)
  1614. {
  1615.         unsigned long color=0;
  1616.         nullpo_retr(-1, sd);
  1617.  
  1618.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  1619.  
  1620.         if(*(command + 5) != 'c' && *(command + 5) != 'C') {
  1621.  
  1622.                 if (!message || !*message) {
  1623.                         clif_displaymessage(fd, "Please, enter a message (usage: @kami <message>).");
  1624.                         return -1;
  1625.                 }
  1626.  
  1627.                 sscanf(message, "%199[^\n]", atcmd_output);
  1628.                 intif_broadcast(atcmd_output, strlen(atcmd_output) + 1, (*(command + 5) == 'b' || *(command + 5) == 'B') ? 0x10 : 0);
  1629.        
  1630.         } else {
  1631.        
  1632.                 if(!message || !*message || (sscanf(message, "%lx %199[^\n]", &color, atcmd_output) < 2)) {
  1633.                         clif_displaymessage(fd, "Please, enter color and message (usage: @kamic <color> <message>).");
  1634.                         return -1;
  1635.                 }
  1636.        
  1637.                 if(color > 0xFFFFFF) {
  1638.                         clif_displaymessage(fd, "Invalid color.");
  1639.                         return -1;
  1640.                 }
  1641.        
  1642.                 intif_broadcast2(atcmd_output, strlen(atcmd_output) + 1, color, 0x190, 12, 0, 0);
  1643.         }
  1644.         return 0;
  1645. }
  1646.  
  1647. /*==========================================
  1648.  *
  1649.  *------------------------------------------*/
  1650. ACMD_FUNC(heal)
  1651. {
  1652.         int hp = 0, sp = 0; // [Valaris] thanks to fov
  1653.         nullpo_retr(-1, sd);
  1654.  
  1655.         sscanf(message, "%d %d", &hp, &sp);
  1656.  
  1657.         // some overflow checks
  1658.         if( hp == INT_MIN ) hp++;
  1659.         if( sp == INT_MIN ) sp++;
  1660.  
  1661.         if ( hp == 0 && sp == 0 ) {
  1662.                 if (!status_percent_heal(&sd->bl, 100, 100))
  1663.                         clif_displaymessage(fd, msg_txt(157)); // HP and SP have already been recovered.
  1664.                 else
  1665.                         clif_displaymessage(fd, msg_txt(17)); // HP, SP recovered.
  1666.                 return 0;
  1667.         }
  1668.  
  1669.         if ( hp > 0 && sp >= 0 ) {
  1670.                 if(!status_heal(&sd->bl, hp, sp, 0))
  1671.                         clif_displaymessage(fd, msg_txt(157)); // HP and SP are already with the good value.
  1672.                 else
  1673.                         clif_displaymessage(fd, msg_txt(17)); // HP, SP recovered.
  1674.                 return 0;
  1675.         }
  1676.  
  1677.         if ( hp < 0 && sp <= 0 ) {
  1678.                 status_damage(NULL, &sd->bl, -hp, -sp, 0, 0);
  1679.                 clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, 4, 0);
  1680.                 clif_displaymessage(fd, msg_txt(156)); // HP or/and SP modified.
  1681.                 return 0;
  1682.         }
  1683.  
  1684.         //Opposing signs.
  1685.         if ( hp ) {
  1686.                 if (hp > 0)
  1687.                         status_heal(&sd->bl, hp, 0, 0);
  1688.                 else {
  1689.                         status_damage(NULL, &sd->bl, -hp, 0, 0, 0);
  1690.                         clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, 4, 0);
  1691.                 }
  1692.         }
  1693.  
  1694.         if ( sp ) {
  1695.                 if (sp > 0)
  1696.                         status_heal(&sd->bl, 0, sp, 0);
  1697.                 else
  1698.                         status_damage(NULL, &sd->bl, 0, -sp, 0, 0);
  1699.         }
  1700.  
  1701.         clif_displaymessage(fd, msg_txt(156)); // HP or/and SP modified.
  1702.         return 0;
  1703. }
  1704.  
  1705. /*==========================================
  1706.  * @item command (usage: @item <name/id_of_item> <quantity>) (modified by [Yor] for pet_egg)
  1707.  *------------------------------------------*/
  1708. ACMD_FUNC(item)
  1709. {
  1710.         char item_name[100];
  1711.         int number = 0, item_id, flag, type = 0;
  1712.         struct item item_tmp;
  1713.         struct item_data *item_data;
  1714.         int get_count, i;
  1715.         nullpo_retr(-1, sd);
  1716.  
  1717.         memset(item_name, '\0', sizeof(item_name));
  1718.  
  1719.         if (!message || !*message || (
  1720.                 sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 &&
  1721.                 sscanf(message, "%99s %d", item_name, &number) < 1
  1722.         )) {
  1723.                 clif_displaymessage(fd, "Please, enter an item name/id (usage: @item <item name or ID> [quantity]).");
  1724.                 return -1;
  1725.         }
  1726.  
  1727.         if (number <= 0)
  1728.                 number = 1;
  1729.  
  1730.         if ((item_data = itemdb_searchname(item_name)) == NULL &&
  1731.             (item_data = itemdb_exists(atoi(item_name))) == NULL)
  1732.         {
  1733.                 clif_displaymessage(fd, msg_txt(19)); // Invalid item ID or name.
  1734.                 return -1;
  1735.         }
  1736.  
  1737.         if( !strcmpi(command+1,"bounditem") )
  1738.                 type = 1;
  1739.         else if( !strcmpi(command+1,"costumeitem") )
  1740.         {
  1741.                 if( !battle_config.costume_reserved_char_id )
  1742.                 {
  1743.                         clif_displaymessage(fd, "Costume convertion is disable. Set a value for costume_reserved_char_id on your eAmod.conf file.");
  1744.                         return -1;
  1745.                 }
  1746.                 if( !(item_data->equip&EQP_HEAD_LOW) &&
  1747.                         !(item_data->equip&EQP_HEAD_MID) &&
  1748.                         !(item_data->equip&EQP_HEAD_TOP) &&
  1749.                         !(item_data->equip&EQP_COS_HEAD_LOW) &&
  1750.                         !(item_data->equip&EQP_COS_HEAD_MID) &&
  1751.                         !(item_data->equip&EQP_COS_HEAD_TOP) )
  1752.                 {
  1753.                         clif_displaymessage(fd, "You cannot costume this item. Costume only work for headgears");
  1754.                         return -1;
  1755.                 }
  1756.                 type = 2;
  1757.         }
  1758.  
  1759.         item_id = item_data->nameid;
  1760.         get_count = number;
  1761.         //Check if it's stackable.
  1762.         if( !itemdb_isstackable2(item_data) )
  1763.         {
  1764.                 if( type == 1 && (item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) )
  1765.                 {
  1766.                         clif_displaymessage(fd, "Cannot create bounded pet eggs or pet armors.");
  1767.                         return -1;
  1768.                 }
  1769.                 get_count = 1;
  1770.         }
  1771.         else if( type == 1 )
  1772.         {
  1773.                 clif_displaymessage(fd, "Cannot create bounded stackable items.");
  1774.                 return -1;
  1775.         }
  1776.  
  1777.         for( i = 0; i < number; i += get_count )
  1778.         {
  1779.                 // if not pet egg
  1780.                 if( !pet_create_egg(sd, item_id) )
  1781.                 {
  1782.                         memset(&item_tmp, 0, sizeof(item_tmp));
  1783.                         item_tmp.nameid = item_id;
  1784.                         item_tmp.identify = 1;
  1785.                         if( type == 1 )
  1786.                                 item_tmp.bound = 1;
  1787.                         else if( type == 2 )
  1788.                         { // Costume Item
  1789.                                 item_tmp.card[0] = CARD0_CREATE;
  1790.                                 item_tmp.card[2] = GetWord(battle_config.costume_reserved_char_id, 0);
  1791.                                 item_tmp.card[3] = GetWord(battle_config.costume_reserved_char_id, 1);
  1792.                         }
  1793.  
  1794.                         if( (flag = pc_additem(sd, &item_tmp, get_count)) )
  1795.                                 clif_additem(sd, 0, 0, flag);
  1796.                 }
  1797.  
  1798.                 //Logs (A)dmins items [Lupus]
  1799.                 log_pick_pc(sd, LOG_TYPE_COMMAND, item_id, get_count, NULL, item_tmp.serial);
  1800.                 item_tmp.serial = 0;
  1801.         }
  1802.  
  1803.         clif_displaymessage(fd, msg_txt(18)); // Item created.
  1804.         return 0;
  1805. }
  1806.  
  1807. /*==========================================
  1808.  *
  1809.  *------------------------------------------*/
  1810. ACMD_FUNC(item2)
  1811. {
  1812.         struct item item_tmp;
  1813.         struct item_data *item_data;
  1814.         char item_name[100];
  1815.         int item_id, number = 0;
  1816.         int identify = 0, refine = 0, attr = 0;
  1817.         int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
  1818.         int flag, bound = 0;
  1819.         int loop, get_count, i;
  1820.         nullpo_retr(-1, sd);
  1821.  
  1822.         memset(item_name, '\0', sizeof(item_name));
  1823.  
  1824.         if (!message || !*message || (
  1825.                 sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 &&
  1826.                 sscanf(message, "%99s %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9
  1827.         )) {
  1828.                 clif_displaymessage(fd, "Please, enter all informations (usage: @item2 <item name or ID> <quantity>");
  1829.                 clif_displaymessage(fd, "  <Identify_flag> <refine> <attribut> <Card1> <Card2> <Card3> <Card4>).");
  1830.                 return -1;
  1831.         }
  1832.  
  1833.         if (number <= 0)
  1834.                 number = 1;
  1835.  
  1836.         item_id = 0;
  1837.         if ((item_data = itemdb_searchname(item_name)) != NULL ||
  1838.             (item_data = itemdb_exists(atoi(item_name))) != NULL)
  1839.                 item_id = item_data->nameid;
  1840.  
  1841.         if( item_id > 500 )
  1842.         {
  1843.                 if( !strcmpi(command+1,"bounditem2") )
  1844.                         bound = 1;
  1845.  
  1846.                 if( !itemdb_isstackable2(item_data) )
  1847.                 {
  1848.                         if( bound && (item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) )
  1849.                         {
  1850.                                 clif_displaymessage(fd, "Cannot create bounded pet eggs or pet armors.");
  1851.                                 return -1;
  1852.                         }
  1853.  
  1854.                         loop = number;
  1855.                         get_count = 1;
  1856.                         if( item_data->type == IT_PETEGG )
  1857.                         {
  1858.                                 identify = 1;
  1859.                                 refine = 0;
  1860.                         }
  1861.                         if( item_data->type == IT_PETARMOR )
  1862.                                 refine = 0;
  1863.                         if( refine > MAX_REFINE )
  1864.                                 refine = MAX_REFINE;
  1865.                 }
  1866.                 else
  1867.                 {
  1868.                         if( bound )
  1869.                         {
  1870.                                 clif_displaymessage(fd, "Cannot create bounded stackable items.");
  1871.                                 return -1;
  1872.                         }
  1873.  
  1874.                         loop = 1;
  1875.                         get_count = number;
  1876.                         identify = 1;
  1877.                         refine = attr = 0;
  1878.                 }
  1879.  
  1880.                 for( i = 0; i < loop; i++ )
  1881.                 {
  1882.                         memset(&item_tmp, 0, sizeof(item_tmp));
  1883.                         item_tmp.nameid = item_id;
  1884.                         item_tmp.identify = identify;
  1885.                         item_tmp.refine = refine;
  1886.                         item_tmp.attribute = attr;
  1887.                         item_tmp.card[0] = c1;
  1888.                         item_tmp.card[1] = c2;
  1889.                         item_tmp.card[2] = c3;
  1890.                         item_tmp.card[3] = c4;
  1891.                         item_tmp.bound = bound;
  1892.  
  1893.                         if( (flag = pc_additem(sd, &item_tmp, get_count)) )
  1894.                                 clif_additem(sd, 0, 0, flag);
  1895.  
  1896.                         //Logs (A)dmins items [Lupus]
  1897.                         log_pick_pc(sd, LOG_TYPE_COMMAND, item_tmp.nameid, number, &item_tmp, item_tmp.serial);
  1898.                         item_tmp.serial = 0;
  1899.                 }
  1900.  
  1901.                 clif_displaymessage(fd, msg_txt(18)); // Item created.
  1902.         }
  1903.         else
  1904.         {
  1905.                 clif_displaymessage(fd, msg_txt(19)); // Invalid item ID or name.
  1906.                 return -1;
  1907.         }
  1908.  
  1909.         return 0;
  1910. }
  1911.  
  1912. /*==========================================
  1913.  *
  1914.  *------------------------------------------*/
  1915. ACMD_FUNC(itemreset)
  1916. {
  1917.         int i;
  1918.         nullpo_retr(-1, sd);
  1919.  
  1920.         for (i = 0; i < MAX_INVENTORY; i++) {
  1921.                 if (sd->status.inventory[i].amount && sd->status.inventory[i].equip == 0) {
  1922.  
  1923.                         //Logs (A)dmins items [Lupus]
  1924.                         log_pick_pc(sd, LOG_TYPE_COMMAND, sd->status.inventory[i].nameid, -sd->status.inventory[i].amount, &sd->status.inventory[i], sd->status.inventory[i].serial );
  1925.  
  1926.                         pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0);
  1927.                 }
  1928.         }
  1929.         clif_displaymessage(fd, msg_txt(20)); // All of your items have been removed.
  1930.  
  1931.         return 0;
  1932. }
  1933.  
  1934. /*==========================================
  1935.  * Atcommand @lvlup
  1936.  *------------------------------------------*/
  1937. ACMD_FUNC(baselevelup)
  1938. {
  1939.         int level=0, i=0, status_point=0;
  1940.         nullpo_retr(-1, sd);
  1941.         level = atoi(message);
  1942.  
  1943.         if (!message || !*message || !level) {
  1944.                 clif_displaymessage(fd, "Please, enter a level adjustment (usage: @lvup/@blevel/@baselvlup <number of levels>).");
  1945.                 return -1;
  1946.         }
  1947.  
  1948.         if (level > 0) {
  1949.                 if (sd->status.base_level == pc_maxbaselv(sd)) { // check for max level by Valaris
  1950.                         clif_displaymessage(fd, msg_txt(47)); // Base level can't go any higher.
  1951.                         return -1;
  1952.                 } // End Addition
  1953.                 if ((unsigned int)level > pc_maxbaselv(sd) || (unsigned int)level > pc_maxbaselv(sd) - sd->status.base_level) // fix positiv overflow
  1954.                         level = pc_maxbaselv(sd) - sd->status.base_level;
  1955.                 for (i = 0; i < level; i++)
  1956.                         status_point += pc_gets_status_point(sd->status.base_level + i);
  1957.  
  1958.                 sd->status.status_point += status_point;
  1959.                 sd->status.base_level += (unsigned int)level;
  1960.                 status_percent_heal(&sd->bl, 100, 100);
  1961.                 clif_misceffect(&sd->bl, 0);
  1962.                 clif_displaymessage(fd, msg_txt(21)); // Base level raised.
  1963.         } else {
  1964.                 if (sd->status.base_level == 1) {
  1965.                         clif_displaymessage(fd, msg_txt(158)); // Base level can't go any lower.
  1966.                         return -1;
  1967.                 }
  1968.                 level*=-1;
  1969.                 if ((unsigned int)level >= sd->status.base_level)
  1970.                         level = sd->status.base_level-1;
  1971.                 for (i = 0; i > -level; i--)
  1972.                         status_point += pc_gets_status_point(sd->status.base_level + i - 1);
  1973.                 if (sd->status.status_point < status_point)
  1974.                         pc_resetstate(sd);
  1975.                 if (sd->status.status_point < status_point)
  1976.                         sd->status.status_point = 0;
  1977.                 else
  1978.                         sd->status.status_point -= status_point;
  1979.                 sd->status.base_level -= (unsigned int)level;
  1980.                 clif_displaymessage(fd, msg_txt(22)); // Base level lowered.
  1981.         }
  1982.         sd->status.base_exp = 0;
  1983.         clif_updatestatus(sd, SP_STATUSPOINT);
  1984.         clif_updatestatus(sd, SP_BASELEVEL);
  1985.         clif_updatestatus(sd, SP_BASEEXP);
  1986.         clif_updatestatus(sd, SP_NEXTBASEEXP);
  1987.         status_calc_pc(sd, 0);
  1988.         if(sd->status.party_id)
  1989.                 party_send_levelup(sd);
  1990.         return 0;
  1991. }
  1992.  
  1993. /*==========================================
  1994.  *
  1995.  *------------------------------------------*/
  1996. ACMD_FUNC(joblevelup)
  1997. {
  1998.         int level=0;
  1999.         nullpo_retr(-1, sd);
  2000.        
  2001.         level = atoi(message);
  2002.  
  2003.         if (!message || !*message || !level) {
  2004.                 clif_displaymessage(fd, "Please, enter a level adjustment (usage: @joblvup/@jlevel/@joblvlup <number of levels>).");
  2005.                 return -1;
  2006.         }
  2007.         if (level > 0) {
  2008.                 if (sd->status.job_level == pc_maxjoblv(sd)) {
  2009.                         clif_displaymessage(fd, msg_txt(23)); // Job level can't go any higher.
  2010.                         return -1;
  2011.                 }
  2012.                 if ((unsigned int)level > pc_maxjoblv(sd) || (unsigned int)level > pc_maxjoblv(sd) - sd->status.job_level) // fix positiv overflow
  2013.                         level = pc_maxjoblv(sd) - sd->status.job_level;
  2014.                 sd->status.job_level += (unsigned int)level;
  2015.                 sd->status.skill_point += level;
  2016.                 clif_misceffect(&sd->bl, 1);
  2017.                 clif_displaymessage(fd, msg_txt(24)); // Job level raised.
  2018.         } else {
  2019.                 if (sd->status.job_level == 1) {
  2020.                         clif_displaymessage(fd, msg_txt(159)); // Job level can't go any lower.
  2021.                         return -1;
  2022.                 }
  2023.                 level *=-1;
  2024.                 if ((unsigned int)level >= sd->status.job_level) // fix negativ overflow
  2025.                         level = sd->status.job_level-1;
  2026.                 sd->status.job_level -= (unsigned int)level;
  2027.                 if (sd->status.skill_point < level)
  2028.                         pc_resetskill(sd,0);    //Reset skills since we need to substract more points.
  2029.                 if (sd->status.skill_point < level)
  2030.                         sd->status.skill_point = 0;
  2031.                 else
  2032.                         sd->status.skill_point -= level;
  2033.                 clif_displaymessage(fd, msg_txt(25)); // Job level lowered.
  2034.         }
  2035.         sd->status.job_exp = 0;
  2036.         clif_updatestatus(sd, SP_JOBLEVEL);
  2037.         clif_updatestatus(sd, SP_JOBEXP);
  2038.         clif_updatestatus(sd, SP_NEXTJOBEXP);
  2039.         clif_updatestatus(sd, SP_SKILLPOINT);
  2040.         status_calc_pc(sd, 0);
  2041.  
  2042.         return 0;
  2043. }
  2044.  
  2045. /*==========================================
  2046.  * @help
  2047.  *------------------------------------------*/
  2048. ACMD_FUNC(help)
  2049. {
  2050.         char buf[2048], w1[2048], w2[2048];
  2051.         int i, gm_level;
  2052.         FILE* fp;
  2053.         nullpo_retr(-1, sd);
  2054.  
  2055.         memset(buf, '\0', sizeof(buf));
  2056.  
  2057.         if ((fp = fopen(help_txt, "r")) != NULL) {
  2058.                 clif_displaymessage(fd, msg_txt(26)); // Help commands:
  2059.                 gm_level = pc_isGM(sd);
  2060.                 while(fgets(buf, sizeof(buf), fp) != NULL) {
  2061.                         if (buf[0] == '/' && buf[1] == '/')
  2062.                                 continue;
  2063.                         for (i = 0; buf[i] != '\0'; i++) {
  2064.                                 if (buf[i] == '\r' || buf[i] == '\n') {
  2065.                                         buf[i] = '\0';
  2066.                                         break;
  2067.                                 }
  2068.                         }
  2069.                         if (sscanf(buf, "%2047[^:]:%2047[^\n]", w1, w2) < 2)
  2070.                                 clif_displaymessage(fd, buf);
  2071.                         else if (gm_level >= atoi(w1))
  2072.                                 clif_displaymessage(fd, w2);
  2073.                 }
  2074.                 fclose(fp);
  2075.         } else {
  2076.                 clif_displaymessage(fd, msg_txt(27)); // File help.txt not found.
  2077.                 return -1;
  2078.         }
  2079.  
  2080.         return 0;
  2081. }
  2082.  
  2083. /*==========================================
  2084.  * @help2 - Char commands [Kayla]
  2085.  *------------------------------------------*/
  2086. ACMD_FUNC(help2)
  2087. {
  2088.         char buf[2048], w1[2048], w2[2048];
  2089.         int i, gm_level;
  2090.         FILE* fp;
  2091.         nullpo_retr(-1, sd);
  2092.  
  2093.         memset(buf, '\0', sizeof(buf));
  2094.  
  2095.         if ((fp = fopen(help2_txt, "r")) != NULL) {
  2096.                 clif_displaymessage(fd, msg_txt(26)); // Help commands:
  2097.                 gm_level = pc_isGM(sd);
  2098.                 while(fgets(buf, sizeof(buf), fp) != NULL) {
  2099.                         if (buf[0] == '/' && buf[1] == '/')
  2100.                                 continue;
  2101.                         for (i = 0; buf[i] != '\0'; i++) {
  2102.                                 if (buf[i] == '\r' || buf[i] == '\n') {
  2103.                                         buf[i] = '\0';
  2104.                                         break;
  2105.                                 }
  2106.                         }
  2107.                         if (sscanf(buf, "%2047[^:]:%2047[^\n]", w1, w2) < 2)
  2108.                                 clif_displaymessage(fd, buf);
  2109.                         else if (gm_level >= atoi(w1))
  2110.                                 clif_displaymessage(fd, w2);
  2111.                 }
  2112.                 fclose(fp);
  2113.         } else {
  2114.                 clif_displaymessage(fd, msg_txt(27)); // File help.txt not found.
  2115.                 return -1;
  2116.         }
  2117.  
  2118.         return 0;
  2119. }
  2120.  
  2121.  
  2122. // helper function, used in foreach calls to stop auto-attack timers
  2123. // parameter: '0' - everyone, 'id' - only those attacking someone with that id
  2124. static int atcommand_stopattack(struct block_list *bl,va_list ap)
  2125. {
  2126.         struct unit_data *ud = unit_bl2ud(bl);
  2127.         int id = va_arg(ap, int);
  2128.         if (ud && ud->attacktimer != INVALID_TIMER && (!id || id == ud->target))
  2129.         {
  2130.                 unit_stop_attack(bl);
  2131.                 return 1;
  2132.         }
  2133.         return 0;
  2134. }
  2135. /*==========================================
  2136.  *
  2137.  *------------------------------------------*/
  2138. static int atcommand_pvpoff_sub(struct block_list *bl,va_list ap)
  2139. {
  2140.         TBL_PC* sd = (TBL_PC*)bl;
  2141.         clif_pvpset(sd, 0, 0, 2);
  2142.         if (sd->pvp_timer != INVALID_TIMER) {
  2143.                 delete_timer(sd->pvp_timer, pc_calc_pvprank_timer);
  2144.                 sd->pvp_timer = INVALID_TIMER;
  2145.         }
  2146.         return 0;
  2147. }
  2148.  
  2149. ACMD_FUNC(pvpoff)
  2150. {
  2151.         nullpo_retr(-1, sd);
  2152.  
  2153.         if (!map[sd->bl.m].flag.pvp) {
  2154.                 clif_displaymessage(fd, msg_txt(160)); // PvP is already Off.
  2155.                 return -1;
  2156.         }
  2157.  
  2158.         map[sd->bl.m].flag.pvp = 0;
  2159.  
  2160.         if (!battle_config.pk_mode)
  2161.                 clif_map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING);
  2162.         map_foreachinmap(atcommand_pvpoff_sub,sd->bl.m, BL_PC);
  2163.         map_foreachinmap(atcommand_stopattack,sd->bl.m, BL_CHAR, 0);
  2164.         clif_displaymessage(fd, msg_txt(31)); // PvP: Off.
  2165.         return 0;
  2166. }
  2167.  
  2168. /*==========================================
  2169.  *
  2170.  *------------------------------------------*/
  2171. static int atcommand_pvpon_sub(struct block_list *bl,va_list ap)
  2172. {
  2173.         TBL_PC* sd = (TBL_PC*)bl;
  2174.         if (sd->state.pvpmode)
  2175.                 pc_pvpmodeoff(sd, 1, 1);
  2176.         if (sd->pvp_timer == INVALID_TIMER) {
  2177.                 sd->pvp_timer = add_timer(gettick() + 200, pc_calc_pvprank_timer, sd->bl.id, 0);
  2178.                 sd->pvp_rank = 0;
  2179.                 sd->pvp_lastusers = 0;
  2180.                 sd->pvp_point = 5;
  2181.                 sd->pvp_won = 0;
  2182.                 sd->pvp_lost = 0;
  2183.         }
  2184.         return 0;
  2185. }
  2186.  
  2187. ACMD_FUNC(pvpon)
  2188. {
  2189.         nullpo_retr(-1, sd);
  2190.  
  2191.         if (map[sd->bl.m].flag.pvp) {
  2192.                 clif_displaymessage(fd, msg_txt(161)); // PvP is already On.
  2193.                 return -1;
  2194.         }
  2195.  
  2196.         map[sd->bl.m].flag.pvp = 1;
  2197.  
  2198.         if (!battle_config.pk_mode)
  2199.         {// display pvp circle and rank
  2200.                 clif_map_property_mapall(sd->bl.m, MAPPROPERTY_FREEPVPZONE);
  2201.                 map_foreachinmap(atcommand_pvpon_sub,sd->bl.m, BL_PC);
  2202.         }
  2203.  
  2204.         clif_displaymessage(fd, msg_txt(32)); // PvP: On.
  2205.  
  2206.         return 0;
  2207. }
  2208.  
  2209. /*==========================================
  2210.  *
  2211.  *------------------------------------------*/
  2212. ACMD_FUNC(gvgoff)
  2213. {
  2214.         nullpo_retr(-1, sd);
  2215.  
  2216.         if (!map[sd->bl.m].flag.gvg) {
  2217.                 clif_displaymessage(fd, msg_txt(162)); // GvG is already Off.
  2218.                 return -1;
  2219.         }
  2220.                
  2221.         map[sd->bl.m].flag.gvg = 0;
  2222.         clif_map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING);
  2223.         map_foreachinmap(atcommand_stopattack,sd->bl.m, BL_CHAR, 0);
  2224.         clif_displaymessage(fd, msg_txt(33)); // GvG: Off.
  2225.  
  2226.         return 0;
  2227. }
  2228.  
  2229. /*==========================================
  2230.  *
  2231.  *------------------------------------------*/
  2232. ACMD_FUNC(gvgon)
  2233. {
  2234.         nullpo_retr(-1, sd);
  2235.  
  2236.         if (map[sd->bl.m].flag.gvg) {
  2237.                 clif_displaymessage(fd, msg_txt(163)); // GvG is already On.
  2238.                 return -1;
  2239.         }
  2240.        
  2241.         map[sd->bl.m].flag.gvg = 1;
  2242.         clif_map_property_mapall(sd->bl.m, MAPPROPERTY_AGITZONE);
  2243.         clif_displaymessage(fd, msg_txt(34)); // GvG: On.
  2244.  
  2245.         return 0;
  2246. }
  2247.  
  2248. /*==========================================
  2249.  *
  2250.  *------------------------------------------*/
  2251. ACMD_FUNC(model)
  2252. {
  2253.         int hair_style = 0, hair_color = 0, cloth_color = 0;
  2254.         nullpo_retr(-1, sd);
  2255.  
  2256.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2257.  
  2258.         if (!message || !*message || sscanf(message, "%d %d %d", &hair_style, &hair_color, &cloth_color) < 1) {
  2259.                 sprintf(atcmd_output, "Please, enter at least a value (usage: @model <hair ID: %d-%d> <hair color: %d-%d> <clothes color: %d-%d>).",
  2260.                         MIN_HAIR_STYLE, MAX_HAIR_STYLE, MIN_HAIR_COLOR, MAX_HAIR_COLOR, MIN_CLOTH_COLOR, MAX_CLOTH_COLOR);
  2261.                 clif_displaymessage(fd, atcmd_output);
  2262.                 return -1;
  2263.         }
  2264.  
  2265.         if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE &&
  2266.                 hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR &&
  2267.                 cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) {
  2268.                         pc_changelook(sd, LOOK_HAIR, hair_style);
  2269.                         pc_changelook(sd, LOOK_HAIR_COLOR, hair_color);
  2270.                         pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color);
  2271.                         clif_displaymessage(fd, msg_txt(36)); // Appearence changed.
  2272.         } else {
  2273.                 clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
  2274.                 return -1;
  2275.         }
  2276.  
  2277.         return 0;
  2278. }
  2279.  
  2280. /*==========================================
  2281.  * @dye && @ccolor
  2282.  *------------------------------------------*/
  2283. ACMD_FUNC(dye)
  2284. {
  2285.         int cloth_color = 0;
  2286.         nullpo_retr(-1, sd);
  2287.  
  2288.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2289.  
  2290.         if (!message || !*message || sscanf(message, "%d", &cloth_color) < 1) {
  2291.                 sprintf(atcmd_output, "Please, enter a clothes color (usage: @dye/@ccolor <clothes color: %d-%d>).", MIN_CLOTH_COLOR, MAX_CLOTH_COLOR);
  2292.                 clif_displaymessage(fd, atcmd_output);
  2293.                 return -1;
  2294.         }
  2295.  
  2296.         if (cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) {
  2297.                 pc_changelook(sd, LOOK_CLOTHES_COLOR, cloth_color);
  2298.                 clif_displaymessage(fd, msg_txt(36)); // Appearence changed.
  2299.         } else {
  2300.                 clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
  2301.                 return -1;
  2302.         }
  2303.  
  2304.         return 0;
  2305. }
  2306.  
  2307. /*==========================================
  2308.  * @hairstyle && @hstyle
  2309.  *------------------------------------------*/
  2310. ACMD_FUNC(hair_style)
  2311. {
  2312.         int hair_style = 0;
  2313.         nullpo_retr(-1, sd);
  2314.  
  2315.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2316.  
  2317.         if (!message || !*message || sscanf(message, "%d", &hair_style) < 1) {
  2318.                 sprintf(atcmd_output, "Please, enter a hair style (usage: @hairstyle/@hstyle <hair ID: %d-%d>).", MIN_HAIR_STYLE, MAX_HAIR_STYLE);
  2319.                 clif_displaymessage(fd, atcmd_output);
  2320.                 return -1;
  2321.         }
  2322.  
  2323.         if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE) {
  2324.                         pc_changelook(sd, LOOK_HAIR, hair_style);
  2325.                         clif_displaymessage(fd, msg_txt(36)); // Appearence changed.
  2326.         } else {
  2327.                 clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
  2328.                 return -1;
  2329.         }
  2330.  
  2331.         return 0;
  2332. }
  2333.  
  2334. /*==========================================
  2335.  * @haircolor && @hcolor
  2336.  *------------------------------------------*/
  2337. ACMD_FUNC(hair_color)
  2338. {
  2339.         int hair_color = 0;
  2340.         nullpo_retr(-1, sd);
  2341.  
  2342.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2343.  
  2344.         if (!message || !*message || sscanf(message, "%d", &hair_color) < 1) {
  2345.                 sprintf(atcmd_output, "Please, enter a hair color (usage: @haircolor/@hcolor <hair color: %d-%d>).", MIN_HAIR_COLOR, MAX_HAIR_COLOR);
  2346.                 clif_displaymessage(fd, atcmd_output);
  2347.                 return -1;
  2348.         }
  2349.  
  2350.         if (hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR) {
  2351.                         pc_changelook(sd, LOOK_HAIR_COLOR, hair_color);
  2352.                         clif_displaymessage(fd, msg_txt(36)); // Appearence changed.
  2353.         } else {
  2354.                 clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
  2355.                 return -1;
  2356.         }
  2357.  
  2358.         return 0;
  2359. }
  2360.  
  2361. /*==========================================
  2362.  * @go [city_number or city_name] - Updated by Harbin
  2363.  *------------------------------------------*/
  2364. ACMD_FUNC(go)
  2365. {
  2366.         int i;
  2367.         int town;
  2368.         char map_name[MAP_NAME_LENGTH];
  2369.         int m;
  2370.  
  2371.         const struct {
  2372.                 char map[MAP_NAME_LENGTH];
  2373.                 int x, y;
  2374.         } data[] = {
  2375.                 { MAP_PRONTERA,    156, 180 }, //  0=Prontera
  2376.                 { MAP_MORROC,      156,  93 }, //  1=Morroc
  2377.                 { MAP_GEFFEN,      119,  59 }, //  2=Geffen
  2378.                 { MAP_PAYON,       162, 233 }, //  3=Payon
  2379.                 { MAP_ALBERTA,     192, 147 }, //  4=Alberta
  2380.                 { MAP_IZLUDE,      128, 114 }, //  5=Izlude
  2381.                 { MAP_ALDEBARAN,   140, 131 }, //  6=Al de Baran
  2382.                 { MAP_LUTIE,       147, 134 }, //  7=Lutie
  2383.                 { MAP_COMODO,      209, 143 }, //  8=Comodo
  2384.                 { MAP_YUNO,        157,  51 }, //  9=Yuno
  2385.                 { MAP_AMATSU,      198,  84 }, // 10=Amatsu
  2386.                 { MAP_GONRYUN,     160, 120 }, // 11=Gonryun
  2387.                 { MAP_UMBALA,       89, 157 }, // 12=Umbala
  2388.                 { MAP_NIFLHEIM,     21, 153 }, // 13=Niflheim
  2389.                 { MAP_LOUYANG,     217,  40 }, // 14=Louyang
  2390.                 { MAP_NOVICE,       53, 111 }, // 15=Training Grounds
  2391.                 { MAP_JAIL,         23,  61 }, // 16=Prison
  2392.                 { MAP_JAWAII,      249, 127 }, // 17=Jawaii
  2393.                 { MAP_AYOTHAYA,    151, 117 }, // 18=Ayothaya
  2394.                 { MAP_EINBROCH,     64, 200 }, // 19=Einbroch
  2395.                 { MAP_LIGHTHALZEN, 158,  92 }, // 20=Lighthalzen
  2396.                 { MAP_EINBECH,      70,  95 }, // 21=Einbech
  2397.                 { MAP_HUGEL,        96, 145 }, // 22=Hugel
  2398.                 { MAP_RACHEL,      130, 110 }, // 23=Rachel
  2399.                 { MAP_VEINS,       216, 123 }, // 24=Veins
  2400.                 { MAP_MOSCOVIA,    223, 184 }, // 25=Moscovia
  2401.         };
  2402.  
  2403.         nullpo_retr(-1, sd);
  2404.  
  2405.         if( map[sd->bl.m].flag.nogo && battle_config.any_warp_GM_min_level > pc_isGM(sd) ) {
  2406.                 clif_displaymessage(sd->fd,"You can not use @go on this map.");
  2407.                 return 0;
  2408.         }
  2409.  
  2410.         if( battle_config.pvpmode_nowarp_cmd && sd->state.pvpmode )
  2411.         {
  2412.                 clif_displaymessage(sd->fd,"You can not use @go while on PVP Mode.");
  2413.                 return -1;
  2414.         }
  2415.  
  2416.         memset(map_name, '\0', sizeof(map_name));
  2417.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2418.  
  2419.         // get the number
  2420.         town = atoi(message);
  2421.  
  2422.         // if no value, display all value
  2423.         if (!message || !*message || sscanf(message, "%11s", map_name) < 1 || town < 0 || town >= ARRAYLENGTH(data)) {
  2424.                 clif_displaymessage(fd, msg_txt(38)); // Invalid location number, or name.
  2425.                 clif_displaymessage(fd, msg_txt(82)); // Please provide a name or number from the list provided:
  2426.                 clif_displaymessage(fd, " 0=Prontera         1=Morroc       2=Geffen");
  2427.                 clif_displaymessage(fd, " 3=Payon            4=Alberta      5=Izlude");
  2428.                 clif_displaymessage(fd, " 6=Al De Baran      7=Lutie        8=Comodo");
  2429.                 clif_displaymessage(fd, " 9=Yuno             10=Amatsu      11=Gonryun");
  2430.                 clif_displaymessage(fd, " 12=Umbala          13=Niflheim    14=Louyang");
  2431.                 clif_displaymessage(fd, " 15=Novice Grounds  16=Prison      17=Jawaii");
  2432.                 clif_displaymessage(fd, " 18=Ayothaya        19=Einbroch    20=Lighthalzen");
  2433.                 clif_displaymessage(fd, " 21=Einbech         22=Hugel       23=Rachel");
  2434.                 clif_displaymessage(fd, " 24=Veins           25=Moscovia");
  2435.                 return -1;
  2436.         }
  2437.  
  2438.         // get possible name of the city
  2439.         map_name[MAP_NAME_LENGTH-1] = '\0';
  2440.         for (i = 0; map_name[i]; i++)
  2441.                 map_name[i] = TOLOWER(map_name[i]);
  2442.         // try to identify the map name
  2443.         if (strncmp(map_name, "prontera", 3) == 0) {
  2444.                 town = 0;
  2445.         } else if (strncmp(map_name, "morocc", 3) == 0) {
  2446.                 town = 1;
  2447.         } else if (strncmp(map_name, "geffen", 3) == 0) {
  2448.                 town = 2;
  2449.         } else if (strncmp(map_name, "payon", 3) == 0 ||
  2450.                    strncmp(map_name, "paion", 3) == 0) {
  2451.                 town = 3;
  2452.         } else if (strncmp(map_name, "alberta", 3) == 0) {
  2453.                 town = 4;
  2454.         } else if (strncmp(map_name, "izlude", 3) == 0 ||
  2455.                    strncmp(map_name, "islude", 3) == 0) {
  2456.                 town = 5;
  2457.         } else if (strncmp(map_name, "aldebaran", 3) == 0 ||
  2458.                    strcmp(map_name,  "al") == 0) {
  2459.                 town = 6;
  2460.         } else if (strncmp(map_name, "lutie", 3) == 0 ||
  2461.                    strcmp(map_name,  "christmas") == 0 ||
  2462.                    strncmp(map_name, "xmas", 3) == 0 ||
  2463.                    strncmp(map_name, "x-mas", 3) == 0) {
  2464.                 town = 7;
  2465.         } else if (strncmp(map_name, "comodo", 3) == 0) {
  2466.                 town = 8;
  2467.         } else if (strncmp(map_name, "yuno", 3) == 0) {
  2468.                 town = 9;
  2469.         } else if (strncmp(map_name, "amatsu", 3) == 0) {
  2470.                 town = 10;
  2471.         } else if (strncmp(map_name, "gonryun", 3) == 0) {
  2472.                 town = 11;
  2473.         } else if (strncmp(map_name, "umbala", 3) == 0) {
  2474.                 town = 12;
  2475.         } else if (strncmp(map_name, "niflheim", 3) == 0) {
  2476.                 town = 13;
  2477.         } else if (strncmp(map_name, "louyang", 3) == 0) {
  2478.                 town = 14;
  2479.         } else if (strncmp(map_name, "new_1-1", 3) == 0 ||
  2480.                    strncmp(map_name, "startpoint", 3) == 0 ||
  2481.                    strncmp(map_name, "begining", 3) == 0) {
  2482.                 town = 15;
  2483.         } else if (strncmp(map_name, "sec_pri", 3) == 0 ||
  2484.                    strncmp(map_name, "prison", 3) == 0 ||
  2485.                    strncmp(map_name, "jails", 3) == 0) {
  2486.                 town = 16;
  2487.         } else if (strncmp(map_name, "jawaii", 3) == 0 ||
  2488.                    strncmp(map_name, "jawai", 3) == 0) {
  2489.                 town = 17;
  2490.         } else if (strncmp(map_name, "ayothaya", 3) == 0 ||
  2491.                    strncmp(map_name, "ayotaya", 3) == 0) {
  2492.                 town = 18;
  2493.         } else if (strncmp(map_name, "einbroch", 5) == 0 ||
  2494.                    strncmp(map_name, "ainbroch", 5) == 0) {
  2495.                 town = 19;
  2496.         } else if (strncmp(map_name, "lighthalzen", 3) == 0) {
  2497.                 town = 20;
  2498.         } else if (strncmp(map_name, "einbech", 3) == 0) {
  2499.                 town = 21;
  2500.         } else if (strncmp(map_name, "hugel", 3) == 0) {
  2501.                 town = 22;
  2502.         } else if (strncmp(map_name, "rachel", 3) == 0) {
  2503.                 town = 23;
  2504.         } else if (strncmp(map_name, "veins", 3) == 0) {
  2505.                 town = 24;
  2506.         } else if (strncmp(map_name, "moscovia", 3) == 0) {
  2507.                 town = 25;
  2508.         }
  2509.  
  2510.         if (town >= 0 && town < ARRAYLENGTH(data))
  2511.         {
  2512.                 m = map_mapname2mapid(data[town].map);
  2513.                 if (m >= 0 && map[m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
  2514.                         clif_displaymessage(fd, msg_txt(247));
  2515.                         return -1;
  2516.                 }
  2517.                 if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
  2518.                         clif_displaymessage(fd, msg_txt(248));
  2519.                         return -1;
  2520.                 }
  2521.                 if (pc_setpos(sd, mapindex_name2id(data[town].map), data[town].x, data[town].y, CLR_TELEPORT) == 0) {
  2522.                         clif_displaymessage(fd, msg_txt(0)); // Warped.
  2523.                 } else {
  2524.                         clif_displaymessage(fd, msg_txt(1)); // Map not found.
  2525.                         return -1;
  2526.                 }
  2527.         } else { // if you arrive here, you have an error in town variable when reading of names
  2528.                 clif_displaymessage(fd, msg_txt(38)); // Invalid location number or name.
  2529.                 return -1;
  2530.         }
  2531.  
  2532.         return 0;
  2533. }
  2534.  
  2535. /*==========================================
  2536.  *
  2537.  *------------------------------------------*/
  2538. ACMD_FUNC(monster)
  2539. {
  2540.         char name[NAME_LENGTH];
  2541.         char monster[NAME_LENGTH];
  2542.         int mob_id;
  2543.         int number = 0;
  2544.         int count;
  2545.         int i, k, range;
  2546.         short mx, my;
  2547.         nullpo_retr(-1, sd);
  2548.  
  2549.         memset(name, '\0', sizeof(name));
  2550.         memset(monster, '\0', sizeof(monster));
  2551.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2552.  
  2553.         if (!message || !*message) {
  2554.                         clif_displaymessage(fd, msg_txt(80)); // Give the display name or monster name/id please.
  2555.                         return -1;
  2556.         }
  2557.         if (sscanf(message, "\"%23[^\"]\" %23s %d", name, monster, &number) > 1 ||
  2558.                 sscanf(message, "%23s \"%23[^\"]\" %d", monster, name, &number) > 1) {
  2559.                 //All data can be left as it is.
  2560.         } else if ((count=sscanf(message, "%23s %d %23s", monster, &number, name)) > 1) {
  2561.                 //Here, it is possible name was not given and we are using monster for it.
  2562.                 if (count < 3) //Blank mob's name.
  2563.                         name[0] = '\0';
  2564.         } else if (sscanf(message, "%23s %23s %d", name, monster, &number) > 1) {
  2565.                 //All data can be left as it is.
  2566.         } else if (sscanf(message, "%23s", monster) > 0) {
  2567.                 //As before, name may be already filled.
  2568.                 name[0] = '\0';
  2569.         } else {
  2570.                 clif_displaymessage(fd, msg_txt(80)); // Give a display name and monster name/id please.
  2571.                 return -1;
  2572.         }
  2573.  
  2574.         if ((mob_id = mobdb_searchname(monster)) == 0) // check name first (to avoid possible name begining by a number)
  2575.                 mob_id = mobdb_checkid(atoi(monster));
  2576.  
  2577.         if (mob_id == 0) {
  2578.                 clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
  2579.                 return -1;
  2580.         }
  2581.  
  2582.         if (mob_id == MOBID_EMPERIUM) {
  2583.                 clif_displaymessage(fd, msg_txt(83)); // Monster 'Emperium' cannot be spawned.
  2584.                 return -1;
  2585.         }
  2586.  
  2587.         if (number <= 0)
  2588.                 number = 1;
  2589.  
  2590.         if( !name[0] )
  2591.                 strcpy(name, "--ja--");
  2592.  
  2593.         // If value of atcommand_spawn_quantity_limit directive is greater than or equal to 1 and quantity of monsters is greater than value of the directive
  2594.         if (battle_config.atc_spawn_quantity_limit && number > battle_config.atc_spawn_quantity_limit)
  2595.                 number = battle_config.atc_spawn_quantity_limit;
  2596.  
  2597.         if (battle_config.etc_log)
  2598.                 ShowInfo("%s monster='%s' name='%s' id=%d count=%d (%d,%d)\n", command, monster, name, mob_id, number, sd->bl.x, sd->bl.y);
  2599.  
  2600.         count = 0;
  2601.         range = (int)sqrt((float)number) +2; // calculation of an odd number (+ 4 area around)
  2602.         for (i = 0; i < number; i++) {
  2603.                 map_search_freecell(&sd->bl, 0, &mx,  &my, range, range, 0);
  2604.                 k = mob_once_spawn(sd, sd->bl.m, mx, my, name, mob_id, 1, "");
  2605.                 count += (k != 0) ? 1 : 0;
  2606.         }
  2607.  
  2608.         if (count != 0)
  2609.                 if (number == count)
  2610.                         clif_displaymessage(fd, msg_txt(39)); // All monster summoned!
  2611.                 else {
  2612.                         sprintf(atcmd_output, msg_txt(240), count); // %d monster(s) summoned!
  2613.                         clif_displaymessage(fd, atcmd_output);
  2614.                 }
  2615.         else {
  2616.                 clif_displaymessage(fd, msg_txt(40)); // Invalid monster ID or name.
  2617.                 return -1;
  2618.         }
  2619.  
  2620.         return 0;
  2621. }
  2622.  
  2623. // small monster spawning [Valaris]
  2624. ACMD_FUNC(monstersmall)
  2625. {
  2626.         char name[NAME_LENGTH] = "";
  2627.         char monster[NAME_LENGTH] = "";
  2628.         int mob_id = 0;
  2629.         int number = 0;
  2630.         int x = 0;
  2631.         int y = 0;
  2632.         int count;
  2633.         int i;
  2634.  
  2635.         nullpo_retr(-1, sd);
  2636.  
  2637.         if (!message || !*message) {
  2638.                 clif_displaymessage(fd, "Give a monster name/id please.");
  2639.                 return -1;
  2640.         }
  2641.  
  2642.         if (sscanf(message, "\"%23[^\"]\" %23s %d %d %d", name, monster, &number, &x, &y) < 2 &&
  2643.             sscanf(message, "%23s \"%23[^\"]\" %d %d %d", monster, name, &number, &x, &y) < 2 &&
  2644.             sscanf(message, "%23s %d %23s %d %d", monster, &number, name, &x, &y) < 1) {
  2645.                 clif_displaymessage(fd, "Give a monster name/id please.");
  2646.                 return -1;
  2647.         }
  2648.  
  2649.         // If monster identifier/name argument is a name
  2650.         if ((mob_id = mobdb_searchname(monster)) == 0) // check name first (to avoid possible name begining by a number)
  2651.                 mob_id = atoi(monster);
  2652.  
  2653.         if (mob_id == 0) {
  2654.                 clif_displaymessage(fd, msg_txt(40));
  2655.                 return -1;
  2656.         }
  2657.  
  2658.         if (mob_id == MOBID_EMPERIUM) {
  2659.                 clif_displaymessage(fd, msg_txt(83));   // Cannot spawn emperium
  2660.                 return -1;
  2661.         }
  2662.  
  2663.         if (mobdb_checkid(mob_id) == 0) {
  2664.                 clif_displaymessage(fd, "Invalid monster ID"); // Invalid Monster ID.
  2665.                 return -1;
  2666.         }
  2667.  
  2668.         if (number <= 0)
  2669.                 number = 1;
  2670.  
  2671.         if( !name[0] )
  2672.                 strcpy(name, "--ja--");
  2673.  
  2674.         // If value of atcommand_spawn_quantity_limit directive is greater than or equal to 1 and quantity of monsters is greater than value of the directive
  2675.         if (battle_config.atc_spawn_quantity_limit >= 1 && number > battle_config.atc_spawn_quantity_limit)
  2676.                 number = battle_config.atc_spawn_quantity_limit;
  2677.  
  2678.         count = 0;
  2679.         for (i = 0; i < number; i++) {
  2680.                 int mx, my;
  2681.                 if (x <= 0)
  2682.                         mx = sd->bl.x + (rand() % 11 - 5);
  2683.                 else
  2684.                         mx = x;
  2685.                 if (y <= 0)
  2686.                         my = sd->bl.y + (rand() % 11 - 5);
  2687.                 else
  2688.                         my = y;
  2689.                 count += (mob_once_spawn(sd, sd->bl.m, mx, my, name, mob_id, 1, "2") != 0) ? 1 : 0;
  2690.         }
  2691.  
  2692.         if (count != 0)
  2693.                 clif_displaymessage(fd, msg_txt(39)); // Monster Summoned!!
  2694.         else
  2695.                 clif_displaymessage(fd, msg_txt(40)); // Invalid Monster ID.
  2696.  
  2697.         return 0;
  2698. }
  2699. // big monster spawning [Valaris]
  2700. ACMD_FUNC(monsterbig)
  2701. {
  2702.         char name[NAME_LENGTH] = "";
  2703.         char monster[NAME_LENGTH] = "";
  2704.         int mob_id = 0;
  2705.         int number = 0;
  2706.         int x = 0;
  2707.         int y = 0;
  2708.         int count;
  2709.         int i;
  2710.  
  2711.         nullpo_retr(-1, sd);
  2712.  
  2713.         if (!message || !*message) {
  2714.                 clif_displaymessage(fd, "Give a monster name/id please.");
  2715.                 return -1;
  2716.         }
  2717.  
  2718.         if (sscanf(message, "\"%23[^\"]\" %23s %d %d %d", name, monster, &number, &x, &y) < 2 &&
  2719.             sscanf(message, "%23s \"%23[^\"]\" %d %d %d", monster, name, &number, &x, &y) < 2 &&
  2720.             sscanf(message, "%23s %d %23s %d %d", monster, &number, name, &x, &y) < 1) {
  2721.                 clif_displaymessage(fd, "Give a monster name/id please.");
  2722.                 return -1;
  2723.         }
  2724.  
  2725.         // If monster identifier/name argument is a name
  2726.         if ((mob_id = mobdb_searchname(monster)) == 0) // check name first (to avoid possible name begining by a number)
  2727.                 mob_id = atoi(monster);
  2728.  
  2729.         if (mob_id == 0) {
  2730.                 clif_displaymessage(fd, msg_txt(40));
  2731.                 return -1;
  2732.         }
  2733.  
  2734.         if (mob_id == MOBID_EMPERIUM) {
  2735.                 clif_displaymessage(fd, msg_txt(83));   // Cannot spawn emperium
  2736.                 return -1;
  2737.         }
  2738.  
  2739.         if (mobdb_checkid(mob_id) == 0) {
  2740.                 clif_displaymessage(fd, "Invalid monster ID"); // Invalid Monster ID.
  2741.                 return -1;
  2742.         }
  2743.  
  2744.         if (number <= 0)
  2745.                 number = 1;
  2746.  
  2747.         if( !name[0] )
  2748.                 strcpy(name, "--ja--");
  2749.  
  2750.         // If value of atcommand_spawn_quantity_limit directive is greater than or equal to 1 and quantity of monsters is greater than value of the directive
  2751.         if (battle_config.atc_spawn_quantity_limit >= 1 && number > battle_config.atc_spawn_quantity_limit)
  2752.                 number = battle_config.atc_spawn_quantity_limit;
  2753.  
  2754.         count = 0;
  2755.         for (i = 0; i < number; i++) {
  2756.                 int mx, my;
  2757.                 if (x <= 0)
  2758.                         mx = sd->bl.x + (rand() % 11 - 5);
  2759.                 else
  2760.                         mx = x;
  2761.                 if (y <= 0)
  2762.                         my = sd->bl.y + (rand() % 11 - 5);
  2763.                 else
  2764.                         my = y;
  2765.                 count += (mob_once_spawn(sd, sd->bl.m, mx, my, name, mob_id, 1, "4") != 0) ? 1 : 0;
  2766.         }
  2767.  
  2768.         if (count != 0)
  2769.                 clif_displaymessage(fd, msg_txt(39)); // Monster Summoned!!
  2770.         else
  2771.                 clif_displaymessage(fd, msg_txt(40)); // Invalid Monster ID.
  2772.  
  2773.         return 0;
  2774. }
  2775.  
  2776. /*==========================================
  2777.  *
  2778.  *------------------------------------------*/
  2779. static int atkillmonster_sub(struct block_list *bl, va_list ap)
  2780. {
  2781.         struct mob_data *md;
  2782.         int flag;
  2783.        
  2784.         nullpo_ret(md=(struct mob_data *)bl);
  2785.         flag = va_arg(ap, int);
  2786.  
  2787.         if (md->guardian_data)
  2788.                 return 0; //Do not touch WoE mobs!
  2789.        
  2790.         if (flag)
  2791.                 status_zap(bl,md->status.hp, 0);
  2792.         else
  2793.                 status_kill(bl);
  2794.         return 1;
  2795. }
  2796.  
  2797. void atcommand_killmonster_sub(const int fd, struct map_session_data* sd, const char* message, const int drop)
  2798. {
  2799.         int map_id;
  2800.         char map_name[MAP_NAME_LENGTH_EXT];
  2801.  
  2802.         if (!sd) return;
  2803.  
  2804.         memset(map_name, '\0', sizeof(map_name));
  2805.  
  2806.         if (!message || !*message || sscanf(message, "%15s", map_name) < 1)
  2807.                 map_id = sd->bl.m;
  2808.         else {
  2809.                 if ((map_id = map_mapname2mapid(map_name)) < 0)
  2810.                         map_id = sd->bl.m;
  2811.         }
  2812.  
  2813.         map_foreachinmap(atkillmonster_sub, map_id, BL_MOB, drop);
  2814.  
  2815.         clif_displaymessage(fd, msg_txt(165)); // All monsters killed!
  2816.  
  2817.         return;
  2818. }
  2819.  
  2820. ACMD_FUNC(killmonster)
  2821. {
  2822.         atcommand_killmonster_sub(fd, sd, message, 1);
  2823.         return 0;
  2824. }
  2825.  
  2826. /*==========================================
  2827.  *
  2828.  *------------------------------------------*/
  2829. ACMD_FUNC(killmonster2)
  2830. {
  2831.         atcommand_killmonster_sub(fd, sd, message, 0);
  2832.         return 0;
  2833. }
  2834.  
  2835. /*==========================================
  2836.  *
  2837.  *------------------------------------------*/
  2838. ACMD_FUNC(refine)
  2839. {
  2840.         int i,j, position = 0, refine = 0, current_position, final_refine;
  2841.         int count;
  2842.         nullpo_retr(-1, sd);
  2843.  
  2844.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2845.  
  2846.         if (!message || !*message || sscanf(message, "%d %d", &position, &refine) < 2) {
  2847.                 clif_displaymessage(fd, "Please, enter a position and an amount (usage: @refine <equip position> <+/- amount>).");
  2848.                 sprintf(atcmd_output, "%d: Lower Headgear", EQP_HEAD_LOW);
  2849.                 clif_displaymessage(fd, atcmd_output);
  2850.                 sprintf(atcmd_output, "%d: Right Hand", EQP_HAND_R);
  2851.                 clif_displaymessage(fd, atcmd_output);
  2852.                 sprintf(atcmd_output, "%d: Garment", EQP_GARMENT);
  2853.                 clif_displaymessage(fd, atcmd_output);
  2854.                 sprintf(atcmd_output, "%d: Left Accessory", EQP_ACC_L);
  2855.                 clif_displaymessage(fd, atcmd_output);
  2856.                 sprintf(atcmd_output, "%d: Body Armor", EQP_ARMOR);
  2857.                 clif_displaymessage(fd, atcmd_output);
  2858.                 sprintf(atcmd_output, "%d: Left Hand", EQP_HAND_L);
  2859.                 clif_displaymessage(fd, atcmd_output);
  2860.                 sprintf(atcmd_output, "%d: Shoes", EQP_SHOES);
  2861.                 clif_displaymessage(fd, atcmd_output);
  2862.                 sprintf(atcmd_output, "%d: Right Accessory", EQP_ACC_R);
  2863.                 clif_displaymessage(fd, atcmd_output);
  2864.                 sprintf(atcmd_output, "%d: Top Headgear", EQP_HEAD_TOP);
  2865.                 clif_displaymessage(fd, atcmd_output);
  2866.                 sprintf(atcmd_output, "%d: Mid Headgear", EQP_HEAD_MID);
  2867.                 clif_displaymessage(fd, atcmd_output);
  2868.                 return -1;
  2869.         }
  2870.  
  2871.         refine = cap_value(refine, -MAX_REFINE, MAX_REFINE);
  2872.  
  2873.         count = 0;
  2874.         for (j = 0; j < EQI_MAX_BONUS; j++) {
  2875.                 if ((i = sd->equip_index[j]) < 0)
  2876.                         continue;
  2877.                 if(j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == i)
  2878.                         continue;
  2879.                 if(j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == i)
  2880.                         continue;
  2881.                 if(j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == i || sd->equip_index[EQI_HEAD_LOW] == i))
  2882.                         continue;
  2883.  
  2884.                 if(position && !(sd->status.inventory[i].equip & position))
  2885.                         continue;
  2886.  
  2887.                 final_refine = cap_value(sd->status.inventory[i].refine + refine, 0, MAX_REFINE);
  2888.                 if (sd->status.inventory[i].refine != final_refine) {
  2889.                         sd->status.inventory[i].refine = final_refine;
  2890.                         current_position = sd->status.inventory[i].equip;
  2891.                         pc_unequipitem(sd, i, 3);
  2892.                         clif_refine(fd, 0, i, sd->status.inventory[i].refine);
  2893.                         clif_delitem(sd, i, 1, 3);
  2894.                         clif_additem(sd, i, 1, 0);
  2895.                         pc_equipitem(sd, i, current_position);
  2896.                         clif_misceffect(&sd->bl, 3);
  2897.                         count++;
  2898.                 }
  2899.         }
  2900.  
  2901.         if (count == 0)
  2902.                 clif_displaymessage(fd, msg_txt(166)); // No item has been refined.
  2903.         else if (count == 1)
  2904.                 clif_displaymessage(fd, msg_txt(167)); // 1 item has been refined.
  2905.         else {
  2906.                 sprintf(atcmd_output, msg_txt(168), count); // %d items have been refined.
  2907.                 clif_displaymessage(fd, atcmd_output);
  2908.         }
  2909.  
  2910.         return 0;
  2911. }
  2912.  
  2913. /*==========================================
  2914.  *
  2915.  *------------------------------------------*/
  2916. ACMD_FUNC(produce)
  2917. {
  2918.         char item_name[100];
  2919.         int item_id, attribute = 0, star = 0;
  2920.         int flag = 0;
  2921.         struct item_data *item_data;
  2922.         struct item tmp_item;
  2923.         nullpo_retr(-1, sd);
  2924.  
  2925.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2926.         memset(item_name, '\0', sizeof(item_name));
  2927.  
  2928.         if (!message || !*message || (
  2929.                 sscanf(message, "\"%99[^\"]\" %d %d", item_name, &attribute, &star) < 1 &&
  2930.                 sscanf(message, "%99s %d %d", item_name, &attribute, &star) < 1
  2931.         )) {
  2932.                 clif_displaymessage(fd, "Please, enter at least an item name/id (usage: @produce <equip name or equip ID> <element> <# of very's>).");
  2933.                 return -1;
  2934.         }
  2935.  
  2936.         item_id = 0;
  2937.         if ((item_data = itemdb_searchname(item_name)) == NULL &&
  2938.             (item_data = itemdb_exists(atoi(item_name))) == NULL)
  2939.         {
  2940.                 clif_displaymessage(fd, msg_txt(170)); //This item is not an equipment.
  2941.                 return -1;
  2942.         }
  2943.         item_id = item_data->nameid;
  2944.         if (itemdb_isequip2(item_data)) {
  2945.                 if (attribute < MIN_ATTRIBUTE || attribute > MAX_ATTRIBUTE)
  2946.                         attribute = ATTRIBUTE_NORMAL;
  2947.                 if (star < MIN_STAR || star > MAX_STAR)
  2948.                         star = 0;
  2949.                 memset(&tmp_item, 0, sizeof tmp_item);
  2950.                 tmp_item.nameid = item_id;
  2951.                 tmp_item.amount = 1;
  2952.                 tmp_item.identify = 1;
  2953.                 tmp_item.card[0] = CARD0_FORGE;
  2954.                 tmp_item.card[1] = item_data->type==IT_WEAPON?
  2955.                         ((star*5) << 8) + attribute:0;
  2956.                 tmp_item.card[2] = GetWord(sd->status.char_id, 0);
  2957.                 tmp_item.card[3] = GetWord(sd->status.char_id, 1);
  2958.                 clif_produceeffect(sd, 0, item_id);
  2959.                 clif_misceffect(&sd->bl, 3);
  2960.                 if ((flag = pc_additem(sd, &tmp_item, 1)))
  2961.                         clif_additem(sd, 0, 0, flag);
  2962.  
  2963.                 //Logs (A)dmins items [Lupus]
  2964.                 log_pick_pc(sd, LOG_TYPE_COMMAND, tmp_item.nameid, 1, &tmp_item, tmp_item.serial);
  2965.         } else {
  2966.                 sprintf(atcmd_output, msg_txt(169), item_id, item_data->name); // The item (%d: '%s') is not equipable.
  2967.                 clif_displaymessage(fd, atcmd_output);
  2968.                 return -1;
  2969.         }
  2970.  
  2971.         return 0;
  2972. }
  2973.  
  2974. /*==========================================
  2975.  *
  2976.  *------------------------------------------*/
  2977. ACMD_FUNC(memo)
  2978. {
  2979.         int position = 0;
  2980.         nullpo_retr(-1, sd);
  2981.  
  2982.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2983.  
  2984.         if( !message || !*message || sscanf(message, "%d", &position) < 1 )
  2985.         {
  2986.                 int i;
  2987.                 clif_displaymessage(sd->fd,  "Your actual memo positions are:");
  2988.                 for( i = 0; i < MAX_MEMOPOINTS; i++ )
  2989.                 {
  2990.                         if( sd->status.memo_point[i].map )
  2991.                                 sprintf(atcmd_output, "%d - %s (%d,%d)", i, mapindex_id2name(sd->status.memo_point[i].map), sd->status.memo_point[i].x, sd->status.memo_point[i].y);
  2992.                         else
  2993.                                 sprintf(atcmd_output, msg_txt(171), i); // %d - void
  2994.                         clif_displaymessage(sd->fd, atcmd_output);
  2995.                 }
  2996.                 return 0;
  2997.         }
  2998.  
  2999.         if( position < 0 || position >= MAX_MEMOPOINTS )
  3000.         {
  3001.                 sprintf(atcmd_output, "Please, enter a valid position (usage: @memo <memo_position:%d-%d>).", 0, MAX_MEMOPOINTS-1);
  3002.                 clif_displaymessage(fd, atcmd_output);
  3003.                 return -1;
  3004.         }
  3005.  
  3006.         pc_memo(sd, position);
  3007.         return 0;
  3008. }
  3009.  
  3010. /*==========================================
  3011.  *
  3012.  *------------------------------------------*/
  3013. ACMD_FUNC(gat)
  3014. {
  3015.         int y;
  3016.         nullpo_retr(-1, sd);
  3017.  
  3018.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  3019.  
  3020.         for (y = 2; y >= -2; y--) {
  3021.                 sprintf(atcmd_output, "%s (x= %d, y= %d) %02X %02X %02X %02X %02X",
  3022.                         map[sd->bl.m].name,   sd->bl.x - 2, sd->bl.y + y,
  3023.                         map_getcell(sd->bl.m, sd->bl.x - 2, sd->bl.y + y, CELL_GETTYPE),
  3024.                         map_getcell(sd->bl.m, sd->bl.x - 1, sd->bl.y + y, CELL_GETTYPE),
  3025.                         map_getcell(sd->bl.m, sd->bl.x,     sd->bl.y + y, CELL_GETTYPE),
  3026.                         map_getcell(sd->bl.m, sd->bl.x + 1, sd->bl.y + y, CELL_GETTYPE),
  3027.                         map_getcell(sd->bl.m, sd->bl.x + 2, sd->bl.y + y, CELL_GETTYPE));
  3028.  
  3029.                 clif_displaymessage(fd, atcmd_output);
  3030.         }
  3031.  
  3032.         return 0;
  3033. }
  3034.  
  3035. /*==========================================
  3036.  *
  3037.  *------------------------------------------*/
  3038. ACMD_FUNC(displaystatus)
  3039. {
  3040.         int i, type, flag, tick, val1, val2, val3;
  3041.         nullpo_retr(-1, sd);
  3042.        
  3043.         if (!message || !*message || (i = sscanf(message, "%d %d %d %d %d %d", &type, &flag, &tick, &val1, &val2, &val3)) < 1) {
  3044.                 clif_displaymessage(fd, "Please, enter a status type/flag (usage: @displaystatus <status type> <flag> <tick> <val1> <val2> <val3>).");
  3045.                 return -1;
  3046.         }
  3047.         if (i < 2) flag = 1;
  3048.         if (i < 3) tick = 0;
  3049.  
  3050.         clif_status_change(&sd->bl, type, flag, tick, val1, val2, val3);
  3051.  
  3052.         return 0;
  3053. }
  3054.  
  3055. /*==========================================
  3056.  * @stpoint (Rewritten by [Yor])
  3057.  *------------------------------------------*/
  3058. ACMD_FUNC(statuspoint)
  3059. {
  3060.         int point;
  3061.         unsigned int new_status_point;
  3062.  
  3063.         if (!message || !*message || (point = atoi(message)) == 0) {
  3064.                 clif_displaymessage(fd, "Please, enter a number (usage: @stpoint <number of points>).");
  3065.                 return -1;
  3066.         }
  3067.  
  3068.         if(point < 0)
  3069.         {
  3070.                 if(sd->status.status_point < (unsigned int)(-point))
  3071.                 {
  3072.                         new_status_point = 0;
  3073.                 }
  3074.                 else
  3075.                 {
  3076.                         new_status_point = sd->status.status_point + point;
  3077.                 }
  3078.         }
  3079.         else if(UINT_MAX - sd->status.status_point < (unsigned int)point)
  3080.         {
  3081.                 new_status_point = UINT_MAX;
  3082.         }
  3083.         else
  3084.         {
  3085.                 new_status_point = sd->status.status_point + point;
  3086.         }
  3087.  
  3088.         if (new_status_point != sd->status.status_point) {
  3089.                 sd->status.status_point = new_status_point;
  3090.                 clif_updatestatus(sd, SP_STATUSPOINT);
  3091.                 clif_displaymessage(fd, msg_txt(174)); // Number of status points changed.
  3092.         } else {
  3093.                 if (point < 0)
  3094.                         clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
  3095.                 else
  3096.                         clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
  3097.                 return -1;
  3098.         }
  3099.  
  3100.         return 0;
  3101. }
  3102.  
  3103. /*==========================================
  3104.  * @skpoint (Rewritten by [Yor])
  3105.  *------------------------------------------*/
  3106. ACMD_FUNC(skillpoint)
  3107. {
  3108.         int point;
  3109.         unsigned int new_skill_point;
  3110.         nullpo_retr(-1, sd);
  3111.  
  3112.         if (!message || !*message || (point = atoi(message)) == 0) {
  3113.                 clif_displaymessage(fd, "Please, enter a number (usage: @skpoint <number of points>).");
  3114.                 return -1;
  3115.         }
  3116.  
  3117.         if(point < 0)
  3118.         {
  3119.                 if(sd->status.skill_point < (unsigned int)(-point))
  3120.                 {
  3121.                         new_skill_point = 0;
  3122.                 }
  3123.                 else
  3124.                 {
  3125.                         new_skill_point = sd->status.skill_point + point;
  3126.                 }
  3127.         }
  3128.         else if(UINT_MAX - sd->status.skill_point < (unsigned int)point)
  3129.         {
  3130.                 new_skill_point = UINT_MAX;
  3131.         }
  3132.         else
  3133.         {
  3134.                 new_skill_point = sd->status.skill_point + point;
  3135.         }
  3136.  
  3137.         if (new_skill_point != sd->status.skill_point) {
  3138.                 sd->status.skill_point = new_skill_point;
  3139.                 clif_updatestatus(sd, SP_SKILLPOINT);
  3140.                 clif_displaymessage(fd, msg_txt(175)); // Number of skill points changed.
  3141.         } else {
  3142.                 if (point < 0)
  3143.                         clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
  3144.                 else
  3145.                         clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
  3146.                 return -1;
  3147.         }
  3148.  
  3149.         return 0;
  3150. }
  3151.  
  3152. /*==========================================
  3153.  * @zeny (Rewritten by [Yor])
  3154.  *------------------------------------------*/
  3155. ACMD_FUNC(zeny)
  3156. {
  3157.         int zeny, new_zeny;
  3158.         nullpo_retr(-1, sd);
  3159.  
  3160.         if (!message || !*message || (zeny = atoi(message)) == 0) {
  3161.                 clif_displaymessage(fd, "Please, enter an amount (usage: @zeny <amount>).");
  3162.                 return -1;
  3163.         }
  3164.  
  3165.         new_zeny = sd->status.zeny + zeny;
  3166.         if (zeny > 0 && (zeny > MAX_ZENY || new_zeny > MAX_ZENY)) // fix positiv overflow
  3167.                 new_zeny = MAX_ZENY;
  3168.         else if (zeny < 0 && (zeny < -MAX_ZENY || new_zeny < 0)) // fix negativ overflow
  3169.                 new_zeny = 0;
  3170.  
  3171.         if (new_zeny != sd->status.zeny) {
  3172.                 sd->status.zeny = new_zeny;
  3173.                 clif_updatestatus(sd, SP_ZENY);
  3174.                 clif_displaymessage(fd, msg_txt(176)); // Current amount of zeny changed.
  3175.         } else {
  3176.                 if (zeny < 0)
  3177.                         clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
  3178.                 else
  3179.                         clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
  3180.                 return -1;
  3181.         }
  3182.  
  3183.         return 0;
  3184. }
  3185.  
  3186. /*==========================================
  3187.  *
  3188.  *------------------------------------------*/
  3189. ACMD_FUNC(param)
  3190. {
  3191.         int i, value = 0, new_value;
  3192.         const char* param[] = { "str", "agi", "vit", "int", "dex", "luk" };
  3193.         short* status[6];
  3194.         //we don't use direct initialization because it isn't part of the c standard.
  3195.         nullpo_retr(-1, sd);
  3196.        
  3197.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  3198.  
  3199.         if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0) {
  3200.                 sprintf(atcmd_output, "Please, enter a valid value (usage: @str,@agi,@vit,@int,@dex,@luk <+/-adjustment>).");
  3201.                 clif_displaymessage(fd, atcmd_output);
  3202.                 return -1;
  3203.         }
  3204.  
  3205.         ARR_FIND( 0, ARRAYLENGTH(param), i, strcmpi(command+1, param[i]) == 0 );
  3206.  
  3207.         if( i == ARRAYLENGTH(param) || i > MAX_STATUS_TYPE) { // normally impossible...
  3208.                 sprintf(atcmd_output, "Please, enter a valid value (usage: @str,@agi,@vit,@int,@dex,@luk <+/-adjustment>).");
  3209.                 clif_displaymessage(fd, atcmd_output);
  3210.                 return -1;
  3211.         }
  3212.  
  3213.         status[0] = &sd->status.str;
  3214.         status[1] = &sd->status.agi;
  3215.         status[2] = &sd->status.vit;
  3216.         status[3] = &sd->status.int_;
  3217.         status[4] = &sd->status.dex;
  3218.         status[5] = &sd->status.luk;
  3219.  
  3220.         if(value < 0 && *status[i] <= -value)
  3221.         {
  3222.                 new_value = 1;
  3223.         }
  3224.         else if(SHRT_MAX - *status[i] < value)
  3225.         {
  3226.                 new_value = SHRT_MAX;
  3227.         }
  3228.         else
  3229.         {
  3230.                 new_value = *status[i] + value;
  3231.         }
  3232.  
  3233.         if (new_value != *status[i]) {
  3234.                 *status[i] = new_value;
  3235.                 clif_updatestatus(sd, SP_STR + i);
  3236.                 clif_updatestatus(sd, SP_USTR + i);
  3237.                 status_calc_pc(sd, 0);
  3238.                 clif_displaymessage(fd, msg_txt(42)); // Stat changed.
  3239.         } else {
  3240.                 if (value < 0)
  3241.                         clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value.
  3242.                 else
  3243.                         clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value.
  3244.                 return -1;
  3245.         }
  3246.  
  3247.         return 0;
  3248. }
  3249.  
  3250. /*==========================================
  3251.  * Stat all by fritz (rewritten by [Yor])
  3252.  *------------------------------------------*/
  3253. ACMD_FUNC(stat_all)
  3254. {
  3255.         int index, count, value, max, new_value;
  3256.         short* status[6];
  3257.         //we don't use direct initialization because it isn't part of the c standard.
  3258.         nullpo_retr(-1, sd);
  3259.        
  3260.         status[0] = &sd->status.str;
  3261.         status[1] = &sd->status.agi;
  3262.         status[2] = &sd->status.vit;
  3263.         status[3] = &sd->status.int_;
  3264.         status[4] = &sd->status.dex;
  3265.         status[5] = &sd->status.luk;
  3266.  
  3267.         if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0) {
  3268.                 value = pc_maxparameter(sd);
  3269.                 max = pc_maxparameter(sd);
  3270.         } else {
  3271.                 max = SHRT_MAX;
  3272.         }
  3273.  
  3274.         count = 0;
  3275.         for (index = 0; index < ARRAYLENGTH(status); index++) {
  3276.  
  3277.                 if (value > 0 && *status[index] > max - value)
  3278.                         new_value = max;
  3279.                 else if (value < 0 && *status[index] <= -value)
  3280.                         new_value = 1;
  3281.                 else
  3282.                         new_value = *status[index] +value;
  3283.                
  3284.                 if (new_value != (int)*status[index]) {
  3285.                         *status[index] = new_value;
  3286.                         clif_updatestatus(sd, SP_STR + index);
  3287.                         clif_updatestatus(sd, SP_USTR + index);
  3288.                         count++;
  3289.                 }
  3290.         }
  3291.  
  3292.         if (count > 0) { // if at least 1 stat modified
  3293.                 status_calc_pc(sd, 0);
  3294.                 clif_displaymessage(fd, msg_txt(84)); // All stats changed!
  3295.         } else {
  3296.                 if (value < 0)
  3297.                         clif_displaymessage(fd, msg_txt(177)); // You cannot decrease that stat anymore.
  3298.                 else
  3299.                         clif_displaymessage(fd, msg_txt(178)); // You cannot increase that stat anymore.
  3300.                 return -1;
  3301.         }
  3302.  
  3303.         return 0;
  3304. }
  3305.  
  3306. /*==========================================
  3307.  *
  3308.  *------------------------------------------*/
  3309. ACMD_FUNC(guildlevelup)
  3310. {
  3311.         int level = 0;
  3312.         short added_level;
  3313.         struct guild *guild_info;
  3314.         nullpo_retr(-1, sd);
  3315.  
  3316.         if (!message || !*message || sscanf(message, "%d", &level) < 1 || level == 0) {
  3317.                 clif_displaymessage(fd, "Please, enter a valid level (usage: @guildlvup/@guildlvlup <# of levels>).");
  3318.                 return -1;
  3319.         }
  3320.  
  3321.         if (sd->status.guild_id <= 0 || (guild_info = guild_search(sd->status.guild_id)) == NULL) {
  3322.                 clif_displaymessage(fd, msg_txt(43)); // You're not in a guild.
  3323.                 return -1;
  3324.         }
  3325.         //if (strcmp(sd->status.name, guild_info->master) != 0) {
  3326.         //      clif_displaymessage(fd, msg_txt(44)); // You're not the master of your guild.
  3327.         //      return -1;
  3328.         //}
  3329.  
  3330.         added_level = (short)level;
  3331.         if (level > 0 && (level > MAX_GUILDLEVEL || added_level > ((short)MAX_GUILDLEVEL - guild_info->guild_lv))) // fix positiv overflow
  3332.                 added_level = (short)MAX_GUILDLEVEL - guild_info->guild_lv;
  3333.         else if (level < 0 && (level < -MAX_GUILDLEVEL || added_level < (1 - guild_info->guild_lv))) // fix negativ overflow
  3334.                 added_level = 1 - guild_info->guild_lv;
  3335.  
  3336.         if (added_level != 0) {
  3337.                 intif_guild_change_basicinfo(guild_info->guild_id, GBI_GUILDLV, &added_level, sizeof(added_level));
  3338.                 clif_displaymessage(fd, msg_txt(179)); // Guild level changed.
  3339.         } else {
  3340.                 clif_displaymessage(fd, msg_txt(45)); // Guild level change failed.
  3341.                 return -1;
  3342.         }
  3343.  
  3344.         return 0;
  3345. }
  3346.  
  3347. /*==========================================
  3348.  *
  3349.  *------------------------------------------*/
  3350. ACMD_FUNC(makeegg)
  3351. {
  3352.         struct item_data *item_data;
  3353.         int id, pet_id;
  3354.         nullpo_retr(-1, sd);
  3355.  
  3356.         if (!message || !*message) {
  3357.                 clif_displaymessage(fd, "Please, enter a monster/egg name/id (usage: @makeegg <pet>).");
  3358.                 return -1;
  3359.         }
  3360.  
  3361.         if ((item_data = itemdb_searchname(message)) != NULL) // for egg name
  3362.                 id = item_data->nameid;
  3363.         else
  3364.         if ((id = mobdb_searchname(message)) != 0) // for monster name
  3365.                 ;
  3366.         else
  3367.                 id = atoi(message);
  3368.  
  3369.         pet_id = search_petDB_index(id, PET_CLASS);
  3370.         if (pet_id < 0)
  3371.                 pet_id = search_petDB_index(id, PET_EGG);
  3372.         if (pet_id >= 0) {
  3373.                 sd->catch_target_class = pet_db[pet_id].class_;
  3374.                 intif_create_pet(
  3375.                         sd->status.account_id, sd->status.char_id,
  3376.                         (short)pet_db[pet_id].class_, (short)mob_db(pet_db[pet_id].class_)->lv,
  3377.                         (short)pet_db[pet_id].EggID, 0, (short)pet_db[pet_id].intimate,
  3378.                         100, 0, 1, pet_db[pet_id].jname);
  3379.         } else {
  3380.                 clif_displaymessage(fd, msg_txt(180)); // The monster/egg name/id doesn't exist.
  3381.                 return -1;
  3382.         }
  3383.  
  3384.         return 0;
  3385. }
  3386.  
  3387. /*==========================================
  3388.  *
  3389.  *------------------------------------------*/
  3390. ACMD_FUNC(hatch)
  3391. {
  3392.         nullpo_retr(-1, sd);
  3393.         if (sd->status.pet_id <= 0)
  3394.                 clif_sendegg(sd);
  3395.         else {
  3396.                 clif_displaymessage(fd, msg_txt(181)); // You already have a pet.
  3397.                 return -1;
  3398.         }
  3399.  
  3400.         return 0;
  3401. }
  3402.  
  3403. /*==========================================
  3404.  *
  3405.  *------------------------------------------*/
  3406. ACMD_FUNC(petfriendly)
  3407. {
  3408.         int friendly;
  3409.         struct pet_data *pd;
  3410.         nullpo_retr(-1, sd);
  3411.  
  3412.         if (!message || !*message || (friendly = atoi(message)) < 0) {
  3413.                 clif_displaymessage(fd, "Please, enter a valid value (usage: @petfriendly <0-1000>).");
  3414.                 return -1;
  3415.         }
  3416.  
  3417.         pd = sd->pd;
  3418.         if (!pd) {
  3419.                 clif_displaymessage(fd, msg_txt(184)); // Sorry, but you have no pet.
  3420.                 return -1;
  3421.         }
  3422.        
  3423.         if (friendly < 0 || friendly > 1000)
  3424.         {
  3425.                 clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
  3426.                 return -1;
  3427.         }
  3428.        
  3429.         if (friendly == pd->pet.intimate) {
  3430.                 clif_displaymessage(fd, msg_txt(183)); // Pet intimacy is already at maximum.
  3431.                 return -1;
  3432.         }
  3433.  
  3434.         pet_set_intimate(pd, friendly);
  3435.         clif_send_petstatus(sd);
  3436.         clif_displaymessage(fd, msg_txt(182)); // Pet intimacy changed.
  3437.         return 0;
  3438. }
  3439.  
  3440. /*==========================================
  3441.  *
  3442.  *------------------------------------------*/
  3443. ACMD_FUNC(pethungry)
  3444. {
  3445.         int hungry;
  3446.         struct pet_data *pd;
  3447.         nullpo_retr(-1, sd);
  3448.  
  3449.         if (!message || !*message || (hungry = atoi(message)) < 0) {
  3450.                 clif_displaymessage(fd, "Please, enter a valid number (usage: @pethungry <0-100>).");
  3451.                 return -1;
  3452.         }
  3453.  
  3454.         pd = sd->pd;
  3455.         if (!sd->status.pet_id || !pd) {
  3456.                 clif_displaymessage(fd, msg_txt(184)); // Sorry, but you have no pet.
  3457.                 return -1;
  3458.         }
  3459.         if (hungry < 0 || hungry > 100) {
  3460.                 clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
  3461.                 return -1;
  3462.         }
  3463.         if (hungry == pd->pet.hungry) {
  3464.                 clif_displaymessage(fd, msg_txt(186)); // Pet hunger is already at maximum.
  3465.                 return -1;
  3466.         }
  3467.  
  3468.         pd->pet.hungry = hungry;
  3469.         clif_send_petstatus(sd);
  3470.         clif_displaymessage(fd, msg_txt(185)); // Pet hunger changed.
  3471.  
  3472.         return 0;
  3473. }
  3474.  
  3475. /*==========================================
  3476.  *
  3477.  *------------------------------------------*/
  3478. ACMD_FUNC(petrename)
  3479. {
  3480.         struct pet_data *pd;
  3481.         nullpo_retr(-1, sd);
  3482.         if (!sd->status.pet_id || !sd->pd) {
  3483.                 clif_displaymessage(fd, msg_txt(184)); // Sorry, but you have no pet.
  3484.                 return -1;
  3485.         }
  3486.         pd = sd->pd;
  3487.         if (!pd->pet.rename_flag) {
  3488.                 clif_displaymessage(fd, msg_txt(188)); // You can already rename your pet.
  3489.                 return -1;
  3490.         }
  3491.  
  3492.         pd->pet.rename_flag = 0;
  3493.         intif_save_petdata(sd->status.account_id, &pd->pet);
  3494.         clif_send_petstatus(sd);
  3495.         clif_displaymessage(fd, msg_txt(187)); // You can now rename your pet.
  3496.  
  3497.         return 0;
  3498. }
  3499.  
  3500. /*==========================================
  3501.  *
  3502.  *------------------------------------------*/
  3503. ACMD_FUNC(recall)
  3504. {
  3505.         struct map_session_data *pl_sd = NULL;
  3506.  
  3507.         nullpo_retr(-1, sd);
  3508.  
  3509.         if (!message || !*message) {
  3510.                 clif_displaymessage(fd, "Please, enter a player name (usage: @recall <player name/id>).");
  3511.                 return -1;
  3512.         }
  3513.  
  3514.         if((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL)
  3515.         {
  3516.                 clif_displaymessage(fd, msg_txt(3)); // Character not found.
  3517.                 return -1;
  3518.         }
  3519.                
  3520.         if (pl_sd == sd)
  3521.         {
  3522.                 clif_displaymessage(fd, "You are already where you are...");
  3523.                 return -1;
  3524.         }
  3525.  
  3526.         if ( pc_isGM(sd) < pc_isGM(pl_sd) )
  3527.         {
  3528.                 clif_displaymessage(fd, msg_txt(81)); // Your GM level doesn't authorize you to preform this action on the specified player.
  3529.                 return -1;
  3530.         }
  3531.        
  3532.         if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
  3533.                 clif_displaymessage(fd, "You are not authorised to warp somenone to your actual map.");
  3534.                 return -1;
  3535.         }
  3536.         if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
  3537.                 clif_displaymessage(fd, "You are not authorized to warp this player from its actual map.");
  3538.                 return -1;
  3539.         }
  3540.         pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
  3541.         sprintf(atcmd_output, msg_txt(46), pl_sd->status.name); // %s recalled!
  3542.         clif_displaymessage(fd, atcmd_output);
  3543.  
  3544.         return 0;
  3545. }
  3546.  
  3547. /*==========================================
  3548.  * charblock command (usage: charblock <player_name>)
  3549.  * This command do a definitiv ban on a player
  3550.  *------------------------------------------*/
  3551. ACMD_FUNC(char_block)
  3552. {
  3553.         nullpo_retr(-1, sd);
  3554.  
  3555.         memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
  3556.  
  3557.         if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
  3558.                 clif_displaymessage(fd, "Please, enter a player name (usage: @charblock/@block <name>).");
  3559.                 return -1;
  3560.         }
  3561.  
  3562.         chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block
  3563.         clif_displaymessage(fd, msg_txt(88)); // Character name sent to char-server to ask it.
  3564.  
  3565.         return 0;
  3566. }
  3567.  
  3568. /*==========================================
  3569.  * charban command (usage: charban <time> <player_name>)
  3570.  * This command do a limited ban on a player
  3571.  * Time is done as follows:
  3572.  *   Adjustment value (-1, 1, +1, etc...)
  3573.  *   Modified element:
  3574.  *     a or y: year
  3575.  *     m:  month
  3576.  *     j or d: day
  3577.  *     h:  hour
  3578.  *     mn: minute
  3579.  *     s:  second
  3580.  * <example> @ban +1m-2mn1s-6y test_player
  3581.  *           this example adds 1 month and 1 second, and substracts 2 minutes and 6 years at the same time.
  3582.  *------------------------------------------*/
  3583. ACMD_FUNC(char_ban)
  3584. {
  3585.         char * modif_p;
  3586.         int year, month, day, hour, minute, second, value;
  3587.         nullpo_retr(-1, sd);
  3588.  
  3589.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  3590.         memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
  3591.  
  3592.         if (!message || !*message || sscanf(message, "%s %23[^\n]", atcmd_output, atcmd_player_name) < 2) {
  3593.                 clif_displaymessage(fd, "Please, enter ban time and a player name (usage: @charban/@ban/@banish/@charbanish <time> <name>).");
  3594.                 return -1;
  3595.         }
  3596.  
  3597.         atcmd_output[sizeof(atcmd_output)-1] = '\0';
  3598.  
  3599.         modif_p = atcmd_output;
  3600.         year = month = day = hour = minute = second = 0;
  3601.         while (modif_p[0] != '\0') {
  3602.                 value = atoi(modif_p);
  3603.                 if (value == 0)
  3604.                         modif_p++;
  3605.                 else {
  3606.                         if (modif_p[0] == '-' || modif_p[0] == '+')
  3607.                                 modif_p++;
  3608.                         while (modif_p[0] >= '0' && modif_p[0] <= '9')
  3609.                                 modif_p++;
  3610.                         if (modif_p[0] == 's') {
  3611.                                 second = value;
  3612.                                 modif_p++;
  3613.                         } else if (modif_p[0] == 'n') {
  3614.                                 minute = value;
  3615.                                 modif_p++;
  3616.                         } else if (modif_p[0] == 'm' && modif_p[1] == 'n') {
  3617.                                 minute = value;
  3618.                                 modif_p = modif_p + 2;
  3619.                         } else if (modif_p[0] == 'h') {
  3620.                                 hour = value;
  3621.                                 modif_p++;
  3622.                         } else if (modif_p[0] == 'd' || modif_p[0] == 'j') {
  3623.                                 day = value;
  3624.                                 modif_p++;
  3625.                         } else if (modif_p[0] == 'm') {
  3626.                                 month = value;
  3627.                                 modif_p++;
  3628.                         } else if (modif_p[0] == 'y' || modif_p[0] == 'a') {
  3629.                                 year = value;
  3630.                                 modif_p++;
  3631.                         } else if (modif_p[0] != '\0') {
  3632.                                 modif_p++;
  3633.                         }
  3634.                 }
  3635.         }
  3636.         if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0) {
  3637.                 clif_displaymessage(fd, msg_txt(85)); // Invalid time for ban command.
  3638.                 return -1;
  3639.         }
  3640.  
  3641.         chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 2, year, month, day, hour, minute, second); // type: 2 - ban
  3642.         clif_displaymessage(fd, msg_txt(88)); // Character name sent to char-server to ask it.
  3643.  
  3644.         return 0;
  3645. }
  3646.  
  3647. /*==========================================
  3648.  * charunblock command (usage: charunblock <player_name>)
  3649.  *------------------------------------------*/
  3650. ACMD_FUNC(char_unblock)
  3651. {
  3652.         nullpo_retr(-1, sd);
  3653.  
  3654.         memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
  3655.  
  3656.         if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
  3657.                 clif_displaymessage(fd, "Please, enter a player name (usage: @charunblock <player_name>).");
  3658.                 return -1;
  3659.         }
  3660.  
  3661.         // send answer to login server via char-server
  3662.         chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 3, 0, 0, 0, 0, 0, 0); // type: 3 - unblock
  3663.         clif_displaymessage(fd, msg_txt(88)); // Character name sent to char-server to ask it.
  3664.  
  3665.         return 0;
  3666. }
  3667.  
  3668. /*==========================================
  3669.  * charunban command (usage: charunban <player_name>)
  3670.  *------------------------------------------*/
  3671. ACMD_FUNC(char_unban)
  3672. {
  3673.         nullpo_retr(-1, sd);
  3674.  
  3675.         memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
  3676.  
  3677.         if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
  3678.                 clif_displaymessage(fd, "Please, enter a player name (usage: @charunban <player_name>).");
  3679.                 return -1;
  3680.         }
  3681.  
  3682.         // send answer to login server via char-server
  3683.         chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban
  3684.         clif_displaymessage(fd, msg_txt(88)); // Character name sent to char-server to ask it.
  3685.  
  3686.         return 0;
  3687. }
  3688.  
  3689. /*==========================================
  3690.  *
  3691.  *------------------------------------------*/
  3692. ACMD_FUNC(night)
  3693. {
  3694.         nullpo_retr(-1, sd);
  3695.  
  3696.         if (night_flag != 1) {
  3697.                 map_night_timer(night_timer_tid, 0, 0, 1);
  3698.         } else {
  3699.                 clif_displaymessage(fd, msg_txt(89)); // Night mode is already enabled.
  3700.                 return -1;
  3701.         }
  3702.  
  3703.         return 0;
  3704. }
  3705.  
  3706. /*==========================================
  3707.  *
  3708.  *------------------------------------------*/
  3709. ACMD_FUNC(day)
  3710. {
  3711.         nullpo_retr(-1, sd);
  3712.  
  3713.         if (night_flag != 0) {
  3714.                 map_day_timer(day_timer_tid, 0, 0, 1);
  3715.         } else {
  3716.                 clif_displaymessage(fd, msg_txt(90)); // Day mode is already enabled.
  3717.                 return -1;
  3718.         }
  3719.  
  3720.         return 0;
  3721. }
  3722.  
  3723. /*==========================================
  3724.  *
  3725.  *------------------------------------------*/
  3726. ACMD_FUNC(doom)
  3727. {
  3728.         struct map_session_data* pl_sd;
  3729.         struct s_mapiterator* iter;
  3730.  
  3731.         nullpo_retr(-1, sd);
  3732.  
  3733.         iter = mapit_getallusers();
  3734.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  3735.         {
  3736.                 if (pl_sd->fd != fd && pc_isGM(sd) >= pc_isGM(pl_sd))
  3737.                 {
  3738.                         status_kill(&pl_sd->bl);
  3739.                         clif_specialeffect(&pl_sd->bl,450,AREA);
  3740.                         clif_displaymessage(pl_sd->fd, msg_txt(61)); // The holy messenger has given judgement.
  3741.                 }
  3742.         }
  3743.         mapit_free(iter);
  3744.  
  3745.         clif_displaymessage(fd, msg_txt(62)); // Judgement was made.
  3746.  
  3747.         return 0;
  3748. }
  3749.  
  3750. /*==========================================
  3751.  *
  3752.  *------------------------------------------*/
  3753. ACMD_FUNC(doommap)
  3754. {
  3755.         struct map_session_data* pl_sd;
  3756.         struct s_mapiterator* iter;
  3757.  
  3758.         nullpo_retr(-1, sd);
  3759.  
  3760.         iter = mapit_getallusers();
  3761.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  3762.         {
  3763.                 if (pl_sd->fd != fd && sd->bl.m == pl_sd->bl.m && pc_isGM(sd) >= pc_isGM(pl_sd))
  3764.                 {
  3765.                         status_kill(&pl_sd->bl);
  3766.                         clif_specialeffect(&pl_sd->bl,450,AREA);
  3767.                         clif_displaymessage(pl_sd->fd, msg_txt(61)); // The holy messenger has given judgement.
  3768.                 }
  3769.         }
  3770.         mapit_free(iter);
  3771.  
  3772.         clif_displaymessage(fd, msg_txt(62)); // Judgement was made.
  3773.  
  3774.         return 0;
  3775. }
  3776.  
  3777. /*==========================================
  3778.  *
  3779.  *------------------------------------------*/
  3780. static void atcommand_raise_sub(struct map_session_data* sd)
  3781. {
  3782.         if (!status_isdead(&sd->bl))
  3783.                 return;
  3784.  
  3785.         if(!status_revive(&sd->bl, 100, 100))
  3786.                 return;
  3787.         clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1);
  3788.         clif_displaymessage(sd->fd, msg_txt(63)); // Mercy has been shown.
  3789. }
  3790.  
  3791. /*==========================================
  3792.  *
  3793.  *------------------------------------------*/
  3794. ACMD_FUNC(raise)
  3795. {
  3796.         struct map_session_data* pl_sd;
  3797.         struct s_mapiterator* iter;
  3798.                
  3799.         nullpo_retr(-1, sd);
  3800.  
  3801.         iter = mapit_getallusers();
  3802.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  3803.                 atcommand_raise_sub(pl_sd);
  3804.         mapit_free(iter);
  3805.  
  3806.         clif_displaymessage(fd, msg_txt(64)); // Mercy has been granted.
  3807.  
  3808.         return 0;
  3809. }
  3810.  
  3811. /*==========================================
  3812.  *
  3813.  *------------------------------------------*/
  3814. ACMD_FUNC(raisemap)
  3815. {
  3816.         struct map_session_data* pl_sd;
  3817.         struct s_mapiterator* iter;
  3818.  
  3819.         nullpo_retr(-1, sd);
  3820.  
  3821.         iter = mapit_getallusers();
  3822.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  3823.                 if (sd->bl.m == pl_sd->bl.m)
  3824.                         atcommand_raise_sub(pl_sd);
  3825.         mapit_free(iter);
  3826.  
  3827.         clif_displaymessage(fd, msg_txt(64)); // Mercy has been granted.
  3828.  
  3829.         return 0;
  3830. }
  3831.  
  3832. /*==========================================
  3833.  *
  3834.  *------------------------------------------*/
  3835. ACMD_FUNC(kick)
  3836. {
  3837.         struct map_session_data *pl_sd;
  3838.         nullpo_retr(-1, sd);
  3839.  
  3840.         memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
  3841.  
  3842.         if (!message || !*message) {
  3843.                 clif_displaymessage(fd, "Please, enter a player name (usage: @kick <player name/id>).");
  3844.                 return -1;
  3845.         }
  3846.  
  3847.         if((pl_sd=map_nick2sd((char *)message)) == NULL && (pl_sd=map_charid2sd(atoi(message))) == NULL)
  3848.         {
  3849.                 clif_displaymessage(fd, msg_txt(3)); // Character not found.
  3850.                 return -1;
  3851.         }
  3852.  
  3853.         if ( pc_isGM(sd) < pc_isGM(pl_sd) )
  3854.         {
  3855.                 clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
  3856.                 return -1;
  3857.         }
  3858.        
  3859.         clif_GM_kick(sd, pl_sd);
  3860.        
  3861.         return 0;
  3862. }
  3863.  
  3864. /*==========================================
  3865.  *
  3866.  *------------------------------------------*/
  3867. ACMD_FUNC(kickall)
  3868. {
  3869.         struct map_session_data* pl_sd;
  3870.         struct s_mapiterator* iter;
  3871.         nullpo_retr(-1, sd);
  3872.  
  3873.         iter = mapit_getallusers();
  3874.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  3875.         {
  3876.                 if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can kick only lower or same gm level
  3877.                         if (sd->status.account_id != pl_sd->status.account_id)
  3878.                                 clif_GM_kick(NULL, pl_sd);
  3879.                 }
  3880.         }
  3881.         mapit_free(iter);
  3882.  
  3883.         clif_displaymessage(fd, msg_txt(195)); // All players have been kicked!
  3884.  
  3885.         return 0;
  3886. }
  3887.  
  3888. /*==========================================
  3889.  *
  3890.  *------------------------------------------*/
  3891. ACMD_FUNC(allskill)
  3892. {
  3893.         nullpo_retr(-1, sd);
  3894.         pc_allskillup(sd); // all skills
  3895.         sd->status.skill_point = 0; // 0 skill points
  3896.         clif_updatestatus(sd, SP_SKILLPOINT); // update
  3897.         clif_displaymessage(fd, msg_txt(76)); // All skills have been added to your skill tree.
  3898.  
  3899.         return 0;
  3900. }
  3901.  
  3902. /*==========================================
  3903.  *
  3904.  *------------------------------------------*/
  3905. ACMD_FUNC(questskill)
  3906. {
  3907.         int skill_id;
  3908.         nullpo_retr(-1, sd);
  3909.  
  3910.         if (!message || !*message || (skill_id = atoi(message)) < 0) {
  3911.                 clif_displaymessage(fd, "Please, enter a quest skill number (usage: @questskill <#:0+>).");
  3912.                 return -1;
  3913.         }
  3914.         if (skill_id < 0 && skill_id >= MAX_SKILL_DB) {
  3915.                 clif_displaymessage(fd, msg_txt(198)); // This skill number doesn't exist.
  3916.                 return -1;
  3917.         }
  3918.         if (!(skill_get_inf2(skill_id) & INF2_QUEST_SKILL)) {
  3919.                 clif_displaymessage(fd, msg_txt(197)); // This skill number doesn't exist or isn't a quest skill.
  3920.                 return -1;
  3921.         }
  3922.         if (pc_checkskill(sd, skill_id) > 0) {
  3923.                 clif_displaymessage(fd, msg_txt(196)); // You already have this quest skill.
  3924.                 return -1;
  3925.         }
  3926.  
  3927.         pc_skill(sd, skill_id, 1, 0);
  3928.         clif_displaymessage(fd, msg_txt(70)); // You have learned the skill.
  3929.  
  3930.         return 0;
  3931. }
  3932.  
  3933. /*==========================================
  3934.  *
  3935.  *------------------------------------------*/
  3936. ACMD_FUNC(lostskill)
  3937. {
  3938.         int skill_id;
  3939.         nullpo_retr(-1, sd);
  3940.  
  3941.         if (!message || !*message || (skill_id = atoi(message)) < 0) {
  3942.                 clif_displaymessage(fd, "Please, enter a quest skill number (usage: @lostskill <#:0+>).");
  3943.                 return -1;
  3944.         }
  3945.         if (skill_id < 0 && skill_id >= MAX_SKILL) {
  3946.                 clif_displaymessage(fd, msg_txt(198)); // This skill number doesn't exist.
  3947.                 return -1;
  3948.         }
  3949.         if (!(skill_get_inf2(skill_id) & INF2_QUEST_SKILL)) {
  3950.                 clif_displaymessage(fd, msg_txt(197)); // This skill number doesn't exist or isn't a quest skill.
  3951.                 return -1;
  3952.         }
  3953.         if (pc_checkskill(sd, skill_id) == 0) {
  3954.                 clif_displaymessage(fd, msg_txt(201)); // You don't have this quest skill.
  3955.                 return -1;
  3956.         }
  3957.  
  3958.         sd->status.skill[skill_id].lv = 0;
  3959.         sd->status.skill[skill_id].flag = 0;
  3960.         clif_deleteskill(sd,skill_id);
  3961.         clif_displaymessage(fd, msg_txt(71)); // You have forgotten the skill.
  3962.  
  3963.         return 0;
  3964. }
  3965.  
  3966. /*==========================================
  3967.  *
  3968.  *------------------------------------------*/
  3969. ACMD_FUNC(spiritball)
  3970. {
  3971.         int max_spiritballs = min(ARRAYLENGTH(sd->spirit_timer), 0x7FFF);
  3972.         int number;
  3973.         nullpo_retr(-1, sd);
  3974.  
  3975.         if( !message || !*message || (number = atoi(message)) < 0 || number > max_spiritballs )
  3976.         {
  3977.                 char msg[CHAT_SIZE_MAX];
  3978.                 safesnprintf(msg, sizeof(msg), "Usage: @spiritball <number: 0-%d>", max_spiritballs);
  3979.                 clif_displaymessage(fd, msg);
  3980.                 return -1;
  3981.         }
  3982.  
  3983.         if( sd->spiritball > 0 )
  3984.                 pc_delspiritball(sd, sd->spiritball, 1);
  3985.         sd->spiritball = number;
  3986.         clif_spiritball(sd);
  3987.         // no message, player can look the difference
  3988.  
  3989.         return 0;
  3990. }
  3991.  
  3992. /*==========================================
  3993.  *
  3994.  *------------------------------------------*/
  3995. ACMD_FUNC(party)
  3996. {
  3997.         char party[NAME_LENGTH];
  3998.         nullpo_retr(-1, sd);
  3999.  
  4000.         memset(party, '\0', sizeof(party));
  4001.  
  4002.         if (!message || !*message || sscanf(message, "%23[^\n]", party) < 1) {
  4003.                 clif_displaymessage(fd, "Please, enter a party name (usage: @party <party_name>).");
  4004.                 return -1;
  4005.         }
  4006.  
  4007.         party_create(sd, party, 0, 0);
  4008.  
  4009.         return 0;
  4010. }
  4011.  
  4012. /*==========================================
  4013.  *
  4014.  *------------------------------------------*/
  4015. ACMD_FUNC(guild)
  4016. {
  4017.         char guild[NAME_LENGTH];
  4018.         int prev;
  4019.         nullpo_retr(-1, sd);
  4020.  
  4021.         memset(guild, '\0', sizeof(guild));
  4022.  
  4023.         if (!message || !*message || sscanf(message, "%23[^\n]", guild) < 1) {
  4024.                 clif_displaymessage(fd, "Please, enter a guild name (usage: @guild <guild_name>).");
  4025.                 return -1;
  4026.         }
  4027.  
  4028.         prev = battle_config.guild_emperium_check;
  4029.         battle_config.guild_emperium_check = 0;
  4030.         guild_create(sd, guild);
  4031.         battle_config.guild_emperium_check = prev;
  4032.  
  4033.         return 0;
  4034. }
  4035.  
  4036. /*==========================================
  4037.  *
  4038.  *------------------------------------------*/
  4039. ACMD_FUNC(agitstart)
  4040. {
  4041.         int i;
  4042.  
  4043.         nullpo_retr(-1, sd);
  4044.         if( agit_flag != 0 )
  4045.         {
  4046.                 clif_displaymessage(fd, msg_txt(73)); // War of Emperium is currently in progress.
  4047.                 return -1;
  4048.         }
  4049.  
  4050.         if( (i = atoi(message)) > 0 )
  4051.                 woe_set = i;
  4052.  
  4053.         agit_flag = 1;
  4054.         guild_agit_start();
  4055.  
  4056.         clif_displaymessage(fd, msg_txt(72)); // War of Emperium has been initiated.
  4057.         return 0;
  4058. }
  4059.  
  4060. /*==========================================
  4061.  *
  4062.  *------------------------------------------*/
  4063. ACMD_FUNC(agitend)
  4064. {
  4065.         nullpo_retr(-1, sd);
  4066.         if (agit_flag == 0) {
  4067.                 clif_displaymessage(fd, msg_txt(75)); // War of Emperium is currently not in progress.
  4068.                 return -1;
  4069.         }
  4070.  
  4071.         guild_agit_end();
  4072.         agit_flag = 0;
  4073.         woe_set = 0;
  4074.         clif_displaymessage(fd, msg_txt(74)); // War of Emperium has been ended.
  4075.  
  4076.         return 0;
  4077. }
  4078.  
  4079. /*==========================================
  4080.  * @mapexit - shuts down the map server
  4081.  *------------------------------------------*/
  4082. ACMD_FUNC(mapexit)
  4083. {
  4084.         nullpo_retr(-1, sd);
  4085.  
  4086.         do_shutdown();
  4087.         return 0;
  4088. }
  4089.  
  4090. /*==========================================
  4091.  * idsearch <part_of_name>: revrited by [Yor]
  4092.  *------------------------------------------*/
  4093. ACMD_FUNC(idsearch)
  4094. {
  4095.         char item_name[100];
  4096.         unsigned int i, match;
  4097.         struct item_data *item_array[MAX_SEARCH];
  4098.         nullpo_retr(-1, sd);
  4099.  
  4100.         memset(item_name, '\0', sizeof(item_name));
  4101.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  4102.  
  4103.         if (!message || !*message || sscanf(message, "%99s", item_name) < 0) {
  4104.                 clif_displaymessage(fd, "Please, enter a part of item name (usage: @idsearch <part_of_item_name>).");
  4105.                 return -1;
  4106.         }
  4107.  
  4108.         sprintf(atcmd_output, msg_txt(77), item_name); // The reference result of '%s' (name: id):
  4109.         clif_displaymessage(fd, atcmd_output);
  4110.         match = itemdb_searchname_array(item_array, MAX_SEARCH, item_name);
  4111.         if (match > MAX_SEARCH) {
  4112.                 sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, match);
  4113.                 clif_displaymessage(fd, atcmd_output);
  4114.                 match = MAX_SEARCH;
  4115.         }
  4116.         for(i = 0; i < match; i++) {
  4117.                 sprintf(atcmd_output, msg_txt(78), item_array[i]->jname, item_array[i]->nameid); // %s: %d
  4118.                 clif_displaymessage(fd, atcmd_output);
  4119.         }
  4120.         sprintf(atcmd_output, msg_txt(79), match); // It is %d affair above.
  4121.         clif_displaymessage(fd, atcmd_output);
  4122.  
  4123.         return 0;
  4124. }
  4125.  
  4126. /*==========================================
  4127.  * Recall All Characters Online To Your Location
  4128.  *------------------------------------------*/
  4129. ACMD_FUNC(recallall)
  4130. {
  4131.         struct map_session_data* pl_sd;
  4132.         struct s_mapiterator* iter;
  4133.         int count;
  4134.         nullpo_retr(-1, sd);
  4135.  
  4136.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  4137.  
  4138.         if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
  4139.                 clif_displaymessage(fd, "You are not authorised to warp somenone to your actual map.");
  4140.                 return -1;
  4141.         }
  4142.  
  4143.         count = 0;
  4144.         iter = mapit_getallusers();
  4145.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  4146.         {
  4147.                 if (sd->status.account_id != pl_sd->status.account_id && pc_isGM(sd) >= pc_isGM(pl_sd))
  4148.                 {
  4149.                         if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd))
  4150.                                 count++;
  4151.                         else {
  4152.                                 if (pc_isdead(pl_sd)) { //Wake them up
  4153.                                         pc_setstand(pl_sd);
  4154.                                         pc_setrestartvalue(pl_sd,1);
  4155.                                 }
  4156.                                 pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
  4157.                         }
  4158.                 }
  4159.         }
  4160.         mapit_free(iter);
  4161.  
  4162.         clif_displaymessage(fd, msg_txt(92)); // All characters recalled!
  4163.         if (count) {
  4164.                 sprintf(atcmd_output, "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count);
  4165.                 clif_displaymessage(fd, atcmd_output);
  4166.         }
  4167.  
  4168.         return 0;
  4169. }
  4170.  
  4171. /*==========================================
  4172.  * Recall online characters of a guild to your location
  4173.  *------------------------------------------*/
  4174. ACMD_FUNC(guildrecall)
  4175. {
  4176.         struct map_session_data* pl_sd;
  4177.         struct s_mapiterator* iter;
  4178.         int count;
  4179.         char guild_name[NAME_LENGTH];
  4180.         struct guild *g;
  4181.         nullpo_retr(-1, sd);
  4182.  
  4183.         memset(guild_name, '\0', sizeof(guild_name));
  4184.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  4185.  
  4186.         if (!message || !*message || sscanf(message, "%23[^\n]", guild_name) < 1) {
  4187.                 clif_displaymessage(fd, "Please, enter a guild name/id (usage: @guildrecall <guild_name/id>).");
  4188.                 return -1;
  4189.         }
  4190.  
  4191.         if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
  4192.                 clif_displaymessage(fd, "You are not authorised to warp somenone to your actual map.");
  4193.                 return -1;
  4194.         }
  4195.  
  4196.         if ((g = guild_searchname(guild_name)) == NULL && // name first to avoid error when name begin with a number
  4197.             (g = guild_search(atoi(message))) == NULL)
  4198.         {
  4199.                 clif_displaymessage(fd, msg_txt(94)); // Incorrect name/ID, or no one from the guild is online.
  4200.                 return -1;
  4201.         }
  4202.  
  4203.         count = 0;
  4204.  
  4205.         iter = mapit_getallusers();
  4206.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  4207.         {
  4208.                 if (sd->status.account_id != pl_sd->status.account_id && pl_sd->status.guild_id == g->guild_id)
  4209.                 {
  4210.                         if (pc_isGM(pl_sd) > pc_isGM(sd))
  4211.                                 continue; //Skip GMs greater than you.
  4212.                         if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd))
  4213.                                 count++;
  4214.                         else
  4215.                                 pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
  4216.                 }
  4217.         }
  4218.         mapit_free(iter);
  4219.  
  4220.         sprintf(atcmd_output, msg_txt(93), g->name); // All online characters of the %s guild have been recalled to your position.
  4221.         clif_displaymessage(fd, atcmd_output);
  4222.         if (count) {
  4223.                 sprintf(atcmd_output, "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count);
  4224.                 clif_displaymessage(fd, atcmd_output);
  4225.         }
  4226.  
  4227.         return 0;
  4228. }
  4229.  
  4230. /*==========================================
  4231.  * Recall online characters of a party to your location
  4232.  *------------------------------------------*/
  4233. ACMD_FUNC(partyrecall)
  4234. {
  4235.         struct map_session_data* pl_sd;
  4236.         struct s_mapiterator* iter;
  4237.         char party_name[NAME_LENGTH];
  4238.         struct party_data *p;
  4239.         int count;
  4240.         nullpo_retr(-1, sd);
  4241.  
  4242.         memset(party_name, '\0', sizeof(party_name));
  4243.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  4244.  
  4245.         if (!message || !*message || sscanf(message, "%23[^\n]", party_name) < 1) {
  4246.                 clif_displaymessage(fd, "Please, enter a party name/id (usage: @partyrecall <party_name/id>).");
  4247.                 return -1;
  4248.         }
  4249.  
  4250.         if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
  4251.                 clif_displaymessage(fd, "You are not authorised to warp somenone to your actual map.");
  4252.                 return -1;
  4253.         }
  4254.  
  4255.         if ((p = party_searchname(party_name)) == NULL && // name first to avoid error when name begin with a number
  4256.             (p = party_search(atoi(message))) == NULL)
  4257.         {
  4258.                 clif_displaymessage(fd, msg_txt(96)); // Incorrect name or ID, or no one from the party is online.
  4259.                 return -1;
  4260.         }
  4261.  
  4262.         count = 0;
  4263.  
  4264.         iter = mapit_getallusers();
  4265.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  4266.         {
  4267.                 if (sd->status.account_id != pl_sd->status.account_id && pl_sd->status.party_id == p->party.party_id)
  4268.                 {
  4269.                         if (pc_isGM(pl_sd) > pc_isGM(sd))
  4270.                                 continue; //Skip GMs greater than you.
  4271.                         if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd))
  4272.                                 count++;
  4273.                         else
  4274.                                 pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
  4275.                 }
  4276.         }
  4277.         mapit_free(iter);
  4278.  
  4279.         sprintf(atcmd_output, msg_txt(95), p->party.name); // All online characters of the %s party have been recalled to your position.
  4280.         clif_displaymessage(fd, atcmd_output);
  4281.         if (count) {
  4282.                 sprintf(atcmd_output, "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", count);
  4283.                 clif_displaymessage(fd, atcmd_output);
  4284.         }
  4285.  
  4286.         return 0;
  4287. }
  4288.  
  4289. /*==========================================
  4290.  *
  4291.  *------------------------------------------*/
  4292. ACMD_FUNC(reloaditemdb)
  4293. {
  4294.         nullpo_retr(-1, sd);
  4295.         itemdb_reload();
  4296.         clif_displaymessage(fd, msg_txt(97)); // Item database has been reloaded.
  4297.  
  4298.         return 0;
  4299. }
  4300.  
  4301. /*==========================================
  4302.  *
  4303.  *------------------------------------------*/
  4304. ACMD_FUNC(reloadmobdb)
  4305. {
  4306.         nullpo_retr(-1, sd);
  4307.         mob_reload();
  4308.         read_petdb();
  4309.         merc_reload();
  4310.         reload_elementaldb();
  4311.         clif_displaymessage(fd, msg_txt(98)); // Monster database has been reloaded.
  4312.  
  4313.         return 0;
  4314. }
  4315.  
  4316. /*==========================================
  4317.  *
  4318.  *------------------------------------------*/
  4319. ACMD_FUNC(reloadskilldb)
  4320. {
  4321.         nullpo_retr(-1, sd);
  4322.         skill_reload();
  4323.         merc_skill_reload();
  4324.         reload_elemental_skilldb();
  4325.         clif_displaymessage(fd, msg_txt(99)); // Skill database has been reloaded.
  4326.  
  4327.         return 0;
  4328. }
  4329.  
  4330. /*==========================================
  4331.  * @reloadatcommand - reloads atcommand_athena.conf
  4332.  *------------------------------------------*/
  4333. ACMD_FUNC(reloadatcommand)
  4334. {
  4335.         atcommand_config_read(ATCOMMAND_CONF_FILENAME);
  4336.         clif_displaymessage(fd, msg_txt(254));
  4337.         return 0;
  4338. }
  4339. /*==========================================
  4340.  * @reloadbattleconf - reloads battle_athena.conf
  4341.  *------------------------------------------*/
  4342. ACMD_FUNC(reloadbattleconf)
  4343. {
  4344.         struct Battle_Config prev_config;
  4345.         memcpy(&prev_config, &battle_config, sizeof(prev_config));
  4346.  
  4347.         battle_config_read(BATTLE_CONF_FILENAME);
  4348.         // It can cause serius problems if we change this setting while server is UP.
  4349.         battle_config.renewal_system_enable = prev_config.renewal_system_enable;
  4350.         battle_config.anti_mayapurple_hack = prev_config.anti_mayapurple_hack;
  4351.  
  4352.         if( prev_config.item_rate_mvp          != battle_config.item_rate_mvp
  4353.         ||  prev_config.item_rate_common       != battle_config.item_rate_common
  4354.         ||  prev_config.item_rate_common_boss  != battle_config.item_rate_common_boss
  4355.         ||  prev_config.item_rate_card         != battle_config.item_rate_card
  4356.         ||  prev_config.item_rate_card_boss    != battle_config.item_rate_card_boss
  4357.         ||  prev_config.item_rate_equip        != battle_config.item_rate_equip
  4358.         ||  prev_config.item_rate_equip_boss   != battle_config.item_rate_equip_boss
  4359.         ||  prev_config.item_rate_heal         != battle_config.item_rate_heal
  4360.         ||  prev_config.item_rate_heal_boss    != battle_config.item_rate_heal_boss
  4361.         ||  prev_config.item_rate_use          != battle_config.item_rate_use
  4362.         ||  prev_config.item_rate_use_boss     != battle_config.item_rate_use_boss
  4363.         ||  prev_config.item_rate_treasure     != battle_config.item_rate_treasure
  4364.         ||  prev_config.item_rate_adddrop      != battle_config.item_rate_adddrop
  4365.         ||  prev_config.logarithmic_drops      != battle_config.logarithmic_drops
  4366.         ||  prev_config.item_drop_common_min   != battle_config.item_drop_common_min
  4367.         ||  prev_config.item_drop_common_max   != battle_config.item_drop_common_max
  4368.         ||  prev_config.item_drop_card_min     != battle_config.item_drop_card_min
  4369.         ||  prev_config.item_drop_card_max     != battle_config.item_drop_card_max
  4370.         ||  prev_config.item_drop_equip_min    != battle_config.item_drop_equip_min
  4371.         ||  prev_config.item_drop_equip_max    != battle_config.item_drop_equip_max
  4372.         ||  prev_config.item_drop_mvp_min      != battle_config.item_drop_mvp_min
  4373.         ||  prev_config.item_drop_mvp_max      != battle_config.item_drop_mvp_max
  4374.         ||  prev_config.item_drop_heal_min     != battle_config.item_drop_heal_min
  4375.         ||  prev_config.item_drop_heal_max     != battle_config.item_drop_heal_max
  4376.         ||  prev_config.item_drop_use_min      != battle_config.item_drop_use_min
  4377.         ||  prev_config.item_drop_use_max      != battle_config.item_drop_use_max
  4378.         ||  prev_config.item_drop_treasure_min != battle_config.item_drop_treasure_min
  4379.         ||  prev_config.item_drop_treasure_max != battle_config.item_drop_treasure_max
  4380.         ||  prev_config.base_exp_rate          != battle_config.base_exp_rate
  4381.         ||  prev_config.job_exp_rate           != battle_config.job_exp_rate
  4382.         )
  4383.         {       // Exp or Drop rates changed.
  4384.                 mob_reload(); //Needed as well so rate changes take effect.
  4385. #ifndef TXT_ONLY
  4386.                 chrif_ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common);
  4387. #endif
  4388.         }
  4389.         clif_displaymessage(fd, msg_txt(255));
  4390.         return 0;
  4391. }
  4392. /*==========================================
  4393.  * @reloadstatusdb - reloads job_db1.txt job_db2.txt job_db2-2.txt refine_db.txt size_fix.txt
  4394.  *------------------------------------------*/
  4395. ACMD_FUNC(reloadstatusdb)
  4396. {
  4397.         status_readdb();
  4398.         clif_displaymessage(fd, msg_txt(256));
  4399.         return 0;
  4400. }
  4401. /*==========================================
  4402.  * @reloadpcdb - reloads exp.txt skill_tree.txt attr_fix.txt statpoint.txt
  4403.  *------------------------------------------*/
  4404. ACMD_FUNC(reloadpcdb)
  4405. {
  4406.         pc_readdb();
  4407.         clif_displaymessage(fd, msg_txt(257));
  4408.         return 0;
  4409. }
  4410.  
  4411. /*==========================================
  4412.  * @reloadmotd - reloads motd.txt
  4413.  *------------------------------------------*/
  4414. ACMD_FUNC(reloadmotd)
  4415. {
  4416.         pc_read_motd();
  4417.         clif_displaymessage(fd, msg_txt(268));
  4418.         return 0;
  4419. }
  4420.  
  4421. /*==========================================
  4422.  * @reloadscript - reloads all scripts (npcs, warps, mob spawns, ...)
  4423.  *------------------------------------------*/
  4424. ACMD_FUNC(reloadscript)
  4425. {
  4426.         nullpo_retr(-1, sd);
  4427.         //atcommand_broadcast( fd, sd, "@broadcast", "eAthena Server is Rehashing..." );
  4428.         //atcommand_broadcast( fd, sd, "@broadcast", "You will feel a bit of lag at this point !" );
  4429.         //atcommand_broadcast( fd, sd, "@broadcast", "Reloading NPCs..." );
  4430.  
  4431.         flush_fifos();
  4432.         script_reload();
  4433.         npc_reload();
  4434.  
  4435.         clif_displaymessage(fd, msg_txt(100)); // Scripts have been reloaded.
  4436.  
  4437.         return 0;
  4438. }
  4439.  
  4440. /*==========================================
  4441.  * @mapinfo [0-3] <map name> by MC_Cameri
  4442.  * => Shows information about the map [map name]
  4443.  * 0 = no additional information
  4444.  * 1 = Show users in that map and their location
  4445.  * 2 = Shows NPCs in that map
  4446.  * 3 = Shows the shops/chats in that map (not implemented)
  4447.  *------------------------------------------*/
  4448. ACMD_FUNC(mapinfo)
  4449. {
  4450.         struct map_session_data* pl_sd;
  4451.         struct s_mapiterator* iter;
  4452.         struct npc_data *nd = NULL;
  4453.         struct chat_data *cd = NULL;
  4454.         char direction[12];
  4455.         int i, m_id, chat_num, list = 0;
  4456.         unsigned short m_index;
  4457.         char mapname[24];
  4458.  
  4459.         nullpo_retr(-1, sd);
  4460.  
  4461.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  4462.         memset(mapname, '\0', sizeof(mapname));
  4463.         memset(direction, '\0', sizeof(direction));
  4464.  
  4465.         sscanf(message, "%d %23[^\n]", &list, mapname);
  4466.  
  4467.         if (list < 0 || list > 3) {
  4468.                 clif_displaymessage(fd, "Please, enter at least a valid list number (usage: @mapinfo <0-3> [map]).");
  4469.                 return -1;
  4470.         }
  4471.  
  4472.         if (mapname[0] == '\0') {
  4473.                 safestrncpy(mapname, mapindex_id2name(sd->mapindex), MAP_NAME_LENGTH);
  4474.                 m_id =  map_mapindex2mapid(sd->mapindex);
  4475.         } else {
  4476.                 m_id = map_mapname2mapid(mapname);
  4477.         }
  4478.  
  4479.         if (m_id < 0) {
  4480.                 clif_displaymessage(fd, msg_txt(1)); // Map not found.
  4481.                 return -1;
  4482.         }
  4483.         m_index = mapindex_name2id(mapname); //This one shouldn't fail since the previous seek did not.
  4484.        
  4485.         clif_displaymessage(fd, "------ Map Info ------");
  4486.  
  4487.         // count chats (for initial message)
  4488.         chat_num = 0;
  4489.         iter = mapit_getallusers();
  4490.         for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  4491.                 if( (cd = (struct chat_data*)map_id2bl(pl_sd->chatID)) != NULL && pl_sd->mapindex == m_index && cd->usersd[0] == pl_sd )
  4492.                         chat_num++;
  4493.         mapit_free(iter);
  4494.  
  4495.         sprintf(atcmd_output, "Map Name: %s | Players In Map: %d | NPCs In Map: %d | Chats In Map: %d", mapname, map[m_id].users, map[m_id].npc_num, chat_num);
  4496.         clif_displaymessage(fd, atcmd_output);
  4497.         clif_displaymessage(fd, "------ Map Flags ------");
  4498.         if (map[m_id].flag.town)
  4499.                 clif_displaymessage(fd, "Town Map");
  4500.  
  4501.         if (battle_config.autotrade_mapflag == map[m_id].flag.autotrade)
  4502.                 clif_displaymessage(fd, "Autotrade Enabled");
  4503.         else
  4504.                 clif_displaymessage(fd, "Autotrade Disabled");
  4505.        
  4506.         if (map[m_id].flag.battleground)
  4507.                 clif_displaymessage(fd, "Battlegrounds ON");
  4508.                
  4509.         strcpy(atcmd_output,"PvP Flags: ");
  4510.         if (map[m_id].flag.pvp)
  4511.                 strcat(atcmd_output, "Pvp ON | ");
  4512.         if (map[m_id].flag.pvp_noguild)
  4513.                 strcat(atcmd_output, "NoGuild | ");
  4514.         if (map[m_id].flag.pvp_noparty)
  4515.                 strcat(atcmd_output, "NoParty | ");
  4516.         if (map[m_id].flag.pvp_nightmaredrop)
  4517.                 strcat(atcmd_output, "NightmareDrop | ");
  4518.         if (map[m_id].flag.pvp_nocalcrank)
  4519.                 strcat(atcmd_output, "NoCalcRank | ");
  4520.         clif_displaymessage(fd, atcmd_output);
  4521.  
  4522.         if (map[m_id].flag.pvp_event)
  4523.         {
  4524.                 sprintf(atcmd_output,"PVP Event Flag: x1 %d | x2 %d | y1 %d | y2 %d", map[m_id].pvpe_x1, map[m_id].pvpe_x2, map[m_id].pvpe_y1, map[m_id].pvpe_y2);
  4525.                 clif_displaymessage(fd, atcmd_output);
  4526.         }
  4527.  
  4528.         strcpy(atcmd_output,"GvG Flags: ");
  4529.         if (map[m_id].flag.gvg)
  4530.                 strcat(atcmd_output, "GvG ON | ");
  4531.         if (map[m_id].flag.gvg_dungeon)
  4532.                 strcat(atcmd_output, "GvG Dungeon | ");
  4533.         if (map[m_id].flag.gvg_castle)
  4534.                 strcat(atcmd_output, "GvG Castle | ");
  4535.         if (map[m_id].flag.gvg_noparty)
  4536.                 strcat(atcmd_output, "NoParty | ");
  4537.         if (map[m_id].flag.woe_set)
  4538.         {
  4539.                 char output[64];
  4540.                 sprintf(output,"WoE Set %d | ", map[m_id].flag.woe_set);
  4541.                 strcat(atcmd_output, output);
  4542.         }
  4543.  
  4544.         clif_displaymessage(fd, atcmd_output);
  4545.  
  4546.         strcpy(atcmd_output,"Teleport Flags: ");
  4547.         if (map[m_id].flag.noteleport)
  4548.                 strcat(atcmd_output, "NoTeleport | ");
  4549.         if (map[m_id].flag.monster_noteleport)
  4550.                 strcat(atcmd_output, "Monster NoTeleport | ");
  4551.         if (map[m_id].flag.nowarp)
  4552.                 strcat(atcmd_output, "NoWarp | ");
  4553.         if (map[m_id].flag.nowarpto)
  4554.                 strcat(atcmd_output, "NoWarpTo | ");
  4555.         if (map[m_id].flag.noreturn)
  4556.                 strcat(atcmd_output, "NoReturn | ");
  4557.         if (map[m_id].flag.nogo)
  4558.                 strcat(atcmd_output, "NoGo | ");
  4559.         if (map[m_id].flag.nomemo)
  4560.                 strcat(atcmd_output, "NoMemo | ");
  4561.         if (map[m_id].flag.blocked)
  4562.                 strcat(atcmd_output, "Blocked | ");
  4563.         clif_displaymessage(fd, atcmd_output);
  4564.  
  4565.         sprintf(atcmd_output, "No Exp Penalty: %s | No Zeny Penalty: %s", (map[m_id].flag.noexppenalty) ? "On" : "Off", (map[m_id].flag.nozenypenalty) ? "On" : "Off");
  4566.         clif_displaymessage(fd, atcmd_output);
  4567.  
  4568.         if (map[m_id].flag.nosave) {
  4569.                 if (!map[m_id].save.map)
  4570.                         sprintf(atcmd_output, "No Save (Return to last Save Point)");
  4571.                 else if (map[m_id].save.x == -1 || map[m_id].save.y == -1 )
  4572.                         sprintf(atcmd_output, "No Save, Save Point: %s,Random",mapindex_id2name(map[m_id].save.map));
  4573.                 else
  4574.                         sprintf(atcmd_output, "No Save, Save Point: %s,%d,%d",
  4575.                                 mapindex_id2name(map[m_id].save.map),map[m_id].save.x,map[m_id].save.y);
  4576.                 clif_displaymessage(fd, atcmd_output);
  4577.         }
  4578.  
  4579.         strcpy(atcmd_output,"Weather Flags: ");
  4580.         if (map[m_id].flag.snow)
  4581.                 strcat(atcmd_output, "Snow | ");
  4582.         if (map[m_id].flag.fog)
  4583.                 strcat(atcmd_output, "Fog | ");
  4584.         if (map[m_id].flag.sakura)
  4585.                 strcat(atcmd_output, "Sakura | ");
  4586.         if (map[m_id].flag.clouds)
  4587.                 strcat(atcmd_output, "Clouds | ");
  4588.         if (map[m_id].flag.clouds2)
  4589.                 strcat(atcmd_output, "Clouds2 | ");
  4590.         if (map[m_id].flag.fireworks)
  4591.                 strcat(atcmd_output, "Fireworks | ");
  4592.         if (map[m_id].flag.leaves)
  4593.                 strcat(atcmd_output, "Leaves | ");
  4594.         if (map[m_id].flag.rain)
  4595.                 strcat(atcmd_output, "Rain | ");
  4596.         if (map[m_id].flag.nightenabled)
  4597.                 strcat(atcmd_output, "Displays Night | ");
  4598.         clif_displaymessage(fd, atcmd_output);
  4599.  
  4600.         strcpy(atcmd_output,"Other Flags: ");
  4601.         if (map[m_id].flag.nobranch)
  4602.                 strcat(atcmd_output, "NoBranch | ");
  4603.         if (map[m_id].flag.notrade)
  4604.                 strcat(atcmd_output, "NoTrade | ");
  4605.         if (map[m_id].flag.novending)
  4606.                 strcat(atcmd_output, "NoVending | ");
  4607.         if (map[m_id].flag.nodrop)
  4608.                 strcat(atcmd_output, "NoDrop | ");
  4609.         if (map[m_id].flag.noskill)
  4610.                 strcat(atcmd_output, "NoSkill | ");
  4611.         if (map[m_id].flag.noicewall)
  4612.                 strcat(atcmd_output, "NoIcewall | ");
  4613.         if (map[m_id].flag.allowks)
  4614.                 strcat(atcmd_output, "AllowKS | ");
  4615.         if (map[m_id].flag.reset)
  4616.                 strcat(atcmd_output, "Reset | ");
  4617.         clif_displaymessage(fd, atcmd_output);
  4618.  
  4619.         strcpy(atcmd_output,"Other Flags: ");
  4620.         if (map[m_id].nocommand)
  4621.                 strcat(atcmd_output, "NoCommand | ");
  4622.         if (map[m_id].flag.nobaseexp)
  4623.                 strcat(atcmd_output, "NoBaseEXP | ");
  4624.         if (map[m_id].flag.nojobexp)
  4625.                 strcat(atcmd_output, "NoJobEXP | ");
  4626.         if (map[m_id].flag.nomobloot)
  4627.                 strcat(atcmd_output, "NoMobLoot | ");
  4628.         if (map[m_id].flag.nomvploot)
  4629.                 strcat(atcmd_output, "NoMVPLoot | ");
  4630.         if (map[m_id].flag.partylock)
  4631.                 strcat(atcmd_output, "PartyLock | ");
  4632.         if (map[m_id].flag.guildlock)
  4633.                 strcat(atcmd_output, "GuildLock | ");
  4634.         clif_displaymessage(fd, atcmd_output);
  4635.  
  4636.         switch (list) {
  4637.         case 0:
  4638.                 // Do nothing. It's list 0, no additional display.
  4639.                 break;
  4640.         case 1:
  4641.                 clif_displaymessage(fd, "----- Players in Map -----");
  4642.                 iter = mapit_getallusers();
  4643.                 for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  4644.                 {
  4645.                         if (pl_sd->mapindex == m_index) {
  4646.                                 sprintf(atcmd_output, "Player '%s' (session #%d) | Location: %d,%d",
  4647.                                         pl_sd->status.name, pl_sd->fd, pl_sd->bl.x, pl_sd->bl.y);
  4648.                                 clif_displaymessage(fd, atcmd_output);
  4649.                         }
  4650.                 }
  4651.                 mapit_free(iter);
  4652.                 break;
  4653.         case 2:
  4654.                 clif_displaymessage(fd, "----- NPCs in Map -----");
  4655.                 for (i = 0; i < map[m_id].npc_num;)
  4656.                 {
  4657.                         nd = map[m_id].npc[i];
  4658.                         switch(nd->ud.dir) {
  4659.                         case 0:  strcpy(direction, "North"); break;
  4660.                         case 1:  strcpy(direction, "North West"); break;
  4661.                         case 2:  strcpy(direction, "West"); break;
  4662.                         case 3:  strcpy(direction, "South West"); break;
  4663.                         case 4:  strcpy(direction, "South"); break;
  4664.                         case 5:  strcpy(direction, "South East"); break;
  4665.                         case 6:  strcpy(direction, "East"); break;
  4666.                         case 7:  strcpy(direction, "North East"); break;
  4667.                         case 9:  strcpy(direction, "North"); break;
  4668.                         default: strcpy(direction, "Unknown"); break;
  4669.                         }
  4670.                         sprintf(atcmd_output, "NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d",
  4671.                                 ++i, nd->name, direction, nd->class_, nd->bl.x, nd->bl.y);
  4672.                         clif_displaymessage(fd, atcmd_output);
  4673.                 }
  4674.                 break;
  4675.         case 3:
  4676.                 clif_displaymessage(fd, "----- Chats in Map -----");
  4677.                 iter = mapit_getallusers();
  4678.                 for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
  4679.                 {
  4680.                         if ((cd = (struct chat_data*)map_id2bl(pl_sd->chatID)) != NULL &&
  4681.                             pl_sd->mapindex == m_index &&
  4682.                             cd->usersd[0] == pl_sd)
  4683.                         {
  4684.                                 sprintf(atcmd_output, "Chat: %s | Player: %s | Location: %d %d",
  4685.                                         cd->title, pl_sd->status.name, cd->bl.x, cd->bl.