Annotation of early-roguelike/arogue7/command.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * command.c - Read and execute the user commands
! 3: *
! 4: * Advanced Rogue
! 5: * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
! 6: * All rights reserved.
! 7: *
! 8: * Based on "Rogue: Exploring the Dungeons of Doom"
! 9: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 10: * All rights reserved.
! 11: *
! 12: * See the file LICENSE.TXT for full copyright and licensing information.
! 13: */
! 14:
! 15: /*
! 16: * Read and execute the user commands
! 17: *
! 18: */
! 19:
! 20: #include "curses.h"
! 21: #include <ctype.h>
! 22: #include <string.h>
! 23: #include <stdlib.h>
! 24: #include <signal.h>
! 25: #include "mach_dep.h"
! 26: #include "rogue.h"
! 27: #ifdef PC7300
! 28: #include "sys/window.h"
! 29: extern struct uwdata wdata;
! 30: #endif
! 31:
! 32: void display(void);
! 33: void help(void);
! 34: void identify(char ch);
! 35: void d_level(void);
! 36: void u_level(void);
! 37: void shell(void);
! 38: void nameit(void);
! 39: void namemonst(void);
! 40: void count_gold(void);
! 41:
! 42: /*
! 43: * command:
! 44: * Process the user commands
! 45: */
! 46:
! 47: void
! 48: command(void)
! 49: {
! 50: unsigned char ch;
! 51: struct linked_list *item;
! 52: unsigned char countch, direction, newcount = FALSE;
! 53: int segment = 1;
! 54: int monst_limit, monst_current;
! 55:
! 56: monst_limit = monst_current = 1;
! 57: while (playing) {
! 58: /*
! 59: * Let the daemons start up, but only do them once a round
! 60: * (round = 10 segments).
! 61: */
! 62: if (segment >= 10) {
! 63: do_daemons(BEFORE);
! 64: do_fuses(BEFORE);
! 65: }
! 66:
! 67: after = TRUE;
! 68: do {
! 69: /* One more tick of the clock. */
! 70: if (segment >= 10 && after && (++turns % DAYLENGTH) == 0) {
! 71: daytime ^= TRUE;
! 72: if (levtype == OUTSIDE) {
! 73: if (daytime) msg("The sun rises above the horizon");
! 74: else msg("The sun sinks below the horizon");
! 75: }
! 76: light(&hero);
! 77: }
! 78:
! 79: /*
! 80: * Don't bother with these updates unless the player's going
! 81: * to do something.
! 82: */
! 83: if (player.t_action == A_NIL && player.t_no_move <= 1) {
! 84: look(after, FALSE);
! 85: lastscore = purse;
! 86: wmove(cw, hero.y, hero.x);
! 87: if (!((running || count) && jump)) {
! 88: status(FALSE);
! 89: }
! 90: }
! 91:
! 92: /* Draw the screen */
! 93: if (!((running || count) && jump)) {
! 94: wmove(cw, hero.y, hero.x);
! 95: draw(cw);
! 96: }
! 97:
! 98: after = TRUE;
! 99:
! 100: /*
! 101: * Read command or continue run
! 102: */
! 103: if (--player.t_no_move <= 0) {
! 104: take = 0; /* Nothing here to start with */
! 105: player.t_no_move = 0; /* Be sure we don't go too negative */
! 106: if (!running) door_stop = FALSE;
! 107:
! 108: /* Was the player being held? */
! 109: if (player.t_action == A_FREEZE) {
! 110: player.t_action = A_NIL;
! 111: msg("You can move again.");
! 112: }
! 113:
! 114: if (player.t_action != A_NIL) ch = (char) player.t_action;
! 115: else if (running) {
! 116: char scratch;
! 117:
! 118: /* If in a corridor or maze, if we are at a turn with
! 119: * only one way to go, turn that way.
! 120: */
! 121: scratch = CCHAR( winat(hero.y, hero.x) );
! 122: if ((scratch==PASSAGE||scratch==DOOR||levtype==MAZELEV) &&
! 123: off(player, ISHUH) &&
! 124: off(player, ISBLIND)) {
! 125: int y, x;
! 126: if (getdelta(runch, &y, &x) == TRUE) {
! 127: corr_move(y, x);
! 128: }
! 129: }
! 130: ch = runch;
! 131: }
! 132: else if (count) ch = countch;
! 133: else {
! 134: ch = readchar();
! 135: if (mpos != 0 && !running) /* Erase message if its there */
! 136: msg("");
! 137: }
! 138:
! 139: /*
! 140: * check for prefixes
! 141: */
! 142: if (isdigit(ch))
! 143: {
! 144: count = 0;
! 145: newcount = TRUE;
! 146: while (isdigit(ch))
! 147: {
! 148: count = count * 10 + (ch - '0');
! 149: if (count > 255)
! 150: count = 255;
! 151: ch = readchar();
! 152: }
! 153: countch = ch;
! 154: /*
! 155: * turn off count for commands which don't make sense
! 156: * to repeat
! 157: */
! 158: switch (ch) {
! 159: case 'h': case 'j': case 'k': case 'l':
! 160: case 'y': case 'u': case 'b': case 'n':
! 161: case 'H': case 'J': case 'K': case 'L':
! 162: case 'Y': case 'U': case 'B': case 'N':
! 163: case C_SEARCH: case '.':
! 164: break;
! 165: default:
! 166: count = 0;
! 167: }
! 168: }
! 169:
! 170: /* Save current direction */
! 171: if (!running) { /* If running, it is already saved */
! 172: switch (ch) {
! 173: case 'h': case 'j': case 'k': case 'l':
! 174: case 'y': case 'u': case 'b': case 'n':
! 175: case 'H': case 'J': case 'K': case 'L':
! 176: case 'Y': case 'U': case 'B': case 'N':
! 177: runch = tolower(ch);
! 178: }
! 179: }
! 180:
! 181: /* Perform the action */
! 182: switch (ch) {
! 183: case 'f':
! 184: if (!on(player, ISBLIND))
! 185: {
! 186: door_stop = TRUE;
! 187: firstmove = TRUE;
! 188: }
! 189: if (count && !newcount)
! 190: ch = direction;
! 191: else
! 192: ch = readchar();
! 193: switch (ch)
! 194: {
! 195: case 'h': case 'j': case 'k': case 'l':
! 196: case 'y': case 'u': case 'b': case 'n':
! 197: ch = toupper(ch);
! 198: }
! 199: direction = ch;
! 200: }
! 201: newcount = FALSE;
! 202:
! 203: /*
! 204: * execute a command
! 205: */
! 206: if (count && !running && player.t_action == A_NIL)
! 207: count--;
! 208: switch (ch) {
! 209: case '!' : shell();
! 210: when 'h' : do_move(0, -1);
! 211: when 'j' : do_move(1, 0);
! 212: when 'k' : do_move(-1, 0);
! 213: when 'l' : do_move(0, 1);
! 214: when 'y' : do_move(-1, -1);
! 215: when 'u' : do_move(-1, 1);
! 216: when 'b' : do_move(1, -1);
! 217: when 'n' : do_move(1, 1);
! 218: when 'H' : do_run('h');
! 219: when 'J' : do_run('j');
! 220: when 'K' : do_run('k');
! 221: when 'L' : do_run('l');
! 222: when 'Y' : do_run('y');
! 223: when 'U' : do_run('u');
! 224: when 'B' : do_run('b');
! 225: when 'N' : do_run('n');
! 226: when A_PICKUP:
! 227: player.t_action = A_NIL;
! 228: if (add_pack(NULL, FALSE, NULL)) {
! 229: char tch;
! 230:
! 231: tch = CCHAR( mvwinch(stdscr, hero.y, hero.x) );
! 232: if (tch != FLOOR && tch != PASSAGE) {
! 233: player.t_action = A_PICKUP; /*get more */
! 234: player.t_no_move += 2 * movement(&player);
! 235: }
! 236: }
! 237: when A_ATTACK:
! 238: /* Is our attackee still there? */
! 239: if (isalpha(winat(player.t_newpos.y,
! 240: player.t_newpos.x))) {
! 241: /* Our friend is still here */
! 242: player.t_action = A_NIL;
! 243: fight(&player.t_newpos, cur_weapon, FALSE);
! 244: }
! 245: else { /* Our monster has moved */
! 246: player.t_action = A_NIL;
! 247: }
! 248: when A_THROW:
! 249: if (player.t_action == A_NIL) {
! 250: item = get_item(pack, "throw", ALL, FALSE, FALSE);
! 251: if (item != NULL && get_dir(&player.t_newpos)) {
! 252: player.t_action = A_THROW;
! 253: player.t_using = item;
! 254: player.t_no_move = 2 * movement(&player);
! 255: }
! 256: else
! 257: after = FALSE;
! 258: }
! 259: else {
! 260: missile(player.t_newpos.y, player.t_newpos.x,
! 261: player.t_using, &player);
! 262: player.t_action = A_NIL;
! 263: player.t_using = 0;
! 264: }
! 265: when 'Q' : after = FALSE; quit(0);
! 266: when 'i' : after = FALSE; inventory(pack, ALL);
! 267: when 'I' : after = FALSE; picky_inven();
! 268: when C_DROP : player.t_action = C_DROP; drop(NULL);
! 269: when 'P' :
! 270: if (levtype != POSTLEV) {
! 271: /* We charge 2 movement units per item */
! 272: player.t_no_move =
! 273: 2 * grab(hero.y, hero.x) * movement(&player);
! 274: }
! 275: else {
! 276: /* Let's quote the wise guy a price */
! 277: buy_it();
! 278: after = FALSE;
! 279: }
! 280: when C_COUNT : count_gold();
! 281: when C_QUAFF : quaff(-1, 0, 0, TRUE);
! 282: when C_READ : read_scroll(-1, 0, TRUE);
! 283: when C_EAT : eat();
! 284: when C_WIELD : wield();
! 285: when C_WEAR : wear();
! 286: when C_TAKEOFF : take_off();
! 287: when 'o' : option();
! 288: when CTRL('N') : nameit();
! 289: when '=' : after = FALSE; display();
! 290: when 'm' : nameitem(NULL, TRUE);
! 291: when '>' : after = FALSE; d_level();
! 292: when '<' : after = FALSE; u_level();
! 293: when '?' : after = FALSE; help();
! 294: when '/' : after = FALSE; identify(0);
! 295: when C_USE : use_mm(-1);
! 296: when CTRL('T') :
! 297: if (player.t_action == A_NIL) {
! 298: if (get_dir(&player.t_newpos)) {
! 299: player.t_action = CTRL('T');
! 300: player.t_no_move = 2 * movement(&player);
! 301: }
! 302: else
! 303: after = FALSE;
! 304: }
! 305: else {
! 306: steal();
! 307: player.t_action = A_NIL;
! 308: }
! 309: when C_DIP : dip_it();
! 310: when 'G' :
! 311: if (player.t_action == A_NIL) {
! 312: player.t_action = 'G';
! 313: player.t_no_move = movement(&player);
! 314: }
! 315: else {
! 316: gsense();
! 317: player.t_action = A_NIL;
! 318: }
! 319: when C_SETTRAP : set_trap(&player, hero.y, hero.x);
! 320: when C_SEARCH :
! 321: if (player.t_action == A_NIL) {
! 322: player.t_action = C_SEARCH;
! 323: player.t_no_move = 5 * movement(&player);
! 324: }
! 325: else {
! 326: search(FALSE, FALSE);
! 327: player.t_action = A_NIL;
! 328: }
! 329: when C_ZAP : if (!player_zap(0, FALSE))
! 330: after=FALSE;
! 331: when C_PRAY : pray();
! 332: when C_CHANT : chant();
! 333: when C_CAST : cast();
! 334: when 'a' :
! 335: if (player.t_action == A_NIL) {
! 336: if (get_dir(&player.t_newpos)) {
! 337: player.t_action = 'a';
! 338: player.t_no_move = 2 * movement(&player);
! 339: }
! 340: else
! 341: after = FALSE;
! 342: }
! 343: else {
! 344: affect();
! 345: player.t_action = A_NIL;
! 346: }
! 347: when 'v' : after = FALSE;
! 348: msg("Advanced Rogue Version %s.",
! 349: release);
! 350: when CTRL('L') : after = FALSE; clearok(curscr, TRUE);
! 351: touchwin(cw); /* MMMMMMMMMM */
! 352: when CTRL('R') : after = FALSE; msg(huh);
! 353: when 'S' :
! 354: after = FALSE;
! 355: if (save_game())
! 356: {
! 357: wclear(cw);
! 358: draw(cw);
! 359: endwin();
! 360: #ifdef PC7300
! 361: endhardwin();
! 362: #endif
! 363: exit(0);
! 364: }
! 365: when '.' :
! 366: player.t_no_move = movement(&player); /* Rest */
! 367: player.t_action = A_NIL;
! 368: when ' ' : after = FALSE; /* Do Nothing */
! 369: #ifdef WIZARD
! 370: when CTRL('P') :
! 371: after = FALSE;
! 372: if (wizard)
! 373: {
! 374: wizard = FALSE;
! 375: trader = 0;
! 376: msg("Not wizard any more");
! 377: }
! 378: else
! 379: {
! 380: if (waswizard || passwd())
! 381: {
! 382: msg("Welcome, oh mighty wizard.");
! 383: wizard = waswizard = TRUE;
! 384: }
! 385: else
! 386: msg("Sorry");
! 387: }
! 388: #endif
! 389: when ESCAPE : /* Escape */
! 390: door_stop = FALSE;
! 391: count = 0;
! 392: after = FALSE;
! 393: when '#':
! 394: if (levtype == POSTLEV) /* buy something */
! 395: buy_it();
! 396: after = FALSE;
! 397: when '$':
! 398: if (levtype == POSTLEV) /* price something */
! 399: price_it();
! 400: after = FALSE;
! 401: when '%':
! 402: if (levtype == POSTLEV) /* sell something */
! 403: sell_it();
! 404: after = FALSE;
! 405: otherwise :
! 406: after = FALSE;
! 407: #ifdef WIZARD
! 408: if (wizard) switch (ch)
! 409: {
! 410: case 'M' : create_obj(TRUE, 0, 0);
! 411: when CTRL('W') : wanderer();
! 412: when CTRL('I') : inventory(lvl_obj, ALL);
! 413: when CTRL('Z') : whatis(NULL);
! 414: when CTRL('D') : level++; new_level(NORMLEV);
! 415: when CTRL('F') : overlay(stdscr,cw);
! 416: when CTRL('X') : overlay(mw,cw);
! 417: when CTRL('J') : teleport();
! 418: when CTRL('E') : msg("food left: %d\tfood level: %d",
! 419: food_left, foodlev);
! 420: when CTRL('A') : activity();
! 421: when CTRL('C') :
! 422: {
! 423: int tlev;
! 424: prbuf[0] = 0;
! 425: msg("Which level? ");
! 426: if(get_str(prbuf,msgw) == NORM) {
! 427: tlev = atoi(prbuf);
! 428: if(tlev < 1) {
! 429: mpos = 0;
! 430: msg("Illegal level.");
! 431: }
! 432: else if (tlev > 199) {
! 433: levtype = MAZELEV;
! 434: level = tlev - 200 + 1;
! 435: }
! 436: else if (tlev > 99) {
! 437: levtype = POSTLEV;
! 438: level = tlev - 100 + 1;
! 439: }
! 440: else {
! 441: levtype = NORMLEV;
! 442: level = tlev;
! 443: }
! 444: new_level(levtype);
! 445: }
! 446: }
! 447: when CTRL('G') :
! 448: {
! 449: item=get_item(pack,"charge",STICK,FALSE,FALSE);
! 450: if (item != NULL) {
! 451: (OBJPTR(item))->o_charges=10000;
! 452: }
! 453: }
! 454: when CTRL('H') :
! 455: {
! 456: register int i;
! 457: register struct object *obj;
! 458:
! 459: for (i = 0; i < 9; i++)
! 460: raise_level();
! 461: /*
! 462: * Give the rogue a sword
! 463: */
! 464: if (cur_weapon==NULL || cur_weapon->o_type !=
! 465: RELIC) {
! 466: item = spec_item(WEAPON, TWOSWORD, 5, 5);
! 467: add_pack(item, TRUE, NULL);
! 468: cur_weapon = OBJPTR(item);
! 469: (OBJPTR(item))->o_flags |= (ISKNOW|ISPROT);
! 470: }
! 471: /*
! 472: * And his suit of armor
! 473: */
! 474: if (player.t_ctype != C_MONK) {
! 475: item = spec_item(ARMOR, PLATE_ARMOR, 10, 0);
! 476: obj = OBJPTR(item);
! 477: if (player.t_ctype == C_THIEF)
! 478: obj->o_which = STUDDED_LEATHER;
! 479: obj->o_flags |= (ISKNOW | ISPROT);
! 480: obj->o_weight = armors[PLATE_ARMOR].a_wght;
! 481: cur_armor = obj;
! 482: add_pack(item, TRUE, NULL);
! 483: }
! 484: purse += 20000;
! 485: }
! 486: otherwise :
! 487: msg("Illegal command '%s'.", unctrl(ch));
! 488: count = 0;
! 489: }
! 490: else
! 491: #endif
! 492: {
! 493: msg("Illegal command '%s'.", unctrl(ch));
! 494: count = 0;
! 495: after = FALSE;
! 496: }
! 497: }
! 498:
! 499: /*
! 500: * If he ran into something to take, let him pick it up.
! 501: * unless it's a trading post
! 502: */
! 503: if (auto_pickup && take != 0 && levtype != POSTLEV) {
! 504: /* get ready to pick it up */
! 505: player.t_action = A_PICKUP;
! 506: player.t_no_move += 2 * movement(&player);
! 507: }
! 508: }
! 509:
! 510: /* If he was fighting, let's stop (for now) */
! 511: if (player.t_quiet < 0) player.t_quiet = 0;
! 512:
! 513: if (!running)
! 514: door_stop = FALSE;
! 515:
! 516: if (after && segment >= 10) {
! 517: /*
! 518: * Kick off the rest if the daemons and fuses
! 519: */
! 520:
! 521: /*
! 522: * If player is infested, take off a hit point
! 523: */
! 524: if (on(player, HASINFEST)) {
! 525: if ((pstats.s_hpt -= infest_dam) <= 0) death(D_INFESTATION);
! 526: }
! 527:
! 528: /*
! 529: * The eye of Vecna is a constant drain on the player
! 530: */
! 531: if (cur_relic[EYE_VECNA]) {
! 532: if ((--pstats.s_hpt) <= 0) death(D_RELIC);
! 533: }
! 534:
! 535: /*
! 536: * if player has body rot then take off five hits
! 537: */
! 538: if (on(player, DOROT)) {
! 539: if ((pstats.s_hpt -= 5) <= 0) death(D_ROT);
! 540: }
! 541: do_daemons(AFTER);
! 542: do_fuses(AFTER);
! 543: }
! 544: } while (after == FALSE);
! 545:
! 546: /* Make the monsters go */
! 547: if (--monst_current <= 0)
! 548: monst_current = monst_limit = runners(monst_limit);
! 549:
! 550: #ifdef NEEDLOOK
! 551: /* Shall we take a look? */
! 552: if (player.t_no_move <= 1 &&
! 553: !((running || count) && jump))
! 554: look(FALSE, FALSE);
! 555: #endif
! 556:
! 557: if (++segment > 10) segment = 1;
! 558: t_free_list(monst_dead);
! 559: }
! 560: }
! 561:
! 562: /*
! 563: * display
! 564: * tell the player what is at a certain coordinates assuming
! 565: * it can be seen.
! 566: */
! 567: void
! 568: display(void)
! 569: {
! 570: coord c;
! 571: struct linked_list *item;
! 572: struct thing *tp;
! 573: int what;
! 574:
! 575: msg("What do you want to display (* for help)?");
! 576: c = get_coordinates();
! 577: mpos = 0;
! 578: if (!cansee(c.y, c.x)) {
! 579: msg("You can't see what is there.");
! 580: return;
! 581: }
! 582: what = mvwinch(cw, c.y, c.x);
! 583: if (isalpha(what)) {
! 584: item = find_mons(c.y, c.x);
! 585: tp = THINGPTR(item);
! 586: msg("%s", monster_name(tp));
! 587: return;
! 588: }
! 589: if ((item = find_obj(c.y, c.x)) != NULL) {
! 590: msg("%s", inv_name(OBJPTR(item), FALSE));
! 591: return;
! 592: }
! 593: identify(what);
! 594: }
! 595:
! 596: /*
! 597: * quit:
! 598: * Have player make certain, then exit.
! 599: */
! 600:
! 601: void
! 602: quit(int sig)
! 603: {
! 604: /*
! 605: * Reset the signal in case we got here via an interrupt
! 606: */
! 607: if (signal(SIGINT, quit) != quit)
! 608: mpos = 0;
! 609: msg("Really quit? <yes or no> ");
! 610: draw(cw);
! 611: prbuf[0] = '\0';
! 612: if ((get_str(prbuf, msgw) == NORM) && strcmp(prbuf, "yes") == 0) {
! 613: clear();
! 614: move(lines-1, 0);
! 615: draw(stdscr);
! 616: writelog(pstats.s_exp + (long) purse, CHICKEN, 0);
! 617: score(pstats.s_exp + (long) purse, CHICKEN, 0);
! 618: #ifdef PC7300
! 619: endhardwin();
! 620: #endif
! 621: exit(0);
! 622: }
! 623: else
! 624: {
! 625: signal(SIGINT, quit);
! 626: wmove(cw, 0, 0);
! 627: wclrtoeol(cw);
! 628: status(FALSE);
! 629: draw(cw);
! 630: mpos = 0;
! 631: count = 0;
! 632: running = FALSE;
! 633: }
! 634: }
! 635:
! 636: /*
! 637: * bugkill:
! 638: * killed by a program bug instead of voluntarily.
! 639: */
! 640:
! 641: void
! 642: bugkill(int sig)
! 643: {
! 644: signal(sig, quit); /* If we get it again, give up */
! 645: death(D_SIGNAL); /* Killed by a bug */
! 646: }
! 647:
! 648:
! 649: /*
! 650: * search:
! 651: * Player gropes about him to find hidden things.
! 652: */
! 653:
! 654: void
! 655: search(bool is_thief, bool door_chime)
! 656: {
! 657: register int x, y;
! 658: register char ch, /* The trap or door character */
! 659: sch, /* Trap or door character (as seen on screen) */
! 660: mch; /* Monster, if a monster is on the trap or door */
! 661: register struct linked_list *item;
! 662: register struct thing *mp; /* Status on surrounding monster */
! 663:
! 664: /*
! 665: * Look all around the hero, if there is something hidden there,
! 666: * give him a chance to find it. If its found, display it.
! 667: */
! 668: if (on(player, ISBLIND))
! 669: return;
! 670: for (x = hero.x - 1; x <= hero.x + 1; x++)
! 671: for (y = hero.y - 1; y <= hero.y + 1; y++)
! 672: {
! 673: if (y==hero.y && x==hero.x)
! 674: continue;
! 675:
! 676: /* Mch and ch will be the same unless there is a monster here */
! 677: mch = CCHAR( winat(y, x) );
! 678: ch = CCHAR( mvwinch(stdscr, y, x) );
! 679: sch = CCHAR( mvwinch(cw, y, x) ); /* What's on the screen */
! 680:
! 681: if (door_chime == FALSE && isatrap(ch)) {
! 682: register struct trap *tp;
! 683:
! 684: /* Is there a monster on the trap? */
! 685: if (mch != ch && (item = find_mons(y, x)) != NULL) {
! 686: mp = THINGPTR(item);
! 687: if (sch == mch) sch = mp->t_oldch;
! 688: }
! 689: else mp = NULL;
! 690:
! 691: /*
! 692: * is this one found already?
! 693: */
! 694: if (isatrap(sch))
! 695: continue; /* give him chance for other traps */
! 696: tp = trap_at(y, x);
! 697: /*
! 698: * if the thief set it then don't display it.
! 699: * if its not a thief he has 50/50 shot
! 700: */
! 701: if((tp->tr_flags&ISTHIEFSET) || (!is_thief && rnd(100)>50))
! 702: continue; /* give him chance for other traps */
! 703: tp->tr_flags |= ISFOUND;
! 704:
! 705: /* Let's update the screen */
! 706: if (mp != NULL && mvwinch(cw, y, x) == mch)
! 707: mp->t_oldch = ch; /* Will change when monst moves */
! 708: else mvwaddch(cw, y, x, ch);
! 709:
! 710: count = 0;
! 711: running = FALSE;
! 712:
! 713: /* Stop what we were doing */
! 714: player.t_no_move = movement(&player);
! 715: player.t_action = A_NIL;
! 716: player.t_using = NULL;
! 717:
! 718: if (fight_flush) md_flushinp();
! 719: msg(tr_name(tp->tr_type));
! 720: }
! 721: else if (ch == SECRETDOOR) {
! 722: if (door_chime == TRUE || (!is_thief && rnd(100) < 20)) {
! 723: struct room *rp;
! 724: coord cp;
! 725:
! 726: /* Is there a monster on the door? */
! 727: if (mch != ch && (item = find_mons(y, x)) != NULL) {
! 728: mp = THINGPTR(item);
! 729:
! 730: /* Screen will change when monster moves */
! 731: if (sch == mch) mp->t_oldch = ch;
! 732: }
! 733: mvaddch(y, x, DOOR);
! 734: count = 0;
! 735: /*
! 736: * if its the entrance to a treasure room, wake it up
! 737: */
! 738: cp.y = y;
! 739: cp.x = x;
! 740: rp = roomin(&cp);
! 741: if (rp->r_flags & ISTREAS)
! 742: wake_room(rp);
! 743:
! 744: /* Make sure we don't shoot into the room */
! 745: if (door_chime == FALSE) {
! 746: count = 0;
! 747: running = FALSE;
! 748:
! 749: /* Stop what we were doing */
! 750: player.t_no_move = movement(&player);
! 751: player.t_action = A_NIL;
! 752: player.t_using = NULL;
! 753: }
! 754: }
! 755: }
! 756: }
! 757: }
! 758:
! 759:
! 760: /*
! 761: * help:
! 762: * Give single character help, or the whole mess if he wants it
! 763: */
! 764:
! 765: void
! 766: help(void)
! 767: {
! 768: register struct h_list *strp = helpstr;
! 769: #ifdef WIZARD
! 770: struct h_list *wizp = wiz_help;
! 771: #endif
! 772: register char helpch;
! 773: register int cnt;
! 774:
! 775: msg("Character you want help for (* for all): ");
! 776: helpch = readchar();
! 777: mpos = 0;
! 778: /*
! 779: * If its not a *, print the right help string
! 780: * or an error if he typed a funny character.
! 781: */
! 782: if (helpch != '*') {
! 783: wmove(msgw, 0, 0);
! 784: while (strp->h_ch) {
! 785: if (strp->h_ch == helpch) {
! 786: msg("%s%s", unctrl(strp->h_ch), strp->h_desc);
! 787: return;
! 788: }
! 789: strp++;
! 790: }
! 791: #ifdef WIZARD
! 792: if (wizard) {
! 793: while (wizp->h_ch) {
! 794: if (wizp->h_ch == helpch) {
! 795: msg("%s%s", unctrl(wizp->h_ch), wizp->h_desc);
! 796: return;
! 797: }
! 798: wizp++;
! 799: }
! 800: }
! 801: #endif
! 802:
! 803: msg("Unknown character '%s'", unctrl(helpch));
! 804: return;
! 805: }
! 806: /*
! 807: * Here we print help for everything.
! 808: * Then wait before we return to command mode
! 809: */
! 810: wclear(hw);
! 811: cnt = 0;
! 812: while (strp->h_ch) {
! 813: mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(strp->h_ch));
! 814: waddstr(hw, strp->h_desc);
! 815: strp++;
! 816: if (++cnt >= 46 && strp->h_ch) {
! 817: wmove(hw, lines-1, 0);
! 818: wprintw(hw, morestr);
! 819: draw(hw);
! 820: wait_for(' ');
! 821: wclear(hw);
! 822: cnt = 0;
! 823: }
! 824: }
! 825: #ifdef WIZARD
! 826: if (wizard) {
! 827: while (wizp->h_ch) {
! 828: mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(wizp->h_ch));
! 829: waddstr(hw, wizp->h_desc);
! 830: wizp++;
! 831: if (++cnt >= 46 && wizp->h_ch) {
! 832: wmove(hw, lines-1, 0);
! 833: wprintw(hw, morestr);
! 834: draw(hw);
! 835: wait_for(' ');
! 836: wclear(hw);
! 837: cnt = 0;
! 838: }
! 839: }
! 840: }
! 841: #endif
! 842: wmove(hw, lines-1, 0);
! 843: wprintw(hw, spacemsg);
! 844: draw(hw);
! 845: wait_for(' ');
! 846: wclear(hw);
! 847: draw(hw);
! 848: wmove(cw, 0, 0);
! 849: wclrtoeol(cw);
! 850: status(FALSE);
! 851: touchwin(cw);
! 852: }
! 853: /*
! 854: * identify:
! 855: * Tell the player what a certain thing is.
! 856: */
! 857:
! 858: void
! 859: identify(char ch)
! 860: {
! 861: register char *str;
! 862:
! 863: if (ch == 0) {
! 864: msg("What do you want identified? ");
! 865: ch = readchar();
! 866: mpos = 0;
! 867: if (ch == ESCAPE)
! 868: {
! 869: msg("");
! 870: return;
! 871: }
! 872: }
! 873: if (isalpha(ch))
! 874: str = monsters[id_monst(ch)].m_name;
! 875: else switch(ch)
! 876: {
! 877: case '|':
! 878: case '-':
! 879: str = (levtype == OUTSIDE) ? "boundary of sector"
! 880: : "wall of a room";
! 881: when GOLD: str = "gold";
! 882: when STAIRS : str = (levtype == OUTSIDE) ? "entrance to a dungeon"
! 883: : "passage leading down";
! 884: when DOOR: str = "door";
! 885: when FLOOR: str = (levtype == OUTSIDE) ? "meadow" : "room floor";
! 886: when VPLAYER: str = "the hero of the game ---> you";
! 887: when IPLAYER: str = "you (but invisible)";
! 888: when PASSAGE: str = "passage";
! 889: when POST: str = "trading post";
! 890: when POOL: str = (levtype == OUTSIDE) ? "lake"
! 891: : "a shimmering pool";
! 892: when TRAPDOOR: str = "trapdoor";
! 893: when ARROWTRAP: str = "arrow trap";
! 894: when SLEEPTRAP: str = "sleeping gas trap";
! 895: when BEARTRAP: str = "bear trap";
! 896: when TELTRAP: str = "teleport trap";
! 897: when DARTTRAP: str = "dart trap";
! 898: when MAZETRAP: str = "entrance to a maze";
! 899: when FOREST: str = "forest";
! 900: when POTION: str = "potion";
! 901: when SCROLL: str = "scroll";
! 902: when FOOD: str = "food";
! 903: when WEAPON: str = "weapon";
! 904: when ' ' : str = "solid rock";
! 905: when ARMOR: str = "armor";
! 906: when MM: str = "miscellaneous magic";
! 907: when RING: str = "ring";
! 908: when STICK: str = "wand or staff";
! 909: when SECRETDOOR:str = "secret door";
! 910: when RELIC: str = "artifact";
! 911: otherwise: str = "unknown character";
! 912: }
! 913: msg("'%s' : %s", unctrl(ch), str);
! 914: }
! 915:
! 916: /*
! 917: * d_level:
! 918: * He wants to go down a level
! 919: */
! 920:
! 921: void
! 922: d_level()
! 923: {
! 924: bool no_phase=FALSE;
! 925: char position = CCHAR( winat(hero.y, hero.x) );
! 926:
! 927:
! 928: /* If we are on a trading post, go to a trading post level. */
! 929: if (position == POST) {
! 930: new_level(POSTLEV);
! 931: return;
! 932: }
! 933:
! 934: /* If we are at a top-level trading post, we probably can't go down */
! 935: if (levtype == POSTLEV && level == 0 && position != STAIRS) {
! 936: msg("I see no way down.");
! 937: return;
! 938: }
! 939:
! 940: if (winat(hero.y, hero.x) != STAIRS) {
! 941: if (off(player, CANINWALL) || /* Must use stairs if can't phase */
! 942: (levtype == OUTSIDE && rnd(100) < 90)) {
! 943: msg("I see no way down.");
! 944: return;
! 945: }
! 946:
! 947: /* Is there any dungeon left below? */
! 948: if (level >= nfloors) {
! 949: msg("There is only solid rock below.");
! 950: return;
! 951: }
! 952:
! 953: extinguish(unphase); /* Using phase to go down gets rid of it */
! 954: no_phase = TRUE;
! 955: }
! 956:
! 957: /* Is this the bottom? */
! 958: if (level >= nfloors) {
! 959: msg("The stairway only goes up.");
! 960: return;
! 961: }
! 962:
! 963: level++;
! 964: new_level(NORMLEV);
! 965: if (no_phase) unphase();
! 966: }
! 967:
! 968: /*
! 969: * u_level:
! 970: * He wants to go up a level
! 971: */
! 972:
! 973: void
! 974: u_level(void)
! 975: {
! 976: bool no_phase = FALSE;
! 977: register struct linked_list *item;
! 978: struct thing *tp;
! 979: struct object *obj;
! 980:
! 981: if (winat(hero.y, hero.x) != STAIRS) {
! 982: if (off(player, CANINWALL)) { /* Must use stairs if can't phase */
! 983: msg("I see no way up.");
! 984: return;
! 985: }
! 986:
! 987: extinguish(unphase);
! 988: no_phase = TRUE;
! 989: }
! 990:
! 991: if (level == 0) {
! 992: msg("The stairway only goes down.");
! 993: return;
! 994: }
! 995:
! 996: /*
! 997: * does he have the item he was quested to get?
! 998: */
! 999: if (level == 1) {
! 1000: for (item = pack; item != NULL; item = next(item)) {
! 1001: obj = OBJPTR(item);
! 1002: if (obj->o_type == RELIC && obj->o_which == quest_item)
! 1003: total_winner();
! 1004: }
! 1005: }
! 1006: /*
! 1007: * check to see if he trapped a UNIQUE, If he did then put it back
! 1008: * in the monster table for next time
! 1009: */
! 1010: for (item = tlist; item != NULL; item = next(item)) {
! 1011: tp = THINGPTR(item);
! 1012: if (on(*tp, ISUNIQUE))
! 1013: monsters[tp->t_index].m_normal = TRUE;
! 1014: }
! 1015: t_free_list(tlist); /* Monsters that fell below are long gone! */
! 1016:
! 1017: if (levtype != POSTLEV) level--;
! 1018: if (level > 0) new_level(NORMLEV);
! 1019: else {
! 1020: level = -1; /* Indicate that we are new to the outside */
! 1021: new_level(OUTSIDE); /* Leaving the dungeon */
! 1022: msg("You emerge into the %s", daytime ? "light" : "night");
! 1023: }
! 1024:
! 1025: if (no_phase) unphase();
! 1026: }
! 1027:
! 1028: /*
! 1029: * Let him escape for a while
! 1030: */
! 1031:
! 1032: void
! 1033: shell(void)
! 1034: {
! 1035: register char *sh;
! 1036:
! 1037: /*
! 1038: * Set the terminal back to original mode
! 1039: */
! 1040: sh = getenv("SHELL");
! 1041: wclear(hw);
! 1042: wmove(hw, lines-1, 0);
! 1043: draw(hw);
! 1044: endwin();
! 1045: in_shell = TRUE;
! 1046: fflush(stdout);
! 1047: /*
! 1048: * Fork and do a shell
! 1049: */
! 1050:
! 1051: md_shellescape();
! 1052:
! 1053: printf(retstr);
! 1054: noecho();
! 1055: raw();
! 1056: keypad(cw,1);
! 1057: keypad(msgw,1);
! 1058: in_shell = FALSE;
! 1059: wait_for('\n');
! 1060: clearok(cw, TRUE);
! 1061: touchwin(cw);
! 1062: }
! 1063:
! 1064: /*
! 1065: * see what we want to name -- an item or a monster.
! 1066: */
! 1067: void
! 1068: nameit(void)
! 1069: {
! 1070: char answer;
! 1071:
! 1072: msg("Name monster or item (m or i)? ");
! 1073: answer = readchar();
! 1074: mpos = 0;
! 1075:
! 1076: while (answer != 'm' && answer != 'i' && answer != ESCAPE) {
! 1077: mpos = 0;
! 1078: msg("Please specify m or i, for monster or item - ");
! 1079: answer = readchar();
! 1080: }
! 1081:
! 1082: switch (answer) {
! 1083: case 'm': namemonst();
! 1084: when 'i': nameitem(NULL, FALSE);
! 1085: }
! 1086: }
! 1087:
! 1088: /*
! 1089: * allow a user to call a potion, scroll, or ring something
! 1090: */
! 1091: void
! 1092: nameitem(struct linked_list *item, bool mark)
! 1093: {
! 1094: register struct object *obj;
! 1095: register char **guess = NULL, *elsewise = NULL;
! 1096: register bool *know;
! 1097:
! 1098: if (item == NULL) {
! 1099: if (mark) item = get_item(pack, "mark", ALL, FALSE, FALSE);
! 1100: else item = get_item(pack, "name", CALLABLE, FALSE, FALSE);
! 1101: if (item == NULL) return;
! 1102: }
! 1103: /*
! 1104: * Make certain that it is somethings that we want to wear
! 1105: */
! 1106: obj = OBJPTR(item);
! 1107: switch (obj->o_type)
! 1108: {
! 1109: case RING:
! 1110: guess = r_guess;
! 1111: know = r_know;
! 1112: elsewise = (r_guess[obj->o_which] != NULL ?
! 1113: r_guess[obj->o_which] : r_stones[obj->o_which]);
! 1114: when POTION:
! 1115: guess = p_guess;
! 1116: know = p_know;
! 1117: elsewise = (p_guess[obj->o_which] != NULL ?
! 1118: p_guess[obj->o_which] : p_colors[obj->o_which]);
! 1119: when SCROLL:
! 1120: guess = s_guess;
! 1121: know = s_know;
! 1122: elsewise = (s_guess[obj->o_which] != NULL ?
! 1123: s_guess[obj->o_which] : s_names[obj->o_which]);
! 1124: when STICK:
! 1125: guess = ws_guess;
! 1126: know = ws_know;
! 1127: elsewise = (ws_guess[obj->o_which] != NULL ?
! 1128: ws_guess[obj->o_which] : ws_made[obj->o_which]);
! 1129: when MM:
! 1130: guess = m_guess;
! 1131: know = m_know;
! 1132: elsewise = (m_guess[obj->o_which] != NULL ?
! 1133: m_guess[obj->o_which] : "nothing");
! 1134: otherwise:
! 1135: if (!mark) {
! 1136: msg("You can't call that anything.");
! 1137: return;
! 1138: }
! 1139: else know = (bool *) 0;
! 1140: }
! 1141: if ((obj->o_flags & ISPOST) || (know && know[obj->o_which]) && !mark) {
! 1142: msg("That has already been identified.");
! 1143: return;
! 1144: }
! 1145: if (mark) {
! 1146: if (obj->o_mark[0]) {
! 1147: addmsg(terse ? "M" : "Was m");
! 1148: msg("arked \"%s\"", obj->o_mark);
! 1149: }
! 1150: msg(terse ? "Mark it: " : "What do you want to mark it? ");
! 1151: prbuf[0] = '\0';
! 1152: }
! 1153: else {
! 1154: if (elsewise) {
! 1155: addmsg(terse ? "N" : "Was n");
! 1156: msg("amed \"%s\"", elsewise);
! 1157: strcpy(prbuf, elsewise);
! 1158: }
! 1159: else prbuf[0] = '\0';
! 1160: msg(terse ? "Name it: " : "What do you want to name it? ");
! 1161: }
! 1162: if (get_str(prbuf, msgw) == NORM) {
! 1163: if (mark) {
! 1164: strncpy(obj->o_mark, prbuf, MARKLEN-1);
! 1165: obj->o_mark[MARKLEN-1] = '\0';
! 1166: }
! 1167: else if (prbuf[0] != '\0') {
! 1168: if (guess[obj->o_which] != NULL)
! 1169: free(guess[obj->o_which]);
! 1170: guess[obj->o_which] = new((unsigned int) strlen(prbuf) + 1);
! 1171: strcpy(guess[obj->o_which], prbuf);
! 1172: }
! 1173: }
! 1174: }
! 1175:
! 1176: /* Name a monster */
! 1177:
! 1178: void
! 1179: namemonst(void)
! 1180: {
! 1181: register struct thing *tp;
! 1182: struct linked_list *item;
! 1183: coord c;
! 1184:
! 1185: /* Find the monster */
! 1186: msg("Choose the monster (* for help)");
! 1187: c = get_coordinates();
! 1188:
! 1189: /* Make sure we can see it and that it is a monster. */
! 1190: mpos = 0;
! 1191: if (!cansee(c.y, c.x)) {
! 1192: msg("You can't see what is there.");
! 1193: return;
! 1194: }
! 1195:
! 1196: if (isalpha(mvwinch(cw, c.y, c.x))) {
! 1197: item = find_mons(c.y, c.x);
! 1198: if (item != NULL) {
! 1199: tp = THINGPTR(item);
! 1200: if (tp->t_name == NULL)
! 1201: strcpy(prbuf, monsters[tp->t_index].m_name);
! 1202: else
! 1203: strcpy(prbuf, tp->t_name);
! 1204:
! 1205: addmsg(terse ? "N" : "Was n");
! 1206: msg("amed \"%s\"", prbuf);
! 1207: msg(terse ? "Name it: " : "What do you want to name it? ");
! 1208:
! 1209: if (get_str(prbuf, msgw) == NORM) {
! 1210: if (prbuf[0] != '\0') {
! 1211: if (tp->t_name != NULL)
! 1212: free(tp->t_name);
! 1213: tp->t_name = new((unsigned int) strlen(prbuf) + 1);
! 1214: strcpy(tp->t_name, prbuf);
! 1215: }
! 1216: }
! 1217: return;
! 1218: }
! 1219: }
! 1220:
! 1221: msg("There is no monster there to name.");
! 1222: }
! 1223:
! 1224: void
! 1225: count_gold(void)
! 1226: {
! 1227: if (player.t_action != C_COUNT) {
! 1228: msg("You take a break to count your money...");
! 1229: player.t_using = NULL;
! 1230: player.t_action = C_COUNT; /* We are counting */
! 1231: player.t_no_move = (purse/300 + 1) * movement(&player);
! 1232: return;
! 1233: }
! 1234: if (purse > 100)
! 1235: msg("You think you have about %d gold pieces.", purse);
! 1236: else
! 1237: msg("You have %d gold pieces.", purse);
! 1238: player.t_action = A_NIL;
! 1239: }
CVSweb