Annotation of early-roguelike/urogue/misc.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: misc.c - all sorts of miscellaneous routines
! 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 <stdlib.h>
! 20: #include <string.h>
! 21: #include <ctype.h>
! 22: #include "rogue.h"
! 23:
! 24: /*
! 25: tr_name()
! 26: print the name of a trap
! 27: */
! 28:
! 29: char *
! 30: tr_name(char ch, char *trname)
! 31: {
! 32: const char *s = NULL;
! 33:
! 34: if (trname == NULL)
! 35: return(" Your found an error in UltraRogue #100.");
! 36:
! 37: switch(ch)
! 38: {
! 39: case TRAPDOOR:
! 40: s = "trapdoor.";
! 41: break;
! 42: case BEARTRAP:
! 43: s = "beartrap.";
! 44: break;
! 45: case SLEEPTRAP:
! 46: s = "sleeping gas trap.";
! 47: break;
! 48: case ARROWTRAP:
! 49: s = "arrow trap.";
! 50: break;
! 51: case TELTRAP:
! 52: s = "teleport trap.";
! 53: break;
! 54: case DARTTRAP:
! 55: s = "dart trap.";
! 56: break;
! 57: case POOL:
! 58: s = "shimmering pool.";
! 59: break;
! 60: case MAZETRAP:
! 61: s = "maze entrance.";
! 62: break;
! 63: case FIRETRAP:
! 64: s = "fire trap.";
! 65: break;
! 66: case POISONTRAP:
! 67: s = "poison pool trap.";
! 68: break;
! 69: case LAIR:
! 70: s = "monster lair.";
! 71: break;
! 72: case RUSTTRAP:
! 73: s = "rust trap.";
! 74: break;
! 75: default:
! 76: ;
! 77: }
! 78:
! 79: sprintf(trname, "You found a %s.", s);
! 80:
! 81: return(trname);
! 82: }
! 83:
! 84: /*
! 85: look()
! 86: A quick glance all around the player
! 87: */
! 88:
! 89: void
! 90: look(int wakeup)
! 91: {
! 92: int x, y;
! 93: char ch, och;
! 94: int oldx, oldy;
! 95: int inpass, horizontal, vertical, do_light = FALSE, do_blank = FALSE;
! 96: int passcount = 0;
! 97: struct room *rp;
! 98: int ey, ex;
! 99:
! 100: /* Are we moving vertically or horizontally? */
! 101:
! 102: if (runch == 'h' || runch == 'l')
! 103: horizontal = TRUE;
! 104: else
! 105: horizontal = FALSE;
! 106:
! 107: if (runch == 'j' || runch == 'k')
! 108: vertical = TRUE;
! 109: else
! 110: vertical = FALSE;
! 111:
! 112: getyx(cw, oldy, oldx); /* Save current position */
! 113:
! 114: /*
! 115: * Blank out the floor around our last position and check for moving
! 116: * out of a corridor in a maze.
! 117: */
! 118:
! 119: if (oldrp != NULL && (oldrp->r_flags & ISDARK) &&
! 120: !(oldrp->r_flags & HASFIRE) && off(player, ISBLIND))
! 121: do_blank = TRUE;
! 122:
! 123: for (x = player.t_oldpos.x - 1; x <= player.t_oldpos.x + 1; x++)
! 124: for (y = player.t_oldpos.y - 1; y <= player.t_oldpos.y + 1;
! 125: y++)
! 126: {
! 127: ch = show(y, x);
! 128:
! 129: if (do_blank && (y != hero.y || x != hero.x) && ch == FLOOR)
! 130: mvwaddch(cw, y, x, ' ');
! 131:
! 132: /* Moving out of a corridor? */
! 133:
! 134: if (levtype == MAZELEV &&
! 135: (ch != '|' && ch != '-') && /* Not a wall */
! 136: ((vertical && x != player.t_oldpos.x &&
! 137: y == player.t_oldpos.y) ||
! 138: (horizontal && y != player.t_oldpos.y &&
! 139: x == player.t_oldpos.x)))
! 140: do_light = TRUE; /* Just came to a turn */
! 141: }
! 142:
! 143: inpass = ((rp = roomin(hero)) == NULL); /* Are we in a passage? */
! 144:
! 145: /* Are we coming out of a wall into a corridor in a maze? */
! 146: och = show(player.t_oldpos.y, player.t_oldpos.x);
! 147: ch = show(hero.y, hero.x);
! 148:
! 149: if (levtype == MAZELEV && (och == '|' || och == '-' ||
! 150: och == SECRETDOOR) && (ch != '|' && ch != '-' && ch != SECRETDOOR))
! 151: {
! 152: do_light = off(player, ISBLIND); /* Light it up if not blind */
! 153: }
! 154:
! 155: /* Look around the player */
! 156:
! 157: ey = hero.y + 1;
! 158: ex = hero.x + 1;
! 159:
! 160: for (x = hero.x - 1; x <= ex; x++)
! 161: if (x >= 0 && x < COLS)
! 162: for (y = hero.y - 1; y <= ey; y++)
! 163: {
! 164: if (y <= 0 || y >= LINES - 2)
! 165: continue;
! 166:
! 167: if (isalpha(mvwinch(mw, y, x)))
! 168: {
! 169: struct linked_list *it;
! 170: struct thing *tp;
! 171:
! 172: if (wakeup)
! 173: it = wake_monster(y, x);
! 174: else
! 175: it = find_mons(y, x);
! 176:
! 177: if (it == NULL)
! 178: continue;
! 179:
! 180: tp = THINGPTR(it);
! 181: tp->t_oldch = CCHAR( mvinch(y, x) );
! 182:
! 183: if (isatrap(tp->t_oldch))
! 184: {
! 185: struct trap *trp = trap_at(y, x);
! 186:
! 187: tp->t_oldch = (trp->tr_flags & ISFOUND) ? tp->t_oldch
! 188: : trp->tr_show;
! 189: }
! 190:
! 191: if (tp->t_oldch == FLOOR &&
! 192: (rp->r_flags & ISDARK)
! 193: && !(rp->r_flags & HASFIRE) &&
! 194: off(player, ISBLIND))
! 195: tp->t_oldch = ' ';
! 196: }
! 197:
! 198: /* Secret doors show as walls */
! 199:
! 200: if ((ch = show(y, x)) == SECRETDOOR)
! 201: ch = secretdoor(y, x);
! 202:
! 203: /*
! 204: * Don't show room walls if he is in a
! 205: * passage and check for maze turns
! 206: */
! 207:
! 208: if (off(player, ISBLIND))
! 209: {
! 210: if (y == hero.y && x == hero.x || (inpass && (ch == '-' ||
! 211: ch == '|')))
! 212: continue;
! 213:
! 214: /* Are we at a crossroads in a maze? */
! 215:
! 216: if (levtype == MAZELEV && (ch != '|' && ch != '-') &&
! 217: /* Not a wall */
! 218: ((vertical && x != hero.x && y == hero.y) ||
! 219: (horizontal && y != hero.y && x == hero.x)))
! 220: do_light = TRUE;
! 221: /* Just came to a turn */
! 222: }
! 223: else if (y != hero.y || x != hero.x)
! 224: continue;
! 225:
! 226: wmove(cw, y, x);
! 227: waddch(cw, ch);
! 228:
! 229: if (door_stop && !firstmove && running)
! 230: {
! 231: switch (runch)
! 232: {
! 233: case 'h':
! 234: if (x == ex)
! 235: continue;
! 236: break;
! 237: case 'j':
! 238: if (y == hero.y - 1)
! 239: continue;
! 240: break;
! 241: case 'k':
! 242: if (y == ey)
! 243: continue;
! 244: break;
! 245: case 'l':
! 246: if (x == hero.x - 1)
! 247: continue;
! 248: break;
! 249: case 'y':
! 250: if ((x + y) - (hero.x + hero.y) >= 1)
! 251: continue;
! 252: break;
! 253: case 'u':
! 254: if ((y - x) - (hero.y - hero.x) >= 1)
! 255: continue;
! 256: break;
! 257: case 'n':
! 258: if ((x + y) - (hero.x + hero.y) <= -1)
! 259: continue;
! 260: break;
! 261: case 'b':
! 262: if ((y - x) - (hero.y - hero.x) <= -1)
! 263: continue;
! 264: break;
! 265: }
! 266:
! 267: switch (ch)
! 268: {
! 269: case DOOR:
! 270: if (x == hero.x || y == hero.y)
! 271: running = FALSE;
! 272: break;
! 273: case PASSAGE:
! 274: if (x == hero.x || y == hero.y)
! 275: passcount++;
! 276: break;
! 277: case FLOOR:
! 278:
! 279: /*
! 280: * Stop by new passages in a
! 281: * maze (floor next to us)
! 282: */
! 283: if ((levtype == MAZELEV) &&
! 284: ((horizontal && x == hero.x && y != hero.y) ||
! 285: (vertical && y == hero.y && x != hero.x)))
! 286: running = FALSE;
! 287:
! 288: case '|':
! 289: case '-':
! 290: case ' ':
! 291: break;
! 292:
! 293: default:
! 294: running = FALSE;
! 295: break;
! 296: }
! 297: }
! 298: }
! 299:
! 300: if (door_stop && !firstmove && passcount > 1)
! 301: running = FALSE;
! 302:
! 303: /*
! 304: * Do we have to light up the area (just stepped into a new
! 305: * corridor)?
! 306: */
! 307:
! 308: if (do_light && wakeup && /* wakeup will be true on a normal move */
! 309: !(rp->r_flags & ISDARK) && /* We have some light */
! 310: !ce(hero, player.t_oldpos)) /* Don't do anything if we didn't move */
! 311: light(&hero);
! 312:
! 313: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 314: wmove(cw, oldy, oldx);
! 315:
! 316: if (wakeup)
! 317: {
! 318: player.t_oldpos = hero; /* Don't change if we didn't move */
! 319: oldrp = rp;
! 320: }
! 321: }
! 322:
! 323: /*
! 324: secret_door()
! 325: Figure out what a secret door looks like.
! 326: */
! 327:
! 328: char
! 329: secretdoor(int y, int x)
! 330: {
! 331: struct room *rp;
! 332: coord cp;
! 333:
! 334: cp.x = x;
! 335: cp.y = y;
! 336:
! 337: if ((rp = roomin(cp)) != NULL)
! 338: {
! 339: if (y == rp->r_pos.y || y == rp->r_pos.y + rp->r_max.y - 1)
! 340: return ('-');
! 341: else
! 342: return ('|');
! 343: }
! 344: return ('p');
! 345: }
! 346:
! 347: /*
! 348: find_obj()
! 349: find the unclaimed object at y, x
! 350: */
! 351:
! 352: struct linked_list *
! 353: find_obj(int y, int x)
! 354: {
! 355: struct linked_list *obj, *sobj;
! 356: struct object *op;
! 357:
! 358: sobj = lvl_obj;
! 359:
! 360: for (obj = sobj; obj != NULL; obj = next(obj))
! 361: {
! 362: op = OBJPTR(obj);
! 363:
! 364: if (op && op->o_pos.y == y && op->o_pos.x == x)
! 365: return(obj);
! 366: }
! 367:
! 368: return(NULL);
! 369: }
! 370:
! 371: /*
! 372: eat()
! 373: He wants to eat something, so let him try
! 374: */
! 375:
! 376: void
! 377: eat(void)
! 378: {
! 379: struct object *obj;
! 380: int amount;
! 381: float scale = (float) (LINES * COLS) / (25.0F * 80.0F);
! 382:
! 383: if ((obj = get_object(pack, "eat", FOOD, NULL)) == NULL)
! 384: return;
! 385:
! 386: switch (obj->o_which)
! 387: {
! 388: case FD_RATION:
! 389: amount = (int)(scale * (HUNGERTIME + rnd(400) - 200));
! 390:
! 391: if (rnd(100) > 70)
! 392: {
! 393: msg("Yuk, this food tastes awful.");
! 394: pstats.s_exp++;
! 395: check_level();
! 396: }
! 397: else
! 398: msg("Yum, that tasted good.");
! 399: break;
! 400:
! 401: case FD_FRUIT:
! 402: amount = (int)(scale * (200 + rnd(HUNGERTIME)));
! 403: msg("My, that was a yummy %s.", fruit);
! 404: break;
! 405:
! 406: case FD_CRAM:
! 407: amount = (int)(scale * (rnd(HUNGERTIME / 2) + 600));
! 408: msg("The cram tastes dry in your mouth.");
! 409: break;
! 410:
! 411: case FD_CAKES:
! 412: amount = (int)(scale * ((HUNGERTIME / 3) + rnd(600)));
! 413: msg("Yum, the honey cakes tasted good.");
! 414: break;
! 415:
! 416: case FD_LEMBA:
! 417: amount = (int)(scale * ((HUNGERTIME / 2) + rnd(900)));
! 418: quaff(&player, P_HEALING, ISNORMAL);
! 419: break;
! 420:
! 421: case FD_MIRUVOR:
! 422: amount = (int)(scale * ((HUNGERTIME / 3) + rnd(500)));
! 423: quaff(&player, P_HEALING, ISNORMAL);
! 424: quaff(&player, P_RESTORE, ISNORMAL);
! 425: break;
! 426:
! 427: default:
! 428: msg("What a strange thing to eat!");
! 429: amount = (int)(scale * HUNGERTIME);
! 430: }
! 431:
! 432: food_left += amount;
! 433:
! 434: if (obj->o_flags & ISBLESSED)
! 435: {
! 436: food_left += 2 * amount;
! 437: msg("You have a tingling feeling in your mouth.");
! 438: }
! 439: else if (food_left > scale * STOMACHSIZE)
! 440: {
! 441: food_left = (int)(scale * STOMACHSIZE);
! 442: msg("You feel satiated and too full to move.");
! 443: no_command = HOLDTIME;
! 444: }
! 445:
! 446: hungry_state = F_OK;
! 447: updpack();
! 448:
! 449: if (obj == cur_weapon)
! 450: cur_weapon = NULL;
! 451:
! 452: if (--obj->o_count <= 0) /* Remove this pack entry if last of food */
! 453: discard_pack(obj);
! 454: }
! 455:
! 456: /*
! 457: * Used to modify the player's strength it keeps track of the highest it has
! 458: * been, just in case
! 459: */
! 460:
! 461: void
! 462: chg_str(int amt, int both, int lost)
! 463: {
! 464: int ring_str; /* ring strengths */
! 465: struct stats *ptr; /* for speed */
! 466:
! 467: ptr = &pstats;
! 468:
! 469: ring_str = ring_value(R_ADDSTR) + (on(player, POWERSTR) ? 10 : 0) +
! 470: (on(player, SUPERHERO) ? 10 : 0);
! 471:
! 472: ptr->s_str -= ring_str;
! 473: ptr->s_str += amt;
! 474:
! 475: if (ptr->s_str < 3)
! 476: {
! 477: ptr->s_str = 3;
! 478: lost = FALSE;
! 479: }
! 480: else if (ptr->s_str > 25)
! 481: ptr->s_str = 25;
! 482:
! 483: if (both)
! 484: max_stats.s_str = ptr->s_str;
! 485:
! 486: if (lost)
! 487: lost_str -= amt;
! 488:
! 489: ptr->s_str += ring_str;
! 490:
! 491: if (ptr->s_str < 0)
! 492: ptr->s_str = 0;
! 493:
! 494: updpack();
! 495: }
! 496:
! 497: /*
! 498: * Used to modify the player's dexterity it keeps track of the highest it has
! 499: * been, just in case
! 500: */
! 501:
! 502: void
! 503: chg_dext(int amt, int both, int lost)
! 504: {
! 505: int ring_dext; /* ring strengths */
! 506: struct stats *ptr; /* for speed */
! 507:
! 508: ptr = &pstats;
! 509:
! 510: ring_dext = ring_value(R_ADDHIT) + (on(player, POWERDEXT) ? 10 : 0) +
! 511: (on(player, SUPERHERO) ? 5 : 0);
! 512:
! 513: ptr->s_dext -= ring_dext;
! 514: ptr->s_dext += amt;
! 515:
! 516: if (ptr->s_dext < 3)
! 517: {
! 518: ptr->s_dext = 3;
! 519: lost = FALSE;
! 520: }
! 521: else if (ptr->s_dext > 25)
! 522: ptr->s_dext = 25;
! 523:
! 524: if (both)
! 525: max_stats.s_dext = ptr->s_dext;
! 526:
! 527: if (lost)
! 528: lost_dext -= amt;
! 529:
! 530: ptr->s_dext += ring_dext;
! 531:
! 532: if (ptr->s_dext < 0)
! 533: ptr->s_dext = 0;
! 534: }
! 535:
! 536: /*
! 537: add_haste()
! 538: add a haste to the player
! 539: */
! 540:
! 541: void
! 542: add_haste(int blessed)
! 543: {
! 544: short hasttime;
! 545:
! 546: if (blessed)
! 547: hasttime = 10;
! 548: else
! 549: hasttime = 6;
! 550:
! 551: if (on(player, ISSLOW)) /* Is person slow? */
! 552: {
! 553: extinguish_fuse(FUSE_NOSLOW);
! 554: noslow(NULL);
! 555:
! 556: if (blessed)
! 557: hasttime = 4;
! 558: else
! 559: return;
! 560: }
! 561:
! 562: if (on(player, ISHASTE))
! 563: {
! 564: msg("You faint from exhaustion.");
! 565: no_command += rnd(hasttime);
! 566: lengthen_fuse(FUSE_NOHASTE, rnd(hasttime) + (roll(1, 4) * hasttime));
! 567: }
! 568: else
! 569: {
! 570: turn_on(player, ISHASTE);
! 571: light_fuse(FUSE_NOHASTE, 0, roll(hasttime, hasttime), AFTER);
! 572: }
! 573: }
! 574:
! 575: /*
! 576: aggravate()
! 577: aggravate all the monsters on this level
! 578: */
! 579:
! 580: void
! 581: aggravate(void)
! 582: {
! 583: struct linked_list *mi;
! 584: struct thing *tp;
! 585:
! 586: for (mi = mlist; mi != NULL; mi = next(mi))
! 587: {
! 588: tp = THINGPTR(mi);
! 589: chase_it(&tp->t_pos, &player);
! 590: }
! 591: }
! 592:
! 593: /*
! 594: vowelstr()
! 595: for printfs: if string starts with a vowel, return "n" for an "an"
! 596: */
! 597:
! 598: char *
! 599: vowelstr(char *str)
! 600: {
! 601: switch (*str)
! 602: {
! 603: case 'a':
! 604: case 'A':
! 605: case 'e':
! 606: case 'E':
! 607: case 'i':
! 608: case 'I':
! 609: case 'o':
! 610: case 'O':
! 611: case 'u':
! 612: case 'U':
! 613: return "n";
! 614: default:
! 615: return "";
! 616: }
! 617: }
! 618:
! 619: /*
! 620: is_object()
! 621: see if the object is one of the currently used items
! 622: */
! 623:
! 624: int
! 625: is_current(struct object *obj)
! 626: {
! 627: if (obj == NULL)
! 628: return FALSE;
! 629:
! 630: if (obj == cur_armor || obj == cur_weapon ||
! 631: obj == cur_ring[LEFT_1] || obj == cur_ring[LEFT_2] ||
! 632: obj == cur_ring[LEFT_3] || obj == cur_ring[LEFT_4] ||
! 633: obj == cur_ring[LEFT_5] ||
! 634: obj == cur_ring[RIGHT_1] || obj == cur_ring[RIGHT_2] ||
! 635: obj == cur_ring[RIGHT_3] || obj == cur_ring[RIGHT_4] ||
! 636: obj == cur_ring[RIGHT_5]) {
! 637: msg("That's already in use.");
! 638: return TRUE;
! 639: }
! 640:
! 641: return FALSE;
! 642: }
! 643:
! 644: /*
! 645: get_dir()
! 646: set up the direction co_ordinate for use in varios "prefix" commands
! 647: */
! 648:
! 649: int
! 650: get_dir(void)
! 651: {
! 652: char *prompt;
! 653: int gotit;
! 654:
! 655: prompt = "Which direction? ";
! 656: msg(prompt);
! 657:
! 658: do
! 659: {
! 660: gotit = TRUE;
! 661:
! 662: switch (readchar())
! 663: {
! 664: case 'h':
! 665: case 'H':
! 666: delta.y = 0;
! 667: delta.x = -1;
! 668: break;
! 669:
! 670: case 'j':
! 671: case 'J':
! 672: delta.y = 1;
! 673: delta.x = 0;
! 674: break;
! 675:
! 676: case 'k':
! 677: case 'K':
! 678: delta.y = -1;
! 679: delta.x = 0;
! 680: break;
! 681:
! 682: case 'l':
! 683: case 'L':
! 684: delta.y = 0;
! 685: delta.x = 1;
! 686: break;
! 687:
! 688: case 'y':
! 689: case 'Y':
! 690: delta.y = -1;
! 691: delta.x = -1;
! 692: break;
! 693:
! 694: case 'u':
! 695: case 'U':
! 696: delta.y = -1;
! 697: delta.x = 1;
! 698: break;
! 699:
! 700: case 'b':
! 701: case 'B':
! 702: delta.y = 1;
! 703: delta.x = -1;
! 704: break;
! 705:
! 706: case 'n':
! 707: case 'N':
! 708: delta.y = 1;
! 709: delta.x = 1;
! 710: break;
! 711:
! 712: case ESCAPE:
! 713: return FALSE;
! 714:
! 715: default:
! 716: mpos = 0;
! 717: msg(prompt);
! 718: gotit = FALSE;
! 719: }
! 720: }
! 721: while(!gotit);
! 722:
! 723: if (on(player, ISHUH) && rnd(100) > 80)
! 724: do
! 725: {
! 726: delta.y = rnd(3) - 1;
! 727: delta.x = rnd(3) - 1;
! 728: }
! 729: while (delta.y == 0 && delta.x == 0);
! 730:
! 731: mpos = 0;
! 732:
! 733: return(TRUE);
! 734: }
! 735:
! 736: /*
! 737: is_wearing()
! 738: is the hero wearing a particular ring
! 739: */
! 740:
! 741: int
! 742: is_wearing(int type)
! 743: {
! 744: #define ISRING(h, r) (cur_ring[h] != NULL && cur_ring[h]->o_which == r)
! 745:
! 746: return(
! 747: ISRING(LEFT_1, type) || ISRING(LEFT_2, type) ||
! 748: ISRING(LEFT_3, type) || ISRING(LEFT_4, type) ||
! 749: ISRING(LEFT_5, type) ||
! 750: ISRING(RIGHT_1, type) || ISRING(RIGHT_2, type) ||
! 751: ISRING(RIGHT_3, type) || ISRING(RIGHT_4, type) ||
! 752: ISRING(RIGHT_5, type) );
! 753: }
! 754:
! 755: /*
! 756: maze_view()
! 757: Returns true if the player can see the specified location
! 758: within the confines of a maze (within one column or row)
! 759: */
! 760:
! 761: int
! 762: maze_view(int y, int x)
! 763: {
! 764: int start, goal, delt, ycheck = 0, xcheck = 0, absy, absx;
! 765: int row;
! 766:
! 767: /* Get the absolute value of y and x differences */
! 768:
! 769: absy = hero.y - y;
! 770: absx = hero.x - x;
! 771:
! 772: if (absy < 0)
! 773: absy = -absy;
! 774:
! 775: if (absx < 0)
! 776: absx = -absx;
! 777:
! 778: /* Must be within one row or column */
! 779:
! 780: if (absy > 1 && absx > 1)
! 781: return(FALSE);
! 782:
! 783: if (absy <= 1) /* Go along row */
! 784: {
! 785: start = hero.x;
! 786: goal = x;
! 787: row = TRUE;
! 788: ycheck = hero.y;
! 789: }
! 790: else /* Go along column */
! 791: {
! 792: start = hero.y;
! 793: goal = y;
! 794: row = FALSE;
! 795: xcheck = hero.x;
! 796: }
! 797:
! 798: if (start <= goal)
! 799: delt = 1;
! 800: else
! 801: delt = -1;
! 802:
! 803: while (start != goal)
! 804: {
! 805: if (row)
! 806: xcheck = start;
! 807: else
! 808: ycheck = start;
! 809:
! 810: switch(CCHAR(winat(ycheck, xcheck)))
! 811: {
! 812: case '|':
! 813: case '-':
! 814: case WALL:
! 815: case DOOR:
! 816: case SECRETDOOR:
! 817: return(FALSE);
! 818:
! 819: default:
! 820: break;
! 821: }
! 822: start += delt;
! 823: }
! 824:
! 825: return(TRUE);
! 826: }
! 827:
! 828: /*
! 829: listen()
! 830: listen for monsters less than 5 units away
! 831: */
! 832:
! 833: void
! 834: listen(void)
! 835: {
! 836: struct linked_list *item;
! 837: struct thing *tp;
! 838: int thief_bonus = -50;
! 839: int mcount = 0;
! 840:
! 841: if (player.t_ctype == C_THIEF)
! 842: thief_bonus = 10;
! 843:
! 844: for (item = mlist; item != NULL; item = next(item))
! 845: {
! 846: tp = THINGPTR(item);
! 847:
! 848: if (DISTANCE(hero, tp->t_pos) < 81
! 849: && rnd(70) < (thief_bonus + 4 * pstats.s_dext +
! 850: 6 * pstats.s_lvl))
! 851: {
! 852: msg("You hear a%s %s nearby.",
! 853: vowelstr(monsters[tp->t_index].m_name),
! 854: monsters[tp->t_index].m_name);
! 855: mcount++;
! 856: }
! 857: }
! 858:
! 859: if (mcount == 0)
! 860: msg("You hear nothing.");
! 861: }
! 862:
! 863: /*
! 864: * nothing_message - print out "Nothing <adverb> happens."
! 865: */
! 866:
! 867: static const char *nothings[] =
! 868: {
! 869: "",
! 870: "unusual ",
! 871: "seems to ",
! 872: "at all ",
! 873: "really ",
! 874: "noticeable ",
! 875: "different ",
! 876: "strange ",
! 877: "wierd ",
! 878: "bizzare ",
! 879: "wonky ",
! 880: ""
! 881: };
! 882:
! 883: void
! 884: nothing_message(int flags)
! 885: {
! 886: int adverb = rnd(sizeof(nothings) / sizeof(char *));
! 887:
! 888: NOOP(flags);
! 889:
! 890: msg("Nothing %shappens.", nothings[adverb]);
! 891: }
! 892:
! 893: /*
! 894: feel_message()
! 895: print out "You feel <description>."
! 896: */
! 897:
! 898: void
! 899: feel_message(void)
! 900: {
! 901: char *charp;
! 902:
! 903: switch (rnd(25))
! 904: {
! 905: case 1: charp = "bad"; break;
! 906: case 2: charp = "hurt"; break;
! 907: case 3: charp = "sick"; break;
! 908: case 4: charp = "faint"; break;
! 909: case 5: charp = "yucky"; break;
! 910: case 6: charp = "wonky"; break;
! 911: case 7: charp = "wierd"; break;
! 912: case 8: charp = "queasy"; break;
! 913: case 9: charp = "wounded"; break;
! 914: case 11: charp = "unusual"; break;
! 915: case 12: charp = "no pain"; break;
! 916: case 13: charp = "strange"; break;
! 917: case 14: charp = "noticable"; break;
! 918: case 15: charp = "bizzare"; break;
! 919: case 16: charp = "distressed";break;
! 920: case 17: charp = "different"; break;
! 921: case 18: charp = "a touch of ague"; break;
! 922: case 19: charp = "a migrane coming on"; break;
! 923: case 20: charp = "Excedrin headache #666"; break;
! 924: case 21: charp = "a disturbance in the force"; break;
! 925: case 22: charp = "like someone dropped a house on you"; break;
! 926: case 23: charp = "as if every nerve in your body is on fire"; break;
! 927: case 24: charp = "like thousands of red-hot army ants are crawling under your skin";
! 928: break;
! 929:
! 930: default:
! 931: charp = "ill";
! 932: break;
! 933: }
! 934: msg("You feel %s.", charp);
! 935: }
! 936:
! 937: /*
! 938: const_bonus()
! 939: Hit point adjustment for changing levels
! 940: */
! 941:
! 942: int
! 943: const_bonus(void)
! 944: {
! 945: int ret_val = -2;
! 946:
! 947: if (pstats.s_const > 12)
! 948: ret_val = pstats.s_const - 12;
! 949: else if (pstats.s_const > 6)
! 950: ret_val = 0;
! 951: else if (pstats.s_const > 3)
! 952: ret_val = -1;
! 953:
! 954: return(ret_val);
! 955: }
! 956:
! 957: /*
! 958: int_wis_bonus()
! 959: Spell point adjustment for changing levels
! 960: */
! 961:
! 962: int
! 963: int_wis_bonus(void)
! 964: {
! 965: int ret_val = -2;
! 966: int casters_stat;
! 967:
! 968: switch (player.t_ctype)
! 969: {
! 970: case C_PALADIN:
! 971: case C_CLERIC:
! 972: casters_stat = pstats.s_wisdom;
! 973: break;
! 974: case C_RANGER:
! 975: case C_DRUID:
! 976: casters_stat = pstats.s_wisdom;
! 977: break;
! 978: case C_MAGICIAN:
! 979: casters_stat = pstats.s_intel;
! 980: break;
! 981: case C_ILLUSION:
! 982: casters_stat = pstats.s_intel;
! 983: break;
! 984:
! 985: default:
! 986: if (is_wearing(R_WIZARD))
! 987: casters_stat = pstats.s_intel;
! 988: else if (is_wearing(R_PIETY))
! 989: casters_stat = pstats.s_wisdom;
! 990: else
! 991: casters_stat = (rnd(2) ? pstats.s_wisdom :
! 992: pstats.s_intel);
! 993: }
! 994:
! 995: if (casters_stat > 12)
! 996: ret_val = casters_stat - 12;
! 997: else if (casters_stat > 6)
! 998: ret_val = 0;
! 999: else if (casters_stat > 3)
! 1000: ret_val = -1;
! 1001:
! 1002: return(ret_val);
! 1003: }
! 1004:
! 1005: void
! 1006: electrificate(void)
! 1007: {
! 1008: int affect_dist = 4 + player.t_stats.s_lvl / 4;
! 1009: struct linked_list *item, *nitem;
! 1010:
! 1011: for (item = mlist; item != NULL; item = nitem)
! 1012: {
! 1013: struct thing *tp = THINGPTR(item);
! 1014: char *mname = monsters[tp->t_index].m_name;
! 1015:
! 1016: nitem = next(item);
! 1017:
! 1018: if (DISTANCE(tp->t_pos, hero) < affect_dist)
! 1019: {
! 1020: int damage = roll(2, player.t_stats.s_lvl);
! 1021:
! 1022: debug("Charge does %d (%d)", damage, tp->t_stats.s_hpt - damage);
! 1023:
! 1024: if (on(*tp, NOBOLT))
! 1025: continue;
! 1026:
! 1027: if ((tp->t_stats.s_hpt -= damage) <= 0)
! 1028: {
! 1029: msg("The %s is killed by an electric shock.", mname);
! 1030: killed(&player, item, NOMESSAGE, POINTS);
! 1031: continue;
! 1032: }
! 1033:
! 1034: if (rnd(tp->t_stats.s_intel / 5) == 0)
! 1035: {
! 1036: turn_on(*tp, ISFLEE);
! 1037: msg("The %s is shocked by electricity.", mname);
! 1038: }
! 1039: else
! 1040: msg("The %s is zapped by your electricity.", mname);
! 1041:
! 1042: summon_help(tp, NOFORCE);
! 1043: turn_off(*tp, ISFRIENDLY);
! 1044: turn_off(*tp, ISCHARMED);
! 1045: turn_on(*tp, ISRUN);
! 1046: turn_off(*tp, ISDISGUISE);
! 1047: chase_it(&tp->t_pos, &player);
! 1048: fighting = after = running = FALSE;
! 1049: }
! 1050: }
! 1051: }
! 1052:
! 1053: /*
! 1054: feed_me - Print out interesting messages about food consumption
! 1055: */
! 1056:
! 1057: static char *f_hungry[] =
! 1058: {
! 1059: "want a cookie",
! 1060: "feel like a snack",
! 1061: "feel like some fruit",
! 1062: "start having the munchies",
! 1063: "are starting to get hungry"
! 1064: };
! 1065:
! 1066: static char *f_weak[] =
! 1067: {
! 1068: "are really hungry",
! 1069: "could eat a horse",
! 1070: "want some food - now",
! 1071: "are starting to feel weak",
! 1072: "feel a gnawing in your stomach",
! 1073: "are even willing to eat up cram",
! 1074: "feel lightheaded from not eating"
! 1075: };
! 1076:
! 1077: static char *f_faint[] =
! 1078: {
! 1079: "get dizzy from not eating",
! 1080: "are starving for nutrients",
! 1081: "feel too weak from lack of food",
! 1082: "see a mirage of an incredible banquet",
! 1083: "have incredible cramps in your stomach"
! 1084: };
! 1085:
! 1086: static char *f_plop[] =
! 1087: {
! 1088: "faint",
! 1089: "pass out",
! 1090: "keel over",
! 1091: "black out"
! 1092: };
! 1093:
! 1094: void
! 1095: feed_me(int hunger)
! 1096: {
! 1097: char *charp = NULL, *charp2 = NULL;
! 1098:
! 1099: switch (hunger)
! 1100: {
! 1101: case F_OK:
! 1102: default:
! 1103: debug("feed_me(%d) called.", hunger);
! 1104: break;
! 1105:
! 1106: case F_HUNGRY:
! 1107: charp = f_hungry[rnd(sizeof(f_hungry) /
! 1108: sizeof(char *))];
! 1109: break;
! 1110:
! 1111: case F_WEAK:
! 1112: charp = f_weak[rnd(sizeof(f_weak) / sizeof(char *))];
! 1113: break;
! 1114:
! 1115: case F_FAINT:
! 1116: charp = f_faint[rnd(sizeof(f_faint) / sizeof(char *))];
! 1117: charp2 = f_plop[rnd(sizeof(f_plop) / sizeof(char *))];
! 1118: break;
! 1119: }
! 1120:
! 1121: msg("You %s.", charp);
! 1122:
! 1123: if (hunger == F_FAINT)
! 1124: msg("You %s.", charp2);
! 1125: }
! 1126:
! 1127:
! 1128: /*
! 1129: get_monster_number()
! 1130: prompt player for a monster on list returns 0 if none selected
! 1131: */
! 1132:
! 1133: int
! 1134: get_monster_number(char *message)
! 1135: {
! 1136: int i;
! 1137: int pres_monst = 1;
! 1138: int ret_val = -1;
! 1139: char buf[2 * LINELEN];
! 1140: char monst_name[2 * LINELEN];
! 1141:
! 1142: while (ret_val == -1)
! 1143: {
! 1144: msg("Which monster do you wish to %s? (* for list)", message);
! 1145:
! 1146: if ((get_string(buf, cw)) != NORM)
! 1147: return(0);
! 1148:
! 1149: if ((i = atoi(buf)) != 0)
! 1150: ret_val = i;
! 1151: else if (buf[0] != '*')
! 1152: {
! 1153: for (i = 1; i < nummonst; i++)
! 1154: if ((strcmp(monsters[i].m_name, buf) == 0))
! 1155: ret_val = i;
! 1156: }
! 1157: /* The following hack should be redone by the windowing code */
! 1158: else
! 1159: while (pres_monst < nummonst) /* Print out the monsters */
! 1160: {
! 1161: int num_lines = LINES - 3;
! 1162:
! 1163: wclear(hw);
! 1164: touchwin(hw);
! 1165:
! 1166: wmove(hw, 2, 0);
! 1167:
! 1168: for (i = 0; i < num_lines && pres_monst < nummonst; i++)
! 1169: {
! 1170: sprintf(monst_name, "[%d] %s\n", pres_monst,
! 1171: monsters[pres_monst].m_name);
! 1172: waddstr(hw, monst_name);
! 1173: pres_monst++;
! 1174: }
! 1175:
! 1176: if (pres_monst < nummonst)
! 1177: {
! 1178: mvwaddstr(hw, LINES - 1, 0, morestr);
! 1179: wrefresh(hw);
! 1180: wait_for(' ');
! 1181: }
! 1182: else
! 1183: {
! 1184: mvwaddstr(hw, 0, 0, "Which monster");
! 1185: waddstr(hw, "? ");
! 1186: wrefresh(hw);
! 1187: }
! 1188: }
! 1189:
! 1190: get_monst:
! 1191: get_string(monst_name, hw);
! 1192: ret_val = atoi(monst_name);
! 1193:
! 1194: if ((ret_val < 1 || ret_val > nummonst - 1))
! 1195: {
! 1196: mvwaddstr(hw, 0, 0, "Please enter a number in the displayed range -- ");
! 1197: wrefresh(hw);
! 1198: goto get_monst;
! 1199: }
! 1200:
! 1201: /* Set up for redraw */
! 1202:
! 1203: clearok(cw, TRUE);
! 1204: touchwin(cw);
! 1205: }
! 1206:
! 1207: return(ret_val);
! 1208: }
CVSweb