Annotation of early-roguelike/arogue5/player.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * This file contains functions for dealing with special player abilities
! 3: *
! 4: * Advanced Rogue
! 5: * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
! 6: * All rights reserved.
! 7: *
! 8: * See the file LICENSE.TXT for full copyright and licensing information.
! 9: */
! 10:
! 11: #include "curses.h"
! 12: #include "rogue.h"
! 13:
! 14:
! 15: /*
! 16: * affect:
! 17: * cleric affecting undead
! 18: */
! 19:
! 20: void
! 21: affect(void)
! 22: {
! 23: register struct linked_list *item;
! 24: register struct thing *tp;
! 25: register const char *mname;
! 26: bool see;
! 27: coord new_pos;
! 28:
! 29: if (player.t_ctype != C_CLERIC && cur_relic[HEIL_ANKH] == 0) {
! 30: msg("Only clerics can affect undead.");
! 31: return;
! 32: }
! 33:
! 34: new_pos.y = hero.y + delta.y;
! 35: new_pos.x = hero.x + delta.x;
! 36:
! 37: if (cansee(new_pos.y, new_pos.x)) see = TRUE;
! 38: else see = FALSE;
! 39:
! 40: /* Anything there? */
! 41: if (new_pos.y < 0 || new_pos.y > LINES-3 ||
! 42: new_pos.x < 0 || new_pos.x > COLS-1 ||
! 43: mvwinch(mw, new_pos.y, new_pos.x) == ' ') {
! 44: msg("Nothing to affect.");
! 45: return;
! 46: }
! 47:
! 48: if ((item = find_mons(new_pos.y, new_pos.x)) == NULL) {
! 49: debug("Affect what @ %d,%d?", new_pos.y, new_pos.x);
! 50: return;
! 51: }
! 52: tp = THINGPTR(item);
! 53: mname = monsters[tp->t_index].m_name;
! 54:
! 55: if (on(player, ISINVIS) && off(*tp, CANSEE)) {
! 56: sprintf(outstring,"%s%s cannot see you", see ? "The " : "It",
! 57: see ? mname : "");
! 58: msg(outstring);
! 59: return;
! 60: }
! 61:
! 62: if (off(*tp, TURNABLE) || on(*tp, WASTURNED))
! 63: goto annoy;
! 64: turn_off(*tp, TURNABLE);
! 65:
! 66: /* Can cleric kill it? */
! 67: if (pstats.s_lvl >= 3 * tp->t_stats.s_lvl) {
! 68: unsigned long test; /* For overflow check */
! 69:
! 70: sprintf(outstring,"You have destroyed %s%s.", see ? "the " : "it", see ? mname : "");
! 71: msg(outstring);
! 72: test = pstats.s_exp + tp->t_stats.s_exp;
! 73:
! 74: /* Be sure there is no overflow before increasing experience */
! 75: if (test > pstats.s_exp) pstats.s_exp = test;
! 76: killed(item, FALSE, TRUE);
! 77: check_level(TRUE);
! 78: return;
! 79: }
! 80:
! 81: /* Can cleric turn it? */
! 82: if (rnd(100) + 1 >
! 83: (100 * ((2 * tp->t_stats.s_lvl) - pstats.s_lvl)) / pstats.s_lvl) {
! 84: unsigned long test; /* Overflow test */
! 85:
! 86: /* Make the monster flee */
! 87: turn_on(*tp, WASTURNED); /* No more fleeing after this */
! 88: turn_on(*tp, ISFLEE);
! 89: runto(tp, &hero);
! 90:
! 91: /* Let player know */
! 92: sprintf(outstring,"You have turned %s%s.", see ? "the " : "it", see ? mname : "");
! 93: msg(outstring);
! 94:
! 95: /* get points for turning monster -- but check overflow first */
! 96: test = pstats.s_exp + tp->t_stats.s_exp/2;
! 97: if (test > pstats.s_exp) pstats.s_exp = test;
! 98: check_level(TRUE);
! 99:
! 100: /* If monster was suffocating, stop it */
! 101: if (on(*tp, DIDSUFFOCATE)) {
! 102: turn_off(*tp, DIDSUFFOCATE);
! 103: extinguish(suffocate);
! 104: }
! 105:
! 106: /* If monster held us, stop it */
! 107: if (on(*tp, DIDHOLD) && (--hold_count == 0))
! 108: turn_off(player, ISHELD);
! 109: turn_off(*tp, DIDHOLD);
! 110: return;
! 111: }
! 112:
! 113: /* Otherwise -- no go */
! 114: annoy:
! 115: sprintf(outstring,"You do not affect %s%s.", see ? "the " : "it", see ? mname : "");
! 116: msg(outstring);
! 117:
! 118: /* Annoy monster */
! 119: if (off(*tp, ISFLEE)) runto(tp, &hero);
! 120: }
! 121:
! 122: /*
! 123: * the magic user is going to try and cast a spell
! 124: */
! 125: void
! 126: cast(void)
! 127: {
! 128: register int i, num_spells, spell_ability;
! 129: int which_spell;
! 130: bool nohw = FALSE;
! 131:
! 132: i = num_spells = spell_ability = which_spell = 0;
! 133:
! 134: if (player.t_ctype != C_MAGICIAN && pstats.s_intel < 16) {
! 135: msg("You are not permitted to cast spells.");
! 136: return;
! 137: }
! 138: if (cur_misc[WEAR_CLOAK] != NULL &&
! 139: cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
! 140: msg("You can't seem to cast a spell!");
! 141: return;
! 142: }
! 143: num_spells = 0;
! 144:
! 145: /* Get the number of avilable spells */
! 146: if (pstats.s_intel >= 16)
! 147: num_spells = pstats.s_intel - 15;
! 148:
! 149: if (player.t_ctype == C_MAGICIAN)
! 150: num_spells += pstats.s_lvl;
! 151:
! 152: if (num_spells > MAXSPELLS)
! 153: num_spells = MAXSPELLS;
! 154:
! 155: spell_ability = pstats.s_lvl * pstats.s_intel;
! 156: if (player.t_ctype != C_MAGICIAN)
! 157: spell_ability /= 2;
! 158:
! 159: /* Prompt for spells */
! 160: msg("Which spell are you casting? (* for list): ");
! 161:
! 162: which_spell = (int) (readchar() - 'a');
! 163: if (which_spell == (int) ESCAPE - (int) 'a') {
! 164: mpos = 0;
! 165: msg("");
! 166: after = FALSE;
! 167: return;
! 168: }
! 169: if (which_spell >= 0 && which_spell < num_spells) nohw = TRUE;
! 170:
! 171: else if (slow_invent) {
! 172: register char c;
! 173: char *spellp = "";
! 174:
! 175: for (i=0; i<num_spells; i++) {
! 176: msg("");
! 177: if (magic_spells[i].s_type == TYP_POTION)
! 178: spellp = p_magic[magic_spells[i].s_which].mi_name;
! 179: else if (magic_spells[i].s_type == TYP_SCROLL)
! 180: spellp = s_magic[magic_spells[i].s_which].mi_name;
! 181: else if (magic_spells[i].s_type == TYP_STICK)
! 182: spellp = ws_magic[magic_spells[i].s_which].mi_name;
! 183: mvwprintw(msgw, 0, 0, "[%c] A spell of %s", (char) ((int) 'a' + i),
! 184: spellp);
! 185: waddstr(msgw, morestr);
! 186: draw(msgw);
! 187: do {
! 188: c = readchar();
! 189: } while (c != ' ' && c != ESCAPE);
! 190: if (c == ESCAPE)
! 191: break;
! 192: }
! 193: msg("");
! 194: mvwaddstr(msgw, 0, 0, "Which spell are you casting? ");
! 195: draw(msgw);
! 196: }
! 197: else {
! 198: /* Set up for redraw */
! 199: msg("");
! 200: clearok(cw, TRUE);
! 201: touchwin(cw);
! 202:
! 203: /* Now display the possible spells */
! 204: wclear(hw);
! 205: touchwin(hw);
! 206: mvwaddstr(hw, 2, 0, " Cost Spell");
! 207: mvwaddstr(hw, 3, 0, "-----------------------------------------------");
! 208: for (i=0; i<num_spells; i++) {
! 209: mvwaddch(hw, i+4, 0, '[');
! 210: waddch(hw, (char) ((int) 'a' + i));
! 211: waddch(hw, ']');
! 212: sprintf(prbuf, " %3d", magic_spells[i].s_cost);
! 213: waddstr(hw, prbuf);
! 214: waddstr(hw, " A spell of ");
! 215: if (magic_spells[i].s_type == TYP_POTION)
! 216: waddstr(hw, p_magic[magic_spells[i].s_which].mi_name);
! 217: else if (magic_spells[i].s_type == TYP_SCROLL)
! 218: waddstr(hw, s_magic[magic_spells[i].s_which].mi_name);
! 219: else if (magic_spells[i].s_type == TYP_STICK)
! 220: waddstr(hw, ws_magic[magic_spells[i].s_which].mi_name);
! 221: }
! 222: sprintf(prbuf,"[Current spell power = %d]",spell_ability - spell_power);
! 223: mvwaddstr(hw, 0, 0, prbuf);
! 224: waddstr(hw, " Which spell are you casting? ");
! 225: draw(hw);
! 226: }
! 227:
! 228: if (!nohw) {
! 229: which_spell = (int) (wgetch(hw) - 'a');
! 230: while (which_spell < 0 || which_spell >= num_spells) {
! 231: if (which_spell == (int) ESCAPE - (int) 'a') {
! 232: after = FALSE;
! 233: return;
! 234: }
! 235: wmove(hw, 0, 0);
! 236: wclrtoeol(hw);
! 237: waddstr(hw, "Please enter one of the listed spells. ");
! 238: draw(hw);
! 239: which_spell = (int) (wgetch(hw) - 'a');
! 240: }
! 241: }
! 242:
! 243: if ((spell_power + magic_spells[which_spell].s_cost) > spell_ability) {
! 244: msg("Your attempt fails.");
! 245: return;
! 246: }
! 247: if (nohw)
! 248: msg("Your spell is successful.");
! 249: else {
! 250: mvwaddstr(hw, 0, 0, "Your spell is successful.--More--");
! 251: wclrtoeol(hw);
! 252: draw(hw);
! 253: wait_for(hw,' ');
! 254: }
! 255: if (magic_spells[which_spell].s_type == TYP_POTION)
! 256: quaff( magic_spells[which_spell].s_which,
! 257: magic_spells[which_spell].s_flag,
! 258: FALSE);
! 259: else if (magic_spells[which_spell].s_type == TYP_SCROLL)
! 260: read_scroll( magic_spells[which_spell].s_which,
! 261: magic_spells[which_spell].s_flag,
! 262: FALSE);
! 263: else if (magic_spells[which_spell].s_type == TYP_STICK) {
! 264: if (!do_zap( TRUE,
! 265: magic_spells[which_spell].s_which,
! 266: magic_spells[which_spell].s_flag)) {
! 267: after = FALSE;
! 268: return;
! 269: }
! 270: }
! 271: spell_power += magic_spells[which_spell].s_cost;
! 272: }
! 273:
! 274: /* Constitution bonus */
! 275:
! 276: int
! 277: const_bonus(void) /* Hit point adjustment for changing levels */
! 278: {
! 279: if (pstats.s_const > 6 && pstats.s_const <= 14)
! 280: return(0);
! 281: if (pstats.s_const > 14)
! 282: return(pstats.s_const-14);
! 283: if (pstats.s_const > 3)
! 284: return(-1);
! 285: return(-2);
! 286: }
! 287:
! 288:
! 289: /* Routines for thieves */
! 290:
! 291: /*
! 292: * gsense:
! 293: * Sense gold
! 294: */
! 295:
! 296: void
! 297: gsense(void)
! 298: {
! 299: /* Only thieves can do this */
! 300: if (player.t_ctype != C_THIEF) {
! 301: msg("You seem to have no gold sense.");
! 302: return;
! 303: }
! 304:
! 305: if (lvl_obj != NULL) {
! 306: struct linked_list *gitem;
! 307: struct object *cur;
! 308: int gtotal = 0;
! 309:
! 310: wclear(hw);
! 311: for (gitem = lvl_obj; gitem != NULL; gitem = next(gitem)) {
! 312: cur = OBJPTR(gitem);
! 313: if (cur->o_type == GOLD) {
! 314: gtotal += cur->o_count;
! 315: mvwaddch(hw, cur->o_pos.y, cur->o_pos.x, GOLD);
! 316: }
! 317: }
! 318: if (gtotal) {
! 319: s_know[S_GFIND] = TRUE;
! 320: msg("You sense gold!");
! 321: overlay(hw,cw);
! 322: return;
! 323: }
! 324: }
! 325: msg("You can sense no gold on this level.");
! 326: }
! 327:
! 328: /*
! 329: * the cleric asks his deity for a spell
! 330: */
! 331: void
! 332: pray(void)
! 333: {
! 334: register int i, num_prayers, prayer_ability;
! 335: int which_prayer;
! 336: bool nohw = FALSE;
! 337:
! 338: which_prayer = num_prayers = prayer_ability = i = 0;
! 339:
! 340: if (player.t_ctype != C_CLERIC && pstats.s_wisdom < 17 &&
! 341: cur_relic[HEIL_ANKH] == 0) {
! 342: msg("You are not permitted to pray.");
! 343: return;
! 344: }
! 345: if (cur_misc[WEAR_CLOAK] != NULL &&
! 346: cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
! 347: msg("You can't seem to pray!");
! 348: return;
! 349: }
! 350: num_prayers = 0;
! 351:
! 352: /* Get the number of avilable prayers */
! 353: if (pstats.s_wisdom > 16)
! 354: num_prayers = (pstats.s_wisdom - 15) / 2;
! 355:
! 356: if (player.t_ctype == C_CLERIC)
! 357: num_prayers += pstats.s_lvl;
! 358:
! 359: if (cur_relic[HEIL_ANKH]) num_prayers += 3;
! 360:
! 361: if (num_prayers > MAXPRAYERS)
! 362: num_prayers = MAXPRAYERS;
! 363:
! 364: prayer_ability = pstats.s_lvl * pstats.s_wisdom;
! 365: if (player.t_ctype != C_CLERIC)
! 366: prayer_ability /= 2;
! 367:
! 368: if (cur_relic[HEIL_ANKH]) prayer_ability *= 2;
! 369:
! 370: /* Prompt for prayer */
! 371: msg("Which prayer are you offering? (* for list): ");
! 372: which_prayer = (int) (readchar() - 'a');
! 373: if (which_prayer == (int) ESCAPE - (int) 'a') {
! 374: mpos = 0;
! 375: msg("");
! 376: after = FALSE;
! 377: return;
! 378: }
! 379: if (which_prayer >= 0 && which_prayer < num_prayers) nohw = TRUE;
! 380:
! 381: else if (slow_invent) {
! 382: register char c;
! 383: char *prayerp = "";
! 384:
! 385: for (i=0; i<num_prayers; i++) {
! 386: msg("");
! 387: if (cleric_spells[i].s_type == TYP_POTION)
! 388: prayerp = p_magic[cleric_spells[i].s_which].mi_name;
! 389: else if (cleric_spells[i].s_type == TYP_SCROLL)
! 390: prayerp = s_magic[cleric_spells[i].s_which].mi_name;
! 391: else if (cleric_spells[i].s_type == TYP_STICK)
! 392: prayerp = ws_magic[cleric_spells[i].s_which].mi_name;
! 393: mvwprintw(msgw, 0, 0, "[%c] A prayer for %s",
! 394: (char) ((int) 'a' + i), prayerp);
! 395: waddstr(msgw, morestr);
! 396: draw(msgw);
! 397: do {
! 398: c = readchar();
! 399: } while (c != ' ' && c != ESCAPE);
! 400: if (c == ESCAPE)
! 401: break;
! 402: }
! 403: msg("");
! 404: mvwaddstr(msgw, 0, 0, "Which prayer are you offering? ");
! 405: draw(msgw);
! 406: }
! 407: else {
! 408: /* Set up for redraw */
! 409: msg("");
! 410: clearok(cw, TRUE);
! 411: touchwin(cw);
! 412:
! 413: /* Now display the possible prayers */
! 414: wclear(hw);
! 415: touchwin(hw);
! 416: mvwaddstr(hw, 2, 0, " Cost Prayer");
! 417: mvwaddstr(hw, 3, 0, "-----------------------------------------------");
! 418: for (i=0; i<num_prayers; i++) {
! 419: mvwaddch(hw, i+4, 0, '[');
! 420: waddch(hw, (char) ((int) 'a' + i));
! 421: waddch(hw, ']');
! 422: sprintf(prbuf, " %3d", cleric_spells[i].s_cost);
! 423: waddstr(hw, prbuf);
! 424: waddstr(hw, " A prayer for ");
! 425: if (cleric_spells[i].s_type == TYP_POTION)
! 426: waddstr(hw, p_magic[cleric_spells[i].s_which].mi_name);
! 427: else if (cleric_spells[i].s_type == TYP_SCROLL)
! 428: waddstr(hw, s_magic[cleric_spells[i].s_which].mi_name);
! 429: else if (cleric_spells[i].s_type == TYP_STICK)
! 430: waddstr(hw, ws_magic[cleric_spells[i].s_which].mi_name);
! 431: }
! 432: sprintf(prbuf,"[Current prayer ability = %d]",prayer_ability-pray_time);
! 433: mvwaddstr(hw, 0, 0, prbuf);
! 434: waddstr(hw, " Which prayer are you offering? ");
! 435: draw(hw);
! 436: }
! 437:
! 438: if (!nohw) {
! 439: which_prayer = (int) (wgetch(hw) - 'a');
! 440: while (which_prayer < 0 || which_prayer >= num_prayers) {
! 441: if (which_prayer == (int) ESCAPE - (int) 'a') {
! 442: after = FALSE;
! 443: return;
! 444: }
! 445: wmove(hw, 0, 0);
! 446: wclrtoeol(hw);
! 447: mvwaddstr(hw, 0, 0, "Please enter one of the listed prayers.");
! 448: draw(hw);
! 449: which_prayer = (int) (wgetch(hw) - 'a');
! 450: }
! 451: }
! 452:
! 453:
! 454: if (cleric_spells[which_prayer].s_cost + pray_time > prayer_ability) {
! 455: msg("Your prayer fails.");
! 456: return;
! 457: }
! 458:
! 459: if (nohw) {
! 460: msg("Your prayer has been granted.--More--");
! 461: wait_for(msgw,' ');
! 462: msg("");
! 463: }
! 464: else {
! 465: mvwaddstr(hw, 0, 0, "Your prayer has been granted.--More--");
! 466: wclrtoeol(hw);
! 467: draw(hw);
! 468: wait_for(hw,' ');
! 469: }
! 470: if (cleric_spells[which_prayer].s_type == TYP_POTION)
! 471: quaff( cleric_spells[which_prayer].s_which,
! 472: cleric_spells[which_prayer].s_flag,
! 473: FALSE);
! 474: else if (cleric_spells[which_prayer].s_type == TYP_SCROLL)
! 475: read_scroll( cleric_spells[which_prayer].s_which,
! 476: cleric_spells[which_prayer].s_flag,
! 477: FALSE);
! 478: else if (cleric_spells[which_prayer].s_type == TYP_STICK) {
! 479: if (!do_zap( TRUE,
! 480: cleric_spells[which_prayer].s_which,
! 481: cleric_spells[which_prayer].s_flag)) {
! 482: after = FALSE;
! 483: return;
! 484: }
! 485: }
! 486: pray_time += cleric_spells[which_prayer].s_cost;
! 487: }
! 488:
! 489:
! 490:
! 491: /*
! 492: * steal:
! 493: * Steal in direction given in delta
! 494: */
! 495:
! 496: void
! 497: steal(void)
! 498: {
! 499: register struct linked_list *item;
! 500: register struct thing *tp;
! 501: register const char *mname;
! 502: coord new_pos;
! 503: int thief_bonus = -50;
! 504: bool isinvisible = FALSE;
! 505:
! 506: new_pos.y = hero.y + delta.y;
! 507: new_pos.x = hero.x + delta.x;
! 508:
! 509: if (on(player, ISBLIND)) {
! 510: msg("You can't see anything.");
! 511: return;
! 512: }
! 513:
! 514: /* Anything there? */
! 515: if (new_pos.y < 0 || new_pos.y > LINES-3 ||
! 516: new_pos.x < 0 || new_pos.x > COLS-1 ||
! 517: mvwinch(mw, new_pos.y, new_pos.x) == ' ') {
! 518: msg("Nothing to steal from.");
! 519: return;
! 520: }
! 521:
! 522: if ((item = find_mons(new_pos.y, new_pos.x)) == NULL)
! 523: debug("Steal from what @ %d,%d?", new_pos.y, new_pos.x);
! 524: tp = THINGPTR(item);
! 525: if (isinvisible = invisible(tp)) mname = "creature";
! 526: else mname = monsters[tp->t_index].m_name;
! 527:
! 528: /* Can player steal something unnoticed? */
! 529: if (player.t_ctype == C_THIEF) thief_bonus = 10;
! 530: if (on(*tp, ISUNIQUE)) thief_bonus -= 15;
! 531: if (isinvisible) thief_bonus -= 20;
! 532: if (on(*tp, ISINWALL) && off(player, CANINWALL)) thief_bonus -= 50;
! 533:
! 534: if (rnd(100) <
! 535: (thief_bonus + 2*dex_compute() + 5*pstats.s_lvl -
! 536: 5*(tp->t_stats.s_lvl - 3))) {
! 537: register struct linked_list *s_item, *pack_ptr;
! 538: int count = 0;
! 539: unsigned long test; /* Overflow check */
! 540:
! 541: s_item = NULL; /* Start stolen goods out as nothing */
! 542:
! 543: /* Find a good item to take */
! 544: for (pack_ptr=tp->t_pack; pack_ptr != NULL; pack_ptr=next(pack_ptr))
! 545: if ((OBJPTR(pack_ptr))->o_type != RELIC &&
! 546: rnd(++count) == 0)
! 547: s_item = pack_ptr;
! 548:
! 549: /*
! 550: * Find anything?
! 551: *
! 552: * if we have a merchant, and his pack is empty then the
! 553: * rogue has already stolen once
! 554: */
! 555: if (s_item == NULL) {
! 556: if (tp->t_index == NUMMONST)
! 557: msg("The %s seems to be shielding his pack from you.", mname);
! 558: else
! 559: msg("The %s apparently has nothing to steal.", mname);
! 560: return;
! 561: }
! 562:
! 563: /* Take it from monster */
! 564: if (tp->t_pack) detach(tp->t_pack, s_item);
! 565:
! 566: /* Give it to player */
! 567: if (add_pack(s_item, FALSE, NULL) == FALSE) {
! 568: (OBJPTR(s_item))->o_pos = hero;
! 569: fall(s_item, TRUE);
! 570: }
! 571:
! 572: /* Get points for stealing -- but first check for overflow */
! 573: test = pstats.s_exp + tp->t_stats.s_exp/2;
! 574: if (test > pstats.s_exp) pstats.s_exp = test;
! 575:
! 576: /*
! 577: * Do adjustments if player went up a level
! 578: */
! 579: check_level(TRUE);
! 580: }
! 581:
! 582: else {
! 583: msg("Your attempt fails.");
! 584:
! 585: /* Annoy monster (maybe) */
! 586: if (rnd(35) >= dex_compute() + thief_bonus) {
! 587: if (tp->t_index == NUMMONST) {
! 588: if (!isinvisible)
! 589: msg("The %s looks insulted and leaves", mname);
! 590: killed(item, FALSE, FALSE);
! 591: }
! 592: else
! 593: runto(tp, &hero);
! 594: }
! 595: }
! 596: }
CVSweb