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