Atrinik Client 2.5
client/keybind.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00047 #include <global.h>
00048 
00050 keybind_struct **keybindings = NULL;
00052 size_t keybindings_num = 0;
00053 
00056 void keybind_load()
00057 {
00058     FILE *fp;
00059     char buf[HUGE_BUF], *cp;
00060     keybind_struct *keybind = NULL;
00061 
00062     fp = fopen_wrapper(FILE_KEYBIND, "r");
00063 
00064     while (fgets(buf, sizeof(buf) - 1, fp))
00065     {
00066         cp = strchr(buf, '\n');
00067 
00068         if (cp)
00069         {
00070             *cp = '\0';
00071         }
00072 
00073         cp = buf;
00074 
00075         while (*cp != '\0')
00076         {
00077             if (isspace(*cp))
00078             {
00079                 cp++;
00080             }
00081             else
00082             {
00083                 break;
00084             }
00085         }
00086 
00087         if (*cp == '#' || *cp == '\0')
00088         {
00089             continue;
00090         }
00091 
00092         /* End of a single keybinding definition, add it to the list. */
00093         if (!strcmp(cp, "end"))
00094         {
00095             keybindings = realloc(keybindings, sizeof(keybindings) * (keybindings_num + 1));
00096             keybindings[keybindings_num] = keybind;
00097             keybindings_num++;
00098             keybind = NULL;
00099         }
00100         /* Are we inside a keybinding definition? */
00101         else if (keybind)
00102         {
00103             if (!strncmp(cp, "command ", 8))
00104             {
00105                 keybind->command = strdup(cp + 8);
00106             }
00107             else if (!strncmp(cp, "key ", 4))
00108             {
00109                 keybind->key = atoi(cp + 4);
00110             }
00111             else if (!strncmp(cp, "mod ", 4))
00112             {
00113                 keybind->mod = atoi(cp + 4);
00114             }
00115             else if (!strncmp(cp, "repeat ", 7))
00116             {
00117                 keybind->repeat = atoi(cp + 7);
00118             }
00119         }
00120         /* Keybinding definition start. */
00121         else if (!strcmp(cp, "bind"))
00122         {
00123             keybind = calloc(1, sizeof(*keybind));
00124         }
00125     }
00126 
00127     fclose(fp);
00128 }
00129 
00132 void keybind_save()
00133 {
00134     FILE *fp;
00135     size_t i;
00136 
00137     fp = fopen_wrapper(FILE_KEYBIND, "w");
00138 
00139     for (i = 0; i < keybindings_num; i++)
00140     {
00141         fprintf(fp, "bind\n");
00142         fprintf(fp, "\t# %s\n\tkey %d\n", SDL_GetKeyName(keybindings[i]->key), keybindings[i]->key);
00143 
00144         if (keybindings[i]->mod)
00145         {
00146             fprintf(fp, "\tmod %d\n", keybindings[i]->mod);
00147         }
00148 
00149         if (keybindings[i]->repeat)
00150         {
00151             fprintf(fp, "\trepeat %d\n", keybindings[i]->repeat);
00152         }
00153 
00154         if (keybindings[i]->command)
00155         {
00156             fprintf(fp, "\tcommand %s\n", keybindings[i]->command);
00157         }
00158 
00159         fprintf(fp, "end\n");
00160     }
00161 
00162     fclose(fp);
00163 }
00164 
00168 void keybind_free(keybind_struct *keybind)
00169 {
00170     free(keybind->command);
00171     free(keybind);
00172 }
00173 
00176 void keybind_deinit()
00177 {
00178     size_t i;
00179 
00180     /* Save them... */
00181     keybind_save();
00182 
00183     for (i = 0; i < keybindings_num; i++)
00184     {
00185         keybind_free(keybindings[i]);
00186     }
00187 
00188     if (keybindings)
00189     {
00190         free(keybindings);
00191         keybindings = NULL;
00192     }
00193 
00194     keybindings_num = 0;
00195 }
00196 
00203 static SDLMod keybind_adjust_kmod(SDLMod mod)
00204 {
00205     /* We only care about left/right shift, ctrl, alt, and super
00206      * modifiers, so remove any others. */
00207     mod &= KMOD_SHIFT | KMOD_CTRL | KMOD_ALT | KMOD_META;
00208 
00209     /* The following code deals with making sure that if the modifier
00210      * contains only for example left shift modifier, right shift is also
00211      * added to the modifier, in order to simplify saving and state
00212      * checks. */
00213     if (mod & KMOD_SHIFT)
00214     {
00215         mod |= KMOD_SHIFT;
00216     }
00217 
00218     if (mod & KMOD_CTRL)
00219     {
00220         mod |= KMOD_CTRL;
00221     }
00222 
00223     if (mod & KMOD_ALT)
00224     {
00225         mod |= KMOD_ALT;
00226     }
00227 
00228     if (mod & KMOD_META)
00229     {
00230         mod |= KMOD_META;
00231     }
00232 
00233     return mod;
00234 }
00235 
00243 keybind_struct *keybind_add(SDLKey key, SDLMod mod, const char *command)
00244 {
00245     keybind_struct *keybind;
00246 
00247     /* Allocate a new keybinding, and store the values. */
00248     keybind = calloc(1, sizeof(*keybind));
00249     keybind->key = key;
00250     keybind->mod = keybind_adjust_kmod(mod);
00251     keybind->command = strdup(command);
00252 
00253     /* Expand the keybindings array, and store the new keybinding. */
00254     keybindings = realloc(keybindings, sizeof(keybindings) * (keybindings_num + 1));
00255     keybindings[keybindings_num] = keybind;
00256     keybindings_num++;
00257 
00258     return keybind;
00259 }
00260 
00267 void keybind_edit(size_t i, SDLKey key, SDLMod mod, const char *command)
00268 {
00269     /* Sanity check. */
00270     if (i >= keybindings_num)
00271     {
00272         return;
00273     }
00274 
00275     /* Store the values. */
00276     keybindings[i]->key = key;
00277     keybindings[i]->mod = mod;
00278     free(keybindings[i]->command);
00279     keybindings[i]->command = strdup(command);
00280 }
00281 
00285 void keybind_remove(size_t i)
00286 {
00287     size_t j;
00288 
00289     /* Sanity check. */
00290     if (i >= keybindings_num)
00291     {
00292         return;
00293     }
00294 
00295     /* Free the entry. */
00296     keybind_free(keybindings[i]);
00297 
00298     /* Shift entries below the removed keybinding, if any. */
00299     for (j = i + 1; j < keybindings_num; j++)
00300     {
00301         keybindings[j - 1] = keybindings[j];
00302     }
00303 
00304     /* Shrink the array. */
00305     keybindings_num--;
00306     keybindings = realloc(keybindings, sizeof(*keybindings) * keybindings_num);
00307 }
00308 
00313 void keybind_repeat_toggle(size_t i)
00314 {
00315     /* Sanity check. */
00316     if (i >= keybindings_num)
00317     {
00318         return;
00319     }
00320 
00321     keybindings[i]->repeat = !keybindings[i]->repeat;
00322 }
00323 
00331 char *keybind_get_key_shortcut(SDLKey key, SDLMod mod, char *buf, size_t len)
00332 {
00333     buf[0] = '\0';
00334 
00335     /* Prefix with the keyboard modifier. */
00336     if (mod & KMOD_SHIFT)
00337     {
00338         strncat(buf, "shift + ", len - strlen(buf) - 1);
00339     }
00340 
00341     if (mod & KMOD_CTRL)
00342     {
00343         strncat(buf, "ctrl + ", len - strlen(buf) - 1);
00344     }
00345 
00346     if (mod & KMOD_ALT)
00347     {
00348         strncat(buf, "alt + ", len - strlen(buf) - 1);
00349     }
00350 
00351     if (mod & KMOD_META)
00352     {
00353         strncat(buf, "super + ", len - strlen(buf) - 1);
00354     }
00355 
00356     strncat(buf, SDL_GetKeyName(key), len - strlen(buf) - 1);
00357 
00358     return buf;
00359 }
00360 
00365 keybind_struct *keybind_find_by_command(const char *cmd)
00366 {
00367     size_t i;
00368 
00369     for (i = 0; i < keybindings_num; i++)
00370     {
00371         if (!strcmp(cmd, keybindings[i]->command))
00372         {
00373             return keybindings[i];
00374         }
00375     }
00376 
00377     return NULL;
00378 }
00379 
00384 int keybind_command_matches_event(const char *cmd, SDL_KeyboardEvent *event)
00385 {
00386     keybind_struct *keybind = keybind_find_by_command(cmd);
00387 
00388     if (!keybind)
00389     {
00390         return 0;
00391     }
00392 
00393     if (event->keysym.sym == keybind->key && (!keybind->mod || keybind->mod == keybind_adjust_kmod(event->keysym.mod)))
00394     {
00395         return 1;
00396     }
00397 
00398     return 0;
00399 }
00400 
00406 int keybind_command_matches_state(const char *cmd)
00407 {
00408     keybind_struct *keybind = keybind_find_by_command(cmd);
00409 
00410     if (!keybind)
00411     {
00412         return 0;
00413     }
00414 
00415     if (key_is_pressed(keybind->key) && (!keybind->mod || keybind->mod == keybind_adjust_kmod(SDL_GetModState())))
00416     {
00417         return 1;
00418     }
00419 
00420     return 0;
00421 }
00422 
00427 int keybind_process_event(SDL_KeyboardEvent *event)
00428 {
00429     size_t i;
00430 
00431     /* Try to handle keybindings with modifier keys first. */
00432     for (i = 0; i < keybindings_num; i++)
00433     {
00434         if (event->keysym.sym == keybindings[i]->key && keybindings[i]->mod == keybind_adjust_kmod(event->keysym.mod))
00435         {
00436             keybind_process(keybindings[i], event->type);
00437             return 1;
00438         }
00439     }
00440 
00441     /* Now handle keys with no modifier keys, regardless of what the
00442      * current keyboard modifier combination is. */
00443     for (i = 0; i < keybindings_num; i++)
00444     {
00445         if (event->keysym.sym == keybindings[i]->key && !keybindings[i]->mod)
00446         {
00447             keybind_process(keybindings[i], event->type);
00448             return 1;
00449         }
00450     }
00451 
00452     return 0;
00453 }
00454 
00457 void keybind_repeat()
00458 {
00459     size_t i;
00460 
00461     /* Same as in keybind_process_event(), handle keybindings with
00462      * modifier keys first. */
00463     for (i = 0; i < keybindings_num; i++)
00464     {
00465         if (keys[keybindings[i]->key].pressed && keybindings[i]->repeat && keybindings[i]->mod == keybind_adjust_kmod(SDL_GetModState()))
00466         {
00467             /* If time to repeat */
00468             if (keys[keybindings[i]->key].time + KEY_REPEAT_TIME - 5 < LastTick)
00469             {
00470                 /* Repeat x times */
00471                 while ((keys[keybindings[i]->key].time += KEY_REPEAT_TIME - 5) < LastTick)
00472                 {
00473                     keybind_process(keybindings[i], SDL_KEYDOWN);
00474                 }
00475             }
00476         }
00477     }
00478 
00479     /* And then keybindings with no modifier keys. */
00480     for (i = 0; i < keybindings_num; i++)
00481     {
00482         if (keys[keybindings[i]->key].pressed && keybindings[i]->repeat && !keybindings[i]->mod)
00483         {
00484             /* If time to repeat */
00485             if (keys[keybindings[i]->key].time + KEY_REPEAT_TIME - 5 < LastTick)
00486             {
00487                 /* Repeat x times */
00488                 while ((keys[keybindings[i]->key].time += KEY_REPEAT_TIME - 5) < LastTick)
00489                 {
00490                     keybind_process(keybindings[i], SDL_KEYDOWN);
00491                 }
00492             }
00493         }
00494     }
00495 }
00496 
00501 void keybind_process(keybind_struct *keybind, uint8 type)
00502 {
00503     char command[MAX_BUF], *cp;
00504 
00505     strncpy(command, keybind->command, sizeof(command) - 1);
00506     command[sizeof(command) - 1] = '\0';
00507 
00508     cp = strtok(command, ";");
00509 
00510     while (cp)
00511     {
00512         while (*cp == ' ')
00513         {
00514             cp++;
00515         }
00516 
00517         if (type == SDL_KEYDOWN)
00518         {
00519             keybind_process_command(cp);
00520         }
00521         else
00522         {
00523             keybind_process_command_up(cp);
00524         }
00525 
00526         cp = strtok(NULL, ";");
00527     }
00528 }
00529 
00534 int keybind_process_command_up(const char *cmd)
00535 {
00536     if (*cmd == '?')
00537     {
00538         cmd++;
00539 
00540         if (!strcmp(cmd, "INVENTORY"))
00541         {
00542             cpl.inventory_win = IWIN_BELOW;
00543         }
00544         else if (!strcmp(cmd, "RUNON"))
00545         {
00546             send_command("/run_stop");
00547             cpl.run_on = 0;
00548         }
00549         else if (!strcmp(cmd, "FIREON"))
00550         {
00551             cpl.fire_on = 0;
00552         }
00553 
00554         return 1;
00555     }
00556 
00557     return 0;
00558 }
00559 
00564 int keybind_process_command(const char *cmd)
00565 {
00566     if (*cmd == '?')
00567     {
00568         int tag = 0, loc = 0;
00569         object *it;
00570 
00571         cmd++;
00572 
00573         if (!strncmp(cmd, "MOVE_", 5))
00574         {
00575             cmd += 5;
00576 
00577             if (!strcmp(cmd, "N"))
00578             {
00579                 move_keys(8);
00580             }
00581             else if (!strcmp(cmd, "NE"))
00582             {
00583                 move_keys(9);
00584             }
00585             else if (!strcmp(cmd, "E"))
00586             {
00587                 move_keys(6);
00588             }
00589             else if (!strcmp(cmd, "SE"))
00590             {
00591                 move_keys(3);
00592             }
00593             else if (!strcmp(cmd, "S"))
00594             {
00595                 move_keys(2);
00596             }
00597             else if (!strcmp(cmd, "SW"))
00598             {
00599                 move_keys(1);
00600             }
00601             else if (!strcmp(cmd, "W"))
00602             {
00603                 move_keys(4);
00604             }
00605             else if (!strcmp(cmd, "NW"))
00606             {
00607                 move_keys(7);
00608             }
00609             else if (!strcmp(cmd, "N"))
00610             {
00611                 move_keys(8);
00612             }
00613             else if (!strcmp(cmd, "STAY"))
00614             {
00615                 move_keys(5);
00616             }
00617         }
00618         else if (!strncmp(cmd, "PAGE", 4))
00619         {
00620             widgetdata *widget;
00621             int scroll_adjust = 0;
00622 
00623             cmd += 4;
00624 
00625             if (!strncmp(cmd, "UP", 2))
00626             {
00627                 widget = cur_widget[*(cmd + 2) == '\0' ? CHATWIN_ID : MSGWIN_ID];
00628                 scroll_adjust = -TEXTWIN_ROWS_VISIBLE(widget);
00629             }
00630             else if (!strncmp(cmd, "DOWN", 4))
00631             {
00632                 widget = cur_widget[*(cmd + 4) == '\0' ? CHATWIN_ID : MSGWIN_ID];
00633                 scroll_adjust = TEXTWIN_ROWS_VISIBLE(widget);
00634             }
00635 
00636             if (scroll_adjust)
00637             {
00638                 TEXTWIN(widget)->scroll += scroll_adjust;
00639                 textwin_scroll_adjust(widget);
00640                 WIDGET_REDRAW(widget);
00641             }
00642         }
00643         else if (!strcmp(cmd, "CONSOLE"))
00644         {
00645             reset_keys();
00646 
00647             if (cpl.input_mode == INPUT_MODE_NO)
00648             {
00649                 cpl.input_mode = INPUT_MODE_CONSOLE;
00650                 text_input_open(253);
00651             }
00652             else if (cpl.input_mode == INPUT_MODE_CONSOLE)
00653             {
00654                 cpl.input_mode = INPUT_MODE_NO;
00655             }
00656         }
00657         else if (!strcmp(cmd, "APPLY"))
00658         {
00659             if (cpl.inventory_win == IWIN_BELOW)
00660             {
00661                 tag = cpl.win_below_tag;
00662             }
00663             else
00664             {
00665                 tag = cpl.win_inv_tag;
00666             }
00667 
00668             if (tag == -1 || !object_find(tag))
00669             {
00670                 return 0;
00671             }
00672 
00673             draw_info_format(COLOR_DGOLD, "apply %s", object_find(tag)->s_name);
00674             client_send_apply(tag);
00675         }
00676         else if (!strcmp(cmd, "EXAMINE"))
00677         {
00678             if (cpl.inventory_win == IWIN_BELOW)
00679             {
00680                 tag = cpl.win_below_tag;
00681             }
00682             else
00683             {
00684                 tag = cpl.win_inv_tag;
00685             }
00686 
00687             if (tag == -1 || !object_find(tag))
00688             {
00689                 return 0;
00690             }
00691 
00692             draw_info_format(COLOR_DGOLD, "examine %s", object_find(tag)->s_name);
00693             client_send_examine(tag);
00694         }
00695         else if (!strcmp(cmd, "MARK"))
00696         {
00697             if (cpl.inventory_win == IWIN_BELOW)
00698             {
00699                 tag = cpl.win_below_tag;
00700             }
00701             else
00702             {
00703                 tag = cpl.win_inv_tag;
00704             }
00705 
00706             if (tag == -1 || !object_find(tag))
00707             {
00708                 return 0;
00709             }
00710 
00711             it = object_find(tag);
00712             draw_info_format(COLOR_DGOLD, "%smark %s", it->tag == cpl.mark_count ? "un" : "", it->s_name);
00713             object_send_mark(it);
00714         }
00715         else if (!strcmp(cmd, "LOCK"))
00716         {
00717             if (cpl.inventory_win == IWIN_BELOW)
00718             {
00719                 tag = cpl.win_below_tag;
00720             }
00721             else
00722             {
00723                 tag = cpl.win_inv_tag;
00724             }
00725 
00726             if (tag == -1  || !object_find(tag))
00727             {
00728                 return 0;
00729             }
00730 
00731             it = object_find(tag);
00732             toggle_locked(it);
00733 
00734             if (it->flags & F_LOCKED)
00735             {
00736                 draw_info_format(COLOR_DGOLD, "unlock %s", it->s_name);
00737             }
00738             else
00739             {
00740                 draw_info_format(COLOR_DGOLD, "lock %s", it->s_name);
00741             }
00742         }
00743         else if (!strcmp(cmd, "GET"))
00744         {
00745             int nrof = 1;
00746 
00747             /* From below to inv. */
00748             if (cpl.inventory_win == IWIN_BELOW)
00749             {
00750                 tag = cpl.win_below_tag;
00751 
00752                 if (cpl.container)
00753                 {
00754                     if (cpl.container->tag != cpl.win_below_ctag)
00755                     {
00756                         loc = cpl.container->tag;
00757                     }
00758                     else
00759                     {
00760                         loc = cpl.ob->tag;
00761                     }
00762                 }
00763                 else
00764                 {
00765                     loc = cpl.ob->tag;
00766                 }
00767             }
00768             /* Inventory */
00769             else
00770             {
00771                 if (cpl.container)
00772                 {
00773                     if (cpl.container->tag == cpl.win_inv_ctag)
00774                     {
00775                         tag = cpl.win_inv_tag;
00776                         loc = cpl.ob->tag;
00777                     }
00778                     /* From inventory to container - if the container is in inv. */
00779                     else
00780                     {
00781                         object *tmp;
00782 
00783                         tag = -1;
00784 
00785                         if (cpl.ob)
00786                         {
00787                             for (tmp = cpl.ob->inv; tmp; tmp = tmp->next)
00788                             {
00789                                 if (tmp->tag == cpl.container->tag)
00790                                 {
00791                                     tag = cpl.win_inv_tag;
00792                                     loc = cpl.container->tag;
00793                                     break;
00794                                 }
00795                             }
00796 
00797                             if (tag == -1)
00798                             {
00799                                 draw_info(COLOR_DGOLD, "You already have it.");
00800                             }
00801                         }
00802                     }
00803                 }
00804                 else
00805                 {
00806                     draw_info(COLOR_DGOLD, "You have no open container to put it in.");
00807                     tag = -1;
00808                 }
00809             }
00810 
00811             if (tag == -1 || !object_find(tag))
00812             {
00813                 return 0;
00814             }
00815 
00816             it = object_find(tag);
00817             nrof = it->nrof;
00818 
00819             if (nrof == 1)
00820             {
00821                 nrof = 0;
00822             }
00823             else if (!(setting_get_int(OPT_CAT_GENERAL, OPT_COLLECT_MODE) & 1))
00824             {
00825                 char buf[MAX_BUF];
00826 
00827                 reset_keys();
00828                 cpl.input_mode = INPUT_MODE_NUMBER;
00829                 text_input_open(22);
00830                 cpl.loc = loc;
00831                 cpl.tag = tag;
00832                 cpl.nrof = nrof;
00833                 cpl.nummode = NUM_MODE_GET;
00834                 snprintf(buf, sizeof(buf), "%d", nrof);
00835                 text_input_add_string(buf);
00836                 strncpy(cpl.num_text, it->s_name, sizeof(cpl.num_text) - 1);
00837                 cpl.num_text[sizeof(cpl.num_text) - 1] = '\0';
00838                 return 0;
00839             }
00840 
00841             draw_info_format(COLOR_DGOLD, "get %s", it->s_name);
00842             client_send_move(loc, tag, nrof);
00843         }
00844         else if (!strcmp(cmd, "DROP"))
00845         {
00846             int nrof = 1;
00847 
00848             /* Drop from inventory */
00849             if (cpl.inventory_win == IWIN_INV)
00850             {
00851                 object *tmp;
00852 
00853                 tag = cpl.win_inv_tag;
00854                 loc = cpl.below->tag;
00855 
00856                 if (cpl.win_inv_ctag == -1 && cpl.container && cpl.below)
00857                 {
00858                     for (tmp = cpl.below->inv; tmp; tmp = tmp->next)
00859                     {
00860                         if (tmp->tag == cpl.container->tag)
00861                         {
00862                             tag = cpl.win_inv_tag;
00863                             loc = cpl.container->tag;
00864                             break;
00865                         }
00866                     }
00867                 }
00868             }
00869             else
00870             {
00871                 draw_info(COLOR_DGOLD, "The item is already on the floor.");
00872                 return 0;
00873             }
00874 
00875             if (tag == -1 || !object_find(tag))
00876             {
00877                 return 0;
00878             }
00879 
00880             it = object_find(tag);
00881             nrof = it->nrof;
00882 
00883             if (it->flags & F_LOCKED)
00884             {
00885                 draw_info(COLOR_DGOLD, "Unlock item first!");
00886                 return 0;
00887             }
00888 
00889             if (nrof == 1)
00890             {
00891                 nrof = 0;
00892             }
00893             else if (!(setting_get_int(OPT_CAT_GENERAL, OPT_COLLECT_MODE) & 2))
00894             {
00895                 char buf[MAX_BUF];
00896 
00897                 reset_keys();
00898                 cpl.input_mode = INPUT_MODE_NUMBER;
00899                 text_input_open(22);
00900                 cpl.loc = loc;
00901                 cpl.tag = tag;
00902                 cpl.nrof = nrof;
00903                 cpl.nummode = NUM_MODE_DROP;
00904                 snprintf(buf, sizeof(buf), "%d", nrof);
00905                 text_input_add_string(buf);
00906                 strncpy(cpl.num_text, it->s_name, sizeof(cpl.num_text) - 1);
00907                 cpl.num_text[sizeof(cpl.num_text) - 1] = '\0';
00908                 return 0;
00909             }
00910 
00911             draw_info_format(COLOR_DGOLD, "drop %s", it->s_name);
00912             client_send_move(loc, tag, nrof);
00913         }
00914         else if (!strcmp(cmd, "HELP"))
00915         {
00916             show_help("main");
00917         }
00918         else if (!strcmp(cmd, "QLIST"))
00919         {
00920             cs_write_string("qlist", 5);
00921         }
00922         else if (!strcmp(cmd, "RANGE"))
00923         {
00924             if (RangeFireMode++ == FIRE_MODE_INIT - 1)
00925             {
00926                 RangeFireMode = 0;
00927             }
00928         }
00929         else if (!strcmp(cmd, "TARGET_ENEMY"))
00930         {
00931             send_command("/target 0");
00932         }
00933         else if (!strcmp(cmd, "TARGET_FRIEND"))
00934         {
00935             send_command("/target 1");
00936         }
00937         else if (!strcmp(cmd, "TARGET_SELF"))
00938         {
00939             send_command("/target 2");
00940         }
00941         else if (!strcmp(cmd, "COMBAT"))
00942         {
00943             send_command("/combat");
00944         }
00945         else if (!strcmp(cmd, "FIRE_READY"))
00946         {
00947             if (cpl.inventory_win == IWIN_INV && cpl.win_inv_tag != -1)
00948             {
00949                 ready_object(object_find(cpl.win_inv_tag));
00950             }
00951         }
00952         else if (!strcmp(cmd, "SPELL_LIST"))
00953         {
00954             cur_widget[SPELLS_ID]->show = 1;
00955             SetPriorityWidget(cur_widget[SPELLS_ID]);
00956         }
00957         else if (!strcmp(cmd, "SKILL_LIST"))
00958         {
00959             cur_widget[SKILLS_ID]->show = 1;
00960             SetPriorityWidget(cur_widget[SKILLS_ID]);
00961         }
00962         else if (!strcmp(cmd, "PARTY_LIST"))
00963         {
00964             send_command("/party list");
00965         }
00966         else if (!strncmp(cmd, "MCON ", 4))
00967         {
00968             keybind_process_command("?CONSOLE");
00969             text_input_add_string(cmd + 4);
00970         }
00971         else if (!strcmp(cmd, "UP"))
00972         {
00973             cursor_keys(0);
00974         }
00975         else if (!strcmp(cmd, "DOWN"))
00976         {
00977             cursor_keys(1);
00978         }
00979         else if (!strcmp(cmd, "LEFT"))
00980         {
00981             cursor_keys(2);
00982         }
00983         else if (!strcmp(cmd, "RIGHT"))
00984         {
00985             cursor_keys(3);
00986         }
00987         else if (!strncmp(cmd, "INVENTORY", 9))
00988         {
00989             if (!strcmp(cmd + 9, "_TOGGLE"))
00990             {
00991                 if (cpl.inventory_win == IWIN_INV)
00992                 {
00993                     cpl.inventory_win = IWIN_BELOW;
00994                     return 1;
00995                 }
00996             }
00997 
00998             SetPriorityWidget(cur_widget[MAIN_INV_ID]);
00999 
01000             if (!setting_get_int(OPT_CAT_GENERAL, OPT_PLAYERDOLL))
01001             {
01002                 SetPriorityWidget(cur_widget[PDOLL_ID]);
01003             }
01004 
01005             cpl.inventory_win = IWIN_INV;
01006         }
01007         else if (!strcmp(cmd, "RUNON"))
01008         {
01009             cpl.run_on = 1;
01010         }
01011         else if (!strcmp(cmd, "FIREON"))
01012         {
01013             cpl.fire_on = 1;
01014         }
01015         else if (!strncmp(cmd, "QUICKSLOT_", 10))
01016         {
01017             cmd += 10;
01018 
01019             if (!strcmp(cmd, "GROUP_PREV"))
01020             {
01021                 quickslot_group--;
01022 
01023                 if (quickslot_group < 1)
01024                 {
01025                     quickslot_group = MAX_QUICKSLOT_GROUPS;
01026                 }
01027             }
01028             else if (!strcmp(cmd, "GROUP_NEXT"))
01029             {
01030                 quickslot_group++;
01031 
01032                 if (quickslot_group > MAX_QUICKSLOT_GROUPS)
01033                 {
01034                     quickslot_group = 1;
01035                 }
01036             }
01037             else
01038             {
01039                 quickslots_handle_key(MAX(1, MIN(8, atoi(cmd))) - 1);
01040             }
01041         }
01042 
01043         return 1;
01044     }
01045     else
01046     {
01047         draw_info(COLOR_DGOLD, cmd);
01048 
01049         if (!client_command_check(cmd))
01050         {
01051             send_command(cmd);
01052         }
01053     }
01054 
01055     return 0;
01056 }