Annotation of early-roguelike/urogue/command.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: command.c - Read and execute the user commands
! 3:
! 4: UltraRogue: The Ultimate Adventure in the Dungeons of Doom
! 5: Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
! 6: All rights reserved.
! 7:
! 8: Based on "Advanced Rogue"
! 9: Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
! 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 <string.h>
! 20: #include <stdlib.h>
! 21: #include <ctype.h>
! 22: #include "rogue.h"
! 23:
! 24: /*
! 25: command()
! 26: Process the user commands
! 27: */
! 28:
! 29: void
! 30: command(void)
! 31: {
! 32: static char repcommand; /* Command to repeat if we are repeating */
! 33: static int fight_to_death; /* Flags if we are fighting to death */
! 34: static coord dir; /* Last direction specified */
! 35:
! 36: object *obj;
! 37: char ch;
! 38: int ntimes = 1; /* Number of player moves */
! 39: coord nullcoord;
! 40:
! 41: nullcoord.x = nullcoord.y = 0;
! 42:
! 43: if (on(player, CANFLY) && rnd(2))
! 44: ntimes++;
! 45:
! 46: if (on(player, ISHASTE))
! 47: ntimes++;
! 48:
! 49: if (fighting && att_bonus())
! 50: ntimes *= 2;
! 51:
! 52: if (on(player, ISSLOW))
! 53: {
! 54: if (player.t_turn != TRUE)
! 55: ntimes--;
! 56:
! 57: player.t_turn ^= TRUE;
! 58: }
! 59:
! 60: if (ntimes == 0)
! 61: return;
! 62:
! 63: while (ntimes--)
! 64: {
! 65: moving = FALSE;
! 66:
! 67: /* If player is infested, take off a hit point */
! 68:
! 69: if (on(player, HASINFEST) && !is_wearing(R_HEALTH))
! 70: {
! 71: if ((pstats.s_hpt -= infest_dam) <= 0)
! 72: {
! 73: death(D_INFESTATION);
! 74: return;
! 75: }
! 76: }
! 77:
! 78: look(after);
! 79:
! 80: if (!running)
! 81: door_stop = FALSE;
! 82:
! 83: status(FALSE);
! 84: wmove(cw, hero.y, hero.x);
! 85:
! 86: if (!((running || count) && jump))
! 87: wrefresh(cw); /* Draw screen */
! 88:
! 89: take = 0;
! 90: after = TRUE;
! 91:
! 92: /*
! 93: * Read command or continue run
! 94: */
! 95:
! 96: if (!no_command)
! 97: {
! 98: if (fighting)
! 99: {
! 100: ch = (fight_to_death) ? 'F' : 'f';
! 101: }
! 102: else if (running)
! 103: {
! 104: /*
! 105: * If in a corridor, if we are at a turn with
! 106: * only one way to go, turn that way.
! 107: */
! 108:
! 109: if ((winat(hero.y, hero.x) == PASSAGE) && off(player, ISHUH) &&
! 110: (off(player, ISBLIND)))
! 111: switch (runch)
! 112: {
! 113: case 'h': corr_move(0, -1); break;
! 114: case 'j': corr_move(1, 0); break;
! 115: case 'k': corr_move(-1, 0); break;
! 116: case 'l': corr_move(0, 1); break;
! 117: }
! 118:
! 119: ch = runch;
! 120: }
! 121: else if (count)
! 122: ch = repcommand;
! 123: else
! 124: {
! 125: ch = readchar();
! 126:
! 127: if (mpos != 0 && !running)
! 128: msg(""); /* Erase message if its there */
! 129: }
! 130: }
! 131: else
! 132: {
! 133: ch = '.';
! 134: fighting = moving = FALSE;
! 135: }
! 136:
! 137: if (no_command)
! 138: {
! 139: if (--no_command == 0)
! 140: msg("You can move again.");
! 141: }
! 142: else
! 143: {
! 144:
! 145: /*
! 146: * check for prefixes
! 147: */
! 148:
! 149: if (isdigit(ch))
! 150: {
! 151: count = 0;
! 152: while (isdigit(ch))
! 153: {
! 154: count = count * 10 + (ch - '0');
! 155: ch = readcharw(cw);
! 156: }
! 157: repcommand = ch;
! 158:
! 159: /*
! 160: * Preserve count for commands which can be
! 161: * repeated.
! 162: */
! 163:
! 164: switch(ch)
! 165: {
! 166: case 'h':
! 167: case 'j':
! 168: case 'k':
! 169: case 'l':
! 170: case 'y':
! 171: case 'u':
! 172: case 'b':
! 173: case 'n':
! 174: case 'H':
! 175: case 'J':
! 176: case 'K':
! 177: case 'L':
! 178: case 'Y':
! 179: case 'U':
! 180: case 'B':
! 181: case 'N':
! 182: case 'q':
! 183: case 'r':
! 184: case 's':
! 185: case 'm':
! 186: case 't':
! 187: case 'C':
! 188: case 'I':
! 189: case '.':
! 190: case 'z':
! 191: case 'p':
! 192: break;
! 193: default:
! 194: count = 0;
! 195: }
! 196: }
! 197:
! 198: /* Save current direction */
! 199:
! 200: if (!running) /* If running, it is already saved */
! 201: switch (ch)
! 202: {
! 203: case 'h':
! 204: case 'j':
! 205: case 'k':
! 206: case 'l':
! 207: case 'y':
! 208: case 'u':
! 209: case 'b':
! 210: case 'n':
! 211: runch = ch;
! 212: break;
! 213: case 'H':
! 214: case 'J':
! 215: case 'K':
! 216: case 'L':
! 217: case 'Y':
! 218: case 'U':
! 219: case 'B':
! 220: case 'N':
! 221: runch = (char) tolower(ch);
! 222: break;
! 223: }
! 224:
! 225: /*
! 226: * execute a command
! 227: */
! 228:
! 229: if (count && !running)
! 230: count--;
! 231:
! 232: switch(ch)
! 233: {
! 234: /*
! 235: * Movement and combat commands
! 236: */
! 237:
! 238: case 'h': do_move(0,-1); break;
! 239: case 'j': do_move(1, 0); break;
! 240: case 'k': do_move(-1, 0); break;
! 241: case 'l': do_move(0, 1); break;
! 242: case 'y': do_move(-1, -1); break;
! 243: case 'u': do_move(-1, 1); break;
! 244: case 'b': do_move(1, -1); break;
! 245: case 'n': do_move(1, 1); break;
! 246: case 'H': do_run('h'); break;
! 247: case 'J': do_run('j'); break;
! 248: case 'K': do_run('k'); break;
! 249: case 'L': do_run('l'); break;
! 250: case 'Y': do_run('y'); break;
! 251: case 'U': do_run('u'); break;
! 252: case 'B': do_run('b'); break;
! 253: case 'N': do_run('n'); break;
! 254: case 'm':
! 255: moving = TRUE;
! 256: if (!get_dir())
! 257: {
! 258: after = FALSE;
! 259: break;
! 260: }
! 261: do_move(delta.y, delta.x);
! 262: break;
! 263: case 'F':
! 264: case 'f':
! 265: fight_to_death = (ch == 'F');
! 266: if (!fighting)
! 267: {
! 268: if (get_dir())
! 269: {
! 270: dir = delta;
! 271: beast = NULL;
! 272: }
! 273: else
! 274: {
! 275: after = FALSE;
! 276: break;
! 277: }
! 278: }
! 279: do_fight(dir, (ch == 'F') ? TRUE : FALSE);
! 280: break;
! 281: case 't':
! 282: if (get_dir())
! 283: missile(delta.y, delta.x, get_item("throw", 0),
! 284: &player);
! 285: else
! 286: after = FALSE;
! 287:
! 288: /*
! 289: * Informational commands - Do not do
! 290: * after daemons
! 291: */
! 292: break;
! 293:
! 294: case 0x7f: /* sometime generated by */
! 295: /* suspend/foreground */
! 296: case ESCAPE:
! 297: case ' ':
! 298: after = FALSE; /* do nothing */
! 299: break;
! 300: case 'Q':
! 301: after = FALSE;
! 302: quit();
! 303: break;
! 304: case 'i':
! 305: after = FALSE;
! 306: inventory(pack, '*');
! 307: break;
! 308: case 'I':
! 309: after = FALSE;
! 310: inventory(pack, 0);
! 311: break;
! 312: case '~':
! 313: after = FALSE;
! 314: next_exp_level(MESSAGE);
! 315: break;
! 316: case '>':
! 317: after = FALSE;
! 318: d_level();
! 319: break;
! 320: case '<':
! 321: after = FALSE;
! 322: u_level();
! 323: break;
! 324: case '?':
! 325: after = FALSE;
! 326: help();
! 327: break;
! 328: case '/':
! 329: after = FALSE;
! 330: identify();
! 331: break;
! 332: case 'v':
! 333: after = FALSE;
! 334: msg("UltraRogue Version %s.", release);
! 335: break;
! 336: case 'o':
! 337: after = FALSE;
! 338: option();
! 339: strcpy(fd_data[1].mi_name, fruit);
! 340: break;
! 341: case 12: /* ctrl-l */
! 342: case 18: /* ctrl-r */
! 343: after = FALSE;
! 344: clearok(cw, TRUE);
! 345: wrefresh(cw);
! 346: break;
! 347: case 16: /* ctrl-p */
! 348: {
! 349: int decrement = FALSE;
! 350: after = FALSE;
! 351:
! 352: if (mpos == 0)
! 353: decrement = TRUE;
! 354:
! 355: msg_index = (msg_index + 9) % 10;
! 356: msg(msgbuf[msg_index]);
! 357: if (decrement)
! 358: msg_index = (msg_index + 9) % 10;
! 359: }
! 360: break;
! 361:
! 362: case 'S':
! 363: after = FALSE;
! 364: if (save_game())
! 365: {
! 366: wclear(cw);
! 367: wrefresh(cw);
! 368: endwin();
! 369: printf("\n");
! 370: exit(0);
! 371: }
! 372: break;
! 373:
! 374: /*
! 375: * Other misc commands
! 376: */
! 377:
! 378: case '.': break; /* rest */
! 379: case ',': add_pack(NULL, NOMESSAGE); break;
! 380: case 'q': quaff(&player, -1, ISNORMAL); break;
! 381: case 'r': read_scroll(&player, -1, ISNORMAL); break;
! 382: case 'd': drop(NULL); break;
! 383: case '^': set_trap(&player, hero.y, hero.x); break;
! 384: case 'c': incant(&player, nullcoord); break;
! 385: case 'D': dip_it(); break;
! 386: case 'e': eat(); break;
! 387: case '=': listen(); break;
! 388: case 'A': apply(); break;
! 389: case 'w': wield(); break;
! 390: case 'W': wear(); break;
! 391: case 'T': take_off(); break;
! 392: case 'P': ring_on(); break;
! 393: case 'R': ring_off(); break;
! 394: case 'p': prayer(); break;
! 395: case 'C': call(FALSE); break;
! 396: case 'M': call(TRUE); break;
! 397: case 's': search(FALSE); break;
! 398:
! 399: /*
! 400: * Directional commands - get_dir sets delta
! 401: */
! 402: case 20: /* ctrl-t */
! 403: if (get_dir())
! 404: steal();
! 405: else
! 406: after = FALSE;
! 407: break;
! 408:
! 409: case 'z':
! 410: if (get_dir())
! 411: do_zap(&player, -1, ISNORMAL);
! 412: else
! 413: after = FALSE;
! 414: break;
! 415:
! 416: case 'a':
! 417: if (get_dir())
! 418: affect();
! 419: else
! 420: after = FALSE;
! 421: touchwin(cw);
! 422: break;
! 423:
! 424: /*
! 425: * wizard commands
! 426: */
! 427:
! 428: #ifdef WIZARD
! 429: case 0x17: /* ctrl-w */
! 430: after = FALSE;
! 431:
! 432: if (!wizard)
! 433: {
! 434: if (!canwizard)
! 435: {
! 436: msg("Illegal command '^W'.");
! 437: break;
! 438: }
! 439:
! 440: if (passwd())
! 441: {
! 442: msg("Welcome, oh mighty wizard.");
! 443: wizard = waswizard = TRUE;
! 444: }
! 445: else
! 446: {
! 447: msg("Incorrect password.");
! 448: break;
! 449: }
! 450: }
! 451:
! 452: msg("Wizard command: ");
! 453: mpos = 0;
! 454: ch = readchar();
! 455:
! 456: switch (ch)
! 457: {
! 458: case 'v':
! 459: wiz_verbose = !wiz_verbose;
! 460: break;
! 461:
! 462: case 'e':
! 463: wizard = FALSE;
! 464: msg("Not wizard any more.");
! 465: break;
! 466:
! 467: case 's': activity(); break;
! 468: case 't': teleport(); break;
! 469: case 'm': overlay(mw, cw); break;
! 470: case 'f': overlay(stdscr, cw); break;
! 471: case 'i': inventory(lvl_obj, 0); break;
! 472: case 'c': buy_it('\0', ISNORMAL); break;
! 473: case 'I': whatis(NULL); break;
! 474: case 'F':
! 475: msg("food left: %d\tfood level: %d",
! 476: food_left,foodlev);
! 477: break;
! 478: case 'M':
! 479: creat_mons(&player, get_monster_number("create"),
! 480: MESSAGE);
! 481: break;
! 482:
! 483: case 'r':
! 484: msg("rnd(4)%d, rnd(40)%d, rnd(100)%d",
! 485: rnd(4), rnd(40), rnd(100));
! 486: break;
! 487:
! 488: case 'C':
! 489: obj = get_object(pack, "charge", STICK, NULL);
! 490:
! 491: if (obj != NULL)
! 492: obj->o_charges = 10000;
! 493:
! 494: break;
! 495:
! 496: case 'w':
! 497: obj = get_object(pack, "price", 0, NULL);
! 498:
! 499: if (obj != NULL)
! 500: msg("Worth %d.", get_worth(obj));
! 501:
! 502: break;
! 503:
! 504: case 'g':
! 505: {
! 506: int tlev;
! 507:
! 508: prbuf[0] = '\0';
! 509: msg("Which level? ");
! 510:
! 511: if (get_string(prbuf, cw) == NORM)
! 512: {
! 513: msg("");
! 514:
! 515: if ((tlev = atoi(prbuf)) < 1)
! 516: msg("Illegal level.");
! 517: else if (tlev > 3000)
! 518: {
! 519: levtype = THRONE;
! 520: level = tlev - 3000;
! 521: }
! 522: else if (tlev > 2000)
! 523: {
! 524: levtype = MAZELEV;
! 525: level = tlev - 2000;
! 526: }
! 527: else if (tlev > 1000)
! 528: {
! 529: levtype = POSTLEV;
! 530: level = tlev - 1000;
! 531: }
! 532: else
! 533: {
! 534: levtype = NORMLEV;
! 535: level = tlev;
! 536: }
! 537:
! 538: new_level(levtype,0);
! 539: }
! 540: }
! 541: break;
! 542:
! 543: case 'o': make_omnipotent(); break;
! 544:
! 545: case ESCAPE: /* Escape */
! 546: door_stop = FALSE;
! 547:
! 548: count = 0;
! 549: after = FALSE;
! 550: break;
! 551:
! 552: default:
! 553: msg("Illegal wizard command '%s', %d.",
! 554: unctrl(ch), ch);
! 555: count = 0;
! 556: break;
! 557:
! 558: }
! 559:
! 560: break;
! 561: #endif
! 562:
! 563: default:
! 564: msg("Illegal command '%s', %d.",
! 565: unctrl(ch), ch);
! 566: count = 0;
! 567: after = FALSE;
! 568: break;
! 569: }
! 570:
! 571: /*
! 572: * turn off flags if no longer needed
! 573: */
! 574: if (!running)
! 575: door_stop = FALSE;
! 576: }
! 577:
! 578: /*
! 579: * If he ran into something to take, let him pick it up.
! 580: */
! 581: if (take != 0)
! 582: if (!moving)
! 583: pick_up(take);
! 584: else
! 585: show_floor();
! 586: if (!running)
! 587: door_stop = FALSE;
! 588: } /* end while */
! 589: }
! 590:
! 591:
! 592: void
! 593: do_after_effects(void)
! 594: {
! 595: int i;
! 596:
! 597: /* Kick off the rest of the daemons and fuses */
! 598:
! 599: look(FALSE);
! 600: do_daemons(AFTER);
! 601: do_fuses(AFTER);
! 602:
! 603: /* Special abilities */
! 604:
! 605: if ((player.t_ctype == C_THIEF || player.t_ctype == C_ASSASIN ||
! 606: player.t_ctype == C_NINJA || player.t_ctype == C_RANGER) &&
! 607: (rnd(100) < (2 * pstats.s_dext + 5 * pstats.s_lvl)))
! 608: search(TRUE);
! 609:
! 610: for (i = 0; i < ring_value(R_SEARCH); i++)
! 611: search(FALSE);
! 612:
! 613: if (is_wearing(R_TELEPORT) && rnd(50) < 2)
! 614: {
! 615: teleport();
! 616:
! 617: if (off(player, ISCLEAR))
! 618: {
! 619: if (on(player, ISHUH))
! 620: lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
! 621: else
! 622: light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
! 623:
! 624: turn_on(player, ISHUH);
! 625: }
! 626: else
! 627: msg("You feel dizzy for a moment, but it quickly passes.");
! 628: }
! 629:
! 630: /* accidents and general clumsiness */
! 631:
! 632: if (fighting && rnd(50) == 0)
! 633: {
! 634: msg("You become tired of this nonsense.");
! 635: fighting = after = FALSE;
! 636: }
! 637:
! 638: if (on(player, ISELECTRIC))
! 639: electrificate();
! 640:
! 641: if (!fighting && (no_command == 0) && cur_weapon != NULL
! 642: && rnd(on(player, STUMBLER) ? 399 : 9999) == 0
! 643: && rnd(pstats.s_dext) <
! 644: 2 - hitweight() + (on(player, STUMBLER) ? 4 : 0))
! 645: {
! 646: msg("You trip and stumble over your weapon.");
! 647: running = after = FALSE;
! 648:
! 649: if (rnd(8) == 0 && (pstats.s_hpt -= roll(1, 10)) <= 0)
! 650: {
! 651: msg("You break your neck and die.");
! 652: death(D_FALL);
! 653: return;
! 654: }
! 655: else if (cur_weapon->o_flags & ISPOISON && rnd(4) == 0)
! 656: {
! 657: msg("You are cut by your %s!",
! 658: inv_name(cur_weapon, LOWERCASE));
! 659:
! 660: if (player.t_ctype != C_PALADIN
! 661: && !(player.t_ctype == C_NINJA &&
! 662: pstats.s_lvl > 12)
! 663: && !save(VS_POISON))
! 664: {
! 665: if (pstats.s_hpt == 1)
! 666: {
! 667: msg("You die from the poison in the cut.");
! 668: death(D_POISON);
! 669: return;
! 670: }
! 671: else
! 672: {
! 673: msg("You feel very sick now.");
! 674: pstats.s_hpt /= 2;
! 675: chg_str(-2, FALSE, FALSE);
! 676: }
! 677: }
! 678: }
! 679: }
! 680:
! 681: /* Time to enforce weapon and armor restrictions */
! 682: if (rnd(9999) == 0)
! 683: if (((cur_weapon == NULL) ||
! 684: (wield_ok(&player, cur_weapon, NOMESSAGE)))
! 685: && ((cur_armor == NULL) ||
! 686: (wear_ok(&player, cur_armor, NOMESSAGE))))
! 687: {
! 688: switch (player.t_ctype)
! 689: {
! 690: case C_CLERIC:
! 691: case C_DRUID:
! 692: case C_RANGER:
! 693: case C_PALADIN:
! 694: if (rnd(luck) != 0)
! 695: /* You better have done
! 696: * little wrong */
! 697: goto bad_cleric;
! 698:
! 699: msg("You are enraptured by the renewed "
! 700: "power of your god.");
! 701: break;
! 702:
! 703: case C_MAGICIAN:
! 704: case C_ILLUSION:
! 705: msg("You become in tune with the universe.");
! 706: break;
! 707:
! 708: case C_THIEF:
! 709: case C_NINJA:
! 710: case C_ASSASIN:
! 711: msg("You become supernaly sensitive to your "
! 712: "surroundings.");
! 713: break;
! 714:
! 715: case C_FIGHTER:
! 716: msg("You catch your second wind.");
! 717: break;
! 718:
! 719: default:
! 720: msg("What a strange type you are!");
! 721: break;
! 722: }
! 723: pstats.s_hpt = max_stats.s_hpt += rnd(pstats.s_lvl) + 1;
! 724: pstats.s_power = max_stats.s_power += rnd(pstats.s_lvl) + 1;
! 725: }
! 726: else
! 727: { /* he blew it - make him pay */
! 728:
! 729: int death_cause = 0;
! 730:
! 731: switch (player.t_ctype)
! 732: {
! 733: case C_CLERIC:
! 734: case C_DRUID:
! 735: case C_RANGER:
! 736: case C_PALADIN:
! 737: bad_cleric:
! 738: msg("Your god scourges you for your misdeeds.");
! 739: death_cause = D_GODWRATH;
! 740: break;
! 741:
! 742: case C_MAGICIAN:
! 743: case C_ILLUSION:
! 744: msg("You short out your manna on the unfamiliar %s.",
! 745: (cur_armor != NULL ? "armor" : "weapon"));
! 746:
! 747: death_cause = D_SPELLFUMBLE;
! 748: break;
! 749:
! 750: case C_THIEF:
! 751: case C_NINJA:
! 752: case C_ASSASIN:
! 753: msg("You trip and fall because of the unfamiliar %s.",
! 754: (cur_armor != NULL ? "armor" : "weapon"));
! 755: death_cause = D_CLUMSY;
! 756: break;
! 757:
! 758: case C_FIGHTER:
! 759: debug("Fighter getting raw deal?");
! 760: break;
! 761:
! 762: default:
! 763: msg("What a strange type you are!");
! 764: break;
! 765: }
! 766:
! 767: aggravate();
! 768: pstats.s_power /= 2;
! 769: pstats.s_hpt /= 2;
! 770: player.t_no_move++;
! 771:
! 772: if ((pstats.s_hpt -= rnd(pstats.s_lvl)) <= 0)
! 773: {
! 774: death(death_cause);
! 775: }
! 776: }
! 777:
! 778: if (rnd(500000) == 0)
! 779: {
! 780: new_level(THRONE,0);
! 781: fighting = running = after = FALSE;
! 782: command();
! 783: }
! 784: }
! 785:
! 786: void
! 787: make_omnipotent(void)
! 788: {
! 789: int i;
! 790: struct linked_list *item;
! 791: struct object *obj;
! 792:
! 793: for (i = 0; i < 20; i++)
! 794: raise_level();
! 795:
! 796: max_stats.s_hpt += 1000;
! 797: max_stats.s_power += 1000;
! 798: pstats.s_hpt = max_stats.s_hpt;
! 799: pstats.s_power = max_stats.s_power;
! 800: max_stats.s_str = pstats.s_str = 25;
! 801: max_stats.s_intel = pstats.s_intel = 25;
! 802: max_stats.s_wisdom = pstats.s_wisdom = 25;
! 803: max_stats.s_dext = pstats.s_dext = 25;
! 804: max_stats.s_const = pstats.s_const = 25;
! 805:
! 806: if (cur_weapon == NULL || cur_weapon->o_which != CLAYMORE)
! 807: {
! 808: item = spec_item(WEAPON, CLAYMORE, 10, 10);
! 809: cur_weapon = OBJPTR(item);
! 810: cur_weapon->o_flags |= ISKNOW;
! 811: add_pack(item, NOMESSAGE);
! 812: }
! 813:
! 814: /* and a kill-o-zap stick */
! 815:
! 816: item = spec_item(STICK, WS_DISINTEGRATE, 10000, 0);
! 817: obj = OBJPTR(item);
! 818: obj->o_flags |= ISKNOW;
! 819: know_items[TYP_STICK][WS_DISINTEGRATE] = TRUE;
! 820:
! 821: if (guess_items[TYP_STICK][WS_DISINTEGRATE])
! 822: {
! 823: ur_free(guess_items[TYP_STICK][WS_DISINTEGRATE]);
! 824: guess_items[TYP_STICK][WS_DISINTEGRATE] = NULL;
! 825: }
! 826:
! 827: add_pack(item, NOMESSAGE);
! 828:
! 829: /* and his suit of armor */
! 830:
! 831: if (cur_armor == NULL ||
! 832: !(cur_armor->o_which == CRYSTAL_ARMOR ||
! 833: cur_armor->o_which == MITHRIL))
! 834: {
! 835: item = spec_item(ARMOR, CRYSTAL_ARMOR, 15, 0);
! 836: obj = OBJPTR(item);
! 837: obj->o_flags |= ISKNOW;
! 838: obj->o_weight =
! 839: (int) (armors[CRYSTAL_ARMOR].a_wght * 0.2);
! 840: cur_armor = obj;
! 841: add_pack(item, NOMESSAGE);
! 842: }
! 843:
! 844: /* and some rings (have to put them on, for now) */
! 845:
! 846:
! 847: if (!is_wearing(R_SEARCH))
! 848: {
! 849: item = spec_item(RING, R_SEARCH, 0, 0);
! 850: obj = OBJPTR(item);
! 851: obj->o_flags |= ISKNOW;
! 852: know_items[TYP_RING][R_SEARCH] = TRUE;
! 853:
! 854: if (guess_items[TYP_RING][R_SEARCH])
! 855: {
! 856: ur_free(guess_items[TYP_RING][R_SEARCH]);
! 857: guess_items[TYP_RING][R_SEARCH] = NULL;
! 858: }
! 859:
! 860: add_pack(item, NOMESSAGE);
! 861: }
! 862:
! 863: if (!is_wearing(R_PIETY))
! 864: {
! 865: item = spec_item(RING, R_PIETY, 0, 0);
! 866: obj = OBJPTR(item);
! 867: obj->o_flags |= ISKNOW;
! 868: know_items[TYP_RING][R_PIETY] = TRUE;
! 869:
! 870: if (guess_items[TYP_RING][R_PIETY])
! 871: {
! 872: ur_free(guess_items[TYP_RING][R_PIETY]);
! 873: guess_items[TYP_RING][R_PIETY] = NULL;
! 874: }
! 875:
! 876: add_pack(item, NOMESSAGE);
! 877: }
! 878:
! 879: item = spec_item(SCROLL, S_ELECTRIFY, 0, 0);
! 880: obj = OBJPTR(item);
! 881: obj->o_flags |= ISKNOW;
! 882: know_items[TYP_SCROLL][S_ELECTRIFY] = TRUE;
! 883:
! 884: if (guess_items[TYP_SCROLL][S_ELECTRIFY])
! 885: {
! 886: ur_free(guess_items[TYP_SCROLL][S_ELECTRIFY]);
! 887: guess_items[TYP_SCROLL][S_ELECTRIFY] = NULL;
! 888: }
! 889:
! 890: add_pack(item, NOMESSAGE);
! 891:
! 892: /* Spiff him up a bit */
! 893: quaff(&player, P_SHERO, ISBLESSED);
! 894: quaff(&player, P_CLEAR, ISBLESSED);
! 895: quaff(&player, P_FIRERESIST, ISBLESSED);
! 896: quaff(&player, P_TRUESEE, ISBLESSED);
! 897: quaff(&player, P_PHASE, ISBLESSED);
! 898: purse += 50000L;
! 899: updpack();
! 900: }
! 901:
! 902:
! 903: /*
! 904: quit()
! 905: Have player make certain, then exit.
! 906: */
! 907:
! 908: void
! 909: quit_handler(int sig)
! 910: {
! 911: if (signal(SIGINT, quit_handler) != quit_handler)
! 912: mpos = 0;
! 913:
! 914: sig = 0;
! 915:
! 916: quit();
! 917: }
! 918:
! 919: void
! 920: quit(void)
! 921: {
! 922: msg("Really quit?");
! 923:
! 924: wrefresh(cw);
! 925:
! 926: if (readchar() == 'y')
! 927: {
! 928: clear();
! 929: wclear(cw);
! 930: wrefresh(cw);
! 931: move(LINES - 1, 0);
! 932: wrefresh(stdscr);
! 933: score(pstats.s_exp, pstats.s_lvl, CHICKEN, 0);
! 934: byebye();
! 935: }
! 936: else
! 937: {
! 938: signal(SIGINT, quit_handler);
! 939: wmove(cw, 0, 0);
! 940: wclrtoeol(cw);
! 941: status(FALSE);
! 942: wrefresh(cw);
! 943: mpos = 0;
! 944: count = 0;
! 945: fighting = running = 0;
! 946: }
! 947: }
! 948:
! 949: /*
! 950: search()
! 951: Player gropes about him to find hidden things.
! 952: */
! 953:
! 954: void
! 955: search(int is_thief)
! 956: {
! 957: int x, y;
! 958: char ch;
! 959:
! 960: /*
! 961: * Look all around the hero, if there is something hidden there, give
! 962: * him a chance to find it. If its found, display it.
! 963: */
! 964:
! 965: if (on(player, ISBLIND))
! 966: return;
! 967:
! 968: for (x = hero.x - 1; x <= hero.x + 1; x++)
! 969: for (y = hero.y - 1; y <= hero.y + 1; y++)
! 970: {
! 971: ch = winat(y, x);
! 972:
! 973: if (isatrap(ch))
! 974: {
! 975: static char trname[1024]; /* temp scratch space */
! 976: struct trap *tp;
! 977: struct room *rp;
! 978:
! 979: if (isatrap( mvwinch(cw, y, x)))
! 980: continue;
! 981:
! 982: tp = trap_at(y, x);
! 983:
! 984: if ((tp->tr_flags & ISTHIEFSET) ||
! 985: (rnd(100) > 50 && !is_thief))
! 986: break;
! 987:
! 988: rp = roomin(hero);
! 989:
! 990: if (tp->tr_type == FIRETRAP && rp != NULL)
! 991: {
! 992: rp->r_flags &= ~ISDARK;
! 993: light(&hero);
! 994: }
! 995:
! 996: tp->tr_flags |= ISFOUND;
! 997: mvwaddch(cw, y, x, ch);
! 998: count = 0;
! 999: running = FALSE;
! 1000: msg(tr_name(tp->tr_type,trname));
! 1001: }
! 1002: else if (ch == SECRETDOOR)
! 1003: {
! 1004: if (rnd(100) < 20 && !is_thief)
! 1005: {
! 1006: mvaddch(y, x, DOOR);
! 1007: count = 0;
! 1008: }
! 1009: }
! 1010: }
! 1011: }
! 1012:
! 1013: /*
! 1014: help()
! 1015: Give single character help, or the whole mess if he wants it
! 1016: */
! 1017:
! 1018: void
! 1019: help(void)
! 1020: {
! 1021: const struct h_list *strp = helpstr;
! 1022: char helpch;
! 1023: int cnt;
! 1024:
! 1025: msg("Character you want help for (* for all): ");
! 1026: helpch = readchar();
! 1027: mpos = 0;
! 1028:
! 1029: /*
! 1030: * If its not a *, print the right help string or an error if he
! 1031: * typed a funny character.
! 1032: */
! 1033:
! 1034: if (helpch != '*')
! 1035: {
! 1036: wmove(cw, 0, 0);
! 1037:
! 1038: while (strp->h_ch)
! 1039: {
! 1040: if (strp->h_desc == 0)
! 1041: if (!wizard)
! 1042: break;
! 1043: else
! 1044: {
! 1045: strp++;
! 1046: continue;
! 1047: }
! 1048:
! 1049: if (strp->h_ch == helpch)
! 1050: {
! 1051: msg("%s%s", unctrl(strp->h_ch), strp->h_desc);
! 1052: break;
! 1053: }
! 1054: strp++;
! 1055: }
! 1056:
! 1057: if (strp->h_ch != helpch)
! 1058: msg("Unknown character '%s'.", unctrl(helpch));
! 1059:
! 1060: return;
! 1061: }
! 1062:
! 1063: /*
! 1064: * Here we print help for everything. Then wait before we return to
! 1065: * command mode
! 1066: */
! 1067:
! 1068: wclear(hw);
! 1069: cnt = 0;
! 1070:
! 1071: while (strp->h_ch)
! 1072: {
! 1073: if (strp->h_desc == 0)
! 1074: if (!wizard)
! 1075: break;
! 1076: else
! 1077: {
! 1078: strp++;
! 1079: continue;
! 1080: }
! 1081:
! 1082: mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(strp->h_ch));
! 1083: waddstr(hw, strp->h_desc);
! 1084: strp++;
! 1085:
! 1086: if (++cnt >= 46 && strp->h_ch && (strp->h_desc != NULL || wizard))
! 1087: {
! 1088: wmove(hw, LINES - 1, 0);
! 1089: wprintw(hw, (char *) morestr);
! 1090: wrefresh(hw);
! 1091: wait_for(' ');
! 1092: wclear(hw);
! 1093: cnt = 0;
! 1094: }
! 1095: }
! 1096:
! 1097: wmove(hw, LINES - 1, 0);
! 1098: wprintw(hw, (char *) morestr);
! 1099: wrefresh(hw);
! 1100: wait_for(' ');
! 1101: wclear(hw);
! 1102: wrefresh(hw);
! 1103:
! 1104: wmove(cw, 0, 0);
! 1105: wclrtoeol(cw);
! 1106: status(FALSE);
! 1107: touchwin(cw);
! 1108:
! 1109: return;
! 1110: }
! 1111:
! 1112: /*
! 1113: identify()
! 1114: Tell the player what a certain thing is.
! 1115: */
! 1116:
! 1117: void
! 1118: identify(void)
! 1119: {
! 1120: int ch;
! 1121: char *str;
! 1122:
! 1123: msg("What do you want identified? ");
! 1124: mpos = 0;
! 1125:
! 1126: if ((ch = readchar()) == ESCAPE)
! 1127: {
! 1128: msg("");
! 1129: return;
! 1130: }
! 1131:
! 1132: if (isalpha(ch))
! 1133: {
! 1134: id_monst(ch);
! 1135: return;
! 1136: }
! 1137:
! 1138: switch (ch)
! 1139: {
! 1140: case '|':
! 1141: case '-': str = "wall of a room"; break;
! 1142: case GOLD: str = "gold"; break;
! 1143: case STAIRS: str = "passage leading down"; break;
! 1144: case DOOR: str = "door"; break;
! 1145: case FLOOR: str = "room floor"; break;
! 1146: case VPLAYER: str = "The hero of the game ---> you"; break;
! 1147: case IPLAYER: str = "you (but invisible)"; break;
! 1148: case PASSAGE: str = "passage"; break;
! 1149: case POST: str = "trading post"; break;
! 1150: case POOL: str = "a shimmering pool"; break;
! 1151: case TRAPDOOR: str = "trapdoor"; break;
! 1152: case ARROWTRAP: str = "arrow trap"; break;
! 1153: case SLEEPTRAP: str = "sleeping gas trap"; break;
! 1154: case BEARTRAP: str = "bear trap"; break;
! 1155: case TELTRAP: str = "teleport trap"; break;
! 1156: case DARTTRAP: str = "dart trap"; break;
! 1157: case MAZETRAP: str = "entrance to a maze"; break;
! 1158: case FIRETRAP: str = "fire trap"; break;
! 1159: case POISONTRAP: str = "poison pool trap"; break;
! 1160: case LAIR: str = "monster lair entrance"; break;
! 1161: case RUSTTRAP: str = "rust trap"; break;
! 1162: case POTION: str = "potion"; break;
! 1163: case SCROLL: str = "scroll"; break;
! 1164: case FOOD: str = "food"; break;
! 1165: case WEAPON: str = "weapon"; break;
! 1166: case ' ': str = "solid rock"; break;
! 1167: case ARMOR: str = "armor"; break;
! 1168: case ARTIFACT: str = "an artifact from bygone ages"; break;
! 1169: case RING: str = "ring"; break;
! 1170: case STICK: str = "wand or staff"; break;
! 1171: default: str = "unknown character"; break;
! 1172: }
! 1173: msg("'%s'; %s", unctrl(ch), str);
! 1174: }
! 1175:
! 1176: /*
! 1177: d_level()
! 1178: He wants to go down a level
! 1179: */
! 1180:
! 1181: void
! 1182: d_level(void)
! 1183: {
! 1184: int no_phase = FALSE;
! 1185:
! 1186: if (mvinch(hero.y, hero.x) != STAIRS)
! 1187: {
! 1188: if (off(player, CANINWALL)) /* Must use stairs if can't phase */
! 1189: {
! 1190: msg("I see no way down.");
! 1191: return;
! 1192: }
! 1193:
! 1194: extinguish_fuse(FUSE_UNPHASE);/*Using phase to go down gets rid of it*/
! 1195: no_phase = TRUE;
! 1196: }
! 1197:
! 1198: if (is_wearing(R_LEVITATION) || on(player, CANFLY))
! 1199: {
! 1200: msg("You can't! You're floating in the air.");
! 1201: return;
! 1202: }
! 1203:
! 1204: if (rnd(pstats.s_dext) < 3 * (2 - hitweight() +
! 1205: (on(player, STUMBLER) ? 4 : 0)))
! 1206: {
! 1207: msg("You trip and fall down the stairs.");
! 1208:
! 1209: if ((pstats.s_hpt -= roll(1, 10)) <= 0)
! 1210: {
! 1211: msg("You break your neck and die.");
! 1212: death(D_FALL);
! 1213: return;
! 1214: }
! 1215: }
! 1216:
! 1217: level++;
! 1218: new_level(NORMLEV,0);
! 1219:
! 1220: if (no_phase)
! 1221: unphase(NULL);
! 1222:
! 1223: return;
! 1224: }
! 1225:
! 1226: /*
! 1227: u_level()
! 1228: He wants to go up a level
! 1229: */
! 1230:
! 1231: void
! 1232: u_level(void)
! 1233: {
! 1234: char ch = 0;
! 1235:
! 1236: if (has_artifact && ((ch = CCHAR(mvinch(hero.y, hero.x))) == STAIRS ||
! 1237: (on(player, CANINWALL)
! 1238: && (is_wearing(R_LEVITATION) || on(player, CANFLY)))))
! 1239: {
! 1240: if (--level == 0)
! 1241: total_winner();
! 1242: else if (rnd(wizard ? 3 : 15) == 0)
! 1243: new_level(THRONE,0);
! 1244: else
! 1245: {
! 1246: new_level(NORMLEV,0);
! 1247: msg("You feel a wrenching sensation in your gut.");
! 1248: }
! 1249:
! 1250: if (on(player, CANINWALL) && ch != STAIRS)
! 1251: {
! 1252: extinguish_fuse(FUSE_UNPHASE);
! 1253: unphase(NULL);
! 1254: }
! 1255:
! 1256: return;
! 1257: }
! 1258: else if (ch != STAIRS &&
! 1259: !(on(player, CANINWALL) && (is_wearing(R_LEVITATION)
! 1260: || on(player, CANFLY))))
! 1261: msg("I see no way up.");
! 1262: else
! 1263: msg("Your way is magically blocked.");
! 1264:
! 1265: return;
! 1266: }
! 1267:
! 1268: /*
! 1269: call()
! 1270: allow a user to call a potion, scroll, or ring something
! 1271: */
! 1272:
! 1273: void
! 1274: call(int mark)
! 1275: {
! 1276: struct object *obj;
! 1277: char *elsewise;
! 1278: int item_type = numthings;
! 1279: char **item_color = NULL;
! 1280:
! 1281: if (mark)
! 1282: obj = get_object(pack, "mark", 0, bff_markable);
! 1283: else
! 1284: obj = get_object(pack, "call", 0, bff_callable);
! 1285:
! 1286: if (obj == NULL)
! 1287: return;
! 1288:
! 1289: switch (obj->o_type)
! 1290: {
! 1291: case RING:
! 1292: item_type = TYP_RING;
! 1293: item_color = r_stones;
! 1294: break;
! 1295: case POTION:
! 1296: item_type = TYP_POTION;
! 1297: item_color = p_colors;
! 1298: break;
! 1299: case SCROLL:
! 1300: item_type = TYP_SCROLL;
! 1301: item_color = s_names;
! 1302: break;
! 1303: case STICK:
! 1304: item_type = TYP_STICK;
! 1305: item_color = ws_made;
! 1306: break;
! 1307: default:
! 1308: if (!mark)
! 1309: {
! 1310: msg("You can't call that anything.");
! 1311: return;
! 1312: }
! 1313: break;
! 1314: }
! 1315:
! 1316: if (!mark && know_items[item_type][obj->o_which])
! 1317: {
! 1318: msg("That has already been identified.");
! 1319: return;
! 1320: }
! 1321:
! 1322: if (mark)
! 1323: {
! 1324: if (obj->o_mark[0])
! 1325: msg("Was marked \"%s\".", obj->o_mark);
! 1326:
! 1327: msg("What do you want to mark it? ");
! 1328: prbuf[0] = '\0';
! 1329: }
! 1330: else
! 1331: {
! 1332: elsewise = (guess_items[item_type][obj->o_which] != NULL ?
! 1333: guess_items[item_type][obj->o_which] : item_color[obj->o_which]);
! 1334:
! 1335: msg("Was called \"%s\".", elsewise);
! 1336: msg("What do you want to call it? ");
! 1337:
! 1338: if (guess_items[item_type][obj->o_which] != NULL)
! 1339: ur_free(guess_items[item_type][obj->o_which]);
! 1340:
! 1341: strcpy(prbuf, elsewise);
! 1342: }
! 1343:
! 1344: if (get_string(prbuf, cw) == NORM)
! 1345: {
! 1346: if (mark)
! 1347: {
! 1348: strncpy(obj->o_mark, prbuf, MARKLEN - 1);
! 1349: obj->o_mark[MARKLEN - 1] = '\0';
! 1350: }
! 1351: else
! 1352: {
! 1353: guess_items[item_type][obj->o_which] = new_alloc(strlen(prbuf) + 1);
! 1354: strcpy(guess_items[item_type][obj->o_which], prbuf);
! 1355: }
! 1356: }
! 1357:
! 1358: return;
! 1359: }
! 1360:
! 1361: /*
! 1362: att_bonus()
! 1363: bonus attacks for certain player classes
! 1364: */
! 1365:
! 1366: int
! 1367: att_bonus(void)
! 1368: {
! 1369: int bonus = FALSE;
! 1370:
! 1371: if ((player.t_ctype == C_FIGHTER || player.t_ctype == C_PALADIN)
! 1372: && (pstats.s_lvl > 12 ||
! 1373: (pstats.s_lvl > 6 && pstats.s_lvl < 13 && rnd(2))))
! 1374: bonus = TRUE;
! 1375:
! 1376: else if ((player.t_ctype == C_RANGER)
! 1377: && (pstats.s_lvl > 14 ||
! 1378: (pstats.s_lvl > 7 && pstats.s_lvl < 15 && rnd(2))))
! 1379: bonus = TRUE;
! 1380:
! 1381: else if ((player.t_ctype == C_NINJA)
! 1382: && (pstats.s_lvl > 8 ||
! 1383: (pstats.s_lvl > 4 && pstats.s_lvl < 9 && rnd(2))))
! 1384: bonus = TRUE;
! 1385:
! 1386: return(bonus);
! 1387: }
CVSweb