From Blush Bird, 1 Week ago, written in Plain Text.
Embed
  1. /****************************************************************************!
  2. *                _           _   _   _                                       *
  3. *               | |__  _ __ / \ | |_| |__   ___ _ __   __ _                  *
  4. *               | '_ \| '__/ _ \| __| '_ \ / _ \ '_ \ / _` |                 *
  5. *               | |_) | | / ___ \ |_| | | |  __/ | | | (_| |                 *
  6. *               |_.__/|_|/_/   \_\__|_| |_|\___|_| |_|\__,_|                 *
  7. *                                                                            *
  8. *                            www.brathena.org                                *
  9. ******************************************************************************
  10. * src/map/atcommand.c                                                        *
  11. * Responsável pelo funcionamento de @comandos dentro do emulador             *
  12. ******************************************************************************
  13. * Copyright (c) brAthena Dev Team                                            *
  14. * Copyright (c) Hercules Dev Team                                            *
  15. * Copyright (c) Athena Dev Teams                                             *
  16. *                                                                            *
  17. * Licenciado sob a licença GNU GPL                                           *
  18. * Para mais informações leia o arquivo LICENSE na raíz do emulador           *
  19. *****************************************************************************/
  20.  
  21. #define BRATHENA_CORE
  22.  
  23. #include "config/core.h" // AUTOLOOTITEM_SIZE, AUTOTRADE_PERSISTENCY, MAX_SUGGESTIONS, MOB_FLEE(), MOB_HIT(), RENEWAL, RENEWAL_DROP, RENEWAL_EXP
  24. #include "atcommand.h"
  25.  
  26. #include "map/battle.h"
  27. #include "map/battleground.h"
  28. #include "map/channel.h"
  29. #include "map/chat.h"
  30. #include "map/chrif.h"
  31. #include "map/clif.h"
  32. #include "map/duel.h"
  33. #include "map/elemental.h"
  34. #include "map/guild.h"
  35. #include "map/homunculus.h"
  36. #include "map/intif.h"
  37. #include "map/itemdb.h"
  38. #include "map/log.h"
  39. #include "map/mail.h"
  40. #include "map/map.h"
  41. #include "map/mapreg.h"
  42. #include "map/mercenary.h"
  43. #include "map/mob.h"
  44. #include "map/npc.h"
  45. #include "map/party.h"
  46. #include "map/pc.h"
  47. #include "map/pc_groups.h" // groupid2name
  48. #include "map/pet.h"
  49. #include "map/quest.h"
  50. #include "map/queue.h"
  51. #include "map/script.h"
  52. #include "map/searchstore.h"
  53. #include "map/skill.h"
  54. #include "map/status.h"
  55. #include "map/storage.h"
  56. #include "map/trade.h"
  57. #include "map/unit.h"
  58. #include "common/cbasetypes.h"
  59. #include "common/conf.h"
  60. #include "common/core.h"
  61. #include "common/memmgr.h"
  62. #include "common/mmo.h" // MAX_CARTS
  63. #include "common/nullpo.h"
  64. #include "common/random.h"
  65. #include "common/showmsg.h"
  66. #include "common/socket.h"
  67. #include "common/strlib.h"
  68. #include "common/sysinfo.h"
  69. #include "common/timer.h"
  70. #include "common/utils.h"
  71.  
  72. #include <math.h>
  73. #include <stdio.h>
  74. #include <stdlib.h>
  75. #include <string.h>
  76.  
  77. struct atcommand_interface atcommand_s;
  78. struct atcommand_interface *atcommand;
  79.  
  80. static char atcmd_output[CHAT_SIZE_MAX];
  81. static char atcmd_player_name[NAME_LENGTH];
  82.  
  83. // @commands (script-based)
  84. struct atcmd_binding_data* get_atcommandbind_byname(const char* name) {
  85.         int i = 0;
  86.  
  87.         nullpo_retr(NULL, name);
  88.         if( *name == atcommand->at_symbol || *name == atcommand->char_symbol )
  89.                 name++; // for backwards compatibility
  90.  
  91.         ARR_FIND( 0, atcommand->binding_count, i, strcmpi(atcommand->binding[i]->command, name) == 0 );
  92.  
  93.         return ( i < atcommand->binding_count ) ? atcommand->binding[i] : NULL;
  94. }
  95.  
  96. const char* atcommand_msgsd(struct map_session_data *sd, int msg_number) {
  97.         Assert_retr("??", msg_number >= 0 && msg_number < MAX_MSG && atcommand->msg_table[0][msg_number] != NULL);
  98.         if (!sd || sd->lang_id >= atcommand->max_message_table || !atcommand->msg_table[sd->lang_id][msg_number])
  99.                 return atcommand->msg_table[0][msg_number];
  100.         return atcommand->msg_table[sd->lang_id][msg_number];
  101. }
  102.  
  103. const char* atcommand_msgfd(int fd, int msg_number) {
  104.         struct map_session_data *sd = sockt->session_is_valid(fd) ? sockt->session[fd]->session_data : NULL;
  105.         Assert_retr("??", msg_number >= 0 && msg_number < MAX_MSG && atcommand->msg_table[0][msg_number] != NULL);
  106.         if (!sd || sd->lang_id >= atcommand->max_message_table || !atcommand->msg_table[sd->lang_id][msg_number])
  107.                 return atcommand->msg_table[0][msg_number];
  108.         return atcommand->msg_table[sd->lang_id][msg_number];
  109. }
  110.  
  111. //-----------------------------------------------------------
  112. // Return the message string of the specified number by [Yor]
  113. //-----------------------------------------------------------
  114. const char* atcommand_msg(int msg_number) {
  115.         Assert_retr("??", msg_number >= 0 && msg_number < MAX_MSG);
  116.         if (atcommand->msg_table[map->default_lang_id][msg_number] != NULL && atcommand->msg_table[map->default_lang_id][msg_number][0] != '\0')
  117.                 return atcommand->msg_table[map->default_lang_id][msg_number];
  118.  
  119.         if(atcommand->msg_table[0][msg_number] != NULL && atcommand->msg_table[0][msg_number][0] != '\0')
  120.                 return atcommand->msg_table[0][msg_number];
  121.  
  122.         return "??";
  123. }
  124.  
  125. /**
  126.  * Reads Message Data
  127.  *
  128.  * @param[in] cfg_name       configuration filename to read.
  129.  * @param[in] allow_override whether to allow duplicate message IDs to override the original value.
  130.  * @return success state.
  131.  */
  132. bool msg_config_read(const char *cfg_name, bool allow_override) {
  133.         int msg_number;
  134.         char line[1024], w1[1024], w2[1024];
  135.         FILE *fp;
  136.         static int called = 1;
  137.  
  138.         nullpo_retr(false, cfg_name);
  139.         if ((fp = fopen(cfg_name, "r")) == NULL) {
  140.                 ShowError("Arquivo de mensagem nao encontrado: %s\n", cfg_name);
  141.                 return false;
  142.         }
  143.  
  144.         if( !atcommand->max_message_table )
  145.                 atcommand->expand_message_table();
  146.  
  147.         while(fgets(line, sizeof(line), fp)) {
  148.                 if (line[0] == '/' && line[1] == '/')
  149.                         continue;
  150.                 if (sscanf(line, "%1023[^:]: %1023[^\r\n]", w1, w2) != 2)
  151.                         continue;
  152.  
  153.                 if (strcmpi(w1, "import") == 0) {
  154.                         atcommand->msg_read(w2, true);
  155.                 } else {
  156.                         msg_number = atoi(w1);
  157.                         if (msg_number >= 0 && msg_number < MAX_MSG) {
  158.                                 if (atcommand->msg_table[0][msg_number] != NULL) {
  159.                                         if (!allow_override) {
  160.                                                 ShowError("Mensagem duplicada: ID '%d' ja esta sendo usado por '%s'. Mensagem '%s' foi ignorada.\n",
  161.                                                           msg_number, w2, atcommand->msg_table[0][msg_number]);
  162.                                                 continue;
  163.                                         }
  164.                                         aFree(atcommand->msg_table[0][msg_number]);
  165.                                 }
  166.                                 /* this could easily become consecutive memory like get_str() and save the malloc overhead for over 1k calls [Ind] */
  167.                                 atcommand->msg_table[0][msg_number] = (char *)aMalloc((strlen(w2) + 1)*sizeof (char));
  168.                                 strcpy(atcommand->msg_table[0][msg_number],w2);
  169.                         }
  170.                 }
  171.         }
  172.         fclose(fp);
  173.  
  174.         if( ++called == 1 ) { //Original
  175.                 if( script->lang_export_fp ) {
  176.                         int i;
  177.                         for(i = 0; i < MAX_MSG;i++) {
  178.                                 if( atcommand->msg_table[0][i] != NULL ) {
  179.                                         fprintf(script->lang_export_fp, "msgctxt \"messages.conf\"\n"
  180.                                                         "msgid \"%s\"\n"
  181.                                                         "msgstr \"\"\n",
  182.                                                         atcommand->msg_table[0][i]
  183.                                                         );
  184.                                 }
  185.                         }
  186.                 }
  187.         }
  188.  
  189.         return true;
  190. }
  191.  
  192. /*==========================================
  193.  * Cleanup Message Data
  194.  *------------------------------------------*/
  195. void do_final_msg(void) {
  196.         int i, j;
  197.  
  198.         for(i = 0; i < atcommand->max_message_table; i++) {
  199.                 for (j = 0; j < MAX_MSG; j++) {
  200.                         if( atcommand->msg_table[i][j] )
  201.                                 aFree(atcommand->msg_table[i][j]);
  202.                 }
  203.                 aFree(atcommand->msg_table[i]);
  204.         }
  205.  
  206.         if( atcommand->msg_table )
  207.                 aFree(atcommand->msg_table);
  208. }
  209.  
  210. /**
  211.  * retrieves the help string associated with a given command.
  212.  */
  213. static inline const char* atcommand_help_string(AtCommandInfo *info) {
  214.         return info->help;
  215. }
  216.  
  217. /*==========================================
  218.  * @send (used for testing packet sends from the client)
  219.  *------------------------------------------*/
  220. ACMD(send)
  221. {
  222.         int len=0,type;
  223.         long num;
  224.  
  225.         // read message type as hex number (without the 0x)
  226.         if (!*message
  227.          || !((sscanf(message, "len %x", &type)==1 && (len=1, true))
  228.          || sscanf(message, "%x", &type)==1)
  229.         ) {
  230.                 clif->message(fd, msg_fd(fd,900)); // Usage:
  231.                 clif->message(fd, msg_fd(fd,901)); // @send len <packet hex number>
  232.                 clif->message(fd, msg_fd(fd,902)); // @send <packet hex number> {<value>}*
  233.                 clif->message(fd, msg_fd(fd,903)); // Value: <type=B(default),W,L><number> or S<length>"<string>"
  234.                 return false;
  235.         }
  236.  
  237. #define PARSE_ERROR(error,p) do {\
  238.         clif->message(fd, (error));\
  239.         safesnprintf(atcmd_output, sizeof(atcmd_output), ">%s", (p));\
  240.         clif->message(fd, atcmd_output);\
  241. } while(0) //define PARSE_ERROR
  242.  
  243. #define CHECK_EOS(p) do { \
  244.         if(*(p) == 0){ \
  245.                 clif->message(fd, "Unexpected end of string");\
  246.                 return false;\
  247.         } \
  248. } while(0) //define CHECK_EOS
  249.  
  250. #define SKIP_VALUE(p) do { \
  251.         while(*(p) && !ISSPACE(*(p))) ++(p); /* non-space */\
  252.         while(*(p) && ISSPACE(*(p)))  ++(p); /* space */\
  253. } while(0) //define SKIP_VALUE
  254.  
  255. #define GET_VALUE(p,num) do { \
  256.         if(sscanf((p), "x%lx", &(num)) < 1 && sscanf((p), "%ld ", &(num)) < 1){\
  257.                 PARSE_ERROR("Invalid number in:",(p));\
  258.                 return false;\
  259.         }\
  260. } while(0) //define GET_VALUE
  261.  
  262.         if (type >= MIN_PACKET_DB && type <= MAX_PACKET_DB) {
  263.                 int off = 2;
  264.                 if (len) {
  265.                         // show packet length
  266.                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,904), type, clif->packet(type)->len); // Packet 0x%x length: %d
  267.                         clif->message(fd, atcmd_output);
  268.                         return true;
  269.                 }
  270.  
  271.                 len = clif->packet(type)->len;
  272.                 if (len == 0) {
  273.                         // unknown packet - ERROR
  274.                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,905), type); // Unknown packet: 0x%x
  275.                         clif->message(fd, atcmd_output);
  276.                         return false;
  277.                 } else if (len == -1) {
  278.                         // dynamic packet
  279.                         len = SHRT_MAX-4; // maximum length
  280.                         off = 4;
  281.                 }
  282.                 WFIFOHEAD(sd->fd, len);
  283.                 WFIFOW(sd->fd,0)=TOW(type);
  284.  
  285.                 // parse packet contents
  286.                 SKIP_VALUE(message);
  287.                 while(*message != 0 && off < len){
  288.                         if(ISDIGIT(*message) || *message == '-' || *message == '+')
  289.                         {// default (byte)
  290.                                 GET_VALUE(message,num);
  291.                                 WFIFOB(sd->fd,off)=TOB(num);
  292.                                 ++off;
  293.                         } else if(TOUPPER(*message) == 'B')
  294.                         {// byte
  295.                                 ++message;
  296.                                 GET_VALUE(message,num);
  297.                                 WFIFOB(sd->fd,off)=TOB(num);
  298.                                 ++off;
  299.                         } else if(TOUPPER(*message) == 'W')
  300.                         {// word (2 bytes)
  301.                                 ++message;
  302.                                 GET_VALUE(message,num);
  303.                                 WFIFOW(sd->fd,off)=TOW(num);
  304.                                 off+=2;
  305.                         } else if(TOUPPER(*message) == 'L')
  306.                         {// long word (4 bytes)
  307.                                 ++message;
  308.                                 GET_VALUE(message,num);
  309.                                 WFIFOL(sd->fd,off)=TOL(num);
  310.                                 off+=4;
  311.                         } else if(TOUPPER(*message) == 'S')
  312.                         {// string - escapes are valid
  313.                                 // get string length - num <= 0 means not fixed length (default)
  314.                                 int end;
  315.                                 ++message;
  316.                                 if(*message == '"'){
  317.                                         num=0;
  318.                                 } else {
  319.                                         GET_VALUE(message,num);
  320.                                         while(*message != '"')
  321.                                         {// find start of string
  322.                                                 if(*message == 0 || ISSPACE(*message)){
  323.                                                         PARSE_ERROR(msg_fd(fd,906),message); // Not a string:
  324.                                                         return false;
  325.                                                 }
  326.                                                 ++message;
  327.                                         }
  328.                                 }
  329.  
  330.                                 // parse string
  331.                                 ++message;
  332.                                 CHECK_EOS(message);
  333.                                 end=(num<=0? 0: min(off+((int)num),len));
  334.                                 for(; *message != '"' && (off < end || end == 0); ++off){
  335.                                         if(*message == '\\'){
  336.                                                 ++message;
  337.                                                 CHECK_EOS(message);
  338.                                                 switch(*message){
  339.                                                         case 'a': num=0x07; break; // Bell
  340.                                                         case 'b': num=0x08; break; // Backspace
  341.                                                         case 't': num=0x09; break; // Horizontal tab
  342.                                                         case 'n': num=0x0A; break; // Line feed
  343.                                                         case 'v': num=0x0B; break; // Vertical tab
  344.                                                         case 'f': num=0x0C; break; // Form feed
  345.                                                         case 'r': num=0x0D; break; // Carriage return
  346.                                                         case 'e': num=0x1B; break; // Escape
  347.                                                         default:  num=*message; break;
  348.                                                         case 'x': // Hexadecimal
  349.                                                         {
  350.                                                                 ++message;
  351.                                                                 CHECK_EOS(message);
  352.                                                                 if(!ISXDIGIT(*message)){
  353.                                                                         PARSE_ERROR(msg_fd(fd,907),message); // Not a hexadecimal digit:
  354.                                                                         return false;
  355.                                                                 }
  356.                                                                 num=(ISDIGIT(*message)?*message-'0':TOLOWER(*message)-'a'+10);
  357.                                                                 if(ISXDIGIT(*message)){
  358.                                                                         ++message;
  359.                                                                         CHECK_EOS(message);
  360.                                                                         num<<=8;
  361.                                                                         num+=(ISDIGIT(*message)?*message-'0':TOLOWER(*message)-'a'+10);
  362.                                                                 }
  363.                                                                 WFIFOB(sd->fd,off)=TOB(num);
  364.                                                                 ++message;
  365.                                                                 CHECK_EOS(message);
  366.                                                                 continue;
  367.                                                         }
  368.                                                         case '0':
  369.                                                         case '1':
  370.                                                         case '2':
  371.                                                         case '3':
  372.                                                         case '4':
  373.                                                         case '5':
  374.                                                         case '6':
  375.                                                         case '7': // Octal
  376.                                                         {
  377.                                                                 num=*message-'0'; // 1st octal digit
  378.                                                                 ++message;
  379.                                                                 CHECK_EOS(message);
  380.                                                                 if(ISDIGIT(*message) && *message < '8'){
  381.                                                                         num<<=3;
  382.                                                                         num+=*message-'0'; // 2nd octal digit
  383.                                                                         ++message;
  384.                                                                         CHECK_EOS(message);
  385.                                                                         if(ISDIGIT(*message) && *message < '8'){
  386.                                                                                 num<<=3;
  387.                                                                                 num+=*message-'0'; // 3rd octal digit
  388.                                                                                 ++message;
  389.                                                                                 CHECK_EOS(message);
  390.                                                                         }
  391.                                                                 }
  392.                                                                 WFIFOB(sd->fd,off)=TOB(num);
  393.                                                                 continue;
  394.                                                         }
  395.                                                 }
  396.                                         } else
  397.                                                 num=*message;
  398.                                         WFIFOB(sd->fd,off)=TOB(num);
  399.                                         ++message;
  400.                                         CHECK_EOS(message);
  401.                                 }//for
  402.                                 while(*message != '"')
  403.                                 {// ignore extra characters
  404.                                         ++message;
  405.                                         CHECK_EOS(message);
  406.                                 }
  407.  
  408.                                 // terminate the string
  409.                                 if(off < end)
  410.                                 {// fill the rest with 0's
  411.                                         memset(WFIFOP(sd->fd,off),0,end-off);
  412.                                         off=end;
  413.                                 }
  414.                         } else
  415.                         {// unknown
  416.                                 PARSE_ERROR(msg_fd(fd,908),message); // Unknown type of value in:
  417.                                 return false;
  418.                         }
  419.                         SKIP_VALUE(message);
  420.                 }
  421.  
  422.                 if (clif->packet(type)->len == -1) { // send dynamic packet
  423.                         WFIFOW(sd->fd,2)=TOW(off);
  424.                         WFIFOSET(sd->fd,off);
  425.                 } else {// send static packet
  426.                         if(off < len)
  427.                                 memset(WFIFOP(sd->fd,off),0,len-off);
  428.                         WFIFOSET(sd->fd,len);
  429.                 }
  430.         } else {
  431.                 clif->message(fd, msg_fd(fd,259)); // Invalid packet
  432.                 return false;
  433.         }
  434.         sprintf (atcmd_output, msg_fd(fd,258), type, type); // Sent packet 0x%x (%d)
  435.         clif->message(fd, atcmd_output);
  436.         return true;
  437. #undef PARSE_ERROR
  438. #undef CHECK_EOS
  439. #undef SKIP_VALUE
  440. #undef GET_VALUE
  441. }
  442.  
  443. /*==========================================
  444.  * @rura, @warp, @mapmove
  445.  *------------------------------------------*/
  446. ACMD(mapmove) {
  447.         char map_name[MAP_NAME_LENGTH_EXT];
  448.         unsigned short map_index;
  449.         short x = 0, y = 0;
  450.         int16 m = -1;
  451.  
  452.         memset(map_name, '\0', sizeof(map_name));
  453.  
  454.         if (!*message ||
  455.                 (sscanf(message, "%15s %5hd %5hd", map_name, &x, &y) < 3 &&
  456.                  sscanf(message, "%15[^,],%5hd,%5hd", map_name, &x, &y) < 1)) {
  457.                         clif->message(fd, msg_fd(fd,909)); // Please enter a map (usage: @warp/@rura/@mapmove <mapname> <x> <y>).
  458.                         return false;
  459.                 }
  460.  
  461.         map_index = mapindex->name2id(map_name);
  462.         if (map_index)
  463.                 m = map->mapindex2mapid(map_index);
  464.  
  465.         if (!map_index || m < 0) { // m < 0 means on different server or that map is disabled! [Kevin]
  466.                 clif->message(fd, msg_fd(fd,1)); // Map not found.
  467.                 return false;
  468.         }
  469.  
  470.         if( sd->bl.m == m && sd->bl.x == x && sd->bl.y == y ) {
  471.                 clif->message(fd, msg_fd(fd,253)); // You already are at your destination!
  472.                 return false;
  473.         }
  474.  
  475.         if ((x || y) && map->getcell(m, &sd->bl, x, y, CELL_CHKNOPASS) && pc_get_group_level(sd) < battle_config.gm_ignore_warpable_area) {
  476.                 //This is to prevent the pc->setpos call from printing an error.
  477.                 clif->message(fd, msg_fd(fd,2));
  478.                 if (!map->search_freecell(NULL, m, &x, &y, 10, 10, 1))
  479.                         x = y = 0; //Invalid cell, use random spot.
  480.         }
  481.         if (map->list[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
  482.                 clif->message(fd, msg_fd(fd,247));
  483.                 return false;
  484.         }
  485.         if (sd->state.pvp || (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))) {
  486.                 clif->message(fd, msg_fd(fd,248));
  487.                 return false;
  488.         }
  489.         if (pc->setpos(sd, map_index, x, y, CLR_TELEPORT) != 0) {
  490.                 clif->message(fd, msg_fd(fd,1)); // Map not found.
  491.                 return false;
  492.         }
  493.  
  494.         clif->message(fd, msg_fd(fd,0)); // Warped.
  495.         return true;
  496. }
  497.  
  498. /*==========================================
  499.  * Displays where a character is. Corrected version by Silent. [Skotlex]
  500.  *------------------------------------------*/
  501. ACMD(where) {
  502.         struct map_session_data* pl_sd;
  503.  
  504.         memset(atcmd_player_name, '\0', sizeof atcmd_player_name);
  505.  
  506.         if (!*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
  507.                 clif->message(fd, msg_fd(fd,910)); // Please enter a player name (usage: @where <char name>).
  508.                 return false;
  509.         }
  510.  
  511.         pl_sd = map->nick2sd(atcmd_player_name);
  512.         if (pl_sd == NULL ||
  513.             strncmp(pl_sd->status.name, atcmd_player_name, NAME_LENGTH) != 0 ||
  514.             (pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) && pc_get_group_level(pl_sd) > pc_get_group_level(sd) && !pc_has_permission(sd, PC_PERM_WHO_DISPLAY_AID))
  515.                 ) {
  516.                 clif->message(fd, msg_fd(fd,3)); // Character not found.
  517.                 return false;
  518.         }
  519.  
  520.         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);
  521.         clif->message(fd, atcmd_output);
  522.  
  523.         return true;
  524. }
  525.  
  526. /*==========================================
  527.  *
  528.  *------------------------------------------*/
  529. ACMD(jumpto) {
  530.         struct map_session_data *pl_sd = NULL;
  531.  
  532.         if (!*message) {
  533.                 clif->message(fd, msg_fd(fd,911)); // Please enter a player name (usage: @jumpto/@warpto/@goto <char name/ID>).
  534.                 return false;
  535.         }
  536.  
  537.         if (sd->state.pvp || (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))) {
  538.                 clif->message(fd, msg_fd(fd,248)); // You are not authorized to warp from your current map.
  539.                 return false;
  540.         }
  541.  
  542.         if( pc_isdead(sd) ) {
  543.                 clif->message(fd, msg_fd(fd,864)); // "You cannot use this command when dead."
  544.                 return false;
  545.         }
  546.  
  547.         if((pl_sd=map->nick2sd((char *)message)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) {
  548.                 clif->message(fd, msg_fd(fd,3)); // Character not found.
  549.                 return false;
  550.         }
  551.  
  552.         if (sd->state.pvp && (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))) {
  553.                 clif->message(fd, msg_fd(fd,247)); // You are not authorized to warp to this map.
  554.                 return false;
  555.         }
  556.  
  557.         if( pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y ) {
  558.                 clif->message(fd, msg_fd(fd,253)); // You already are at your destination!
  559.                 return false;
  560.         }
  561.  
  562.         pc->setpos(sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT);
  563.         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,4), pl_sd->status.name); // Jumped to %s
  564.         clif->message(fd, atcmd_output);
  565.  
  566.         return true;
  567. }
  568.  
  569. /*==========================================
  570.  *
  571.  *------------------------------------------*/
  572. ACMD(jump)
  573. {
  574.         short x = 0, y = 0;
  575.  
  576.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  577.  
  578.         sscanf(message, "%5hd %5hd", &x, &y);
  579.  
  580.         if (sd->state.pvp && (map->list[sd->bl.m].flag.noteleport && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))) {
  581.                 clif->message(fd, msg_fd(fd,248)); // You are not authorized to warp from your current map.
  582.                 return false;
  583.         }
  584.  
  585.         if( pc_isdead(sd) ) {
  586.                 clif->message(fd, msg_fd(fd,864)); // "You cannot use this command when dead."
  587.                 return false;
  588.         }
  589.  
  590.         if ((x || y) && map->getcell(sd->bl.m, &sd->bl, x, y, CELL_CHKNOPASS)) {
  591.                 //This is to prevent the pc->setpos call from printing an error.
  592.                 clif->message(fd, msg_fd(fd,2));
  593.                 if (!map->search_freecell(NULL, sd->bl.m, &x, &y, 10, 10, 1))
  594.                         x = y = 0; //Invalid cell, use random spot.
  595.         }
  596.  
  597.         if (x && y && sd->bl.x == x && sd->bl.y == y) {
  598.                 clif->message(fd, msg_fd(fd,253)); // You already are at your destination!
  599.                 return false;
  600.         }
  601.  
  602.         pc->setpos(sd, sd->mapindex, x, y, CLR_TELEPORT);
  603.         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,5), sd->bl.x, sd->bl.y); // Jumped to %d %d
  604.         clif->message(fd, atcmd_output);
  605.         return true;
  606. }
  607.  
  608. /*==========================================
  609.  * Display list of online characters with
  610.  * various info.
  611.  *------------------------------------------*/
  612. ACMD(who) {
  613.         const struct map_session_data *pl_sd = NULL;
  614.         struct s_mapiterator *iter = NULL;
  615.         char player_name[NAME_LENGTH] = "";
  616.         int count = 0;
  617.         int level = 0;
  618.         StringBuf buf;
  619.         /**
  620.          * 1 = @who  : Player name, [Title], [Party name], [Guild name]
  621.          * 2 = @who2 : Player name, [Title], BLvl, JLvl, Job
  622.          * 3 = @who3 : [CID/AID] Player name [Title], Map, X, Y
  623.          */
  624.         int display_type = 1;
  625.         int map_id = -1;
  626.  
  627.         if (stristr(info->command, "map") != NULL) {
  628.                 char map_name[MAP_NAME_LENGTH_EXT] = "";
  629.                 if (sscanf(message, "%15s %23s", map_name, player_name) < 1 || (map_id = map->mapname2mapid(map_name)) < 0)
  630.                         map_id = sd->bl.m;
  631.         } else {
  632.                 sscanf(message, "%23s", player_name);
  633.         }
  634.  
  635.         if (stristr(info->command, "2") != NULL)
  636.                 display_type = 2;
  637.         else if (stristr(info->command, "3") != NULL)
  638.                 display_type = 3;
  639.  
  640.         level = pc_get_group_level(sd);
  641.         StrBuf->Init(&buf);
  642.  
  643.         iter = mapit_getallusers();
  644.         for (pl_sd = BL_UCCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCCAST(BL_PC, mapit->next(iter))) {
  645.                 if (!((pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) || pc_isinvisible(pl_sd)) && pc_get_group_level(pl_sd) > level)) { // you can look only lower or same level
  646.                         if (stristr(pl_sd->status.name, player_name) == NULL // search with no case sensitive
  647.                                 || (map_id >= 0 && pl_sd->bl.m != map_id))
  648.                                 continue;
  649.                         switch (display_type) {
  650.                                 case 2: {
  651.                                         StrBuf->Printf(&buf, msg_fd(fd,343), pl_sd->status.name); // "Name: %s "
  652.                                         if (pc_get_group_id(pl_sd) > 0) // Player title, if exists
  653.                                                 StrBuf->Printf(&buf, msg_fd(fd,344), pcg->get_name(pl_sd->group)); // "(%s) "
  654.                                         StrBuf->Printf(&buf, msg_fd(fd,347), pl_sd->status.base_level, pl_sd->status.job_level,
  655.                                                                          pc->job_name(pl_sd->status.class_)); // "| Lv:%d/%d | Job: %s"
  656.                                         break;
  657.                                 }
  658.                                 case 3: {
  659.                                         if (pc_has_permission(sd, PC_PERM_WHO_DISPLAY_AID))
  660.                                                 StrBuf->Printf(&buf, msg_fd(fd,912), pl_sd->status.char_id, pl_sd->status.account_id); // "(CID:%d/AID:%d) "
  661.                                         StrBuf->Printf(&buf, msg_fd(fd,343), pl_sd->status.name); // "Name: %s "
  662.                                         if (pc_get_group_id(pl_sd) > 0) // Player title, if exists
  663.                                                 StrBuf->Printf(&buf, msg_fd(fd,344), pcg->get_name(pl_sd->group)); // "(%s) "
  664.                                         StrBuf->Printf(&buf, msg_fd(fd,348), mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y); // "| Location: %s %d %d"
  665.                                         break;
  666.                                 }
  667.                                 default: {
  668.                                         struct party_data *p = party->search(pl_sd->status.party_id);
  669.                                         struct guild *g = pl_sd->guild;
  670.  
  671.                                         StrBuf->Printf(&buf, msg_fd(fd,343), pl_sd->status.name); // "Name: %s "
  672.                                         if (pc_get_group_id(pl_sd) > 0) // Player title, if exists
  673.                                                 StrBuf->Printf(&buf, msg_fd(fd,344), pcg->get_name(pl_sd->group)); // "(%s) "
  674.                                         if (p != NULL)
  675.                                                 StrBuf->Printf(&buf, msg_fd(fd,345), p->party.name); // " | Party: '%s'"
  676.                                         if (g != NULL)
  677.                                                 StrBuf->Printf(&buf, msg_fd(fd,346), g->name); // " | Guild: '%s'"
  678.                                         break;
  679.                                 }
  680.                         }
  681.                         clif->messagecolor_self(fd, COLOR_DEFAULT, StrBuf->Value(&buf));/** for whatever reason clif->message crashes with some patterns, see bugreport:8186 **/
  682.                         StrBuf->Clear(&buf);
  683.                         count++;
  684.                 }
  685.         }
  686.         mapit->free(iter);
  687.  
  688.         if (map_id < 0) {
  689.                 if (count == 0)
  690.                         StrBuf->AppendStr(&buf, msg_fd(fd,28)); // No player found.
  691.                 else if (count == 1)
  692.                         StrBuf->AppendStr(&buf, msg_fd(fd,29)); // 1 player found.
  693.                 else
  694.                         StrBuf->Printf(&buf, msg_fd(fd,30), count); // %d players found.
  695.         } else {
  696.                 if (count == 0)
  697.                         StrBuf->Printf(&buf, msg_fd(fd,54), map->list[map_id].name); // No player found in map '%s'.
  698.                 else if (count == 1)
  699.                         StrBuf->Printf(&buf, msg_fd(fd,55), map->list[map_id].name); // 1 player found in map '%s'.
  700.                 else
  701.                         StrBuf->Printf(&buf, msg_fd(fd,56), count, map->list[map_id].name); // %d players found in map '%s'.
  702.         }
  703.         clif->message(fd, StrBuf->Value(&buf));
  704.         StrBuf->Destroy(&buf);
  705.         return true;
  706. }
  707.  
  708. /*==========================================
  709.  *
  710.  *------------------------------------------*/
  711. ACMD(whogm)
  712. {
  713.         const struct map_session_data *pl_sd;
  714.         struct s_mapiterator* iter;
  715.         int j, count;
  716.         int level;
  717.         char match_text[CHAT_SIZE_MAX];
  718.         char player_name[NAME_LENGTH];
  719.         struct guild *g;
  720.         struct party_data *p;
  721.  
  722.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  723.         memset(match_text, '\0', sizeof(match_text));
  724.         memset(player_name, '\0', sizeof(player_name));
  725.  
  726.         if (sscanf(message, "%199[^\n]", match_text) < 1)
  727.                 strcpy(match_text, "");
  728.         for (j = 0; match_text[j]; j++)
  729.                 match_text[j] = TOLOWER(match_text[j]);
  730.  
  731.         count = 0;
  732.         level = pc_get_group_level(sd);
  733.  
  734.         iter = mapit_getallusers();
  735.         for (pl_sd = BL_UCCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCCAST(BL_PC, mapit->next(iter))) {
  736.                 int pl_level = pc_get_group_level(pl_sd);
  737.                 if (!pl_level)
  738.                         continue;
  739.  
  740.                 if (match_text[0]) {
  741.                         memcpy(player_name, pl_sd->status.name, NAME_LENGTH);
  742.                         for (j = 0; player_name[j]; j++)
  743.                                 player_name[j] = TOLOWER(player_name[j]);
  744.                         // search with no case sensitive
  745.                         if (strstr(player_name, match_text) == NULL)
  746.                                 continue;
  747.                 }
  748.                 if (pl_level > level) {
  749.                         if (pc_isinvisible(pl_sd))
  750.                                 continue;
  751.                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,913), pl_sd->status.name); // Name: %s (GM)
  752.                         clif->message(fd, atcmd_output);
  753.                         count++;
  754.                         continue;
  755.                 }
  756.  
  757.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,914), // Name: %s (GM:%d) | Location: %s %d %d
  758.                                 pl_sd->status.name, pl_level,
  759.                                 mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y);
  760.                 clif->message(fd, atcmd_output);
  761.  
  762.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,915), // BLvl: %d | Job: %s (Lvl: %d)
  763.                                 pl_sd->status.base_level,
  764.                                 pc->job_name(pl_sd->status.class_), pl_sd->status.job_level);
  765.                 clif->message(fd, atcmd_output);
  766.  
  767.                 p = party->search(pl_sd->status.party_id);
  768.                 g = pl_sd->guild;
  769.  
  770.                 safesnprintf(atcmd_output, sizeof(atcmd_output),msg_fd(fd,916), // Party: '%s' | Guild: '%s'
  771.                                 p?p->party.name:msg_fd(fd,917), g?g->name:msg_fd(fd,917)); // None.
  772.  
  773.                 clif->message(fd, atcmd_output);
  774.                 count++;
  775.         }
  776.         mapit->free(iter);
  777.  
  778.         if (count == 0)
  779.                 clif->message(fd, msg_fd(fd,150)); // No GM found.
  780.         else if (count == 1)
  781.                 clif->message(fd, msg_fd(fd,151)); // 1 GM found.
  782.         else {
  783.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,152), count); // %d GMs found.
  784.                 clif->message(fd, atcmd_output);
  785.         }
  786.  
  787.         return true;
  788. }
  789.  
  790. /*==========================================
  791.  *
  792.  *------------------------------------------*/
  793. ACMD(save)
  794. {
  795.         pc->setsavepoint(sd, sd->mapindex, sd->bl.x, sd->bl.y);
  796.         if (sd->status.pet_id > 0 && sd->pd)
  797.                 intif->save_petdata(sd->status.account_id, &sd->pd->pet);
  798.  
  799.         chrif->save(sd,0);
  800.  
  801.         clif->message(fd, msg_fd(fd,6)); // Your save point has been changed.
  802.  
  803.         return true;
  804. }
  805.  
  806. /*==========================================
  807.  *
  808.  *------------------------------------------*/
  809. ACMD(load) {
  810.         int16 m;
  811.  
  812.         m = map->mapindex2mapid(sd->status.save_point.map);
  813.         if (m >= 0 && map->list[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
  814.                 clif->message(fd, msg_fd(fd,249)); // You are not authorized to warp to your save map.
  815.                 return false;
  816.         }
  817.         if (sd->state.pvp || (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))) {
  818.                 clif->message(fd, msg_fd(fd,248)); // You are not authorized to warp from your current map.
  819.                 return false;
  820.         }
  821.  
  822.         pc->setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT);
  823.         clif->message(fd, msg_fd(fd,7)); // Warping to save point..
  824.  
  825.         return true;
  826. }
  827.  
  828. /*==========================================
  829.  *
  830.  *------------------------------------------*/
  831. ACMD(speed)
  832. {
  833.         int speed;
  834.  
  835.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  836.  
  837.         if (!*message || sscanf(message, "%12d", &speed) < 1) {
  838.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,918), MIN_WALK_SPEED, MAX_WALK_SPEED); // Please enter a speed value (usage: @speed <%d-%d>).
  839.                 clif->message(fd, atcmd_output);
  840.                 return false;
  841.         }
  842.  
  843.         sd->state.permanent_speed = 0;
  844.  
  845.         if (speed < 0)
  846.                 sd->base_status.speed = DEFAULT_WALK_SPEED;
  847.         else
  848.                 sd->base_status.speed = cap_value(speed, MIN_WALK_SPEED, MAX_WALK_SPEED);
  849.  
  850.         if( sd->base_status.speed != DEFAULT_WALK_SPEED ) {
  851.                 sd->state.permanent_speed = 1; // Set lock when set to non-default speed.
  852.                 clif->message(fd, msg_fd(fd,8)); // Speed changed.
  853.         } else
  854.                 clif->message(fd, msg_fd(fd,172)); //Speed returned to normal.
  855.  
  856.         status_calc_bl(&sd->bl, SCB_SPEED);
  857.  
  858.         return true;
  859. }
  860.  
  861. /*==========================================
  862.  *
  863.  *------------------------------------------*/
  864. ACMD(storage)
  865. {
  866.         if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading || sd->state.storage_flag)
  867.                 return false;
  868.  
  869.         if (storage->open(sd) == 1) { //Already open.
  870.                 clif->message(fd, msg_fd(fd,250));
  871.                 return false;
  872.         }
  873.  
  874.         clif->message(fd, msg_fd(fd,919)); // Storage opened.
  875.  
  876.         return true;
  877. }
  878.  
  879. /*==========================================
  880.  *
  881.  *------------------------------------------*/
  882. ACMD(guildstorage)
  883. {
  884.         if (!sd->status.guild_id) {
  885.                 clif->message(fd, msg_fd(fd,252));
  886.                 return false;
  887.         }
  888.  
  889.         if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading)
  890.                 return false;
  891.  
  892.         if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) {
  893.                 clif->message(fd, msg_fd(fd,250));
  894.                 return false;
  895.         }
  896.  
  897.         if (sd->state.storage_flag == STORAGE_FLAG_GUILD) {
  898.                 clif->message(fd, msg_fd(fd,251));
  899.                 return false;
  900.         }
  901.  
  902.         if( gstorage->open(sd) ) {
  903.                 clif->message(fd, msg_fd(fd,1201)); // Your guild's storage has already been opened by another member, try again later.
  904.                 return false;
  905.         }
  906.  
  907.         clif->message(fd, msg_fd(fd,920)); // Guild storage opened.
  908.         return true;
  909. }
  910.  
  911. /*==========================================
  912.  *
  913.  *------------------------------------------*/
  914. ACMD(option)
  915. {
  916.         int param1 = 0, param2 = 0, param3 = 0;
  917.  
  918.         if (!*message || sscanf(message, "%12d %12d %12d", &param1, &param2, &param3) < 1 || param1 < 0 || param2 < 0 || param3 < 0)
  919.         {// failed to match the parameters so inform the user of the options
  920.                 const char* text;
  921.  
  922.                 // attempt to find the setting information for this command
  923.                 text = atcommand_help_string( info );
  924.  
  925.                 // notify the user of the requirement to enter an option
  926.                 clif->message(fd, msg_fd(fd,921)); // Please enter at least one option.
  927.  
  928.                 if( text ) {// send the help text associated with this command
  929.                         clif->messageln( fd, text );
  930.                 }
  931.  
  932.                 return false;
  933.         }
  934.  
  935.         sd->sc.opt1 = param1;
  936.         sd->sc.opt2 = param2;
  937.         pc->setoption(sd, param3);
  938.  
  939.         clif->message(fd, msg_fd(fd,9)); // Options changed.
  940.  
  941.         return true;
  942. }
  943.  
  944. /*==========================================
  945.  *
  946.  *------------------------------------------*/
  947. ACMD(hide) {
  948.         if (pc_isinvisible(sd)) {
  949.                 sd->sc.option &= ~OPTION_INVISIBLE;
  950.                 if (sd->disguise != -1 )
  951.                         status->set_viewdata(&sd->bl, sd->disguise);
  952.                 else
  953.                         status->set_viewdata(&sd->bl, sd->status.class_);
  954.                 clif->message(fd, msg_fd(fd,10)); // Invisible: Off
  955.  
  956.                 // increment the number of pvp players on the map
  957.                 map->list[sd->bl.m].users_pvp++;
  958.  
  959.                 if( map->list[sd->bl.m].flag.pvp && !map->list[sd->bl.m].flag.pvp_nocalcrank ) {
  960.                         // register the player for ranking calculations
  961.                         sd->pvp_timer = timer->add( timer->gettick() + 200, pc->calc_pvprank_timer, sd->bl.id, 0 );
  962.                 }
  963.                 //bugreport:2266
  964.                 map->foreachinmovearea(clif->insight, &sd->bl, AREA_SIZE, sd->bl.x, sd->bl.y, BL_ALL, &sd->bl);
  965.         } else {
  966.                 sd->sc.option |= OPTION_INVISIBLE;
  967.                 sd->vd.class_ = INVISIBLE_CLASS;
  968.                 clif->message(fd, msg_fd(fd,11)); // Invisible: On
  969.  
  970.                 // decrement the number of pvp players on the map
  971.                 map->list[sd->bl.m].users_pvp--;
  972.  
  973.                 if( map->list[sd->bl.m].flag.pvp && !map->list[sd->bl.m].flag.pvp_nocalcrank && sd->pvp_timer != INVALID_TIMER ) {
  974.                         // unregister the player for ranking
  975.                         timer->delete( sd->pvp_timer, pc->calc_pvprank_timer );
  976.                         sd->pvp_timer = INVALID_TIMER;
  977.                 }
  978.         }
  979.         clif->changeoption(&sd->bl);
  980.  
  981.         return true;
  982. }
  983.  
  984. /*==========================================
  985.  * Changes a character's class
  986.  *------------------------------------------*/
  987. ACMD(jobchange)
  988. {
  989.         int job = 0, upper = 0;
  990.         bool found = false;
  991.  
  992.         if (*message == '\0') { // No message, just show the list
  993.                 found = false;
  994.         } else if (sscanf(message, "%12d %12d", &job, &upper) >= 1) { // Numeric job ID
  995.                 found = true;
  996.         } else { // Job name
  997.                 int i;
  998.  
  999.                 // Normal Jobs
  1000.                 for (i = JOB_NOVICE; !found && i < JOB_MAX_BASIC; i++) {
  1001.                         if (strncmpi(message, pc->job_name(i), 16) == 0) {
  1002.                                 job = i;
  1003.                                 found = true;
  1004.                                 break;
  1005.                         }
  1006.                 }
  1007.  
  1008.                 // High Jobs, Babies and Third
  1009.                 for (i = JOB_NOVICE_HIGH; !found && i < JOB_MAX; i++) {
  1010.                         if (strncmpi(message, pc->job_name(i), 16) == 0) {
  1011.                                 job = i;
  1012.                                 found = true;
  1013.                                 break;
  1014.                         }
  1015.                 }
  1016.         }
  1017.  
  1018.         if (!found || !pc->db_checkid(job)) {
  1019.                 const char *text = atcommand_help_string(info);
  1020.                 if (text)
  1021.                         clif->messageln(fd, text);
  1022.                 return false;
  1023.         }
  1024.  
  1025.         // Deny direct transformation into dummy jobs
  1026.         if (job == JOB_KNIGHT2 || job == JOB_CRUSADER2
  1027.          || job == JOB_WEDDING || job == JOB_XMAS || job == JOB_SUMMER
  1028.          || job == JOB_LORD_KNIGHT2 || job == JOB_PALADIN2
  1029.          || job == JOB_BABY_KNIGHT2 || job == JOB_BABY_CRUSADER2
  1030.          || job == JOB_STAR_GLADIATOR2
  1031.          || (job >= JOB_RUNE_KNIGHT2 && job <= JOB_MECHANIC_T2)
  1032.          || (job >= JOB_BABY_RUNE2 && job <= JOB_BABY_MECHANIC2)
  1033.         ) {
  1034.                 /* WHY DO WE LIST THEM THEN? */
  1035.                 clif->message(fd, msg_fd(fd,923)); //"You can not change to this job by command."
  1036.                 return true;
  1037.         }
  1038.  
  1039.         if (pc->jobchange(sd, job, upper) != 0) {
  1040.                 clif->message(fd, msg_fd(fd,155)); // You are unable to change your job.
  1041.                 return false;
  1042.         }
  1043.  
  1044.         clif->message(fd, msg_fd(fd,12)); // Your job has been changed.
  1045.         return true;
  1046. }
  1047.  
  1048. /*==========================================
  1049.  *
  1050.  *------------------------------------------*/
  1051. ACMD(kill)
  1052. {
  1053.         status_kill(&sd->bl);
  1054.         clif->message(sd->fd, msg_fd(fd,13)); // A pity! You've died.
  1055.         if (fd != sd->fd)
  1056.                 clif->message(fd, msg_fd(fd,14)); // Character killed.
  1057.         return true;
  1058. }
  1059.  
  1060. /*==========================================
  1061.  *
  1062.  *------------------------------------------*/
  1063. ACMD(alive)
  1064. {
  1065.         if (!status->revive(&sd->bl, 100, 100)) {
  1066.                 clif->message(fd, msg_fd(fd,867)); // "You're not dead."
  1067.                 return false;
  1068.         }
  1069.         clif->skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1);
  1070.         clif->message(fd, msg_fd(fd,16)); // You've been revived! It's a miracle!
  1071.         return true;
  1072. }
  1073.  
  1074. /*==========================================
  1075.  * +kamic [LuzZza]
  1076.  *------------------------------------------*/
  1077. ACMD(kami)
  1078. {
  1079.         unsigned int color=0;
  1080.  
  1081.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  1082.  
  1083.         if(*(info->command + 4) != 'c' && *(info->command + 4) != 'C') {
  1084.                 if (!*message) {
  1085.                         clif->message(fd, msg_fd(fd,980)); // Please enter a message (usage: @kami <message>).
  1086.                         return false;
  1087.                 }
  1088.  
  1089.                 sscanf(message, "%199[^\n]", atcmd_output);
  1090.                 if (stristr(info->command, "l") != NULL)
  1091.                         clif->broadcast(&sd->bl, atcmd_output, (int)strlen(atcmd_output) + 1, BC_DEFAULT, ALL_SAMEMAP);
  1092.                 else
  1093.                         intif->broadcast(atcmd_output, (int)strlen(atcmd_output) + 1, (*(info->command + 4) == 'b' || *(info->command + 4) == 'B') ? BC_BLUE : BC_YELLOW);
  1094.         } else {
  1095.                 if(!*message || (sscanf(message, "%10u %199[^\n]", &color, atcmd_output) < 2)) {
  1096.                         clif->message(fd, msg_fd(fd,981)); // Please enter color and message (usage: @kamic <color> <message>).
  1097.                         return false;
  1098.                 }
  1099.  
  1100.                 if(color > 0xFFFFFF) {
  1101.                         clif->message(fd, msg_fd(fd,982)); // Invalid color.
  1102.                         return false;
  1103.                 }
  1104.                 intif->broadcast2(atcmd_output, (int)strlen(atcmd_output) + 1, color, 0x190, 12, 0, 0);
  1105.         }
  1106.         return true;
  1107. }
  1108.  
  1109. /*==========================================
  1110.  *
  1111.  *------------------------------------------*/
  1112. ACMD(heal)
  1113. {
  1114.         int hp = 0, sp = 0; // [Valaris] thanks to fov
  1115.  
  1116.         sscanf(message, "%12d %12d", &hp, &sp);
  1117.  
  1118.         // some overflow checks
  1119.         if( hp == INT_MIN ) hp++;
  1120.         if( sp == INT_MIN ) sp++;
  1121.  
  1122.         if ( hp == 0 && sp == 0 ) {
  1123.                 if (!status_percent_heal(&sd->bl, 100, 100))
  1124.                         clif->message(fd, msg_fd(fd,157)); // HP and SP have already been recovered.
  1125.                 else
  1126.                         clif->message(fd, msg_fd(fd,17)); // HP, SP recovered.
  1127.                 return true;
  1128.         }
  1129.  
  1130.         if ( hp > 0 && sp >= 0 ) {
  1131.                 if(!status->heal(&sd->bl, hp, sp, 0))
  1132.                         clif->message(fd, msg_fd(fd,157)); // HP and SP are already with the good value.
  1133.                 else
  1134.                         clif->message(fd, msg_fd(fd,17)); // HP, SP recovered.
  1135.                 return true;
  1136.         }
  1137.  
  1138.         if ( hp < 0 && sp <= 0 ) {
  1139.                 status->damage(NULL, &sd->bl, -hp, -sp, 0, 0);
  1140.                 clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, BDT_ENDURE, 0);
  1141.                 clif->message(fd, msg_fd(fd,156)); // HP or/and SP modified.
  1142.                 return true;
  1143.         }
  1144.  
  1145.         //Opposing signs.
  1146.         if ( hp ) {
  1147.                 if (hp > 0)
  1148.                         status->heal(&sd->bl, hp, 0, 0);
  1149.                 else {
  1150.                         status->damage(NULL, &sd->bl, -hp, 0, 0, 0);
  1151.                         clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, BDT_ENDURE, 0);
  1152.                 }
  1153.         }
  1154.  
  1155.         if ( sp ) {
  1156.                 if (sp > 0)
  1157.                         status->heal(&sd->bl, 0, sp, 0);
  1158.                 else
  1159.                         status->damage(NULL, &sd->bl, 0, -sp, 0, 0);
  1160.         }
  1161.  
  1162.         clif->message(fd, msg_fd(fd,156)); // HP or/and SP modified.
  1163.         return true;
  1164. }
  1165.  
  1166. /*==========================================
  1167.  * @item command (usage: @item <name/id_of_item> <quantity>) (modified by [Yor] for pet_egg)
  1168.  * @itembound command (usage: @itembound <name/id_of_item> <quantity> <bound type>) (revised by [Mhalicot])
  1169.  *------------------------------------------*/
  1170. ACMD(item)
  1171. {
  1172.         char item_name[100];
  1173.         int number = 0, item_id, flag = 0, bound = 0, costume = 0;
  1174.         struct item item_tmp;
  1175.         struct item_data *item_data;
  1176.         int get_count, i;
  1177.  
  1178.         memset(item_name, '\0', sizeof(item_name));
  1179.  
  1180.         if (!strcmpi(info->command,"itembound") && (!*message || (
  1181.                 sscanf(message, "\"%99[^\"]\" %12d %12d", item_name, &number, &bound) < 2 &&
  1182.                 sscanf(message, "%99s %12d %12d", item_name, &number, &bound) < 2
  1183.         ))) {
  1184.                 clif->message(fd, msg_fd(fd,295)); // Please enter an item name or ID (usage: @itembound <item name/ID> <quantity> <bound_type>).
  1185.                 return false;
  1186.         } else if (!*message
  1187.                || ( sscanf(message, "\"%99[^\"]\" %12d", item_name, &number) < 1
  1188.                  && sscanf(message, "%99s %12d", item_name, &number) < 1
  1189.         )) {
  1190.                 clif->message(fd, msg_fd(fd,983)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity>).
  1191.                 return false;
  1192.         }
  1193.  
  1194.         if (number <= 0)
  1195.                 number = 1;
  1196.  
  1197.         if ((item_data = itemdb->search_name(item_name)) == NULL &&
  1198.             (item_data = itemdb->exists(atoi(item_name))) == NULL)
  1199.         {
  1200.                 clif->message(fd, msg_fd(fd,19)); // Invalid item ID or name.
  1201.                 return false;
  1202.         }
  1203.  
  1204.         if(!strcmpi(info->command,"itembound") ) {
  1205.                 if( !(bound >= IBT_MIN && bound <= IBT_MAX) ) {
  1206.                         clif->message(fd, msg_fd(fd,298)); // Invalid bound type
  1207.                         return false;
  1208.                 }
  1209.                 switch( (enum e_item_bound_type)bound ) {
  1210.                         case IBT_CHARACTER:
  1211.                         case IBT_ACCOUNT:
  1212.                                 break; /* no restrictions */
  1213.                         case IBT_PARTY:
  1214.                                 if( !sd->status.party_id ) {
  1215.                                         clif->message(fd, msg_fd(fd,1498)); //You can't add a party bound item to a character without party!
  1216.                                         return false;
  1217.                                 }
  1218.                                 break;
  1219.                         case IBT_GUILD:
  1220.                                 if( !sd->status.guild_id ) {
  1221.                                         clif->message(fd, msg_fd(fd,1499)); //You can't add a guild bound item to a character without guild!
  1222.                                         return false;
  1223.                                 }
  1224.                                 break;
  1225.                 }
  1226.         }
  1227.  
  1228.         if( !strcmpi(info->command,"costumeitem") ) {
  1229.                 if( !battle_config.reserved_costume_id ) {
  1230.                         clif->message(fd, "A conversão visual está desabilitada. Defina um valor para a variável reserved_costume_id no arquivo battle/items.conf");
  1231.                         return -1;
  1232.                 }
  1233.                 if( !(item_data->equip&EQP_HEAD_LOW) &&
  1234.                         !(item_data->equip&EQP_HEAD_MID) &&
  1235.                         !(item_data->equip&EQP_HEAD_TOP) &&
  1236.                         !(item_data->equip&EQP_COSTUME_HEAD_LOW) &&
  1237.                         !(item_data->equip&EQP_COSTUME_HEAD_MID) &&
  1238.                         !(item_data->equip&EQP_COSTUME_HEAD_TOP) )
  1239.                 {
  1240.                         clif->message(fd, "Você não pode converter este item. A conversão visual só pode ser feita em chapéus.");
  1241.                         return -1;
  1242.                 }
  1243.                 costume = 1;
  1244.         }
  1245.  
  1246.         item_id = item_data->nameid;
  1247.         get_count = number;
  1248.         //Check if it's stackable.
  1249.         if (!itemdb->isstackable2(item_data)) {
  1250.                 if( bound && (item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) ) {
  1251.                         clif->message(fd, msg_fd(fd,498)); // Cannot create bounded pet eggs or pet armors.
  1252.                         return false;
  1253.                 }
  1254.                 get_count = 1;
  1255.         }
  1256.  
  1257.         for (i = 0; i < number; i += get_count) {
  1258.                 // if not pet egg
  1259.                 if (!pet->create_egg(sd, item_id)) {
  1260.                         memset(&item_tmp, 0, sizeof(item_tmp));
  1261.                         item_tmp.nameid = item_id;
  1262.                         item_tmp.identify = 1;
  1263.                         item_tmp.bound = (unsigned char)bound;
  1264.  
  1265.                         if( costume == 1 ) { // Costume Item
  1266.                                 item_tmp.card[0] = CARD0_CREATE;
  1267.                                 item_tmp.card[2] = GetWord(battle_config.reserved_costume_id, 0);
  1268.                                 item_tmp.card[3] = GetWord(battle_config.reserved_costume_id, 1);
  1269.                         }
  1270.  
  1271.                         if ((flag = pc->additem(sd, &item_tmp, get_count)))
  1272.                                 clif->additem(sd, 0, 0, flag);
  1273.                         else logs->item_getrem(1, sd, &item_tmp, get_count, "Cmd");
  1274.                 }
  1275.         }
  1276.  
  1277.         if (flag == 0)
  1278.                 clif->message(fd, msg_fd(fd,18)); // Item created.
  1279.         return true;
  1280. }
  1281.  
  1282. /*==========================================
  1283.  * @item2 and @itembound2 command (revised by [Mhalicot])
  1284.  *------------------------------------------*/
  1285. ACMD(item2)
  1286. {
  1287.         struct item item_tmp;
  1288.         struct item_data *item_data;
  1289.         char item_name[100];
  1290.         int item_id, number = 0, bound = 0;
  1291.         int identify = 0, refine = 0, attr = 0;
  1292.         int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
  1293.  
  1294.         memset(item_name, '\0', sizeof(item_name));
  1295.  
  1296.         if (!strcmpi(info->command,"itembound2") && (!*message || (
  1297.                 sscanf(message, "\"%99[^\"]\" %12d %12d %12d %12d %12d %12d %12d %12d %12d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 &&
  1298.                 sscanf(message, "%99s %12d %12d %12d %12d %12d %12d %12d %12d %12d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 ))) {
  1299.                 clif->message(fd, msg_fd(fd,296)); // Please enter all parameters (usage: @itembound2 <item name/ID> <quantity>
  1300.                 clif->message(fd, msg_fd(fd,297)); //   <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4> <bound_type>).
  1301.                 return false;
  1302.         } else if (!*message
  1303.                  || ( sscanf(message, "\"%99[^\"]\" %12d %12d %12d %12d %12d %12d %12d %12d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9
  1304.                    && sscanf(message, "%99s %12d %12d %12d %12d %12d %12d %12d %12d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9
  1305.         )) {
  1306.                 clif->message(fd, msg_fd(fd,984)); // Please enter all parameters (usage: @item2 <item name/ID> <quantity>
  1307.                 clif->message(fd, msg_fd(fd,985)); //   <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4>).
  1308.                 return false;
  1309.         }
  1310.  
  1311.         if (number <= 0)
  1312.                 number = 1;
  1313.  
  1314.         if( !strcmpi(info->command,"itembound2") && !(bound >= IBT_MIN && bound <= IBT_MAX) ) {
  1315.                 clif->message(fd, msg_fd(fd,298)); // Invalid bound type
  1316.                 return false;
  1317.         }
  1318.  
  1319.         item_id = 0;
  1320.         if ((item_data = itemdb->search_name(item_name)) != NULL ||
  1321.             (item_data = itemdb->exists(atoi(item_name))) != NULL)
  1322.                 item_id = item_data->nameid;
  1323.  
  1324.         if (item_id > 500) {
  1325.                 int flag = 0;
  1326.                 int loop, get_count, i;
  1327.                 loop = 1;
  1328.                 get_count = number;
  1329.                 if( !strcmpi(info->command,"itembound2") )
  1330.                         bound = 1;
  1331.                 if( !itemdb->isstackable2(item_data) ) {
  1332.                         if( bound && (item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) ) {
  1333.                                 clif->message(fd, msg_fd(fd,498)); // Cannot create bounded pet eggs or pet armors.
  1334.                                 return false;
  1335.                         }
  1336.                         loop = number;
  1337.                         get_count = 1;
  1338.                         if (item_data->type == IT_PETEGG) {
  1339.                                 identify = 1;
  1340.                                 refine = 0;
  1341.                         }
  1342.                         if (item_data->type == IT_PETARMOR)
  1343.                                 refine = 0;
  1344.                 } else {
  1345.                         identify = 1;
  1346.                         refine = attr = 0;
  1347.                 }
  1348.                 refine = cap_value(refine, 0, MAX_REFINE);
  1349.                 for (i = 0; i < loop; i++) {
  1350.                         memset(&item_tmp, 0, sizeof(item_tmp));
  1351.                         item_tmp.nameid = item_id;
  1352.                         item_tmp.identify = identify;
  1353.                         item_tmp.refine = refine;
  1354.                         item_tmp.attribute = attr;
  1355.                         item_tmp.bound = (unsigned char)bound;
  1356.                         item_tmp.card[0] = c1;
  1357.                         item_tmp.card[1] = c2;
  1358.                         item_tmp.card[2] = c3;
  1359.                         item_tmp.card[3] = c4;
  1360.  
  1361.                         if ((flag = pc->additem(sd, &item_tmp, get_count)))
  1362.                                 clif->additem(sd, 0, 0, flag);
  1363.                         else logs->item_getrem(1, sd, &item_tmp, get_count, "Cmd");
  1364.                 }
  1365.  
  1366.                 if (flag == 0)
  1367.                         clif->message(fd, msg_fd(fd,18)); // Item created.
  1368.         } else {
  1369.                 clif->message(fd, msg_fd(fd,19)); // Invalid item ID or name.
  1370.                 return false;
  1371.         }
  1372.  
  1373.         return true;
  1374. }
  1375.  
  1376. /*==========================================
  1377.  *
  1378.  *------------------------------------------*/
  1379. ACMD(itemreset)
  1380. {
  1381.         int i;
  1382.  
  1383.         for (i = 0; i < MAX_INVENTORY; i++) {
  1384.                 if (sd->status.inventory[i].amount && sd->status.inventory[i].equip == 0) {
  1385.                         logs->item_getrem(0, sd, &sd->status.inventory[i], -sd->status.inventory[i].amount, "Cmd");
  1386.                         pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL);
  1387.                 }
  1388.         }
  1389.         clif->message(fd, msg_fd(fd,20)); // All of your items have been removed.
  1390.  
  1391.         return true;
  1392. }
  1393.  
  1394. /*==========================================
  1395.  * Atcommand @lvlup
  1396.  *------------------------------------------*/
  1397. ACMD(baselevelup)
  1398. {
  1399.         int level=0, i=0, status_point=0;
  1400.  
  1401.         if (!*message || !(level = atoi(message))) {
  1402.                 clif->message(fd, msg_fd(fd,986)); // Please enter a level adjustment (usage: @lvup/@blevel/@baselvlup <number of levels>).
  1403.                 return false;
  1404.         }
  1405.  
  1406.         if (level > 0) {
  1407.                 if (sd->status.base_level >= pc->maxbaselv(sd)) { // check for max level by Valaris
  1408.                         clif->message(fd, msg_fd(fd,47)); // Base level can't go any higher.
  1409.                         return false;
  1410.                 } // End Addition
  1411.                 if ((unsigned int)level > pc->maxbaselv(sd) || (unsigned int)level > pc->maxbaselv(sd) - sd->status.base_level) // fix positive overflow
  1412.                         level = pc->maxbaselv(sd) - sd->status.base_level;
  1413.                 for (i = 0; i < level; i++)
  1414.                         status_point += pc->gets_status_point(sd->status.base_level + i);
  1415.  
  1416.                 sd->status.status_point += status_point;
  1417.                 sd->status.base_level += (unsigned int)level;
  1418.                 status_calc_pc(sd, SCO_FORCE);
  1419.                 status_percent_heal(&sd->bl, 100, 100);
  1420.                 clif->misceffect(&sd->bl, 0);
  1421.                 clif->message(fd, msg_fd(fd,21)); // Base level raised.
  1422.         } else {
  1423.                 if (sd->status.base_level == 1) {
  1424.                         clif->message(fd, msg_fd(fd,158)); // Base level can't go any lower.
  1425.                         return false;
  1426.                 }
  1427.                 level*=-1;
  1428.                 if ((unsigned int)level >= sd->status.base_level)
  1429.                         level = sd->status.base_level-1;
  1430.                 for (i = 0; i > -level; i--)
  1431.                         status_point += pc->gets_status_point(sd->status.base_level + i - 1);
  1432.                 if (sd->status.status_point < status_point)
  1433.                         pc->resetstate(sd);
  1434.                 if (sd->status.status_point < status_point)
  1435.                         sd->status.status_point = 0;
  1436.                 else
  1437.                         sd->status.status_point -= status_point;
  1438.                 sd->status.base_level -= (unsigned int)level;
  1439.                 clif->message(fd, msg_fd(fd,22)); // Base level lowered.
  1440.                 status_calc_pc(sd, SCO_FORCE);
  1441.         }
  1442.         sd->status.base_exp = 0;
  1443.         clif->updatestatus(sd, SP_STATUSPOINT);
  1444.         clif->updatestatus(sd, SP_BASELEVEL);
  1445.         clif->updatestatus(sd, SP_BASEEXP);
  1446.         clif->updatestatus(sd, SP_NEXTBASEEXP);
  1447.         pc->baselevelchanged(sd);
  1448.         if(sd->status.party_id)
  1449.                 party->send_levelup(sd);
  1450.         return true;
  1451. }
  1452.  
  1453. /*==========================================
  1454.  *
  1455.  *------------------------------------------*/
  1456. ACMD(joblevelup)
  1457. {
  1458.         int level=0;
  1459.  
  1460.         if (!*message || !(level = atoi(message))) {
  1461.                 clif->message(fd, msg_fd(fd,987)); // Please enter a level adjustment (usage: @joblvup/@jlevel/@joblvlup <number of levels>).
  1462.                 return false;
  1463.         }
  1464.         if (level > 0) {
  1465.                 if (sd->status.job_level >= pc->maxjoblv(sd)) {
  1466.                         clif->message(fd, msg_fd(fd,23)); // Job level can't go any higher.
  1467.                         return false;
  1468.                 }
  1469.                 if ((unsigned int)level > pc->maxjoblv(sd) || (unsigned int)level > pc->maxjoblv(sd) - sd->status.job_level) // fix positive overflow
  1470.                         level = pc->maxjoblv(sd) - sd->status.job_level;
  1471.                 sd->status.job_level += (unsigned int)level;
  1472.                 sd->status.skill_point += level;
  1473.                 clif->misceffect(&sd->bl, 1);
  1474.                 clif->message(fd, msg_fd(fd,24)); // Job level raised.
  1475.         } else {
  1476.                 if (sd->status.job_level == 1) {
  1477.                         clif->message(fd, msg_fd(fd,159)); // Job level can't go any lower.
  1478.                         return false;
  1479.                 }
  1480.                 level *=-1;
  1481.                 if ((unsigned int)level >= sd->status.job_level) // fix negative overflow
  1482.                         level = sd->status.job_level-1;
  1483.                 sd->status.job_level -= (unsigned int)level;
  1484.                 if (sd->status.skill_point < level)
  1485.                         pc->resetskill(sd, PCRESETSKILL_NONE); //Reset skills since we need to subtract more points.
  1486.                 if (sd->status.skill_point < level)
  1487.                         sd->status.skill_point = 0;
  1488.                 else
  1489.                         sd->status.skill_point -= level;
  1490.                 clif->message(fd, msg_fd(fd,25)); // Job level lowered.
  1491.         }
  1492.         sd->status.job_exp = 0;
  1493.         clif->updatestatus(sd, SP_JOBLEVEL);
  1494.         clif->updatestatus(sd, SP_JOBEXP);
  1495.         clif->updatestatus(sd, SP_NEXTJOBEXP);
  1496.         clif->updatestatus(sd, SP_SKILLPOINT);
  1497.         status_calc_pc(sd, SCO_FORCE);
  1498.  
  1499.         return true;
  1500. }
  1501.  
  1502. /*==========================================
  1503.  * @help
  1504.  *------------------------------------------*/
  1505. ACMD(help) {
  1506.         const char *command_name = NULL;
  1507.         char *default_command = "help";
  1508.         AtCommandInfo *tinfo = NULL;
  1509.  
  1510.         if (!*message) {
  1511.                 command_name = default_command; // If no command_name specified, display help for @help.
  1512.         } else {
  1513.                 if (*message == atcommand->at_symbol || *message == atcommand->char_symbol)
  1514.                         ++message;
  1515.                 command_name = atcommand->check_alias(message);
  1516.         }
  1517.  
  1518.         if (!atcommand->can_use2(sd, command_name, COMMAND_ATCOMMAND)) {
  1519.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,153), message); // "%s is Unknown Command"
  1520.                 clif->message(fd, atcmd_output);
  1521.                 atcommand->get_suggestions(sd, command_name, true);
  1522.                 return false;
  1523.         }
  1524.  
  1525.         tinfo = atcommand->get_info_byname(atcommand->check_alias(command_name));
  1526.  
  1527.         if ( !tinfo || tinfo->help == NULL ) {
  1528.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,988), atcommand->at_symbol, command_name); // There is no help for %c%s.
  1529.                 clif->message(fd, atcmd_output);
  1530.                 atcommand->get_suggestions(sd, command_name, true);
  1531.                 return false;
  1532.         }
  1533.  
  1534.         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,989), atcommand->at_symbol, command_name); // Help for command %c%s:
  1535.         clif->message(fd, atcmd_output);
  1536.  
  1537.         {   // Display aliases
  1538.                 DBIterator* iter;
  1539.                 AtCommandInfo *command_info;
  1540.                 AliasInfo *alias_info = NULL;
  1541.                 StringBuf buf;
  1542.                 bool has_aliases = false;
  1543.  
  1544.                 StrBuf->Init(&buf);
  1545.                 StrBuf->AppendStr(&buf, msg_fd(fd,990)); // Available aliases:
  1546.                 command_info = atcommand->get_info_byname(command_name);
  1547.                 iter = db_iterator(atcommand->alias_db);
  1548.                 for (alias_info = dbi_first(iter); dbi_exists(iter); alias_info = dbi_next(iter)) {
  1549.                         if (alias_info->command == command_info) {
  1550.                                 StrBuf->Printf(&buf, " %s", alias_info->alias);
  1551.                                 has_aliases = true;
  1552.                         }
  1553.                 }
  1554.                 dbi_destroy(iter);
  1555.                 if (has_aliases)
  1556.                         clif->message(fd, StrBuf->Value(&buf));
  1557.                 StrBuf->Destroy(&buf);
  1558.         }
  1559.  
  1560.         // Display help contents
  1561.         clif->messageln(fd, tinfo->help);
  1562.         return true;
  1563. }
  1564.  
  1565. /**
  1566.  * Helper function, used in foreach calls to stop auto-attack timers.
  1567.  *
  1568.  * @see map_foreachinmap
  1569.  *
  1570.  * Arglist parameters:
  1571.  * - (int) id: If 0, stop any attacks. Otherwise, the target block list id to stop attacking.
  1572.  */
  1573. int atcommand_stopattack(struct block_list *bl,va_list ap)
  1574. {
  1575.         struct unit_data *ud = NULL;
  1576.         int id = 0;
  1577.         nullpo_ret(bl);
  1578.  
  1579.         ud = unit->bl2ud(bl);
  1580.         id = va_arg(ap, int);
  1581.  
  1582.         if (ud && ud->attacktimer != INVALID_TIMER && (!id || id == ud->target)) {
  1583.                 unit->stop_attack(bl);
  1584.                 return 1;
  1585.         }
  1586.         return 0;
  1587. }
  1588.  
  1589. /*==========================================
  1590.  *
  1591.  *------------------------------------------*/
  1592. int atcommand_pvpoff_sub(struct block_list *bl,va_list ap)
  1593. {
  1594.         struct map_session_data *sd = NULL;
  1595.         nullpo_ret(bl);
  1596.         Assert_ret(bl->type == BL_PC);
  1597.         sd = BL_UCAST(BL_PC, bl);
  1598.  
  1599.         clif->pvpset(sd, 0, 0, 2);
  1600.         if (sd->pvp_timer != INVALID_TIMER) {
  1601.                 timer->delete(sd->pvp_timer, pc->calc_pvprank_timer);
  1602.                 sd->pvp_timer = INVALID_TIMER;
  1603.         }
  1604.         return 0;
  1605. }
  1606.  
  1607. ACMD(pvpoff)
  1608. {
  1609.         if(sd->bl.m == map->mapname2mapid("prontera")) {
  1610.         clif->message(fd, "@pvpon não é permitido neste mapa.");
  1611.         return false;
  1612.     }
  1613.  
  1614.         if (!map->list[sd->bl.m].flag.pvp) {
  1615.                 clif->message(fd, msg_fd(fd,160)); // PvP is already Off.
  1616.                 return false;
  1617.         }
  1618.  
  1619.         map->zone_change2(sd->bl.m,map->list[sd->bl.m].prev_zone);
  1620.         map->list[sd->bl.m].flag.pvp = 0;
  1621.  
  1622.         if (!battle_config.pk_mode) {
  1623.                 clif->map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING);
  1624.                 clif->maptypeproperty2(&sd->bl,ALL_SAMEMAP);
  1625.         }
  1626.         map->foreachinmap(atcommand->pvpoff_sub,sd->bl.m, BL_PC);
  1627.         map->foreachinmap(atcommand->stopattack,sd->bl.m, BL_CHAR, 0);
  1628.         clif->message(fd, msg_fd(fd,31)); // PvP: Off.
  1629.         return true;
  1630. }
  1631.  
  1632. /*==========================================
  1633.  *
  1634.  *------------------------------------------*/
  1635. int atcommand_pvpon_sub(struct block_list *bl,va_list ap)
  1636. {
  1637.         struct map_session_data *sd = NULL;
  1638.         nullpo_ret(bl);
  1639.         Assert_ret(bl->type == BL_PC);
  1640.         sd = BL_UCAST(BL_PC, bl);
  1641.  
  1642.         if (sd->pvp_timer == INVALID_TIMER) {
  1643.                 sd->pvp_timer = timer->add(timer->gettick() + 200, pc->calc_pvprank_timer, sd->bl.id, 0);
  1644.                 sd->pvp_rank = 0;
  1645.                 sd->pvp_lastusers = 0;
  1646.                 sd->pvp_point = 5;
  1647.                 sd->pvp_won = 0;
  1648.                 sd->pvp_lost = 0;
  1649.         }
  1650.         return 0;
  1651. }
  1652.  
  1653. ACMD(pvpon)
  1654. {
  1655.         if(sd->bl.m == map->mapname2mapid("prontera")) {
  1656.         clif->message(fd, "@pvpon não é permitido neste mapa.");
  1657.         return false;
  1658.     }
  1659.  
  1660.         if (map->list[sd->bl.m].flag.pvp) {
  1661.                 clif->message(fd, msg_fd(fd,161)); // PvP is already On.
  1662.                 return false;
  1663.         }
  1664.  
  1665.         map->zone_change2(sd->bl.m,strdb_get(map->zone_db, MAP_ZONE_PVP_NAME));
  1666.         map->list[sd->bl.m].flag.pvp = 1;
  1667.  
  1668.         if (!battle_config.pk_mode) {// display pvp circle and rank
  1669.                 clif->map_property_mapall(sd->bl.m, MAPPROPERTY_FREEPVPZONE);
  1670.                 clif->maptypeproperty2(&sd->bl,ALL_SAMEMAP);
  1671.                 map->foreachinmap(atcommand->pvpon_sub,sd->bl.m, BL_PC);
  1672.         }
  1673.  
  1674.         clif->message(fd, msg_fd(fd,32)); // PvP: On.
  1675.  
  1676.         return true;
  1677. }
  1678.  
  1679. /*==========================================
  1680.  *
  1681.  *------------------------------------------*/
  1682. ACMD(gvgoff) {
  1683.  
  1684.         if (!map->list[sd->bl.m].flag.gvg) {
  1685.                 clif->message(fd, msg_fd(fd,162)); // GvG is already Off.
  1686.                 return false;
  1687.         }
  1688.  
  1689.         map->zone_change2(sd->bl.m,map->list[sd->bl.m].prev_zone);
  1690.         map->list[sd->bl.m].flag.gvg = 0;
  1691.         clif->map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING);
  1692.         clif->maptypeproperty2(&sd->bl,ALL_SAMEMAP);
  1693.         map->foreachinmap(atcommand->stopattack,sd->bl.m, BL_CHAR, 0);
  1694.         clif->message(fd, msg_fd(fd,33)); // GvG: Off.
  1695.  
  1696.         return true;
  1697. }
  1698.  
  1699. /*==========================================
  1700.  *
  1701.  *------------------------------------------*/
  1702. ACMD(gvgon)
  1703. {
  1704.         if (map->list[sd->bl.m].flag.gvg) {
  1705.                 clif->message(fd, msg_fd(fd,163)); // GvG is already On.
  1706.                 return false;
  1707.         }
  1708.  
  1709.         map->zone_change2(sd->bl.m,strdb_get(map->zone_db, MAP_ZONE_GVG_NAME));
  1710.         map->list[sd->bl.m].flag.gvg = 1;
  1711.         clif->map_property_mapall(sd->bl.m, MAPPROPERTY_AGITZONE);
  1712.         clif->maptypeproperty2(&sd->bl,ALL_SAMEMAP);
  1713.         clif->message(fd, msg_fd(fd,34)); // GvG: On.
  1714.  
  1715.         return true;
  1716. }
  1717.  
  1718. /*==========================================
  1719.  *
  1720.  *------------------------------------------*/
  1721. ACMD(model)
  1722. {
  1723.         int hair_style = 0, hair_color = 0, cloth_color = 0;
  1724.  
  1725.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  1726.  
  1727.         if (!*message || sscanf(message, "%12d %12d %12d", &hair_style, &hair_color, &cloth_color) < 1) {
  1728.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,991), // Please enter at least one value (usage: @model <hair ID: %d-%d> <hair color: %d-%d> <clothes color: %d-%d>).
  1729.                         MIN_HAIR_STYLE, MAX_HAIR_STYLE, MIN_HAIR_COLOR, MAX_HAIR_COLOR, MIN_CLOTH_COLOR, MAX_CLOTH_COLOR);
  1730.                 clif->message(fd, atcmd_output);
  1731.                 return false;
  1732.         }
  1733.  
  1734.         if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE &&
  1735.                 hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR &&
  1736.                 cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) {
  1737.                 pc->changelook(sd, LOOK_HAIR, hair_style);
  1738.                 pc->changelook(sd, LOOK_HAIR_COLOR, hair_color);
  1739.                 pc->changelook(sd, LOOK_CLOTHES_COLOR, cloth_color);
  1740.                 clif->message(fd, msg_fd(fd,36)); // Appearance changed.
  1741.         } else {
  1742.                 clif->message(fd, msg_fd(fd,37)); // An invalid number was specified.
  1743.                 return false;
  1744.         }
  1745.  
  1746.         return true;
  1747. }
  1748.  
  1749. /*==========================================
  1750.  * @bodystyle [Rytech]
  1751.  *------------------------------------------*/
  1752. ACMD(bodystyle)
  1753. {
  1754.         int body_style = 0;
  1755.  
  1756.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  1757.  
  1758.         if (!*message || sscanf(message, "%d", &body_style) < 1) {
  1759.                 sprintf(atcmd_output, "Please, enter a body style (usage: @bodystyle <body ID: %d-%d>).", MIN_BODY_STYLE, MAX_BODY_STYLE);
  1760.                 clif->message(fd, atcmd_output);
  1761.                 return false;
  1762.         }
  1763.  
  1764.         if (body_style >= MIN_BODY_STYLE && body_style <= MAX_BODY_STYLE) {
  1765.                 pc->changelook(sd, LOOK_BODY2, body_style);
  1766.                 clif->message(fd, msg_txt(36)); // Appearence changed.
  1767.         } else {
  1768.                 clif->message(fd, msg_txt(37)); // An invalid number was specified.
  1769.                 return false;
  1770.         }
  1771.  
  1772.         return true;
  1773. }
  1774.  
  1775. /*==========================================
  1776.  * @dye && @ccolor
  1777.  *------------------------------------------*/
  1778. ACMD(dye)
  1779. {
  1780.         int cloth_color = 0;
  1781.  
  1782.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  1783.  
  1784.         if (!*message || sscanf(message, "%12d", &cloth_color) < 1) {
  1785.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,992), MIN_CLOTH_COLOR, MAX_CLOTH_COLOR); // Please enter a clothes color (usage: @dye/@ccolor <clothes color: %d-%d>).
  1786.                 clif->message(fd, atcmd_output);
  1787.                 return false;
  1788.         }
  1789.  
  1790.         if (cloth_color >= MIN_CLOTH_COLOR && cloth_color <= MAX_CLOTH_COLOR) {
  1791.                 if (pc->changelook(sd, LOOK_CLOTHES_COLOR, cloth_color) != 0)
  1792.                         return false;
  1793.                 clif->message(fd, msg_fd(fd,36)); // Appearance changed.
  1794.         } else {
  1795.                 clif->message(fd, msg_fd(fd,37)); // An invalid number was specified.
  1796.                 return false;
  1797.         }
  1798.  
  1799.         return true;
  1800. }
  1801.  
  1802. /*==========================================
  1803.  * @hairstyle && @hstyle
  1804.  *------------------------------------------*/
  1805. ACMD(hair_style)
  1806. {
  1807.         int hair_style = 0;
  1808.  
  1809.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  1810.  
  1811.         if (!*message || sscanf(message, "%12d", &hair_style) < 1) {
  1812.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,993), MIN_HAIR_STYLE, MAX_HAIR_STYLE); // Please enter a hair style (usage: @hairstyle/@hstyle <hair ID: %d-%d>).
  1813.                 clif->message(fd, atcmd_output);
  1814.                 return false;
  1815.         }
  1816.  
  1817.         if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE) {
  1818.                 if(pc->changelook(sd, LOOK_HAIR, hair_style)){
  1819.                         clif->message(fd, "Impossível alterar."); // An invalid number was specified.
  1820.                         return false;
  1821.                 } else {
  1822.                         clif->message(fd, msg_fd(fd,36)); // Appearance changed.
  1823.                 }
  1824.         } else {
  1825.                 clif->message(fd, msg_fd(fd,37)); // An invalid number was specified.
  1826.                 return false;
  1827.         }
  1828.  
  1829.         return true;
  1830. }
  1831.  
  1832. /*==========================================
  1833.  * @haircolor && @hcolor
  1834.  *------------------------------------------*/
  1835. ACMD(hair_color)
  1836. {
  1837.         int hair_color = 0;
  1838.  
  1839.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  1840.  
  1841.         if (!*message || sscanf(message, "%12d", &hair_color) < 1) {
  1842.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,994), MIN_HAIR_COLOR, MAX_HAIR_COLOR); // Please enter a hair color (usage: @haircolor/@hcolor <hair color: %d-%d>).
  1843.                 clif->message(fd, atcmd_output);
  1844.                 return false;
  1845.         }
  1846.  
  1847.         if (hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR) {
  1848.                 if (pc->changelook(sd, LOOK_HAIR_COLOR, hair_color) != 0)
  1849.                         return false;
  1850.                 clif->message(fd, msg_fd(fd,36)); // Appearance changed.
  1851.         } else {
  1852.                 clif->message(fd, msg_fd(fd,37)); // An invalid number was specified.
  1853.                 return false;
  1854.         }
  1855.  
  1856.         return true;
  1857. }
  1858.  
  1859. /*==========================================
  1860.  * @go [city_number or city_name] - Updated by Harbin
  1861.  *------------------------------------------*/
  1862. ACMD(go) {
  1863.         int town = INT_MAX; // Initialized to INT_MAX instead of -1 to avoid conflicts with those who map [-3:-1] to @memo locations.
  1864.         char map_name[MAP_NAME_LENGTH];
  1865.  
  1866.         const struct {
  1867.                 char map[MAP_NAME_LENGTH];
  1868.                 int x, y;
  1869.                 int min_match; ///< Minimum string length to match
  1870.         } data[] = {
  1871.                 { MAP_AE_CITY,     100,  60, 3 }, //  0 = Prontera
  1872.                 { MAP_MORROC,      156,  93, 4 }, //  1 = Morroc
  1873.                 { MAP_GEFFEN,      119,  59, 3 }, //  2 = Geffen
  1874.                 { MAP_PAYON,       162, 233, 3 }, //  3 = Payon
  1875.                 { MAP_ALBERTA,     192, 147, 3 }, //  4 = Alberta
  1876. #ifdef RENEWAL
  1877.                 { MAP_IZLUDE,      128, 146, 3 }, //  5 = Izlude (Renewal)
  1878. #else
  1879.                 { MAP_IZLUDE,      128, 114, 3 }, //  5 = Izlude
  1880. #endif
  1881.                 { MAP_ALDEBARAN,   140, 131, 3 }, //  6 = Aldebaran
  1882.                 { MAP_LUTIE,       147, 134, 3 }, //  7 = Lutie
  1883.                 { MAP_COMODO,      209, 143, 3 }, //  8 = Comodo
  1884.                 { MAP_YUNO,        157,  51, 3 }, //  9 = Juno
  1885.                 { MAP_AMATSU,      198,  84, 3 }, // 10 = Amatsu
  1886.                 { MAP_GONRYUN,     160, 120, 3 }, // 11 = Kunlun
  1887.                 { MAP_UMBALA,       89, 157, 3 }, // 12 = Umbala
  1888.                 { MAP_NIFLHEIM,     21, 153, 3 }, // 13 = Niflheim
  1889.                 { MAP_LOUYANG,     217,  40, 3 }, // 14 = Luoyang
  1890.                 { MAP_NOVICE,       53, 111, 3 }, // 15 = Training Grounds
  1891.                 { MAP_JAIL,         23,  61, 3 }, // 16 = Prison
  1892.                 { MAP_JAWAII,      249, 127, 3 }, // 17 = Jawaii
  1893.                 { MAP_AYOTHAYA,    151, 117, 3 }, // 18 = Ayothaya
  1894.                 { MAP_EINBROCH,     64, 200, 5 }, // 19 = Einbroch
  1895.                 { MAP_LIGHTHALZEN, 158,  92, 3 }, // 20 = Lighthalzen
  1896.                 { MAP_EINBECH,      70,  95, 5 }, // 21 = Einbech
  1897.                 { MAP_HUGEL,        96, 145, 3 }, // 22 = Hugel
  1898.                 { MAP_RACHEL,      130, 110, 3 }, // 23 = Rachel
  1899.                 { MAP_VEINS,       216, 123, 3 }, // 24 = Veins
  1900.                 { MAP_MOSCOVIA,    223, 184, 3 }, // 25 = Moscovia
  1901.                 { MAP_MIDCAMP,     180, 240, 3 }, // 26 = Midgard Camp
  1902.                 { MAP_MANUK,       282, 138, 3 }, // 27 = Manuk
  1903.                 { MAP_SPLENDIDE,   197, 176, 3 }, // 28 = Splendide
  1904.                 { MAP_BRASILIS,    182, 239, 3 }, // 29 = Brasilis
  1905.                 { MAP_DICASTES,    198, 187, 3 }, // 30 = El Dicastes
  1906.                 { MAP_MORA,         44, 151, 4 }, // 31 = Mora
  1907.                 { MAP_DEWATA,      200, 180, 3 }, // 32 = Dewata
  1908.                 { MAP_MALANGDO,    140, 114, 5 }, // 33 = Malangdo Island
  1909.                 { MAP_MALAYA,      242, 211, 5 }, // 34 = Malaya Port
  1910.                 { MAP_ECLAGE,      110,  39, 3 }, // 35 = Eclage
  1911.         };
  1912.  
  1913.         memset(map_name, '\0', sizeof(map_name));
  1914.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  1915.  
  1916.         if (!*message || sscanf(message, "%11s", map_name) < 1) {
  1917.                 // no value matched so send the list of locations
  1918.                 const char* text;
  1919.  
  1920.                 // attempt to find the text help string
  1921.                 text = atcommand_help_string( info );
  1922.  
  1923.                 clif->message(fd, msg_fd(fd,38)); // Invalid location number, or name.
  1924.  
  1925.                 if (text) { // send the text to the client
  1926.                         clif->messageln( fd, text );
  1927.                 }
  1928.  
  1929.                 return false;
  1930.         }
  1931.  
  1932.         // Numeric entry
  1933.         if (ISDIGIT(*message) || (message[0] == '-' && ISDIGIT(message[1]))) {
  1934.                 town = atoi(message);
  1935.         }
  1936.  
  1937.         if (town < 0 || town >= ARRAYLENGTH(data)) {
  1938.                 int i;
  1939.                 map_name[MAP_NAME_LENGTH-1] = '\0';
  1940.  
  1941.                 // Match maps on the list
  1942.                 for (i = 0; i < ARRAYLENGTH(data); i++) {
  1943.                         if (strncmpi(map_name, data[i].map, data[i].min_match) == 0) {
  1944.                                 town = i;
  1945.                                 break;
  1946.                         }
  1947.                 }
  1948.         }
  1949.  
  1950.         if (town < 0 || town >= ARRAYLENGTH(data)) {
  1951.                 // Alternate spellings
  1952.                 if (strncmpi(map_name, "morroc", 4) == 0) { // Correct town name for 'morocc'
  1953.                         town = 1;
  1954.                 } else if (strncmpi(map_name, "lutie", 3) == 0) { // Correct town name for 'xmas'
  1955.                         town = 7;
  1956.                 } else if (strncmpi(map_name, "juno", 3) == 0) { // Correct town name for 'yuno'
  1957.                         town = 9;
  1958.                 } else if (strncmpi(map_name, "kunlun", 3) == 0) { // Original town name for 'gonryun'
  1959.                         town = 11;
  1960.                 } else if (strncmpi(map_name, "luoyang", 3) == 0) { // Original town name for 'louyang'
  1961.                         town = 14;
  1962.                 } else if (strncmpi(map_name, "startpoint", 3) == 0 // Easy to remember alternatives to 'new_1-1'
  1963.                         || strncmpi(map_name, "beginning", 3) == 0) {
  1964.                         town = 15;
  1965.                 } else if (strncmpi(map_name, "prison", 3) == 0 // Easy to remember alternatives to 'sec_pri'
  1966.                         || strncmpi(map_name, "jail", 3) == 0) {
  1967.                         town = 16;
  1968.                 } else if (strncmpi(map_name, "rael", 3) == 0) { // Original town name for 'rachel'
  1969.                         town = 23;
  1970.                 }
  1971.         }
  1972.  
  1973.         if (town >= 0 && town < ARRAYLENGTH(data)) {
  1974.                 int16 m = map->mapname2mapid(data[town].map);
  1975.                 if (m >= 0 && map->list[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
  1976.                         clif->message(fd, msg_fd(fd,247));
  1977.                         return false;
  1978.                 }
  1979.                 if (sd->state.pvp || (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))) {
  1980.                         clif->message(fd, msg_fd(fd,248));
  1981.                         return false;
  1982.                 }
  1983.                 if (pc->setpos(sd, mapindex->name2id(data[town].map), data[town].x, data[town].y, CLR_TELEPORT) == 0) {
  1984.                         clif->message(fd, msg_fd(fd,0)); // Warped.
  1985.                 } else {
  1986.                         clif->message(fd, msg_fd(fd,1)); // Map not found.
  1987.                         return false;
  1988.                 }
  1989.         } else {
  1990.                 clif->message(fd, msg_fd(fd,38)); // Invalid location number or name.
  1991.                 return false;
  1992.         }
  1993.  
  1994.         return true;
  1995. }
  1996.  
  1997. /*==========================================
  1998.  *
  1999.  *------------------------------------------*/
  2000. ACMD(monster)
  2001. {
  2002.         char name[NAME_LENGTH];
  2003.         char monster[NAME_LENGTH];
  2004.         char eventname[EVENT_NAME_LENGTH] = "";
  2005.         int mob_id;
  2006.         int number = 0;
  2007.         int count;
  2008.         int i, range;
  2009.         short mx, my;
  2010.         unsigned int size;
  2011.  
  2012.         memset(name, '\0', sizeof(name));
  2013.         memset(monster, '\0', sizeof(monster));
  2014.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2015.  
  2016.         if (!*message) {
  2017.                 clif->message(fd, msg_fd(fd,80)); // Please specify a display name or monster name/id.
  2018.                 return false;
  2019.         }
  2020.         if (sscanf(message, "\"%23[^\"]\" %23s %12d", name, monster, &number) > 1 ||
  2021.                 sscanf(message, "%23s \"%23[^\"]\" %12d", monster, name, &number) > 1) {
  2022.                 //All data can be left as it is.
  2023.         } else if ((count=sscanf(message, "%23s %12d %23s", monster, &number, name)) > 1) {
  2024.                 //Here, it is possible name was not given and we are using monster for it.
  2025.                 if (count < 3) //Blank mob's name.
  2026.                         name[0] = '\0';
  2027.         } else if (sscanf(message, "%23s %23s %12d", name, monster, &number) > 1) {
  2028.                 //All data can be left as it is.
  2029.         } else if (sscanf(message, "%23s", monster) > 0) {
  2030.                 //As before, name may be already filled.
  2031.                 name[0] = '\0';
  2032.         } else {
  2033.                 clif->message(fd, msg_fd(fd,80)); // Give a display name and monster name/id please.
  2034.                 return false;
  2035.         }
  2036.  
  2037.         if ((mob_id = mob->db_searchname(monster)) == 0) // check name first (to avoid possible name beginning by a number)
  2038.                 mob_id = mob->db_checkid(atoi(monster));
  2039.  
  2040.         if (mob_id == 0) {
  2041.                 clif->message(fd, msg_fd(fd,40)); // Invalid monster ID or name.
  2042.                 return false;
  2043.         }
  2044.  
  2045.         if (number <= 0)
  2046.                 number = 1;
  2047.  
  2048.         if (!name[0])
  2049.                 strcpy(name,mob->db(mob_id)->name);
  2050.  
  2051.         // 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
  2052.         if (battle_config.atc_spawn_quantity_limit && number > battle_config.atc_spawn_quantity_limit)
  2053.                 number = battle_config.atc_spawn_quantity_limit;
  2054.  
  2055.         if (strcmpi(info->command, "monstersmall") == 0)
  2056.                 size = SZ_MEDIUM;
  2057.         else if (strcmpi(info->command, "monsterbig") == 0)
  2058.                 size = SZ_BIG;
  2059.         else
  2060.                 size = SZ_SMALL;
  2061.  
  2062.         if (battle_config.etc_log)
  2063.                 ShowInfo("%s monstro='%s' nome='%s' id=%d total=%d (%d,%d)\n", command, monster, name, mob_id, number, sd->bl.x, sd->bl.y);
  2064.  
  2065.         count = 0;
  2066.         range = (int)sqrt((float)number) +2; // calculation of an odd number (+ 4 area around)
  2067.         for (i = 0; i < number; i++) {
  2068.                 int k;
  2069.                 map->search_freecell(&sd->bl, 0, &mx,  &my, range, range, 0);
  2070.                 k = mob->once_spawn(sd, sd->bl.m, mx, my, name, mob_id, 1, eventname, size, AI_NONE|(mob_id == MOBID_EMPELIUM?0x200:0x0));
  2071.                 count += (k != 0) ? 1 : 0;
  2072.         }
  2073.  
  2074.         if (count != 0)
  2075.                 if (number == count)
  2076.                         clif->message(fd, msg_fd(fd,39)); // All monster summoned!
  2077.                 else {
  2078.                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,240), count); // %d monster(s) summoned!
  2079.                         clif->message(fd, atcmd_output);
  2080.                 }
  2081.                 else {
  2082.                         clif->message(fd, msg_fd(fd,40)); // Invalid monster ID or name.
  2083.                         return false;
  2084.                 }
  2085.  
  2086.         return true;
  2087. }
  2088.  
  2089. /*==========================================
  2090.  *
  2091.  *------------------------------------------*/
  2092. int atkillmonster_sub(struct block_list *bl, va_list ap)
  2093. {
  2094.         struct mob_data *md = NULL;
  2095.         int flag = va_arg(ap, int);
  2096.         nullpo_ret(bl);
  2097.         Assert_ret(bl->type == BL_MOB);
  2098.         md = BL_UCAST(BL_MOB, bl);
  2099.  
  2100.         if (md->guardian_data)
  2101.                 return 0; //Do not touch WoE mobs!
  2102.  
  2103.         if (flag)
  2104.                 status_zap(bl,md->status.hp, 0);
  2105.         else
  2106.                 status_kill(bl);
  2107.         return 1;
  2108. }
  2109.  
  2110. ACMD(killmonster) {
  2111.         int map_id, drop_flag;
  2112.         char map_name[MAP_NAME_LENGTH_EXT];
  2113.  
  2114.         memset(map_name, '\0', sizeof(map_name));
  2115.  
  2116.         if (!*message || sscanf(message, "%15s", map_name) < 1) {
  2117.                 map_id = sd->bl.m;
  2118.         } else {
  2119.                 if ((map_id = map->mapname2mapid(map_name)) < 0)
  2120.                         map_id = sd->bl.m;
  2121.         }
  2122.  
  2123.         drop_flag = strcmpi(info->command, "killmonster2");
  2124.  
  2125.         map->foreachinmap(atcommand->atkillmonster_sub, map_id, BL_MOB, -drop_flag);
  2126.  
  2127.         clif->message(fd, msg_fd(fd,165)); // All monsters killed!
  2128.  
  2129.         return true;
  2130. }
  2131.  
  2132. /*==========================================
  2133.  *
  2134.  *------------------------------------------*/
  2135. ACMD(refine)
  2136. {
  2137.         int j, position = 0, refine = 0, current_position, final_refine;
  2138.         int count;
  2139.  
  2140.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2141.  
  2142.         if (!*message || sscanf(message, "%12d %12d", &position, &refine) < 2) {
  2143.                 clif->message(fd, msg_fd(fd,996)); // Please enter a position and an amount (usage: @refine <equip position> <+/- amount>).
  2144.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,997), EQP_HEAD_LOW); // %d: Lower Headgear
  2145.                 clif->message(fd, atcmd_output);
  2146.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,998), EQP_HAND_R); // %d: Right Hand
  2147.                 clif->message(fd, atcmd_output);
  2148.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,999), EQP_GARMENT); // %d: Garment
  2149.                 clif->message(fd, atcmd_output);
  2150.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1000), EQP_ACC_L); // %d: Left Accessory
  2151.                 clif->message(fd, atcmd_output);
  2152.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1001), EQP_ARMOR); // %d: Body Armor
  2153.                 clif->message(fd, atcmd_output);
  2154.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1002), EQP_HAND_L); // %d: Left Hand
  2155.                 clif->message(fd, atcmd_output);
  2156.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1003), EQP_SHOES); // %d: Shoes
  2157.                 clif->message(fd, atcmd_output);
  2158.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1004), EQP_ACC_R); // %d: Right Accessory
  2159.                 clif->message(fd, atcmd_output);
  2160.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1005), EQP_HEAD_TOP); // %d: Top Headgear
  2161.                 clif->message(fd, atcmd_output);
  2162.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1006), EQP_HEAD_MID); // %d: Mid Headgear
  2163.                 clif->message(fd, atcmd_output);
  2164.                 return false;
  2165.         }
  2166.  
  2167.         refine = cap_value(refine, -MAX_REFINE, MAX_REFINE);
  2168.  
  2169.         count = 0;
  2170.         for (j = 0; j < EQI_MAX; j++) {
  2171.                 int idx = sd->equip_index[j];
  2172.                 if (idx < 0)
  2173.                         continue;
  2174.                 if(j == EQI_AMMO) continue; /* can't equip ammo */
  2175.                 if(j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == idx)
  2176.                         continue;
  2177.                 if(j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == idx)
  2178.                         continue;
  2179.                 if(j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == idx || sd->equip_index[EQI_HEAD_LOW] == idx))
  2180.                         continue;
  2181.  
  2182.                 if(position && !(sd->status.inventory[idx].equip & position))
  2183.                         continue;
  2184.  
  2185.                 final_refine = cap_value(sd->status.inventory[idx].refine + refine, 0, MAX_REFINE);
  2186.                 if (sd->status.inventory[idx].refine != final_refine) {
  2187.                         sd->status.inventory[idx].refine = final_refine;
  2188.                         current_position = sd->status.inventory[idx].equip;
  2189.                         pc->unequipitem(sd, idx, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
  2190.                         clif->refine(fd, 0, idx, sd->status.inventory[idx].refine);
  2191.                         logs->produce(sd, &sd->status.inventory[idx], 1, "Sucess Refine");
  2192.                         clif->delitem(sd, idx, 1, DELITEM_MATERIALCHANGE);
  2193.                         clif->additem(sd, idx, 1, 0);
  2194.                         pc->equipitem(sd, idx, current_position);
  2195.                         clif->misceffect(&sd->bl, 3);
  2196.                         count++;
  2197.                 }
  2198.         }
  2199.  
  2200.         if (count == 0)
  2201.                 clif->message(fd, msg_fd(fd,166)); // No item has been refined.
  2202.         else if (count == 1)
  2203.                 clif->message(fd, msg_fd(fd,167)); // 1 item has been refined.
  2204.         else {
  2205.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,168), count); // %d items have been refined.
  2206.                 clif->message(fd, atcmd_output);
  2207.         }
  2208.  
  2209.         return true;
  2210. }
  2211.  
  2212. /*==========================================
  2213.  *
  2214.  *------------------------------------------*/
  2215. ACMD(produce)
  2216. {
  2217.         char item_name[100];
  2218.         int item_id, attribute = 0, star = 0;
  2219.         struct item_data *item_data;
  2220.         struct item tmp_item;
  2221.  
  2222.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2223.         memset(item_name, '\0', sizeof(item_name));
  2224.  
  2225.         if (!*message || (
  2226.                                                                   sscanf(message, "\"%99[^\"]\" %12d %12d", item_name, &attribute, &star) < 1 &&
  2227.                                                                   sscanf(message, "%99s %12d %12d", item_name, &attribute, &star) < 1
  2228.                                                                   )) {
  2229.                 clif->message(fd, msg_fd(fd,1007)); // Please enter at least one item name/ID (usage: @produce <equip name/ID> <element> <# of very's>).
  2230.                 return false;
  2231.         }
  2232.  
  2233.         if ( (item_data = itemdb->search_name(item_name)) == NULL &&
  2234.                 (item_data = itemdb->exists(atoi(item_name))) == NULL ) {
  2235.                 clif->message(fd, msg_fd(fd,170)); //This item is not an equipment.
  2236.                 return false;
  2237.         }
  2238.  
  2239.         item_id = item_data->nameid;
  2240.  
  2241.         if (itemdb->isequip2(item_data)) {
  2242.                 int flag = 0;
  2243.                 if (attribute < MIN_ATTRIBUTE || attribute > MAX_ATTRIBUTE)
  2244.                         attribute = ATTRIBUTE_NORMAL;
  2245.                 if (star < MIN_STAR || star > MAX_STAR)
  2246.                         star = 0;
  2247.                 memset(&tmp_item, 0, sizeof tmp_item);
  2248.                 tmp_item.nameid = item_id;
  2249.                 tmp_item.amount = 1;
  2250.                 tmp_item.identify = 1;
  2251.                 tmp_item.card[0] = CARD0_FORGE;
  2252.                 tmp_item.card[1] = item_data->type==IT_WEAPON?
  2253.                 ((star*5) << 8) + attribute:0;
  2254.                 tmp_item.card[2] = GetWord(sd->status.char_id, 0);
  2255.                 tmp_item.card[3] = GetWord(sd->status.char_id, 1);
  2256.                 tmp_item.bound = (unsigned char)1;
  2257.                 clif->produce_effect(sd, 0, item_id);
  2258.                 clif->misceffect(&sd->bl, 3);
  2259.  
  2260.                 if ((flag = pc->additem(sd, &tmp_item, 1)))
  2261.                         clif->additem(sd, 0, 0, flag);
  2262.                 else logs->produce(sd, &tmp_item, 1, "Crafting Sucess");
  2263.         } else {
  2264.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,169), item_id, item_data->name); // The item (%d: '%s') is not equipable.
  2265.                 clif->message(fd, atcmd_output);
  2266.                 return false;
  2267.         }
  2268.  
  2269.         return true;
  2270. }
  2271.  
  2272. /*==========================================
  2273.  *
  2274.  *------------------------------------------*/
  2275. ACMD(memo)
  2276. {
  2277.         int position = 0;
  2278.  
  2279.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2280.  
  2281.         if (!*message || sscanf(message, "%d", &position) < 1)
  2282.         {
  2283.                 int i;
  2284.                 clif->message(sd->fd,  msg_fd(fd,868)); // "Your current memo positions are:"
  2285.                 for( i = 0; i < MAX_MEMOPOINTS; i++ )
  2286.                 {
  2287.                         if( sd->status.memo_point[i].map )
  2288.                                 safesnprintf(atcmd_output, sizeof(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);
  2289.                         else
  2290.                                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,171), i); // %d - void
  2291.                         clif->message(sd->fd, atcmd_output);
  2292.                 }
  2293.                 return true;
  2294.         }
  2295.  
  2296.         if( position < 0 || position >= MAX_MEMOPOINTS )
  2297.         {
  2298.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1008), 0, MAX_MEMOPOINTS-1); // Please enter a valid position (usage: @memo <memo_position:%d-%d>).
  2299.                 clif->message(fd, atcmd_output);
  2300.                 return false;
  2301.         }
  2302.  
  2303.         pc->memo(sd, position);
  2304.         return true;
  2305. }
  2306.  
  2307. /*==========================================
  2308.  *
  2309.  *------------------------------------------*/
  2310. ACMD(gat) {
  2311.         int y;
  2312.  
  2313.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2314.  
  2315.         for (y = 2; y >= -2; y--) {
  2316.                 safesnprintf(atcmd_output, sizeof(atcmd_output), "%s (x= %d, y= %d) %02X %02X %02X %02X %02X",
  2317.                                 map->list[sd->bl.m].name, sd->bl.x - 2, sd->bl.y + y,
  2318.                                 map->getcell(sd->bl.m, &sd->bl, sd->bl.x - 2, sd->bl.y + y, CELL_GETTYPE),
  2319.                                 map->getcell(sd->bl.m, &sd->bl, sd->bl.x - 1, sd->bl.y + y, CELL_GETTYPE),
  2320.                                 map->getcell(sd->bl.m, &sd->bl, sd->bl.x,     sd->bl.y + y, CELL_GETTYPE),
  2321.                                 map->getcell(sd->bl.m, &sd->bl, sd->bl.x + 1, sd->bl.y + y, CELL_GETTYPE),
  2322.                                 map->getcell(sd->bl.m, &sd->bl, sd->bl.x + 2, sd->bl.y + y, CELL_GETTYPE));
  2323.  
  2324.                 clif->message(fd, atcmd_output);
  2325.         }
  2326.  
  2327.         return true;
  2328. }
  2329.  
  2330. /*==========================================
  2331.  *
  2332.  *------------------------------------------*/
  2333. ACMD(displaystatus)
  2334. {
  2335.         int i, type, flag, tick, val1 = 0, val2 = 0, val3 = 0;
  2336.  
  2337.         if (!*message || (i = sscanf(message, "%d %d %d %d %d %d", &type, &flag, &tick, &val1, &val2, &val3)) < 1) {
  2338.                 clif->message(fd, msg_fd(fd,1009)); // Please enter a status type/flag (usage: @displaystatus <status type> <flag> <tick> {<val1> {<val2> {<val3>}}}).
  2339.                 return false;
  2340.         }
  2341.         if (i < 2) flag = 1;
  2342.         if (i < 3) tick = 0;
  2343.  
  2344.         if( flag == 0 )
  2345.                 clif->sc_end(&sd->bl,sd->bl.id,AREA,type);
  2346.         else
  2347.                 clif->status_change(&sd->bl, type, flag, tick, val1, val2, val3);
  2348.  
  2349.         return true;
  2350. }
  2351.  
  2352. /*==========================================
  2353.  * @stpoint (Rewritten by [Yor])
  2354.  *------------------------------------------*/
  2355. ACMD(statuspoint)
  2356. {
  2357.         int point;
  2358.         unsigned int new_status_point;
  2359.  
  2360.         if (!*message || (point = atoi(message)) == 0) {
  2361.                 clif->message(fd, msg_fd(fd,1010)); // Please enter a number (usage: @stpoint <number of points>).
  2362.                 return false;
  2363.         }
  2364.  
  2365.         if(point < 0)
  2366.         {
  2367.                 if(sd->status.status_point < (unsigned int)(-point))
  2368.                 {
  2369.                         new_status_point = 0;
  2370.                 }
  2371.                 else
  2372.                 {
  2373.                         new_status_point = sd->status.status_point + point;
  2374.                 }
  2375.         }
  2376.         else if(UINT_MAX - sd->status.status_point < (unsigned int)point)
  2377.         {
  2378.                 new_status_point = UINT_MAX;
  2379.         }
  2380.         else
  2381.         {
  2382.                 new_status_point = sd->status.status_point + point;
  2383.         }
  2384.  
  2385.         if (new_status_point != sd->status.status_point) {
  2386.                 sd->status.status_point = new_status_point;
  2387.                 clif->updatestatus(sd, SP_STATUSPOINT);
  2388.                 clif->message(fd, msg_fd(fd,174)); // Number of status points changed.
  2389.         } else {
  2390.                 if (point < 0)
  2391.                         clif->message(fd, msg_fd(fd,41)); // Unable to decrease the number/value.
  2392.                 else
  2393.                         clif->message(fd, msg_fd(fd,149)); // Unable to increase the number/value.
  2394.                 return false;
  2395.         }
  2396.  
  2397.         return true;
  2398. }
  2399.  
  2400. /*==========================================
  2401.  * @skpoint (Rewritten by [Yor])
  2402.  *------------------------------------------*/
  2403. ACMD(skillpoint)
  2404. {
  2405.         int point;
  2406.         unsigned int new_skill_point;
  2407.  
  2408.         if (!*message || (point = atoi(message)) == 0) {
  2409.                 clif->message(fd, msg_fd(fd,1011)); // Please enter a number (usage: @skpoint <number of points>).
  2410.                 return false;
  2411.         }
  2412.  
  2413.         if(point < 0)
  2414.         {
  2415.                 if(sd->status.skill_point < (unsigned int)(-point))
  2416.                 {
  2417.                         new_skill_point = 0;
  2418.                 }
  2419.                 else
  2420.                 {
  2421.                         new_skill_point = sd->status.skill_point + point;
  2422.                 }
  2423.         }
  2424.         else if(UINT_MAX - sd->status.skill_point < (unsigned int)point)
  2425.         {
  2426.                 new_skill_point = UINT_MAX;
  2427.         }
  2428.         else
  2429.         {
  2430.                 new_skill_point = sd->status.skill_point + point;
  2431.         }
  2432.  
  2433.         if (new_skill_point != sd->status.skill_point) {
  2434.                 sd->status.skill_point = new_skill_point;
  2435.                 clif->updatestatus(sd, SP_SKILLPOINT);
  2436.                 clif->message(fd, msg_fd(fd,175)); // Number of skill points changed.
  2437.         } else {
  2438.                 if (point < 0)
  2439.                         clif->message(fd, msg_fd(fd,41)); // Unable to decrease the number/value.
  2440.                 else
  2441.                         clif->message(fd, msg_fd(fd,149)); // Unable to increase the number/value.
  2442.                 return false;
  2443.         }
  2444.  
  2445.         return true;
  2446. }
  2447.  
  2448. /*==========================================
  2449.  * @zeny
  2450.  *------------------------------------------*/
  2451. ACMD(zeny)
  2452. {
  2453.         int zeny=0, ret=-1;
  2454.  
  2455.         if (!*message || (zeny = atoi(message)) == 0) {
  2456.                 clif->message(fd, msg_fd(fd,1012)); // Please enter an amount (usage: @zeny <amount>).
  2457.                 return false;
  2458.         }
  2459.  
  2460.         if(zeny > 0){
  2461.             if((ret=pc->getzeny(sd,zeny,"Cmd",NULL)) == 1)
  2462.                         clif->message(fd, msg_fd(fd,149)); // Unable to increase the number/value.
  2463.         }
  2464.         else {
  2465.             if( sd->status.zeny < -zeny ) zeny = -sd->status.zeny;
  2466.                 if ((ret = pc->payzeny(sd, -zeny, "Cmd", NULL)) == 1)
  2467.                         clif->message(fd, msg_fd(fd,41)); // Unable to decrease the number/value.
  2468.         }
  2469.  
  2470.         if( ret ) //ret != 0 means cmd failure
  2471.                 return false;
  2472.  
  2473.         clif->message(fd, msg_fd(fd,176));
  2474.         return true;
  2475. }
  2476.  
  2477. /*==========================================
  2478.  *
  2479.  *------------------------------------------*/
  2480. ACMD(param) {
  2481.         int i, value = 0, new_value, max;
  2482.         const char* param[] = { "str", "agi", "vit", "int", "dex", "luk" };
  2483.         short* stats[6];
  2484.         //we don't use direct initialization because it isn't part of the c standard.
  2485.  
  2486.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2487.  
  2488.         if (!*message || sscanf(message, "%d", &value) < 1 || value == 0) {
  2489.                 clif->message(fd, msg_fd(fd,1013)); // Please enter a valid value (usage: @str/@agi/@vit/@int/@dex/@luk <+/-adjustment>).
  2490.                 return false;
  2491.         }
  2492.  
  2493.         ARR_FIND( 0, ARRAYLENGTH(param), i, strcmpi(info->command, param[i]) == 0 );
  2494.  
  2495.         if( i == ARRAYLENGTH(param) || i > MAX_STATUS_TYPE) { // normally impossible...
  2496.                 clif->message(fd, msg_fd(fd,1013)); // Please enter a valid value (usage: @str/@agi/@vit/@int/@dex/@luk <+/-adjustment>).
  2497.                 return false;
  2498.         }
  2499.  
  2500.         stats[0] = &sd->status.str;
  2501.         stats[1] = &sd->status.agi;
  2502.         stats[2] = &sd->status.vit;
  2503.         stats[3] = &sd->status.int_;
  2504.         stats[4] = &sd->status.dex;
  2505.         stats[5] = &sd->status.luk;
  2506.  
  2507.         if( battle_config.atcommand_max_stat_bypass )
  2508.                 max = SHRT_MAX;
  2509.         else
  2510.                 max = pc_maxparameter(sd);
  2511.  
  2512.         if(value < 0 && *stats[i] <= -value) {
  2513.                 new_value = 1;
  2514.         } else if(max - *stats[i] < value) {
  2515.                 new_value = max;
  2516.         } else {
  2517.                 new_value = *stats[i] + value;
  2518.         }
  2519.  
  2520.         if (new_value != *stats[i]) {
  2521.                 *stats[i] = new_value;
  2522.                 clif->updatestatus(sd, SP_STR + i);
  2523.                 clif->updatestatus(sd, SP_USTR + i);
  2524.                 status_calc_pc(sd, SCO_FORCE);
  2525.                 clif->message(fd, msg_fd(fd,42)); // Stat changed.
  2526.         } else {
  2527.                 if (value < 0)
  2528.                         clif->message(fd, msg_fd(fd,41)); // Unable to decrease the number/value.
  2529.                 else
  2530.                         clif->message(fd, msg_fd(fd,149)); // Unable to increase the number/value.
  2531.                 return false;
  2532.         }
  2533.  
  2534.         return true;
  2535. }
  2536.  
  2537. /*==========================================
  2538.  * Stat all by fritz (rewritten by [Yor])
  2539.  *------------------------------------------*/
  2540. ACMD(stat_all) {
  2541.         int index, count, value, max, new_value;
  2542.         short* stats[6];
  2543.         //we don't use direct initialization because it isn't part of the c standard.
  2544.  
  2545.         stats[0] = &sd->status.str;
  2546.         stats[1] = &sd->status.agi;
  2547.         stats[2] = &sd->status.vit;
  2548.         stats[3] = &sd->status.int_;
  2549.         stats[4] = &sd->status.dex;
  2550.         stats[5] = &sd->status.luk;
  2551.  
  2552.         if (!*message || sscanf(message, "%d", &value) < 1 || value == 0) {
  2553.                 value = pc_maxparameter(sd);
  2554.                 max = pc_maxparameter(sd);
  2555.         } else {
  2556.                 if( battle_config.atcommand_max_stat_bypass )
  2557.                         max = SHRT_MAX;
  2558.                 else
  2559.                         max = pc_maxparameter(sd);
  2560.         }
  2561.  
  2562.         count = 0;
  2563.         for (index = 0; index < ARRAYLENGTH(stats); index++) {
  2564.                 if (value > 0 && *stats[index] > max - value)
  2565.                         new_value = max;
  2566.                 else if (value < 0 && *stats[index] <= -value)
  2567.                         new_value = 1;
  2568.                 else
  2569.                         new_value = *stats[index] +value;
  2570.  
  2571.                 if (new_value != (int)*stats[index]) {
  2572.                         *stats[index] = new_value;
  2573.                         clif->updatestatus(sd, SP_STR + index);
  2574.                         clif->updatestatus(sd, SP_USTR + index);
  2575.                         count++;
  2576.                 }
  2577.         }
  2578.  
  2579.         if (count > 0) { // if at least 1 stat modified
  2580.                 status_calc_pc(sd, SCO_FORCE);
  2581.                 clif->message(fd, msg_fd(fd,84)); // All stats changed!
  2582.         } else {
  2583.                 if (value < 0)
  2584.                         clif->message(fd, msg_fd(fd,177)); // You cannot decrease that stat anymore.
  2585.                 else
  2586.                         clif->message(fd, msg_fd(fd,178)); // You cannot increase that stat anymore.
  2587.                 return false;
  2588.         }
  2589.  
  2590.         return true;
  2591. }
  2592.  
  2593. /*==========================================
  2594.  *
  2595.  *------------------------------------------*/
  2596. ACMD(guildlevelup) {
  2597.         int level = 0;
  2598.         int16 added_level;
  2599.         struct guild *guild_info;
  2600.  
  2601.         if (!*message || sscanf(message, "%d", &level) < 1 || level == 0) {
  2602.                 clif->message(fd, msg_fd(fd,1014)); // Please enter a valid level (usage: @guildlvup/@guildlvlup <# of levels>).
  2603.                 return false;
  2604.         }
  2605.  
  2606.         if (sd->status.guild_id <= 0 || (guild_info = sd->guild) == NULL) {
  2607.                 clif->message(fd, msg_fd(fd,43)); // You're not in a guild.
  2608.                 return false;
  2609.         }
  2610. #if 0 // By enabling this, only the guild leader can use this command
  2611.         if (strcmp(sd->status.name, guild_info->master) != 0) {
  2612.                 clif->message(fd, msg_fd(fd,44)); // You're not the master of your guild.
  2613.                 return false;
  2614.         }
  2615. #endif // 0
  2616.  
  2617.         if (level > INT16_MAX || (level > 0 && level > MAX_GUILDLEVEL - guild_info->guild_lv)) // fix positive overflow
  2618.                 level = MAX_GUILDLEVEL - guild_info->guild_lv;
  2619.         else if (level < INT16_MIN || (level < 0 && level < 1 - guild_info->guild_lv)) // fix negative overflow
  2620.                 level = 1 - guild_info->guild_lv;
  2621.         added_level = (int16)level;
  2622.  
  2623.         if (added_level != 0) {
  2624.                 intif->guild_change_basicinfo(guild_info->guild_id, GBI_GUILDLV, &added_level, sizeof(added_level));
  2625.                 clif->message(fd, msg_fd(fd,179)); // Guild level changed.
  2626.         } else {
  2627.                 clif->message(fd, msg_fd(fd,45)); // Guild level change failed.
  2628.                 return false;
  2629.         }
  2630.  
  2631.         return true;
  2632. }
  2633.  
  2634. /*==========================================
  2635.  *
  2636.  *------------------------------------------*/
  2637. ACMD(makeegg)
  2638. {
  2639.         struct item_data *item_data;
  2640.         int id, pet_id;
  2641.  
  2642.         if (!*message) {
  2643.                 clif->message(fd, msg_fd(fd,1015)); // Please enter a monster/egg name/ID (usage: @makeegg <pet>).
  2644.                 return false;
  2645.         }
  2646.  
  2647.         if ((item_data = itemdb->search_name(message)) != NULL) // for egg name
  2648.                 id = item_data->nameid;
  2649.         else
  2650.                 if ((id = mob->db_searchname(message)) != 0) // for monster name
  2651.                         ;
  2652.                 else
  2653.                         id = atoi(message);
  2654.  
  2655.         pet_id = pet->search_petDB_index(id, PET_CLASS);
  2656.         if (pet_id < 0)
  2657.                 pet_id = pet->search_petDB_index(id, PET_EGG);
  2658.         if (pet_id >= 0) {
  2659.                 sd->catch_target_class = pet->db[pet_id].class_;
  2660.                 intif->create_pet(
  2661.                                                  sd->status.account_id, sd->status.char_id,
  2662.                                                  (short)pet->db[pet_id].class_, (short)mob->db(pet->db[pet_id].class_)->lv,
  2663.                                                  (short)pet->db[pet_id].EggID, 0, (short)pet->db[pet_id].intimate,
  2664.                                                  100, 0, 1, pet->db[pet_id].jname);
  2665.         } else {
  2666.                 clif->message(fd, msg_fd(fd,180)); // The monster/egg name/id doesn't exist.
  2667.                 return false;
  2668.         }
  2669.  
  2670.         return true;
  2671. }
  2672.  
  2673. /*==========================================
  2674.  *
  2675.  *------------------------------------------*/
  2676. ACMD(hatch)
  2677. {
  2678.         if (sd->status.pet_id <= 0)
  2679.                 clif->sendegg(sd);
  2680.         else {
  2681.                 clif->message(fd, msg_fd(fd,181)); // You already have a pet.
  2682.                 return false;
  2683.         }
  2684.  
  2685.         return true;
  2686. }
  2687.  
  2688. /*==========================================
  2689.  *
  2690.  *------------------------------------------*/
  2691. ACMD(petfriendly)
  2692. {
  2693.         int friendly;
  2694.         struct pet_data *pd;
  2695.  
  2696.         if (!*message || (friendly = atoi(message)) < 0) {
  2697.                 clif->message(fd, msg_fd(fd,1016)); // Please enter a valid value (usage: @petfriendly <0-1000>).
  2698.                 return false;
  2699.         }
  2700.  
  2701.         pd = sd->pd;
  2702.         if (!pd) {
  2703.                 clif->message(fd, msg_fd(fd,184)); // Sorry, but you have no pet.
  2704.                 return false;
  2705.         }
  2706.  
  2707.         if (friendly < 0 || friendly > 1000)
  2708.         {
  2709.                 clif->message(fd, msg_fd(fd,37)); // An invalid number was specified.
  2710.                 return false;
  2711.         }
  2712.  
  2713.         if (friendly == pd->pet.intimate) {
  2714.                 clif->message(fd, msg_fd(fd,183)); // Pet intimacy is already at maximum.
  2715.                 return false;
  2716.         }
  2717.  
  2718.         pet->set_intimate(pd, friendly);
  2719.         clif->send_petstatus(sd);
  2720.         clif->message(fd, msg_fd(fd,182)); // Pet intimacy changed.
  2721.         return true;
  2722. }
  2723.  
  2724. /*==========================================
  2725.  *
  2726.  *------------------------------------------*/
  2727. ACMD(pethungry)
  2728. {
  2729.         int hungry;
  2730.         struct pet_data *pd;
  2731.  
  2732.         if (!*message || (hungry = atoi(message)) < 0) {
  2733.                 clif->message(fd, msg_fd(fd,1017)); // Please enter a valid number (usage: @pethungry <0-100>).
  2734.                 return false;
  2735.         }
  2736.  
  2737.         pd = sd->pd;
  2738.         if (!sd->status.pet_id || !pd) {
  2739.                 clif->message(fd, msg_fd(fd,184)); // Sorry, but you have no pet.
  2740.                 return false;
  2741.         }
  2742.         if (hungry < 0 || hungry > 100) {
  2743.                 clif->message(fd, msg_fd(fd,37)); // An invalid number was specified.
  2744.                 return false;
  2745.         }
  2746.         if (hungry == pd->pet.hungry) {
  2747.                 clif->message(fd, msg_fd(fd,186)); // Pet hunger is already at maximum.
  2748.                 return false;
  2749.         }
  2750.  
  2751.         pd->pet.hungry = hungry;
  2752.         clif->send_petstatus(sd);
  2753.         clif->message(fd, msg_fd(fd,185)); // Pet hunger changed.
  2754.  
  2755.         return true;
  2756. }
  2757.  
  2758. /*==========================================
  2759.  *
  2760.  *------------------------------------------*/
  2761. ACMD(petrename)
  2762. {
  2763.         struct pet_data *pd;
  2764.         if (!sd->status.pet_id || !sd->pd) {
  2765.                 clif->message(fd, msg_fd(fd,184)); // Sorry, but you have no pet.
  2766.                 return false;
  2767.         }
  2768.         pd = sd->pd;
  2769.         if (!pd->pet.rename_flag) {
  2770.                 clif->message(fd, msg_fd(fd,188)); // You can already rename your pet.
  2771.                 return false;
  2772.         }
  2773.  
  2774.         pd->pet.rename_flag = 0;
  2775.         intif->save_petdata(sd->status.account_id, &pd->pet);
  2776.         clif->send_petstatus(sd);
  2777.         clif->message(fd, msg_fd(fd,187)); // You can now rename your pet.
  2778.  
  2779.         return true;
  2780. }
  2781.  
  2782. /*==========================================
  2783.  *
  2784.  *------------------------------------------*/
  2785. ACMD(recall) {
  2786.         struct map_session_data *pl_sd = NULL;
  2787.  
  2788.         if (!*message) {
  2789.                 clif->message(fd, msg_fd(fd,1018)); // Please enter a player name (usage: @recall <char name/ID>).
  2790.                 return false;
  2791.         }
  2792.  
  2793.         if((pl_sd=map->nick2sd((char *)message)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) {
  2794.                 clif->message(fd, msg_fd(fd,3)); // Character not found.
  2795.                 return false;
  2796.         }
  2797.  
  2798.         if ( pc_get_group_level(sd) < pc_get_group_level(pl_sd) )
  2799.         {
  2800.                 clif->message(fd, msg_fd(fd,81)); // Your GM level doesn't authorize you to preform this action on the specified player.
  2801.                 return false;
  2802.         }
  2803.  
  2804.         if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
  2805.                 clif->message(fd, msg_fd(fd,1019)); // You are not authorized to warp someone to this map.
  2806.                 return false;
  2807.         }
  2808.         if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
  2809.                 clif->message(fd, msg_fd(fd,1020)); // You are not authorized to warp this player from their map.
  2810.                 return false;
  2811.         }
  2812.         if (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y) {
  2813.                 return false;
  2814.         }
  2815.         pc->setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
  2816.         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,46), pl_sd->status.name); // %s recalled!
  2817.         clif->message(fd, atcmd_output);
  2818.  
  2819.         return true;
  2820. }
  2821.  
  2822. /*==========================================
  2823.  * charblock command (usage: charblock <player_name>)
  2824.  * This command do a definitiv ban on a player
  2825.  *------------------------------------------*/
  2826. ACMD(char_block)
  2827. {
  2828.  
  2829.         memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
  2830.  
  2831.         if (!*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
  2832.                 clif->message(fd, msg_fd(fd,1021)); // Please enter a player name (usage: @block <char name>).
  2833.                 return false;
  2834.         }
  2835.  
  2836.         chrif->char_ask_name(sd->status.account_id, atcmd_player_name, CHAR_ASK_NAME_BLOCK, 0, 0, 0, 0, 0, 0);
  2837.         clif->message(fd, msg_fd(fd,88)); // Character name sent to char-server to ask it.
  2838.  
  2839.         return true;
  2840. }
  2841.  
  2842. /*==========================================
  2843.  * charban command (usage: charban <time> <player_name>)
  2844.  * This command do a limited ban on a player
  2845.  * Time is done as follows:
  2846.  *   Adjustment value (-1, 1, +1, etc...)
  2847.  *   Modified element:
  2848.  *     a or y: year
  2849.  *     m:  month
  2850.  *     j or d: day
  2851.  *     h:  hour
  2852.  *     mn: minute
  2853.  *     s:  second
  2854.  * <example> @ban +1m-2mn1s-6y test_player
  2855.  *           this example adds 1 month and 1 second, and subtracts 2 minutes and 6 years at the same time.
  2856.  *------------------------------------------*/
  2857. ACMD(char_ban)
  2858. {
  2859.         char *modif_p;
  2860.         int year, month, day, hour, minute, second;
  2861.         time_t timestamp;
  2862.         struct tm *tmtime;
  2863.  
  2864.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  2865.         memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
  2866.  
  2867.         if (!*message || sscanf(message, "%255s %23[^\n]", atcmd_output, atcmd_player_name) < 2) {
  2868.                 clif->message(fd, msg_fd(fd,1022)); // Please enter ban time and a player name (usage: @ban <time> <char name>).
  2869.                 return false;
  2870.         }
  2871.  
  2872.         atcmd_output[sizeof(atcmd_output)-1] = '\0';
  2873.  
  2874.         modif_p = atcmd_output;
  2875.         year = month = day = hour = minute = second = 0;
  2876.         while (modif_p[0] != '\0') {
  2877.                 int value = atoi(modif_p);
  2878.                 if (value == 0)
  2879.                         modif_p++;
  2880.                 else {
  2881.                         if (modif_p[0] == '-' || modif_p[0] == '+')
  2882.                                 modif_p++;
  2883.                         while (modif_p[0] >= '0' && modif_p[0] <= '9')
  2884.                                 modif_p++;
  2885.                         if (modif_p[0] == 's') {
  2886.                                 second = value;
  2887.                                 modif_p++;
  2888.                         } else if (modif_p[0] == 'n') {
  2889.                                 minute = value;
  2890.                                 modif_p++;
  2891.                         } else if (modif_p[0] == 'm' && modif_p[1] == 'n') {
  2892.                                 minute = value;
  2893.                                 modif_p = modif_p + 2;
  2894.                         } else if (modif_p[0] == 'h') {
  2895.                                 hour = value;
  2896.                                 modif_p++;
  2897.                         } else if (modif_p[0] == 'd' || modif_p[0] == 'j') {
  2898.                                 day = value;
  2899.                                 modif_p++;
  2900.                         } else if (modif_p[0] == 'm') {
  2901.                                 month = value;
  2902.                                 modif_p++;
  2903.                         } else if (modif_p[0] == 'y' || modif_p[0] == 'a') {
  2904.                                 year = value;
  2905.                                 modif_p++;
  2906.                         } else if (modif_p[0] != '\0') {
  2907.                                 modif_p++;
  2908.                         }
  2909.                 }
  2910.         }
  2911.         if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0) {
  2912.                 clif->message(fd, msg_fd(fd,85)); // Invalid time for ban command.
  2913.                 return false;
  2914.         }
  2915.         /**
  2916.          * We now check if you can adjust the ban to negative (and if this is the case)
  2917.          **/
  2918.         timestamp = time(NULL);
  2919.         tmtime = localtime(&timestamp);
  2920.         tmtime->tm_year = tmtime->tm_year + year;
  2921.         tmtime->tm_mon  = tmtime->tm_mon + month;
  2922.         tmtime->tm_mday = tmtime->tm_mday + day;
  2923.         tmtime->tm_hour = tmtime->tm_hour + hour;
  2924.         tmtime->tm_min  = tmtime->tm_min + minute;
  2925.         tmtime->tm_sec  = tmtime->tm_sec + second;
  2926.         timestamp = mktime(tmtime);
  2927.         if( timestamp <= time(NULL) && !pc->can_use_command(sd, "@unban") ) {
  2928.                 clif->message(fd,msg_fd(fd,1023)); // You are not allowed to reduce the length of a ban.
  2929.                 return false;
  2930.         }
  2931.  
  2932.         chrif->char_ask_name(sd->status.account_id, atcmd_player_name,
  2933.                              !strcmpi(info->command,"charban") ? CHAR_ASK_NAME_CHARBAN : CHAR_ASK_NAME_BAN, year, month, day, hour, minute, second);
  2934.         clif->message(fd, msg_fd(fd,88)); // Character name sent to char-server to ask it.
  2935.  
  2936.         return true;
  2937. }
  2938.  
  2939. /*==========================================
  2940.  * charunblock command (usage: charunblock <player_name>)
  2941.  *------------------------------------------*/
  2942. ACMD(char_unblock)
  2943. {
  2944.         memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
  2945.  
  2946.         if (!*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
  2947.                 clif->message(fd, msg_fd(fd,1024)); // Please enter a player name (usage: @unblock <char name>).
  2948.                 return false;
  2949.         }
  2950.  
  2951.         // send answer to login server via char-server
  2952.         chrif->char_ask_name(sd->status.account_id, atcmd_player_name, CHAR_ASK_NAME_UNBLOCK, 0, 0, 0, 0, 0, 0);
  2953.         clif->message(fd, msg_fd(fd,88)); // Character name sent to char-server to ask it.
  2954.  
  2955.         return true;
  2956. }
  2957.  
  2958. /*==========================================
  2959.  * charunban command (usage: charunban <player_name>)
  2960.  *------------------------------------------*/
  2961. ACMD(char_unban)
  2962. {
  2963.         memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
  2964.  
  2965.         if (!*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
  2966.                 clif->message(fd, msg_fd(fd,1025)); // Please enter a player name (usage: @unban <char name>).
  2967.                 return false;
  2968.         }
  2969.  
  2970.         // send answer to login server via char-server
  2971.         chrif->char_ask_name(sd->status.account_id, atcmd_player_name,
  2972.                              !strcmpi(info->command,"charunban") ? CHAR_ASK_NAME_CHARUNBAN : CHAR_ASK_NAME_UNBAN, 0, 0, 0, 0, 0, 0);
  2973.         clif->message(fd, msg_fd(fd,88)); // Character name sent to char-server to ask it.
  2974.  
  2975.         return true;
  2976. }
  2977.  
  2978. /*==========================================
  2979.  *
  2980.  *------------------------------------------*/
  2981. ACMD(night)
  2982. {
  2983.         if (map->night_flag != 1) {
  2984.                 pc->map_night_timer(pc->night_timer_tid, 0, 0, 1);
  2985.         } else {
  2986.                 clif->message(fd, msg_fd(fd,89)); // Night mode is already enabled.
  2987.                 return false;
  2988.         }
  2989.  
  2990.         return true;
  2991. }
  2992.  
  2993. /*==========================================
  2994.  *
  2995.  *------------------------------------------*/
  2996. ACMD(day)
  2997. {
  2998.         if (map->night_flag != 0) {
  2999.                 pc->map_day_timer(pc->day_timer_tid, 0, 0, 1);
  3000.         } else {
  3001.                 clif->message(fd, msg_fd(fd,90)); // Day mode is already enabled.
  3002.                 return false;
  3003.         }
  3004.  
  3005.         return true;
  3006. }
  3007.  
  3008. /*==========================================
  3009.  *
  3010.  *------------------------------------------*/
  3011. ACMD(doom)
  3012. {
  3013.         struct map_session_data* pl_sd;
  3014.         struct s_mapiterator* iter;
  3015.  
  3016.         iter = mapit_getallusers();
  3017.         for (pl_sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCAST(BL_PC, mapit->next(iter))) {
  3018.                 if (pl_sd->fd != fd && pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) {
  3019.                         status_kill(&pl_sd->bl);
  3020.                         clif->specialeffect(&pl_sd->bl,450,AREA);
  3021.                         clif->message(pl_sd->fd, msg_fd(fd,61)); // The holy messenger has given judgment.
  3022.                 }
  3023.         }
  3024.         mapit->free(iter);
  3025.  
  3026.         clif->message(fd, msg_fd(fd,62)); // Judgment was made.
  3027.  
  3028.         return true;
  3029. }
  3030.  
  3031. /*==========================================
  3032.  *
  3033.  *------------------------------------------*/
  3034. ACMD(doommap)
  3035. {
  3036.         struct map_session_data* pl_sd;
  3037.         struct s_mapiterator* iter;
  3038.  
  3039.         iter = mapit_getallusers();
  3040.         for (pl_sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCAST(BL_PC, mapit->next(iter))) {
  3041.                 if (pl_sd->fd != fd && sd->bl.m == pl_sd->bl.m && pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) {
  3042.                         status_kill(&pl_sd->bl);
  3043.                         clif->specialeffect(&pl_sd->bl,450,AREA);
  3044.                         clif->message(pl_sd->fd, msg_fd(fd,61)); // The holy messenger has given judgment.
  3045.                 }
  3046.         }
  3047.         mapit->free(iter);
  3048.  
  3049.         clif->message(fd, msg_fd(fd,62)); // Judgment was made.
  3050.  
  3051.         return true;
  3052. }
  3053.  
  3054. /*==========================================
  3055.  *
  3056.  *------------------------------------------*/
  3057. void atcommand_raise_sub(struct map_session_data* sd)
  3058. {
  3059.         nullpo_retv(sd);
  3060.         status->revive(&sd->bl, 100, 100);
  3061.  
  3062.         clif->skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1);
  3063.         clif->message(sd->fd, msg_sd(sd,63)); // Mercy has been shown.
  3064. }
  3065.  
  3066. /*==========================================
  3067.  *
  3068.  *------------------------------------------*/
  3069. ACMD(raise)
  3070. {
  3071.         struct map_session_data* pl_sd;
  3072.         struct s_mapiterator* iter;
  3073.  
  3074.         iter = mapit_getallusers();
  3075.         for (pl_sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCAST(BL_PC, mapit->next(iter)))
  3076.                 if( pc_isdead(pl_sd) )
  3077.                         atcommand->raise_sub(pl_sd);
  3078.         mapit->free(iter);
  3079.  
  3080.         clif->message(fd, msg_fd(fd,64)); // Mercy has been granted.
  3081.  
  3082.         return true;
  3083. }
  3084.  
  3085. /*==========================================
  3086.  *
  3087.  *------------------------------------------*/
  3088. ACMD(raisemap)
  3089. {
  3090.         struct map_session_data* pl_sd;
  3091.         struct s_mapiterator* iter;
  3092.  
  3093.         iter = mapit_getallusers();
  3094.         for (pl_sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCAST(BL_PC, mapit->next(iter)))
  3095.                 if (sd->bl.m == pl_sd->bl.m && pc_isdead(pl_sd) )
  3096.                         atcommand->raise_sub(pl_sd);
  3097.         mapit->free(iter);
  3098.  
  3099.         clif->message(fd, msg_fd(fd,64)); // Mercy has been granted.
  3100.  
  3101.         return true;
  3102. }
  3103.  
  3104. /*==========================================
  3105.  *
  3106.  *------------------------------------------*/
  3107. ACMD(kick)
  3108. {
  3109.         struct map_session_data *pl_sd;
  3110.  
  3111.         memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
  3112.  
  3113.         if (!*message) {
  3114.                 clif->message(fd, msg_fd(fd,1026)); // Please enter a player name (usage: @kick <char name/ID>).
  3115.                 return false;
  3116.         }
  3117.  
  3118.         if((pl_sd=map->nick2sd((char *)message)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) {
  3119.                 clif->message(fd, msg_fd(fd,3)); // Character not found.
  3120.                 return false;
  3121.         }
  3122.  
  3123.         if (pc_get_group_level(sd) < pc_get_group_level(pl_sd))
  3124.         {
  3125.                 clif->message(fd, msg_fd(fd,81)); // Your GM level don't authorize you to do this action on this player.
  3126.                 return false;
  3127.         }
  3128.  
  3129.         clif->GM_kick(sd, pl_sd);
  3130.  
  3131.         return true;
  3132. }
  3133.  
  3134. /*==========================================
  3135.  *
  3136.  *------------------------------------------*/
  3137. ACMD(kickall)
  3138. {
  3139.         struct map_session_data* pl_sd;
  3140.         struct s_mapiterator* iter;
  3141.  
  3142.         iter = mapit_getallusers();
  3143.         for (pl_sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCAST(BL_PC, mapit->next(iter))) {
  3144.                 if (pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) { // you can kick only lower or same gm level
  3145.                         if (sd->status.account_id != pl_sd->status.account_id)
  3146.                                 clif->GM_kick(NULL, pl_sd);
  3147.                 }
  3148.         }
  3149.         mapit->free(iter);
  3150.  
  3151.         clif->message(fd, msg_fd(fd,195)); // All players have been kicked!
  3152.  
  3153.         return true;
  3154. }
  3155.  
  3156. /*==========================================
  3157.  *
  3158.  *------------------------------------------*/
  3159. ACMD(allskill)
  3160. {
  3161.         pc->allskillup(sd); // all skills
  3162.         sd->status.skill_point = 0; // 0 skill points
  3163.         clif->updatestatus(sd, SP_SKILLPOINT); // update
  3164.         clif->message(fd, msg_fd(fd,76)); // All skills have been added to your skill tree.
  3165.  
  3166.         return true;
  3167. }
  3168.  
  3169. /*==========================================
  3170.  *
  3171.  *------------------------------------------*/
  3172. ACMD(questskill)
  3173. {
  3174.         uint16 skill_id, index;
  3175.  
  3176.         if (!*message || (skill_id = atoi(message)) <= 0)
  3177.         { // also send a list of skills applicable to this command
  3178.                 const char* text;
  3179.  
  3180.                 // attempt to find the text corresponding to this command
  3181.                 text = atcommand_help_string( info );
  3182.  
  3183.                 // send the error message as always
  3184.                 clif->message(fd, msg_fd(fd,1027)); // Please enter a quest skill number.
  3185.  
  3186.                 if( text ) {// send the skill ID list associated with this command
  3187.                         clif->messageln( fd, text );
  3188.                 }
  3189.  
  3190.                 return false;
  3191.         }
  3192.         if( !(index = skill->get_index(skill_id)) ) {
  3193.                 clif->message(fd, msg_fd(fd,198)); // This skill number doesn't exist.
  3194.                 return false;
  3195.         }
  3196.         if (!(skill->get_inf2(skill_id) & INF2_QUEST_SKILL)) {
  3197.                 clif->message(fd, msg_fd(fd,197)); // This skill number doesn't exist or isn't a quest skill.
  3198.                 return false;
  3199.         }
  3200.         if (pc->checkskill2(sd, index) > 0) {
  3201.                 clif->message(fd, msg_fd(fd,196)); // You already have this quest skill.
  3202.                 return false;
  3203.         }
  3204.  
  3205.         pc->skill(sd, skill_id, 1, SKILL_GRANT_PERMANENT);
  3206.         clif->message(fd, msg_fd(fd,70)); // You have learned the skill.
  3207.  
  3208.         return true;
  3209. }
  3210.  
  3211. /*==========================================
  3212.  *
  3213.  *------------------------------------------*/
  3214. ACMD(lostskill)
  3215. {
  3216.         uint16 skill_id, index;
  3217.  
  3218.         if (!*message || (skill_id = atoi(message)) <= 0)
  3219.         { // also send a list of skills applicable to this command
  3220.                 const char* text;
  3221.  
  3222.                 // attempt to find the text corresponding to this command
  3223.                 text = atcommand_help_string( info );
  3224.  
  3225.                 // send the error message as always
  3226.                 clif->message(fd, msg_fd(fd,1027)); // Please enter a quest skill number.
  3227.  
  3228.                 if( text ) {// send the skill ID list associated with this command
  3229.                         clif->messageln( fd, text );
  3230.                 }
  3231.  
  3232.                 return false;
  3233.         }
  3234.         if (!( index = skill->get_index(skill_id))) {
  3235.                 clif->message(fd, msg_fd(fd,198)); // This skill number doesn't exist.
  3236.                 return false;
  3237.         }
  3238.         if (!(skill->get_inf2(skill_id) & INF2_QUEST_SKILL)) {
  3239.                 clif->message(fd, msg_fd(fd,197)); // This skill number doesn't exist or isn't a quest skill.
  3240.                 return false;
  3241.         }
  3242.         if (pc->checkskill2(sd, index) == 0) {
  3243.                 clif->message(fd, msg_fd(fd,201)); // You don't have this quest skill.
  3244.                 return false;
  3245.         }
  3246.  
  3247.         sd->status.skill[index].lv = 0;
  3248.         sd->status.skill[index].flag = 0;
  3249.         clif->deleteskill(sd,skill_id);
  3250.         clif->message(fd, msg_fd(fd,71)); // You have forgotten the skill.
  3251.  
  3252.         return true;
  3253. }
  3254.  
  3255. /*==========================================
  3256.  *
  3257.  *------------------------------------------*/
  3258. ACMD(spiritball)
  3259. {
  3260.         int max_spiritballs;
  3261.         int number;
  3262.  
  3263.         max_spiritballs = min(ARRAYLENGTH(sd->spirit_timer), 0x7FFF);
  3264.  
  3265.         if (!*message || (number = atoi(message)) < 0 || number > max_spiritballs)
  3266.         {
  3267.                 char msg[CHAT_SIZE_MAX];
  3268.                 safesnprintf(msg, sizeof(msg), msg_fd(fd,1028), max_spiritballs); // Please enter an amount (usage: @spiritball <number: 0-%d>).
  3269.                 clif->message(fd, msg);
  3270.                 return false;
  3271.         }
  3272.  
  3273.         if( sd->spiritball > 0 )
  3274.                 pc->delspiritball(sd, sd->spiritball, 1);
  3275.         sd->spiritball = number;
  3276.         clif->spiritball(&sd->bl);
  3277.         // no message, player can look the difference
  3278.  
  3279.         return true;
  3280. }
  3281.  
  3282. /*==========================================
  3283.  *
  3284.  *------------------------------------------*/
  3285. ACMD(party)
  3286. {
  3287.         char party_name[NAME_LENGTH];
  3288.  
  3289.         memset(party_name, '\0', sizeof(party_name));
  3290.  
  3291.         if (!*message || sscanf(message, "%23[^\n]", party_name) < 1) {
  3292.                 clif->message(fd, msg_fd(fd,1029)); // Please enter a party name (usage: @party <party_name>).
  3293.                 return false;
  3294.         }
  3295.  
  3296.         party->create(sd, party_name, 0, 0);
  3297.  
  3298.         return true;
  3299. }
  3300.  
  3301. /*==========================================
  3302.  *
  3303.  *------------------------------------------*/
  3304. ACMD(guild)
  3305. {
  3306.         char guild_name[NAME_LENGTH];
  3307.         int prev;
  3308.  
  3309.         memset(guild_name, '\0', sizeof(guild_name));
  3310.  
  3311.         if (!*message || sscanf(message, "%23[^\n]", guild_name) < 1) {
  3312.                 clif->message(fd, msg_fd(fd,1030)); // Please enter a guild name (usage: @guild <guild_name>).
  3313.                 return false;
  3314.         }
  3315.  
  3316.         prev = battle_config.guild_emperium_check;
  3317.         battle_config.guild_emperium_check = 0;
  3318.         guild->create(sd, guild_name);
  3319.         battle_config.guild_emperium_check = prev;
  3320.  
  3321.         return true;
  3322. }
  3323.  
  3324. ACMD(breakguild)
  3325. {
  3326.         if (sd->status.guild_id) { // Check if the player has a guild
  3327.                 struct guild *g = sd->guild; // Search the guild
  3328.                 if (g) { // Check if guild was found
  3329.                         if (sd->state.gmaster_flag) { // Check if player is guild master
  3330.                                 int ret = 0;
  3331.                                 ret = guild->dobreak(sd, g->name); // Break guild
  3332.                                 if (ret) { // Check if anything went wrong
  3333.                                         return true; // Guild was broken
  3334.                                 } else {
  3335.                                         return false; // Something went wrong
  3336.                                 }
  3337.                         } else { // Not guild master
  3338.                                 clif->message(fd, msg_fd(fd,1181)); // You need to be a Guild Master to use this command.
  3339.                                 return false;
  3340.                         }
  3341.                 } else { // Guild was not found. HOW?
  3342.                         clif->message(fd, msg_fd(fd,252)); // You are not in a guild.
  3343.                         return false;
  3344.                 }
  3345.         } else { // Player does not have a guild
  3346.                 clif->message(fd, msg_fd(fd,252)); // You are not in a guild.
  3347.                 return false;
  3348.         }
  3349.         return true;
  3350. }
  3351.  
  3352. /*==========================================
  3353.  *
  3354.  *------------------------------------------*/
  3355. ACMD(agitstart) {
  3356.         if (map->agit_flag == 1) {
  3357.                 clif->message(fd, msg_fd(fd,73)); // War of Emperium is currently in progress.
  3358.                 return false;
  3359.         }
  3360.  
  3361.         map->agit_flag = 1;
  3362.         guild->agit_start();
  3363.         clif->message(fd, msg_fd(fd,72)); // War of Emperium has been initiated.
  3364.  
  3365.         return true;
  3366. }
  3367.  
  3368. /*==========================================
  3369.  *
  3370.  *------------------------------------------*/
  3371. ACMD(agitstart2) {
  3372.         if (map->agit2_flag == 1) {
  3373.                 clif->message(fd, msg_fd(fd,404)); // "War of Emperium SE is currently in progress."
  3374.                 return false;
  3375.         }
  3376.  
  3377.         map->agit2_flag = 1;
  3378.         guild->agit2_start();
  3379.         clif->message(fd, msg_fd(fd,403)); // "War of Emperium SE has been initiated."
  3380.  
  3381.         return true;
  3382. }
  3383.  
  3384. /*==========================================
  3385.  *
  3386.  *------------------------------------------*/
  3387. ACMD(agitend) {
  3388.         if (map->agit_flag == 0) {
  3389.                 clif->message(fd, msg_fd(fd,75)); // War of Emperium is currently not in progress.
  3390.                 return false;
  3391.         }
  3392.  
  3393.         map->agit_flag = 0;
  3394.         guild->agit_end();
  3395.         clif->message(fd, msg_fd(fd,74)); // War of Emperium has been ended.
  3396.  
  3397.         return true;
  3398. }
  3399.  
  3400. /*==========================================
  3401.  *
  3402.  *------------------------------------------*/
  3403. ACMD(agitend2) {
  3404.         if (map->agit2_flag == 0) {
  3405.                 clif->message(fd, msg_fd(fd,406)); // "War of Emperium SE is currently not in progress."
  3406.                 return false;
  3407.         }
  3408.  
  3409.         map->agit2_flag = 0;
  3410.         guild->agit2_end();
  3411.         clif->message(fd, msg_fd(fd,405)); // "War of Emperium SE has been ended."
  3412.  
  3413.         return true;
  3414. }
  3415.  
  3416. /*==========================================
  3417.  * @mapexit - shuts down the map server
  3418.  *------------------------------------------*/
  3419. ACMD(mapexit) {
  3420.         map->do_shutdown();
  3421.         return true;
  3422. }
  3423.  
  3424. /*==========================================
  3425.  * idsearch <part_of_name>: rewrite by [Yor]
  3426.  *------------------------------------------*/
  3427. ACMD(idsearch)
  3428. {
  3429.         char item_name[100];
  3430.         unsigned int i, match;
  3431.         struct item_data *item_array[MAX_SEARCH];
  3432.  
  3433.         memset(item_name, '\0', sizeof(item_name));
  3434.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  3435.  
  3436.         if (!*message || sscanf(message, "%99s", item_name) < 0) {
  3437.                 clif->message(fd, msg_fd(fd,1031)); // Please enter part of an item name (usage: @idsearch <part_of_item_name>).
  3438.                 return false;
  3439.         }
  3440.  
  3441.         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,77), item_name); // Search results for '%s' (name: id):
  3442.         clif->message(fd, atcmd_output);
  3443.         match = itemdb->search_name_array(item_array, MAX_SEARCH, item_name, 0);
  3444.         if (match > MAX_SEARCH) {
  3445.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,269), MAX_SEARCH, match);
  3446.                 clif->message(fd, atcmd_output);
  3447.                 match = MAX_SEARCH;
  3448.         }
  3449.         for(i = 0; i < match; i++) {
  3450.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,78), item_array[i]->jname, item_array[i]->nameid); // %s: %d
  3451.                 clif->message(fd, atcmd_output);
  3452.         }
  3453.         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,79), match); // %d results found.
  3454.         clif->message(fd, atcmd_output);
  3455.  
  3456.         return true;
  3457. }
  3458.  
  3459. /*==========================================
  3460.  * Recall All Characters Online To Your Location
  3461.  *------------------------------------------*/
  3462. ACMD(recallall)
  3463. {
  3464.         struct map_session_data* pl_sd;
  3465.         struct s_mapiterator* iter;
  3466.         int count;
  3467.  
  3468.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  3469.  
  3470.         if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
  3471.                 clif->message(fd, msg_fd(fd,1032)); // You are not authorized to warp someone to your current map.
  3472.                 return false;
  3473.         }
  3474.  
  3475.         count = 0;
  3476.         iter = mapit_getallusers();
  3477.         for (pl_sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCAST(BL_PC, mapit->next(iter))) {
  3478.                 if (sd->status.account_id != pl_sd->status.account_id && pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) {
  3479.                         if (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y)
  3480.                                 continue; // Don't waste time warping the character to the same place.
  3481.                         if( pl_sd->state.vending || pl_sd->state.buyingstore || pl_sd->state.autotrade ) //check if player is vending or buying
  3482.                                 continue;
  3483.                         if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))
  3484.                                 count++;
  3485.                         else {
  3486.                                 if (pc_isdead(pl_sd)) { //Wake them up
  3487.                                         pc->setstand(pl_sd);
  3488.                                         pc->setrestartvalue(pl_sd,1);
  3489.                                 }
  3490.                                 pc->setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
  3491.                         }
  3492.                 }
  3493.         }
  3494.         mapit->free(iter);
  3495.  
  3496.         clif->message(fd, msg_fd(fd,92)); // All characters recalled!
  3497.         if (count) {
  3498.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1033), count); // Because you are not authorized to warp from some maps, %d player(s) have not been recalled.
  3499.                 clif->message(fd, atcmd_output);
  3500.         }
  3501.  
  3502.         return true;
  3503. }
  3504.  
  3505. /*==========================================
  3506.  * Recall online characters of a guild to your location
  3507.  *------------------------------------------*/
  3508. ACMD(guildrecall)
  3509. {
  3510.         struct map_session_data* pl_sd;
  3511.         struct s_mapiterator* iter;
  3512.         int count;
  3513.         char guild_name[NAME_LENGTH];
  3514.         struct guild *g;
  3515.  
  3516.         memset(guild_name, '\0', sizeof(guild_name));
  3517.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  3518.  
  3519.         if (!*message || sscanf(message, "%23[^\n]", guild_name) < 1) {
  3520.                 clif->message(fd, msg_fd(fd,1034)); // Please enter a guild name/ID (usage: @guildrecall <guild_name/ID>).
  3521.                 return false;
  3522.         }
  3523.  
  3524.         if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
  3525.                 clif->message(fd, msg_fd(fd,1032)); // You are not authorized to warp someone to your current map.
  3526.                 return false;
  3527.         }
  3528.  
  3529.         if ((g = guild->searchname(guild_name)) == NULL && // name first to avoid error when name begin with a number
  3530.             (g = guild->search(atoi(message))) == NULL)
  3531.         {
  3532.                 clif->message(fd, msg_fd(fd,94)); // Incorrect name/ID, or no one from the guild is online.
  3533.                 return false;
  3534.         }
  3535.  
  3536.         count = 0;
  3537.  
  3538.         iter = mapit_getallusers();
  3539.         for (pl_sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCAST(BL_PC, mapit->next(iter))) {
  3540.                 if (sd->status.account_id != pl_sd->status.account_id && pl_sd->status.guild_id == g->guild_id) {
  3541.                         if (pc_get_group_level(pl_sd) > pc_get_group_level(sd) || (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y))
  3542.                                 continue; // Skip GMs greater than you...             or chars already on the cell
  3543.                         if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))
  3544.                                 count++;
  3545.                         else
  3546.                                 pc->setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
  3547.                 }
  3548.         }
  3549.         mapit->free(iter);
  3550.  
  3551.         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,93), g->name); // All online characters of the %s guild have been recalled to your position.
  3552.         clif->message(fd, atcmd_output);
  3553.         if (count) {
  3554.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1033), count); // Because you are not authorized to warp from some maps, %d player(s) have not been recalled.
  3555.                 clif->message(fd, atcmd_output);
  3556.         }
  3557.  
  3558.         return true;
  3559. }
  3560.  
  3561. /*==========================================
  3562.  * Recall online characters of a party to your location
  3563.  *------------------------------------------*/
  3564. ACMD(partyrecall)
  3565. {
  3566.         struct map_session_data* pl_sd;
  3567.         struct s_mapiterator* iter;
  3568.         char party_name[NAME_LENGTH];
  3569.         struct party_data *p;
  3570.         int count;
  3571.  
  3572.         memset(party_name, '\0', sizeof(party_name));
  3573.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  3574.  
  3575.         if (!*message || sscanf(message, "%23[^\n]", party_name) < 1) {
  3576.                 clif->message(fd, msg_fd(fd,1035)); // Please enter a party name/ID (usage: @partyrecall <party_name/ID>).
  3577.                 return false;
  3578.         }
  3579.  
  3580.         if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
  3581.                 clif->message(fd, msg_fd(fd,1032)); // You are not authorized to warp someone to your current map.
  3582.                 return false;
  3583.         }
  3584.  
  3585.         if ((p = party->searchname(party_name)) == NULL && // name first to avoid error when name begin with a number
  3586.             (p = party->search(atoi(message))) == NULL)
  3587.         {
  3588.                 clif->message(fd, msg_fd(fd,96)); // Incorrect name or ID, or no one from the party is online.
  3589.                 return false;
  3590.         }
  3591.  
  3592.         count = 0;
  3593.  
  3594.         iter = mapit_getallusers();
  3595.         for (pl_sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCAST(BL_PC, mapit->next(iter))) {
  3596.                 if (sd->status.account_id != pl_sd->status.account_id && pl_sd->status.party_id == p->party.party_id) {
  3597.                         if (pc_get_group_level(pl_sd) > pc_get_group_level(sd) || (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y))
  3598.                                 continue; // Skip GMs greater than you...             or chars already on the cell
  3599.                         if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))
  3600.                                 count++;
  3601.                         else
  3602.                                 pc->setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN);
  3603.                 }
  3604.         }
  3605.         mapit->free(iter);
  3606.  
  3607.         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,95), p->party.name); // All online characters of the %s party have been recalled to your position.
  3608.         clif->message(fd, atcmd_output);
  3609.         if (count) {
  3610.                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1033), count); // Because you are not authorized to warp from some maps, %d player(s) have not been recalled.
  3611.                 clif->message(fd, atcmd_output);
  3612.         }
  3613.  
  3614.         return true;
  3615. }
  3616.  
  3617. /*==========================================
  3618.  *
  3619.  *------------------------------------------*/
  3620. ACMD(reloaditemdb)
  3621. {
  3622.         itemdb->reload();
  3623.         clif->message(fd, msg_fd(fd,97)); // Item database has been reloaded.
  3624.  
  3625.         return true;
  3626. }
  3627.  
  3628. /*==========================================
  3629.  *
  3630.  *------------------------------------------*/
  3631. ACMD(reloadmobdb) {
  3632.         mob->reload();
  3633.         pet->read_db();
  3634.         homun->reload();
  3635.         mercenary->read_db();
  3636.         mercenary->read_skilldb();
  3637.         elemental->reload_db();
  3638.         clif->message(fd, msg_fd(fd,98)); // Monster database has been reloaded.
  3639.  
  3640.         return true;
  3641. }
  3642.  
  3643. /*==========================================
  3644.  *
  3645.  *------------------------------------------*/
  3646. ACMD(reloadskilldb)
  3647. {
  3648.         skill->reload();
  3649.         homun->reload_skill();
  3650.         elemental->reload_skilldb();
  3651.         mercenary->read_skilldb();
  3652.         clif->message(fd, msg_fd(fd,99)); // Skill database has been reloaded.
  3653.  
  3654.         return true;
  3655. }
  3656.  
  3657. /*==========================================
  3658.  * @reloadatcommand - reloads conf/atcommand.conf conf/groups.conf
  3659.  *------------------------------------------*/
  3660. ACMD(reloadatcommand) {
  3661.         config_t run_test;
  3662.  
  3663.         if (libconfig->read_file(&run_test, "conf/groups.conf")) {
  3664.                 clif->message(fd, msg_fd(fd,1036)); // Error reading groups.conf, reload failed.
  3665.                 return false;
  3666.         }
  3667.  
  3668.         libconfig->destroy(&run_test);
  3669.  
  3670.         if (libconfig->read_file(&run_test, map->ATCOMMAND_CONF_FILENAME)) {
  3671.                 clif->message(fd, msg_fd(fd,1037)); // Error reading atcommand.conf, reload failed.
  3672.                 return false;
  3673.         }
  3674.  
  3675.         libconfig->destroy(&run_test);
  3676.  
  3677.         atcommand->doload();
  3678.         pcg->reload();
  3679.         clif->message(fd, msg_fd(fd,254));
  3680.         return true;
  3681. }
  3682. /*==========================================
  3683.  * @reloadbattleconf - reloads /conf/battle.conf
  3684.  *------------------------------------------*/
  3685. ACMD(reloadbattleconf)
  3686. {
  3687.         struct Battle_Config prev_config;
  3688.         memcpy(&prev_config, &battle_config, sizeof(prev_config));
  3689.  
  3690.         battle->config_read(map->BATTLE_CONF_FILENAME);
  3691.  
  3692.         if( prev_config.item_rate_mvp          != battle_config.item_rate_mvp
  3693.            ||  prev_config.item_rate_common       != battle_config.item_rate_common
  3694.            ||  prev_config.item_rate_common_boss  != battle_config.item_rate_common_boss
  3695.            ||  prev_config.item_rate_card         != battle_config.item_rate_card
  3696.            ||  prev_config.item_rate_card_boss    != battle_config.item_rate_card_boss
  3697.            ||  prev_config.item_rate_equip        != battle_config.item_rate_equip
  3698.            ||  prev_config.item_rate_equip_boss   != battle_config.item_rate_equip_boss
  3699.            ||  prev_config.item_rate_heal         != battle_config.item_rate_heal
  3700.            ||  prev_config.item_rate_heal_boss    != battle_config.item_rate_heal_boss
  3701.            ||  prev_config.item_rate_use          != battle_config.item_rate_use
  3702.            ||  prev_config.item_rate_use_boss     != battle_config.item_rate_use_boss
  3703.            ||  prev_config.item_rate_treasure     != battle_config.item_rate_treasure
  3704.            ||  prev_config.item_rate_adddrop      != battle_config.item_rate_adddrop
  3705.            ||  prev_config.logarithmic_drops      != battle_config.logarithmic_drops
  3706.            ||  prev_config.item_drop_common_min   != battle_config.item_drop_common_min
  3707.            ||  prev_config.item_drop_common_max   != battle_config.item_drop_common_max
  3708.            ||  prev_config.item_drop_card_min     != battle_config.item_drop_card_min
  3709.            ||  prev_config.item_drop_card_max     != battle_config.item_drop_card_max
  3710.            ||  prev_config.item_drop_equip_min    != battle_config.item_drop_equip_min
  3711.            ||  prev_config.item_drop_equip_max    != battle_config.item_drop_equip_max
  3712.            ||  prev_config.item_drop_mvp_min      != battle_config.item_drop_mvp_min
  3713.            ||  prev_config.item_drop_mvp_max      != battle_config.item_drop_mvp_max
  3714.            ||  prev_config.item_drop_heal_min     != battle_config.item_drop_heal_min
  3715.            ||  prev_config.item_drop_heal_max     != battle_config.item_drop_heal_max
  3716.            ||  prev_config.item_drop_use_min      != battle_config.item_drop_use_min
  3717.            ||  prev_config.item_drop_use_max      != battle_config.item_drop_use_max
  3718.            ||  prev_config.item_drop_treasure_min != battle_config.item_drop_treasure_min
  3719.            ||  prev_config.item_drop_treasure_max != battle_config.item_drop_treasure_max
  3720.            ||  prev_config.base_exp_rate          != battle_config.base_exp_rate
  3721.            ||  prev_config.job_exp_rate           != battle_config.job_exp_rate
  3722.         ) { // Exp or Drop rates changed.
  3723.                 mob->reload(); //Needed as well so rate changes take effect.
  3724.                 chrif->ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common);
  3725.         }
  3726.         clif->message(fd, msg_fd(fd,255));
  3727.         return true;
  3728. }
  3729. /*==========================================
  3730.  * @reloadstatusdb - reloads job_db1.txt job_db2.txt job_db2-2.txt refine_db.txt size_fix.txt
  3731.  *------------------------------------------*/
  3732. ACMD(reloadstatusdb) {
  3733.         status->readdb();
  3734.         clif->message(fd, msg_fd(fd,256));
  3735.         return true;
  3736. }
  3737. /*==========================================
  3738.  * @reloadpcdb - reloads exp.txt skill_tree.txt attr_fix.txt statpoint.txt
  3739.  *------------------------------------------*/
  3740. ACMD(reloadpcdb)
  3741. {
  3742.         pc->readdb();
  3743.         clif->message(fd, msg_fd(fd,257));
  3744.         return true;
  3745. }
  3746.  
  3747. /*==========================================
  3748.  * @reloadscript - reloads all scripts (npcs, warps, mob spawns, ...)
  3749.  *------------------------------------------*/
  3750. ACMD(reloadscript) {
  3751.         struct s_mapiterator* iter;
  3752.         struct map_session_data* pl_sd;
  3753.  
  3754.         //atcommand_broadcast( fd, sd, "@broadcast", "Server is reloading scripts..." );
  3755.         //atcommand_broadcast( fd, sd, "@broadcast", "You will feel a bit of lag at this point !" );
  3756.  
  3757.         iter = mapit_getallusers();
  3758.         for (pl_sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCAST(BL_PC, mapit->next(iter))) {
  3759.                 if (pl_sd->npc_id || pl_sd->npc_shopid) {
  3760.                         if (pl_sd->state.using_fake_npc) {
  3761.                                 clif->clearunit_single(pl_sd->npc_id, CLR_OUTSIGHT, pl_sd->fd);
  3762.                                 pl_sd->state.using_fake_npc = 0;
  3763.                         }
  3764.                         if (pl_sd->state.menu_or_input)
  3765.                                 pl_sd->state.menu_or_input = 0;
  3766.                         if (pl_sd->npc_menu)
  3767.                                 pl_sd->npc_menu = 0;
  3768.  
  3769.                         pl_sd->npc_id = 0;
  3770.                         pl_sd->npc_shopid = 0;
  3771.                         if (pl_sd->st && pl_sd->st->state != END)
  3772.                                 pl_sd->st->state = END;
  3773.                 }
  3774.         }
  3775.         mapit->free(iter);
  3776.  
  3777.         sockt->flush_fifos();
  3778.         map->reloadnpc(true); // reload config files seeking for npcs
  3779.         script->reload();
  3780.         npc->reload();
  3781.  
  3782.         clif->message(fd, msg_fd(fd,100)); // Scripts have been reloaded.
  3783.  
  3784.         return true;
  3785. }
  3786.  
  3787. /*==========================================
  3788.  * @mapinfo [0-3] <map name> by MC_Cameri
  3789.  * => Shows information about the map [map name]
  3790.  * 0 = no additional information
  3791.  * 1 = Show users in that map and their location
  3792.  * 2 = Shows NPCs in that map
  3793.  * 3 = Shows the chats in that map
  3794.  TODO# add the missing mapflags e.g. adjust_skill_damage to display
  3795.  *------------------------------------------*/
  3796. ACMD(mapinfo)
  3797. {
  3798.         const struct map_session_data *pl_sd;
  3799.         struct s_mapiterator* iter;
  3800.         const struct chat_data *cd = NULL;
  3801.         char direction[12];
  3802.         int i, m_id, chat_num = 0, list = 0, vend_num = 0;
  3803.         unsigned short m_index;
  3804.         char mapname[24];
  3805.  
  3806.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  3807.         memset(mapname, '\0', sizeof(mapname));
  3808.         memset(direction, '\0', sizeof(direction));
  3809.  
  3810.         sscanf(message, "%12d %23[^\n]", &list, mapname);
  3811.  
  3812.         if (list < 0 || list > 3) {
  3813.                 clif->message(fd, msg_fd(fd,1038)); // Please enter at least one valid list number (usage: @mapinfo <0-3> <map>).
  3814.                 return false;
  3815.         }
  3816.  
  3817.         if (mapname[0] == '\0') {
  3818.                 safestrncpy(mapname, mapindex_id2name(sd->mapindex), MAP_NAME_LENGTH);
  3819.                 m_id =  map->mapindex2mapid(sd->mapindex);
  3820.         } else {
  3821.                 m_id = map->mapname2mapid(mapname);
  3822.         }
  3823.  
  3824.         if (m_id < 0) {
  3825.                 clif->message(fd, msg_fd(fd,1)); // Map not found.
  3826.                 return false;
  3827.         }
  3828.         m_index = mapindex->name2id(mapname); //This one shouldn't fail since the previous seek did not.
  3829.  
  3830.         clif->message(fd, msg_fd(fd,1039)); // ------ Map Info ------
  3831.  
  3832.         // count chats (for initial message)
  3833.         chat_num = 0;
  3834.         iter = mapit_getallusers();
  3835.         for (pl_sd = BL_UCCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCCAST(BL_PC, mapit->next(iter))) {
  3836.                 if( pl_sd->mapindex == m_index ) {
  3837.                         if( pl_sd->state.vending )
  3838.                                 vend_num++;
  3839.                         else if ((cd = map->id2cd(pl_sd->chatID)) != NULL && cd->usersd[0] == pl_sd)
  3840.                                 chat_num++;
  3841.                 }
  3842.         }
  3843.         mapit->free(iter);
  3844.  
  3845.         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1040), mapname, map->list[m_id].zone->name, map->list[m_id].users, map->list[m_id].npc_num, chat_num, vend_num); // Map: %s (Zone:%s) | Players: %d | NPCs: %d | Chats: %d | Vendings: %d
  3846.         clif->message(fd, atcmd_output);
  3847.         clif->message(fd, msg_fd(fd,1041)); // ------ Map Flags ------
  3848.         if (map->list[m_id].flag.town)
  3849.                 clif->message(fd, msg_fd(fd,1042)); // Town Map
  3850.  
  3851.         if (battle_config.autotrade_mapflag == map->list[m_id].flag.autotrade)
  3852.                 clif->message(fd, msg_fd(fd,1043)); // Autotrade Enabled
  3853.         else
  3854.                 clif->message(fd, msg_fd(fd,1044)); // Autotrade Disabled
  3855.  
  3856.         if (map->list[m_id].flag.battleground)
  3857.                 clif->message(fd, msg_fd(fd,1045)); // Battlegrounds ON
  3858.  
  3859.         strcpy(atcmd_output,msg_fd(fd,1046)); // PvP Flags:
  3860.         if (map->list[m_id].flag.pvp)
  3861.                 strcat(atcmd_output, msg_fd(fd,1047)); // Pvp ON |
  3862.         if (map->list[m_id].flag.pvp_noguild)
  3863.                 strcat(atcmd_output, msg_fd(fd,1048)); // NoGuild |
  3864.         if (map->list[m_id].flag.pvp_noparty)
  3865.                 strcat(atcmd_output, msg_fd(fd,1049)); // NoParty |
  3866.         if (map->list[m_id].flag.pvp_nightmaredrop)
  3867.                 strcat(atcmd_output, msg_fd(fd,1050)); // NightmareDrop |
  3868.         if (map->list[m_id].flag.pvp_nocalcrank)
  3869.                 strcat(atcmd_output, msg_fd(fd,1051)); // NoCalcRank |
  3870.         clif->message(fd, atcmd_output);
  3871.  
  3872.         strcpy(atcmd_output,msg_fd(fd,1052)); // GvG Flags:
  3873.         if (map->list[m_id].flag.gvg)
  3874.                 strcat(atcmd_output, msg_fd(fd,1053)); // GvG ON |
  3875.         if (map->list[m_id].flag.gvg_dungeon)
  3876.                 strcat(atcmd_output, msg_fd(fd,1054)); // GvG Dungeon |
  3877.         if (map->list[m_id].flag.gvg_castle)
  3878.                 strcat(atcmd_output, msg_fd(fd,1055)); // GvG Castle |
  3879.         if (map->list[m_id].flag.gvg_noparty)
  3880.                 strcat(atcmd_output, msg_fd(fd,1056)); // NoParty |
  3881.         clif->message(fd, atcmd_output);
  3882.  
  3883.         strcpy(atcmd_output,msg_fd(fd,1057)); // Teleport Flags:
  3884.         if (map->list[m_id].flag.noteleport)
  3885.                 strcat(atcmd_output, msg_fd(fd,1058)); // NoTeleport |
  3886.         if (map->list[m_id].flag.monster_noteleport)
  3887.                 strcat(atcmd_output, msg_fd(fd,1059)); // Monster NoTeleport |
  3888.         if (map->list[m_id].flag.nowarp)
  3889.                 strcat(atcmd_output, msg_fd(fd,1060)); // NoWarp |
  3890.         if (map->list[m_id].flag.nowarpto)
  3891.                 strcat(atcmd_output, msg_fd(fd,1061)); // NoWarpTo |
  3892.         if (map->list[m_id].flag.noreturn)
  3893.                 strcat(atcmd_output, msg_fd(fd,1062)); // NoReturn |
  3894.         if (map->list[m_id].flag.nomemo)
  3895.                 strcat(atcmd_output, msg_fd(fd,1064)); // NoMemo |
  3896.         clif->message(fd, atcmd_output);
  3897.  
  3898.         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1065),  // No Exp Penalty: %s | No Zeny Penalty: %s
  3899.                         (map->list[m_id].flag.noexppenalty) ? msg_fd(fd,1066) : msg_fd(fd,1067),
  3900.                         (map->list[m_id].flag.nozenypenalty) ? msg_fd(fd,1066) : msg_fd(fd,1067)); // On / Off
  3901.         clif->message(fd, atcmd_output);
  3902.  
  3903.         if (map->list[m_id].flag.nosave) {
  3904.                 if (!map->list[m_id].save.map)
  3905.                         clif->message(fd, msg_fd(fd,1068)); // No Save (Return to last Save Point)
  3906.                 else if (map->list[m_id].save.x == -1 || map->list[m_id].save.y == -1 ) {
  3907.                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1069), mapindex_id2name(map->list[m_id].save.map)); // No Save, Save Point: %s,Random
  3908.                         clif->message(fd, atcmd_output);
  3909.                 } else {
  3910.                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1070), // No Save, Save Point: %s,%d,%d
  3911.                                         mapindex_id2name(map->list[m_id].save.map),map->list[m_id].save.x,map->list[m_id].save.y);
  3912.                         clif->message(fd, atcmd_output);
  3913.                 }
  3914.         }
  3915.  
  3916.         strcpy(atcmd_output,msg_fd(fd,1071)); // Weather Flags:
  3917.         if (map->list[m_id].flag.snow)
  3918.                 strcat(atcmd_output, msg_fd(fd,1072)); // Snow |
  3919.         if (map->list[m_id].flag.fog)
  3920.                 strcat(atcmd_output, msg_fd(fd,1073)); // Fog |
  3921.         if (map->list[m_id].flag.sakura)
  3922.                 strcat(atcmd_output, msg_fd(fd,1074)); // Sakura |
  3923.         if (map->list[m_id].flag.clouds)
  3924.                 strcat(atcmd_output, msg_fd(fd,1075)); // Clouds |
  3925.         if (map->list[m_id].flag.clouds2)
  3926.                 strcat(atcmd_output, msg_fd(fd,1076)); // Clouds2 |
  3927.         if (map->list[m_id].flag.fireworks)
  3928.                 strcat(atcmd_output, msg_fd(fd,1077)); // Fireworks |
  3929.         if (map->list[m_id].flag.leaves)
  3930.                 strcat(atcmd_output, msg_fd(fd,1078)); // Leaves |
  3931.         if (map->list[m_id].flag.nightenabled)
  3932.                 strcat(atcmd_output, msg_fd(fd,1080)); // Displays Night |
  3933.         clif->message(fd, atcmd_output);
  3934.  
  3935.         strcpy(atcmd_output,msg_fd(fd,1081)); // Other Flags:
  3936.         if (map->list[m_id].flag.nobranch)
  3937.                 strcat(atcmd_output, msg_fd(fd,1082)); // NoBranch |
  3938.         if (map->list[m_id].flag.notrade)
  3939.                 strcat(atcmd_output, msg_fd(fd,1083)); // NoTrade |
  3940.         if (map->list[m_id].flag.novending)
  3941.                 strcat(atcmd_output, msg_fd(fd,1084)); // NoVending |
  3942.         if (map->list[m_id].flag.nodrop)
  3943.                 strcat(atcmd_output, msg_fd(fd,1085)); // NoDrop |
  3944.         if (map->list[m_id].flag.noskill)
  3945.                 strcat(atcmd_output, msg_fd(fd,1086)); // NoSkill |
  3946.         if (map->list[m_id].flag.noicewall)
  3947.                 strcat(atcmd_output, msg_fd(fd,1087)); // NoIcewall |
  3948.         if (map->list[m_id].flag.allowks)
  3949.                 strcat(atcmd_output, msg_fd(fd,1088)); // AllowKS |
  3950.         if (map->list[m_id].flag.reset)
  3951.                 strcat(atcmd_output, msg_fd(fd,1089)); // Reset |
  3952.         clif->message(fd, atcmd_output);
  3953.  
  3954.         strcpy(atcmd_output,msg_fd(fd,1090)); // Other Flags:
  3955.         if (map->list[m_id].nocommand)
  3956.                 strcat(atcmd_output, msg_fd(fd,1091)); // NoCommand |
  3957.         if (map->list[m_id].flag.nobaseexp)
  3958.                 strcat(atcmd_output, msg_fd(fd,1092)); // NoBaseEXP |
  3959.         if (map->list[m_id].flag.nojobexp)
  3960.                 strcat(atcmd_output, msg_fd(fd,1093)); // NoJobEXP |
  3961.         if (map->list[m_id].flag.nomobloot)
  3962.                 strcat(atcmd_output, msg_fd(fd,1094)); // NoMobLoot |
  3963.         if (map->list[m_id].flag.nomvploot)
  3964.                 strcat(atcmd_output, msg_fd(fd,1095)); // NoMVPLoot |
  3965.         if (map->list[m_id].flag.partylock)
  3966.                 strcat(atcmd_output, msg_fd(fd,1096)); // PartyLock |
  3967.         if (map->list[m_id].flag.guildlock)
  3968.                 strcat(atcmd_output, msg_fd(fd,1097)); // GuildLock |
  3969.         if (map->list[m_id].flag.noviewid != EQP_NONE)
  3970.                 strcat(atcmd_output, msg_fd(fd,1079)); // NoViewID |
  3971.         if (map->list[m_id].flag.blocked)
  3972.                 strcat(atcmd_output, "Bloqueado | ");
  3973.         if (map->list[m_id].flag.antimob)
  3974.                 strcat(atcmd_output, "KS PvP Protection | ");
  3975.         if (map->list[m_id].flag.zombie)
  3976.                 strcat(atcmd_output, "Modo Zumbi | ");
  3977.         clif->message(fd, atcmd_output);
  3978.  
  3979.         switch (list) {
  3980.                 case 0:
  3981.                         // Do nothing. It's list 0, no additional display.
  3982.                         break;
  3983.                 case 1:
  3984.                         clif->message(fd, msg_fd(fd,1098)); // ----- Players in Map -----
  3985.                         iter = mapit_getallusers();
  3986.                         for (pl_sd = BL_UCCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCCAST(BL_PC, mapit->next(iter))) {
  3987.                                 if (pl_sd->mapindex == m_index) {
  3988.                                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1099), // Player '%s' (session #%d) | Location: %d,%d
  3989.                                                         pl_sd->status.name, pl_sd->fd, pl_sd->bl.x, pl_sd->bl.y);
  3990.                                         clif->message(fd, atcmd_output);
  3991.                                 }
  3992.                         }
  3993.                         mapit->free(iter);
  3994.                         break;
  3995.                 case 2:
  3996.                         clif->message(fd, msg_fd(fd,1100)); // ----- NPCs in Map -----
  3997.                         for (i = 0; i < map->list[m_id].npc_num;) {
  3998.                                 struct npc_data *nd = map->list[m_id].npc[i];
  3999.                                 switch(nd->dir) {
  4000.                                         case 0:  strcpy(direction, msg_fd(fd,1101)); break; // North
  4001.                                         case 1:  strcpy(direction, msg_fd(fd,1102)); break; // North West
  4002.                                         case 2:  strcpy(direction, msg_fd(fd,1103)); break; // West
  4003.                                         case 3:  strcpy(direction, msg_fd(fd,1104)); break; // South West
  4004.                                         case 4:  strcpy(direction, msg_fd(fd,1105)); break; // South
  4005.                                         case 5:  strcpy(direction, msg_fd(fd,1106)); break; // South East
  4006.                                         case 6:  strcpy(direction, msg_fd(fd,1107)); break; // East
  4007.                                         case 7:  strcpy(direction, msg_fd(fd,1108)); break; // North East
  4008.                                         case 9:  strcpy(direction, msg_fd(fd,1109)); break; // North
  4009.                                         default: strcpy(direction, msg_fd(fd,1110)); break; // Unknown
  4010.                                 }
  4011.                                 if(strcmp(nd->name,nd->exname) == 0)
  4012.                                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1111), // NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d
  4013.                                                 ++i, nd->name, direction, nd->class_, nd->bl.x, nd->bl.y);
  4014.                                 else
  4015.                                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1112), // NPC %d: %s::%s | Direction: %s | Sprite: %d | Location: %d %d
  4016.                                                 ++i, nd->name, nd->exname, direction, nd->class_, nd->bl.x, nd->bl.y);
  4017.                                 clif->message(fd, atcmd_output);
  4018.                         }
  4019.                         break;
  4020.                 case 3:
  4021.                         clif->message(fd, msg_fd(fd,1113)); // ----- Chats in Map -----
  4022.                         iter = mapit_getallusers();
  4023.                         for (pl_sd = BL_UCCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCCAST(BL_PC, mapit->next(iter))) {
  4024.                                 if ((cd = map->id2cd(pl_sd->chatID)) != NULL && pl_sd->mapindex == m_index && cd->usersd[0] == pl_sd) {
  4025.                                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1114), // Chat: %s | Player: %s | Location: %d %d
  4026.                                                         cd->title, pl_sd->status.name, cd->bl.x, cd->bl.y);
  4027.                                         clif->message(fd, atcmd_output);
  4028.                                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1115), //    Users: %d/%d | Password: %s | Public: %s
  4029.                                                         cd->users, cd->limit, cd->pass, (cd->pub) ? msg_fd(fd,1116) : msg_fd(fd,1117)); // Yes / No
  4030.                                         clif->message(fd, atcmd_output);
  4031.                                 }
  4032.                         }
  4033.                         mapit->free(iter);
  4034.                         break;
  4035.                 default: // normally impossible to arrive here
  4036.                         clif->message(fd, msg_fd(fd,1118)); // Please enter at least one valid list number (usage: @mapinfo <0-3> <map>).
  4037.                         return false;
  4038.         }
  4039.  
  4040.         return true;
  4041. }
  4042.  
  4043. /*==========================================
  4044.  *
  4045.  *------------------------------------------*/
  4046. ACMD(mount_peco)
  4047. {
  4048.         if (sd->disguise != -1) {
  4049.                 clif->message(fd, msg_fd(fd,212)); // Cannot mount while in disguise.
  4050.                 return false;
  4051.         }
  4052.  
  4053.         if (sd->sc.data[SC_ALL_RIDING]) {
  4054.                 clif->message(fd, msg_fd(fd,1476)); // You are already mounting something else
  4055.                 return false;
  4056.         }
  4057.  
  4058.         if ((sd->class_&MAPID_THIRDMASK) == MAPID_RUNE_KNIGHT) {
  4059.                 if (!pc->checkskill(sd,RK_DRAGONTRAINING)) {
  4060.                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,213), skill->get_desc(RK_DRAGONTRAINING)); // You need %s to mount!
  4061.                         clif->message(fd, atcmd_output);
  4062.                         return false;
  4063.                 }
  4064.                 if (!pc_isridingdragon(sd)) {
  4065.                         clif->message(sd->fd,msg_fd(fd,1119)); // You have mounted your Dragon.
  4066.                         pc->setridingdragon(sd, OPTION_DRAGON1);
  4067.                 } else {
  4068.                         clif->message(sd->fd,msg_fd(fd,1120)); // You have released your Dragon.
  4069.                         pc->setridingdragon(sd, 0);
  4070.                 }
  4071.                 return true;
  4072.         }
  4073.         if ((sd->class_&MAPID_THIRDMASK) == MAPID_RANGER) {
  4074.                 if (!pc->checkskill(sd,RA_WUGRIDER)) {
  4075.                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,213), skill->get_desc(RA_WUGRIDER)); // You need %s to mount!
  4076.                         clif->message(fd, atcmd_output);
  4077.                         return false;
  4078.                 }
  4079.                 if (!pc_isridingwug(sd)) {
  4080.                         clif->message(sd->fd,msg_fd(fd,1121)); // You have mounted your Warg.
  4081.                         pc->setridingwug(sd, true);
  4082.                 } else {
  4083.                         clif->message(sd->fd,msg_fd(fd,1122)); // You have released your Warg.
  4084.                         pc->setridingwug(sd, false);
  4085.                 }
  4086.                 return true;
  4087.         }
  4088.         if ((sd->class_&MAPID_THIRDMASK) == MAPID_MECHANIC) {
  4089.                 if (!pc_ismadogear(sd)) {
  4090.                         clif->message(sd->fd,msg_fd(fd,1123)); // You have mounted your Mado Gear.
  4091.                         pc->setmadogear(sd, true);
  4092.                 } else {
  4093.                         clif->message(sd->fd,msg_fd(fd,1124)); // You have released your Mado Gear.
  4094.                         pc->setmadogear(sd, false);
  4095.                 }
  4096.                 return true;
  4097.         }
  4098.         if (sd->class_&MAPID_SWORDMAN && sd->class_&JOBL_2) {
  4099.                 if (!pc_isridingpeco(sd)) { // if actually no peco
  4100.                         if (!pc->checkskill(sd, KN_RIDING)) {
  4101.                                 safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,213), skill->get_desc(KN_RIDING)); // You need %s to mount!
  4102.                                 clif->message(fd, atcmd_output);
  4103.                                 return false;
  4104.                         }
  4105.                         pc->setridingpeco(sd, true);
  4106.                         clif->message(fd, msg_fd(fd,102)); // You have mounted a Peco Peco.
  4107.                 } else {//Dismount
  4108.                         pc->setridingpeco(sd, false);
  4109.                         clif->message(fd, msg_fd(fd,214)); // You have released your Peco Peco.
  4110.                 }
  4111.                 return true;
  4112.         }
  4113.         clif->message(fd, msg_fd(fd,215)); // Your class can't mount!
  4114.         return false;
  4115. }
  4116.  
  4117. /*==========================================
  4118.  *Spy Commands by Syrus22
  4119.  *------------------------------------------*/
  4120. ACMD(guildspy) {
  4121.         char guild_name[NAME_LENGTH];
  4122.         struct guild *g;
  4123.  
  4124.         memset(guild_name, '\0', sizeof(guild_name));
  4125.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  4126.  
  4127.         if (!map->enable_spy)
  4128.         {
  4129.                 clif->message(fd, msg_fd(fd,1125)); // The mapserver has spy command support disabled.
  4130.                 return false;
  4131.         }
  4132.         if (!*message || sscanf(message, "%23[^\n]", guild_name) < 1) {
  4133.                 clif->message(fd, msg_fd(fd,1126)); // Please enter a guild name/ID (usage: @guildspy <guild_name/ID>).
  4134.                 return false;
  4135.         }
  4136.  
  4137.         if ((g = guild->searchname(guild_name)) != NULL || // name first to avoid error when name begin with a number
  4138.             (g = guild->search(atoi(message))) != NULL) {
  4139.                 if (sd->guildspy == g->guild_id) {
  4140.                         sd->guildspy = 0;
  4141.                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,103), g->name); // No longer spying on the %s guild.
  4142.                         clif->message(fd, atcmd_output);
  4143.                 } else {
  4144.                         sd->guildspy = g->guild_id;
  4145.                         safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,104), g->name); // Spying on the %s guild.
  4146.                         clif->message(fd, atcmd_output);
  4147.                 }
  4148.         } else {
  4149.                 clif->message(fd, msg_fd(fd,94)); // Incorrect name/ID, or no one from the specified guild is online.
  4150.                 return false;
  4151.         }
  4152.  
  4153.         return true;
  4154. }
  4155.  
  4156. /*==========================================
  4157.  *
  4158.  *------------------------------------------*/
  4159. ACMD(partyspy) {
  4160.         char party_name[NAME_LENGTH];
  4161.         struct party_data *p;
  4162.  
  4163.         memset(party_name, '\0', sizeof(party_name));
  4164.         memset(atcmd_output, '\0', sizeof(atcmd_output));
  4165.  
  4166.         if (!map->enable_spy)
  4167.         {
  4168.                 clif->message(fd, msg_fd(fd,1125)); // The mapserver has spy command support disabled.
  4169.                 return false;
  4170.         }
  4171.  
  4172.         if (!*message || sscanf(message, "%23[^\n]", party_name) < 1) {
  4173.                 clif->message(fd, msg_fd(fd,1127)); // Please enter a party name/ID (usage: @partyspy <party_name/ID>).
  4174.                 return false;
  4175.         }
  4176.  
  4177.         if ((p = party->searchname(party_name)) != NULL || // name first to avoid error when name begin with a number
  4178.             (p = party->search(atoi(message))) != NULL) {