Annotation of early-roguelike/rogue3/command.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * Read and execute the user commands
! 3: *
! 4: * @(#)command.c 3.45 (Berkeley) 6/15/81
! 5: *
! 6: * Rogue: Exploring the Dungeons of Doom
! 7: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 8: * All rights reserved.
! 9: *
! 10: * See the file LICENSE.TXT for full copyright and licensing information.
! 11: */
! 12:
! 13: #include <stdlib.h>
! 14: #include <ctype.h>
! 15: #include <signal.h>
! 16: #include <string.h>
! 17: #include "curses.h"
! 18: #include "machdep.h"
! 19: #include "rogue.h"
! 20:
! 21: /*
! 22: * command:
! 23: * Process the user commands
! 24: */
! 25:
! 26: void
! 27: command()
! 28: {
! 29: int ch;
! 30: int ntimes = 1; /* Number of player moves */
! 31: static int countch, direction, newcount = FALSE;
! 32:
! 33:
! 34: if (on(player, ISHASTE)) ntimes++;
! 35: /*
! 36: * Let the daemons start up
! 37: */
! 38: do_daemons(BEFORE);
! 39: do_fuses(BEFORE);
! 40: while (ntimes--)
! 41: {
! 42: look(TRUE);
! 43: if (!running)
! 44: door_stop = FALSE;
! 45: status();
! 46: lastscore = purse;
! 47: wmove(cw, hero.y, hero.x);
! 48: if (!((running || count) && jump))
! 49: draw(cw); /* Draw screen */
! 50: take = 0;
! 51: after = TRUE;
! 52: /*
! 53: * Read command or continue run
! 54: */
! 55: if (wizard)
! 56: waswizard = TRUE;
! 57: if (!no_command)
! 58: {
! 59: if (running) ch = runch;
! 60: else if (count) ch = countch;
! 61: else
! 62: {
! 63: ch = readchar(cw);
! 64: if (mpos != 0 && !running) /* Erase message if its there */
! 65: msg("");
! 66: }
! 67: }
! 68: else ch = ' ';
! 69: if (no_command)
! 70: {
! 71: if (--no_command == 0)
! 72: msg("You can move again.");
! 73: }
! 74: else
! 75: {
! 76: /*
! 77: * check for prefixes
! 78: */
! 79: if (isdigit(ch))
! 80: {
! 81: count = 0;
! 82: newcount = TRUE;
! 83: while (isdigit(ch))
! 84: {
! 85: count = count * 10 + (ch - '0');
! 86: ch = readchar(cw);
! 87: }
! 88: countch = ch;
! 89: /*
! 90: * turn off count for commands which don't make sense
! 91: * to repeat
! 92: */
! 93: switch (ch) {
! 94: case 'h': case 'j': case 'k': case 'l':
! 95: case 'y': case 'u': case 'b': case 'n':
! 96: case 'H': case 'J': case 'K': case 'L':
! 97: case 'Y': case 'U': case 'B': case 'N':
! 98: case 'q': case 'r': case 's': case 'f':
! 99: case 't': case 'C': case 'I': case '.':
! 100: case 'z': case 'p':
! 101: break;
! 102: default:
! 103: count = 0;
! 104: }
! 105: }
! 106: switch (ch)
! 107: {
! 108: case 'f':
! 109: if (!on(player, ISBLIND))
! 110: {
! 111: door_stop = TRUE;
! 112: firstmove = TRUE;
! 113: }
! 114: if (count && !newcount)
! 115: ch = direction;
! 116: else
! 117: ch = readchar(cw);
! 118: switch (ch)
! 119: {
! 120: case 'h': case 'j': case 'k': case 'l':
! 121: case 'y': case 'u': case 'b': case 'n':
! 122: ch = toupper(ch);
! 123: }
! 124: direction = ch;
! 125: }
! 126: newcount = FALSE;
! 127: /*
! 128: * execute a command
! 129: */
! 130: if (count && !running)
! 131: count--;
! 132: switch (ch)
! 133: {
! 134: case '!' : shell();
! 135: when 'h' : do_move(0, -1);
! 136: when 'j' : do_move(1, 0);
! 137: when 'k' : do_move(-1, 0);
! 138: when 'l' : do_move(0, 1);
! 139: when 'y' : do_move(-1, -1);
! 140: when 'u' : do_move(-1, 1);
! 141: when 'b' : do_move(1, -1);
! 142: when 'n' : do_move(1, 1);
! 143: when 'H' : do_run('h');
! 144: when 'J' : do_run('j');
! 145: when 'K' : do_run('k');
! 146: when 'L' : do_run('l');
! 147: when 'Y' : do_run('y');
! 148: when 'U' : do_run('u');
! 149: when 'B' : do_run('b');
! 150: when 'N' : do_run('n');
! 151: when 't':
! 152: if (!get_dir())
! 153: after = FALSE;
! 154: else
! 155: missile(delta.y, delta.x);
! 156: when 'Q' : after = FALSE; quit(0);
! 157: when 'i' : after = FALSE; inventory(pack, 0);
! 158: when 'I' : after = FALSE; picky_inven();
! 159: when 'd' : drop();
! 160: when 'q' : quaff();
! 161: when 'r' : read_scroll();
! 162: when 'e' : eat();
! 163: when 'w' : wield();
! 164: when 'W' : wear();
! 165: when 'T' : take_off();
! 166: when 'P' : ring_on();
! 167: when 'R' : ring_off();
! 168: when 'o' : option();
! 169: when 'c' : call();
! 170: when '>' : after = FALSE; d_level();
! 171: when '<' : after = FALSE; u_level();
! 172: when '?' : after = FALSE; help();
! 173: when '/' : after = FALSE; identify();
! 174: when 's' : search();
! 175: when 'z' : do_zap(FALSE);
! 176: when 'p':
! 177: if (get_dir())
! 178: do_zap(TRUE);
! 179: else
! 180: after = FALSE;
! 181: when 'v' : after = FALSE; msg("Rogue version %s. (mctesq was here)", release);
! 182: when CTRL('L') : after = FALSE; clearok(curscr,TRUE);draw(curscr);
! 183: when CTRL('R') : after = FALSE; msg(huh);
! 184: when 'S' :
! 185: after = FALSE;
! 186: if (save_game())
! 187: {
! 188: wmove(cw, LINES-1, 0);
! 189: wclrtoeol(cw);
! 190: draw(cw);
! 191: endwin();
! 192: printf("See you soon, %s!\n", whoami);
! 193: exit(0);
! 194: }
! 195: when '.' : ; /* Rest command */
! 196: #ifdef WIZARD
! 197: when CTRL('P') :
! 198: after = FALSE;
! 199: if (wizard)
! 200: {
! 201: wizard = FALSE;
! 202: msg("Not wizard any more");
! 203: }
! 204: else
! 205: {
! 206: if (wizard = passwd())
! 207: {
! 208: msg("You are suddenly as smart as Ken Arnold in dungeon #%d", dnum);
! 209: wizard = TRUE;
! 210: waswizard = TRUE;
! 211: }
! 212: else
! 213: msg("Sorry");
! 214: }
! 215: #endif
! 216: when ESCAPE : /* Escape */
! 217: door_stop = FALSE;
! 218: count = 0;
! 219: after = FALSE;
! 220: otherwise :
! 221: after = FALSE;
! 222: if (wizard) switch (ch)
! 223: {
! 224: case '@' : msg("@ %d,%d", hero.y, hero.x);
! 225: when 'C' : create_obj();
! 226: when CTRL('I') : inventory(lvl_obj, 0);
! 227: when CTRL('W') : whatis();
! 228: when CTRL('D') : level++; new_level();
! 229: when CTRL('U') : level--; new_level();
! 230: when CTRL('F') : show_win(stdscr, "--More (level map)--");
! 231: when CTRL('X') : show_win(mw, "--More (monsters)--");
! 232: when CTRL('T') : teleport();
! 233: when CTRL('E') : msg("food left: %d", food_left);
! 234: when CTRL('A') : msg("%d things in your pack", inpack);
! 235: when CTRL('C') : add_pass();
! 236: when CTRL('N') :
! 237: {
! 238: struct linked_list *item;
! 239:
! 240: if ((item = get_item("charge", STICK)) != NULL)
! 241: ((struct object *) ldata(item))->o_charges = 10000;
! 242: }
! 243: when CTRL('H') :
! 244: {
! 245: int i;
! 246: struct linked_list *item;
! 247: struct object *obj;
! 248:
! 249: for (i = 0; i < 9; i++)
! 250: raise_level();
! 251: /*
! 252: * Give the rogue a sword (+1,+1)
! 253: */
! 254: item = new_item(sizeof *obj);
! 255: obj = (struct object *) ldata(item);
! 256: obj->o_type = WEAPON;
! 257: obj->o_which = TWOSWORD;
! 258: init_weapon(obj, SWORD);
! 259: obj->o_hplus = 1;
! 260: obj->o_dplus = 1;
! 261: add_pack(item, TRUE);
! 262: cur_weapon = obj;
! 263: /*
! 264: * And his suit of armor
! 265: */
! 266: item = new_item(sizeof *obj);
! 267: obj = (struct object *) ldata(item);
! 268: obj->o_type = ARMOR;
! 269: obj->o_which = PLATE_MAIL;
! 270: obj->o_ac = -5;
! 271: obj->o_flags |= ISKNOW;
! 272: cur_armor = obj;
! 273: add_pack(item, TRUE);
! 274: }
! 275: otherwise :
! 276: msg("Illegal command '%s'.", unctrl(ch));
! 277: count = 0;
! 278: }
! 279: else
! 280: {
! 281: msg("Illegal command '%s'.", unctrl(ch));
! 282: count = 0;
! 283: }
! 284: }
! 285: /*
! 286: * turn off flags if no longer needed
! 287: */
! 288: if (!running)
! 289: door_stop = FALSE;
! 290: }
! 291: /*
! 292: * If he ran into something to take, let him pick it up.
! 293: */
! 294: if (take != 0)
! 295: pick_up(take);
! 296: if (!running)
! 297: door_stop = FALSE;
! 298: if (!after)
! 299: ntimes++;
! 300: }
! 301: /*
! 302: * Kick off the rest if the daemons and fuses
! 303: */
! 304: if (after)
! 305: {
! 306: look(FALSE);
! 307: do_daemons(AFTER);
! 308: do_fuses(AFTER);
! 309: if (ISRING(LEFT, R_SEARCH))
! 310: search();
! 311: else if (ISRING(LEFT, R_TELEPORT) && rnd(100) < 2)
! 312: teleport();
! 313: if (ISRING(RIGHT, R_SEARCH))
! 314: search();
! 315: else if (ISRING(RIGHT, R_TELEPORT) && rnd(100) < 2)
! 316: teleport();
! 317: }
! 318: }
! 319:
! 320: /*
! 321: * quit:
! 322: * Have player make certain, then exit.
! 323: */
! 324:
! 325: void
! 326: quit(int p)
! 327: {
! 328: /*
! 329: * Reset the signal in case we got here via an interrupt
! 330: */
! 331: if (signal(SIGINT, quit) != &quit)
! 332: mpos = 0;
! 333: msg("Really quit?");
! 334: draw(cw);
! 335: if (readchar(cw) == 'y')
! 336: {
! 337: clear();
! 338: move(LINES-1, 0);
! 339: draw(stdscr);
! 340: endwin();
! 341: writelog(purse, 1, 0);
! 342: score(purse, 1, 0);
! 343: printf("[Press return to exit]\n");
! 344: fflush(NULL);
! 345: getchar();
! 346: exit(0);
! 347: }
! 348: else
! 349: {
! 350: signal(SIGINT, quit);
! 351: wmove(cw, 0, 0);
! 352: wclrtoeol(cw);
! 353: status();
! 354: draw(cw);
! 355: mpos = 0;
! 356: count = 0;
! 357: }
! 358: }
! 359:
! 360: /*
! 361: * search:
! 362: * Player gropes about him to find hidden things.
! 363: */
! 364:
! 365: void
! 366: search()
! 367: {
! 368: int x, y;
! 369: int ch;
! 370:
! 371: /*
! 372: * Look all around the hero, if there is something hidden there,
! 373: * give him a chance to find it. If its found, display it.
! 374: */
! 375: if (on(player, ISBLIND))
! 376: return;
! 377: for (x = hero.x - 1; x <= hero.x + 1; x++)
! 378: for (y = hero.y - 1; y <= hero.y + 1; y++)
! 379: {
! 380: ch = winat(y, x);
! 381: switch (ch)
! 382: {
! 383: case SECRETDOOR:
! 384: if (rnd(100) < 20) {
! 385: mvaddch(y, x, DOOR);
! 386: count = 0;
! 387: }
! 388: break;
! 389: case TRAP:
! 390: {
! 391: struct trap *tp;
! 392:
! 393: if (mvwinch(cw, y, x) == TRAP)
! 394: break;
! 395: if (rnd(100) > 50)
! 396: break;
! 397: tp = trap_at(y, x);
! 398: tp->tr_flags |= ISFOUND;
! 399: mvwaddch(cw, y, x, TRAP);
! 400: count = 0;
! 401: running = FALSE;
! 402: msg(tr_name(tp->tr_type));
! 403: }
! 404: }
! 405: }
! 406: }
! 407:
! 408: /*
! 409: * help:
! 410: * Give single character help, or the whole mess if he wants it
! 411: */
! 412:
! 413: void
! 414: help()
! 415: {
! 416: struct h_list *strp = helpstr;
! 417: int helpch;
! 418: int cnt;
! 419:
! 420: msg("Character you want help for (* for all): ");
! 421: helpch = readchar(cw);
! 422: mpos = 0;
! 423: /*
! 424: * If its not a *, print the right help string
! 425: * or an error if he typed a funny character.
! 426: */
! 427: if (helpch != '*')
! 428: {
! 429: wmove(cw, 0, 0);
! 430: while (strp->h_ch)
! 431: {
! 432: if (strp->h_ch == helpch)
! 433: {
! 434: msg("%s%s", unctrl(strp->h_ch), strp->h_desc);
! 435: break;
! 436: }
! 437: strp++;
! 438: }
! 439: if (strp->h_ch != helpch)
! 440: msg("Unknown character '%s'", unctrl(helpch));
! 441: return;
! 442: }
! 443: /*
! 444: * Here we print help for everything.
! 445: * Then wait before we return to command mode
! 446: */
! 447: wclear(hw);
! 448: cnt = 0;
! 449: while (strp->h_ch)
! 450: {
! 451: mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(strp->h_ch));
! 452: waddstr(hw, strp->h_desc);
! 453: cnt++;
! 454: strp++;
! 455: }
! 456: wmove(hw, LINES-1, 0);
! 457: wprintw(hw, "--Press space to continue--");
! 458: draw(hw);
! 459: wait_for(hw,' ');
! 460: wclear(hw);
! 461: draw(hw);
! 462: wmove(cw, 0, 0);
! 463: wclrtoeol(cw);
! 464: status();
! 465: touchwin(cw);
! 466: }
! 467:
! 468: /*
! 469: * identify:
! 470: * Tell the player what a certain thing is.
! 471: */
! 472:
! 473: void
! 474: identify()
! 475: {
! 476: int ch;
! 477: char *str;
! 478:
! 479: msg("What do you want identified? ");
! 480: ch = readchar(cw);
! 481: mpos = 0;
! 482: if (ch == ESCAPE)
! 483: {
! 484: msg("");
! 485: return;
! 486: }
! 487: if (isalpha(ch) && isupper(ch))
! 488: str = monsters[ch-'A'].m_name;
! 489: else switch(ch)
! 490: {
! 491: case '|':
! 492: case '-':
! 493: str = "wall of a room";
! 494: when GOLD: str = "gold";
! 495: when STAIRS : str = "passage leading down";
! 496: when DOOR: str = "door";
! 497: when FLOOR: str = "room floor";
! 498: when PLAYER: str = "you";
! 499: when PASSAGE: str = "passage";
! 500: when TRAP: str = "trap";
! 501: when POTION: str = "potion";
! 502: when SCROLL: str = "scroll";
! 503: when FOOD: str = "food";
! 504: when WEAPON: str = "weapon";
! 505: when ' ' : str = "solid rock";
! 506: when ARMOR: str = "armor";
! 507: when AMULET: str = "The Amulet of Yendor";
! 508: when RING: str = "ring";
! 509: when STICK: str = "wand or staff";
! 510: otherwise: str = "unknown character";
! 511: }
! 512: msg("'%s' : %s", unctrl(ch), str);
! 513: }
! 514:
! 515: /*
! 516: * d_level:
! 517: * He wants to go down a level
! 518: */
! 519:
! 520: void
! 521: d_level()
! 522: {
! 523: if (winat(hero.y, hero.x) != STAIRS)
! 524: msg("I see no way down.");
! 525: else
! 526: {
! 527: level++;
! 528: new_level();
! 529: }
! 530: }
! 531:
! 532: /*
! 533: * u_level:
! 534: * He wants to go up a level
! 535: */
! 536:
! 537: void
! 538: u_level()
! 539: {
! 540: if (winat(hero.y, hero.x) == STAIRS)
! 541: {
! 542: if (amulet)
! 543: {
! 544: level--;
! 545: if (level == 0)
! 546: total_winner();
! 547: new_level();
! 548: msg("You feel a wrenching sensation in your gut.");
! 549: return;
! 550: }
! 551: }
! 552: msg("I see no way up.");
! 553: }
! 554:
! 555: /*
! 556: * Let him escape for a while
! 557: */
! 558:
! 559: void
! 560: shell()
! 561: {
! 562: /*
! 563: * Set the terminal back to original mode
! 564: */
! 565: wclear(hw);
! 566: wmove(hw, LINES-1, 0);
! 567: draw(hw);
! 568: endwin();
! 569: in_shell = TRUE;
! 570: fflush(stdout);
! 571:
! 572: md_shellescape();
! 573:
! 574: printf("\n[Press return to continue]");
! 575: fflush(stdout);
! 576: noecho();
! 577: crmode();
! 578: in_shell = FALSE;
! 579: wait_for(cw,'\n');
! 580: clearok(cw, TRUE);
! 581: touchwin(cw);
! 582: draw(cw);
! 583: }
! 584:
! 585: /*
! 586: * allow a user to call a potion, scroll, or ring something
! 587: */
! 588: void
! 589: call()
! 590: {
! 591: struct object *obj;
! 592: struct linked_list *item;
! 593: char **guess, *elsewise;
! 594: int *know;
! 595:
! 596: item = get_item("call", CALLABLE);
! 597: /*
! 598: * Make certain that it is somethings that we want to wear
! 599: */
! 600: if (item == NULL)
! 601: return;
! 602: obj = (struct object *) ldata(item);
! 603: switch (obj->o_type)
! 604: {
! 605: case RING:
! 606: guess = r_guess;
! 607: know = r_know;
! 608: elsewise = (r_guess[obj->o_which] != NULL ?
! 609: r_guess[obj->o_which] : r_stones[obj->o_which]);
! 610: when POTION:
! 611: guess = p_guess;
! 612: know = p_know;
! 613: elsewise = (p_guess[obj->o_which] != NULL ?
! 614: p_guess[obj->o_which] : p_colors[obj->o_which]);
! 615: when SCROLL:
! 616: guess = s_guess;
! 617: know = s_know;
! 618: elsewise = (s_guess[obj->o_which] != NULL ?
! 619: s_guess[obj->o_which] : s_names[obj->o_which]);
! 620: when STICK:
! 621: guess = ws_guess;
! 622: know = ws_know;
! 623: elsewise = (ws_guess[obj->o_which] != NULL ?
! 624: ws_guess[obj->o_which] : ws_made[obj->o_which]);
! 625: otherwise:
! 626: msg("You can't call that anything");
! 627: return;
! 628: }
! 629: if (know[obj->o_which])
! 630: {
! 631: msg("That has already been identified");
! 632: return;
! 633: }
! 634: if (terse)
! 635: addmsg("C");
! 636: else
! 637: addmsg("Was c");
! 638: msg("alled \"%s\"", elsewise);
! 639: if (terse)
! 640: msg("Call it: ");
! 641: else
! 642: msg("What do you want to call it? ");
! 643: strcpy(prbuf, elsewise);
! 644: if (get_str(prbuf, cw) == NORM)
! 645: {
! 646: if (guess[obj->o_which] != NULL)
! 647: free(guess[obj->o_which]);
! 648: guess[obj->o_which] = malloc((unsigned int) strlen(prbuf) + 1);
! 649: if (guess[obj->o_which] != NULL)
! 650: strcpy(guess[obj->o_which], prbuf);
! 651: }
! 652: }
CVSweb