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