Annotation of early-roguelike/urogue/player.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: player.c - functions for dealing with special player abilities
! 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 <ctype.h>
! 21: #include "rogue.h"
! 22:
! 23: /*
! 24: * Pray to a deity
! 25: *
! 26: * 00-10 Good stuff happens
! 27: * 11-40 A good deity answers
! 28: * 41-60 Nothing happens
! 29: * 61-90 A bad deity answers, but with good results
! 30: * 91-99 You were better off before
! 31: */
! 32:
! 33: void
! 34: prayer(void)
! 35: {
! 36: int chance, i, times;
! 37: char num_str[20];
! 38: int ch;
! 39: struct linked_list *item;
! 40: struct thing *tp;
! 41: int is_godly;
! 42:
! 43: if (player.t_praycnt > pstats.s_lvl)
! 44: {
! 45: msg("Are you sure you want to bother the gods?");
! 46: ch = readchar();
! 47:
! 48: if (tolower(ch) != 'y')
! 49: {
! 50: after = FALSE;
! 51: return;
! 52: }
! 53: else
! 54: msg("Here goes...");
! 55: }
! 56:
! 57: msg("You are surrounded by orange smoke...");
! 58:
! 59: if (rnd(3) == 0)
! 60: luck--;
! 61:
! 62: if (is_wearing(R_PIETY) || (rnd(luck) == 0 &&
! 63: (player.t_ctype == C_DRUID || player.t_ctype == C_CLERIC ||
! 64: ((player.t_ctype == C_PALADIN || player.t_ctype == C_RANGER)
! 65: && pstats.s_lvl > 8))))
! 66: is_godly = ISBLESSED;
! 67: else
! 68: is_godly = ISNORMAL;
! 69:
! 70: if (is_wearing(R_PIETY))
! 71: player.t_praycnt += rnd(2);
! 72: else
! 73: player.t_praycnt++;
! 74:
! 75: if (wizard)
! 76: {
! 77: msg("What roll?[0..%d] ", 99);
! 78: ch = get_string(num_str, cw);
! 79:
! 80: if (ch == QUIT)
! 81: {
! 82: msg("");
! 83: return;
! 84: }
! 85: chance = atoi(num_str);
! 86: }
! 87: else
! 88: {
! 89: chance = rnd(100) + roll(10, luck) - 5;
! 90:
! 91: if (player.t_praycnt > pstats.s_lvl)
! 92: chance += 50;
! 93:
! 94: if (is_godly)
! 95: chance -= 50;
! 96: }
! 97:
! 98: chance = max(0, min(chance, 100));
! 99:
! 100: if (chance == 0)
! 101: {
! 102: msg("The heavens open and glorious radiance surrounds you!");
! 103:
! 104: pstats.s_hpt = max_stats.s_hpt;
! 105: pstats.s_power = max_stats.s_power;
! 106:
! 107: if (is_godly)
! 108: times = 8;
! 109: else
! 110: times = 1;
! 111:
! 112: /*
! 113: * kill all monsters surrounding the hero except unique ones
! 114: * This will change when I implement the deity option. If
! 115: * The deity is "stronger" than the unique monster, then the
! 116: * monster will be killed.
! 117: */
! 118:
! 119: for (i = 0; i < times; i++)
! 120: {
! 121: item = f_mons_a(player.t_pos.y, player.t_pos.x, TRUE);
! 122:
! 123: if (item)
! 124: {
! 125: tp = THINGPTR(item);
! 126:
! 127: msg("A bolt of eldritch energy strikes down the %s!",
! 128: monsters[tp->t_index].m_name);
! 129:
! 130: killed(NULL, item, NOMESSAGE, POINTS);
! 131: }
! 132: }
! 133: }
! 134: else if (chance == 2)
! 135: {
! 136: msg("Aule, Lord of Crafts, hears your call.");
! 137: read_scroll(&player, S_MAKEITEMEM, is_godly);
! 138: }
! 139:
! 140: /* Save 3-9 for other wonderful stuff */
! 141: else if (chance < 15)
! 142: {
! 143: msg("Orome, Lord of Forests, hears your call.");
! 144: read_scroll(&player, S_SUMMON, is_godly);
! 145: }
! 146: else if (chance < 20)
! 147: {
! 148: msg("Hermes, the Winged Messenger, hears your call.");
! 149: quaff(&player, P_HASTE, is_godly);
! 150: }
! 151: else if (chance < 25)
! 152: {
! 153: msg("Lorien, Master of Dreams, hears your call.");
! 154: read_scroll(&player, S_SLEEP, is_godly);
! 155: }
! 156: else if (chance < 30)
! 157: {
! 158: msg("Este, Lady of Healing, hears your call.");
! 159: quaff(&player, P_RESTORE, is_godly);
! 160: quaff(&player, P_HEALING, is_godly);
! 161: }
! 162: else if (chance < 35)
! 163: {
! 164: msg("Thor, God of Thunder, hears your call.");
! 165: msg("A bolt of lighting strikes you!");
! 166: read_scroll(&player, S_ELECTRIFY, is_godly);
! 167: }
! 168: else if (chance < 40)
! 169: {
! 170: msg("Lorien, Master of Illusion, hears your call.");
! 171: quaff(&player, P_DISGUISE, is_godly);
! 172: }
! 173: else if (chance < 60) /* Nothing happens */
! 174: {
! 175: msg("Boccob, the Uncaring, ignores you.");
! 176: }
! 177:
! 178: /* You don't really want one of these gods answering your call */
! 179:
! 180: else if (chance < 65)
! 181: {
! 182: msg("Jubilex, Master of Slimes and Oozes, hears your call.");
! 183: read_scroll(&player, S_HOLD, is_godly);
! 184: luck++;
! 185: }
! 186: else if (chance < 70)
! 187: {
! 188: msg("Sauron, Lord of the Ring, hears your call.");
! 189: quaff(&player, P_INVIS, is_godly);
! 190: luck++;
! 191: }
! 192: else if (chance < 75)
! 193: {
! 194: msg("Orcus, Lord of Undead, hears your call.");
! 195: quaff(&player, P_PHASE, is_godly);
! 196: luck++;
! 197: }
! 198: else if (chance < 80)
! 199: {
! 200: msg("Incabulos, God of Evil Sendings, hears your call.");
! 201: quaff(&player, P_CLEAR, is_godly);
! 202: luck++;
! 203: }
! 204: else if (chance < 85)
! 205: {
! 206: msg("Raxivort, Night Flutterer, hears your call.");
! 207: quaff(&player, P_SEEINVIS, is_godly);
! 208: luck++;
! 209: }
! 210: else if (chance < 90)
! 211: {
! 212: msg("Morgoth, Lord of Fire, hears your call.");
! 213: quaff(&player, P_FIRERESIST, is_godly);
! 214: luck++;
! 215: }
! 216: else if (chance < 100) /* You are in for it now! */
! 217: {
! 218: msg("You fall into a horrible trance-like state.");
! 219: no_command += SLEEPTIME;
! 220: }
! 221: if (chance == 100)
! 222: {
! 223: msg("The heavens open - but wait!");
! 224: msg("A bolt of eldritch energy strikes you!");
! 225:
! 226: if (pstats.s_hpt > 1)
! 227: pstats.s_hpt /= 2;
! 228:
! 229: msg("The gods must be angry with you.");
! 230: }
! 231: }
! 232:
! 233: /* Routines for thieves */
! 234:
! 235: /*
! 236: gsense()
! 237: Sense gold returns TRUE if gold was detected
! 238: */
! 239:
! 240: int
! 241: gsense(void)
! 242: {
! 243: if (lvl_obj != NULL)
! 244: {
! 245: struct linked_list *gitem;
! 246: struct object *cur;
! 247: int gtotal = 0;
! 248:
! 249: wclear(hw);
! 250:
! 251: for (gitem = lvl_obj; gitem != NULL; gitem = next(gitem))
! 252: {
! 253: cur = OBJPTR(gitem);
! 254:
! 255: if (cur->o_type == GOLD)
! 256: {
! 257: gtotal += cur->o_count;
! 258: mvwaddch(hw, cur->o_pos.y, cur->o_pos.x, GOLD);
! 259:
! 260: }
! 261: }
! 262:
! 263: if (gtotal)
! 264: {
! 265: msg("You sense gold!");
! 266: overlay(hw, cw);
! 267: return(TRUE);
! 268: }
! 269: }
! 270:
! 271: nothing_message(ISNORMAL);
! 272:
! 273: return(FALSE);
! 274: }
! 275:
! 276:
! 277: /*
! 278: is_stealth()
! 279: is player quiet about something
! 280: */
! 281:
! 282: int
! 283: is_stealth(struct thing *tp)
! 284: {
! 285: return (rnd(25) < tp->t_stats.s_dext ||
! 286: (tp == &player && is_wearing(R_STEALTH)));
! 287: }
! 288:
! 289: /*
! 290: steal()
! 291: Steal in direction given in delta
! 292: */
! 293:
! 294: void
! 295: steal(void)
! 296: {
! 297: struct linked_list *item;
! 298: struct thing *tp;
! 299: coord new_pos;
! 300: short thief_bonus;
! 301: char *unsuccess = "";
! 302: char *gain = "";
! 303: char *notice = "is not";
! 304:
! 305: new_pos.y = hero.y + delta.y;
! 306: new_pos.x = hero.x + delta.x;
! 307:
! 308: /* Anything there? */
! 309:
! 310: if (new_pos.y < 0 || new_pos.y > LINES - 3 ||
! 311: new_pos.x < 0 || new_pos.x > COLS - 1 ||
! 312: mvwinch(mw, new_pos.y, new_pos.x) == ' ')
! 313: {
! 314: msg("There is no one to steal from.");
! 315: return;
! 316: }
! 317:
! 318: if ((item = find_mons(new_pos.y, new_pos.x)) == NULL)
! 319: return;
! 320:
! 321: tp = THINGPTR(item);
! 322:
! 323: /* Can player steal something unnoticed? */
! 324:
! 325: if (player.t_ctype == C_THIEF || player.t_ctype == C_NINJA)
! 326: thief_bonus = 10;
! 327: else
! 328: thief_bonus = -50;
! 329:
! 330: if (rnd(50) >= 3 * pstats.s_dext + thief_bonus)
! 331: {
! 332: chase_it(&new_pos, &player);
! 333: turn_off(*tp, ISFRIENDLY);
! 334: notice = "is";
! 335: }
! 336:
! 337: if (rnd(100) <
! 338: (thief_bonus + 2 * pstats.s_dext + 5 * pstats.s_lvl -
! 339: 5 * (tp->t_stats.s_lvl - 3)))
! 340: {
! 341: struct linked_list *s_item, *pack_ptr;
! 342: int cnt = 0;
! 343:
! 344: s_item = NULL; /* Start stolen goods out as nothing */
! 345:
! 346: /* Find a good item to take */
! 347:
! 348: if (tp->t_pack != NULL)
! 349: {
! 350: /* Count up the number of items in the monster's pack */
! 351:
! 352: for (pack_ptr = tp->t_pack; pack_ptr != NULL; pack_ptr = next(pack_ptr))
! 353: cnt++;
! 354:
! 355: /* Pick one */
! 356: cnt = rnd(cnt);
! 357:
! 358: /* Take it from the monster */
! 359:
! 360: for (pack_ptr = tp->t_pack; --cnt == 0; pack_ptr = next(pack_ptr))
! 361: ;
! 362:
! 363: s_item = pack_ptr;
! 364: detach(tp->t_pack, s_item);
! 365:
! 366: /* Give it to player */
! 367:
! 368: if (add_pack(s_item, MESSAGE) == FALSE)
! 369: {
! 370: (OBJPTR(s_item))->o_pos = hero;
! 371: fall(&player, s_item, TRUE, FALSE);
! 372: }
! 373:
! 374: /* Get points for stealing from unfriendly monsters */
! 375:
! 376: if (off(*tp, ISFRIENDLY))
! 377: {
! 378: if (player.t_ctype == C_THIEF)
! 379: pstats.s_exp += 2 * tp->t_stats.s_exp / 3;
! 380: else
! 381: pstats.s_exp += tp->t_stats.s_exp / min(pstats.s_lvl, 10);
! 382:
! 383: check_level();
! 384: }
! 385: }
! 386: else
! 387: {
! 388: gain = " gains you nothing and";
! 389: }
! 390: }
! 391: else
! 392: {
! 393: unsuccess = " unsuccessful";
! 394: }
! 395:
! 396: msg("Your%s attempt%s %s noticed.", unsuccess, gain, notice);
! 397: }
! 398:
! 399: /*
! 400: affect()
! 401: cleric affecting undead
! 402: */
! 403:
! 404: void
! 405: affect(void)
! 406: {
! 407: struct linked_list *item;
! 408: struct thing *tp;
! 409: char *mname;
! 410: coord new_pos;
! 411: int is_godly;
! 412: int effective_level;
! 413:
! 414: if (player.t_ctype != C_CLERIC && player.t_ctype != C_PALADIN &&
! 415: !is_wearing(R_PIETY))
! 416: {
! 417: msg("Only clerics and paladins can affect undead.");
! 418: return;
! 419: }
! 420:
! 421: is_godly = (player.t_ctype == C_CLERIC || player.t_ctype == C_PALADIN);
! 422:
! 423: if (is_godly && is_wearing(R_PIETY))
! 424: effective_level = 2 * pstats.s_lvl;
! 425: else
! 426: effective_level = pstats.s_lvl;
! 427:
! 428: new_pos.y = hero.y + delta.y;
! 429: new_pos.x = hero.x + delta.x;
! 430:
! 431: /* Anything there? */
! 432:
! 433: if (new_pos.y < 0 || new_pos.y > LINES - 3 ||
! 434: new_pos.x < 0 || new_pos.x > COLS - 1 ||
! 435: mvwinch(mw, new_pos.y, new_pos.x) == ' ')
! 436: {
! 437: msg("Nothing to affect.");
! 438: return;
! 439: }
! 440:
! 441: if ((item = find_mons(new_pos.y, new_pos.x)) == NULL)
! 442: {
! 443: debug("Affect what @ %d,%d?", new_pos.y, new_pos.x);
! 444: return;
! 445: }
! 446:
! 447: tp = THINGPTR(item);
! 448: mname = monsters[tp->t_index].m_name;
! 449:
! 450: if (off(*tp, ISUNDEAD))
! 451: {
! 452: msg("Your holy symbol has no effect on the %s.", mname);
! 453: goto annoy;
! 454: }
! 455:
! 456: if (on(*tp, WASTURNED))
! 457: {
! 458: msg("Your holy symbol merely enrages the %s.", mname);
! 459: goto annoy;
! 460: }
! 461:
! 462: /* Can cleric destroy it? */
! 463:
! 464: if (effective_level >= 3 * tp->t_stats.s_lvl)
! 465: {
! 466: msg("You have destroyed the %s.", mname);
! 467: killed(&player, item, NOMESSAGE, POINTS);
! 468: return;
! 469: }
! 470:
! 471: /* Can cleric turn it? */
! 472:
! 473: if (rnd(100) + 1 >
! 474: (100 * ((2 * tp->t_stats.s_lvl) - effective_level)) /
! 475: effective_level)
! 476: {
! 477: msg("You have turned the %s.", mname);
! 478: turn_on(*tp, WASTURNED); /* One turn per monster */
! 479: turn_on(*tp, ISRUN);
! 480: turn_on(*tp, ISFLEE);
! 481:
! 482: /* If monster was suffocating, stop it */
! 483: if (on(*tp, DIDSUFFOCATE))
! 484: {
! 485: turn_off(*tp, DIDSUFFOCATE);
! 486: extinguish_fuse(FUSE_SUFFOCATE);
! 487: }
! 488:
! 489: /* If monster held us, stop it */
! 490: if (on(*tp, DIDHOLD) && (--hold_count == 0))
! 491: turn_off(player, ISHELD);
! 492:
! 493: turn_off(*tp, DIDHOLD);
! 494:
! 495: return;
! 496: }
! 497:
! 498: msg("The %s momentarily recoils from your holy symbol.", mname);
! 499:
! 500: annoy:
! 501:
! 502: if (off(*tp, WASTURNED))
! 503: chase_it(&new_pos, &player);
! 504: }
! 505:
! 506: /*
! 507: undead_sense()
! 508: cleric or paladin finding the ungodly
! 509: */
! 510:
! 511: void
! 512: undead_sense(void)
! 513: {
! 514: struct linked_list *item;
! 515: struct thing *tp;
! 516: int showit = FALSE;
! 517:
! 518: wclear(hw);
! 519:
! 520: for (item = mlist; item != NULL; item = next(item))
! 521: {
! 522: tp = THINGPTR(item);
! 523:
! 524: if (on(*tp, ISUNDEAD))
! 525: {
! 526: mvwaddch(hw, tp->t_pos.y, tp->t_pos.x, '&');
! 527: showit = TRUE;
! 528: }
! 529: }
! 530:
! 531: if (showit)
! 532: {
! 533: msg("You feel the presense of the ungodly.");
! 534: overlay(hw, cw);
! 535: wrefresh(cw);
! 536: wclear(hw);
! 537: }
! 538: }
CVSweb