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