Annotation of early-roguelike/arogue7/scrolls.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * scrolls.c - Functions for dealing with scrolls
! 3: *
! 4: * Advanced Rogue
! 5: * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
! 6: * All rights reserved.
! 7: *
! 8: * Based on "Rogue: Exploring the Dungeons of Doom"
! 9: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 10: * All rights reserved.
! 11: *
! 12: * See the file LICENSE.TXT for full copyright and licensing information.
! 13: */
! 14:
! 15: /*
! 16: * Read a scroll and let it happen
! 17: *
! 18: */
! 19:
! 20: #include "curses.h"
! 21: #include <stdlib.h>
! 22: #include <ctype.h>
! 23: #include <string.h>
! 24: #include "rogue.h"
! 25:
! 26: /*
! 27: * let the hero get rid of some type of monster (but not a UNIQUE!)
! 28: */
! 29: void
! 30: genocide(void)
! 31: {
! 32: register struct linked_list *ip;
! 33: register struct thing *mp;
! 34: register struct linked_list *nip;
! 35: register int num_monst = NUMMONST-NUMUNIQUE-1, /* cannot genocide uniques */
! 36: pres_monst=1,
! 37: num_lines=2*(lines-3);
! 38: register int which_monst;
! 39:
! 40: which_monst = makemonster(FALSE, "Genocide", "wipe out");
! 41: if (which_monst <= 0) {
! 42: msg("");
! 43: return;
! 44: }
! 45:
! 46: /* Remove this monster from the present level */
! 47: for (ip = mlist; ip; ip = nip) {
! 48: mp = THINGPTR(ip);
! 49: nip = next(ip);
! 50: if (mp->t_index == which_monst) {
! 51: killed(ip, FALSE, FALSE, TRUE);
! 52: }
! 53: }
! 54:
! 55: /* Remove from available monsters */
! 56: monsters[which_monst].m_normal = FALSE;
! 57: monsters[which_monst].m_wander = FALSE;
! 58: mpos = 0;
! 59: msg("You have wiped out the %s.", monsters[which_monst].m_name);
! 60: }
! 61:
! 62: void
! 63: read_scroll(int which, int flag, bool is_scroll)
! 64: {
! 65: register struct object *obj = NULL, *nobj;
! 66: register struct linked_list *item, *nitem;
! 67: register int i,j;
! 68: register char ch, nch;
! 69: bool cursed, blessed;
! 70:
! 71: blessed = FALSE;
! 72: cursed = FALSE;
! 73: item = NULL;
! 74:
! 75: if (which < 0) {
! 76: if (on(player, ISBLIND)) {
! 77: msg("You can't see to read anything");
! 78: return;
! 79: }
! 80: if (on(player, ISINWALL)) {
! 81: msg("You can't see the scroll while inside rock!");
! 82: return;
! 83: }
! 84:
! 85: /* This is a scroll or book. */
! 86: if (player.t_action != C_READ) {
! 87: int units;
! 88:
! 89: item = get_item(pack, "read", READABLE, FALSE, FALSE);
! 90:
! 91: /*
! 92: * Make certain that it is somethings that we want to read
! 93: */
! 94: if (item == NULL)
! 95: return;
! 96:
! 97: /* How long does it take to read? */
! 98: units = usage_time(item);
! 99: if (units < 0) return;
! 100:
! 101: player.t_using = item; /* Remember what it is */
! 102: player.t_no_move = units * movement(&player);
! 103: if ((OBJPTR(item))->o_type == SCROLL) player.t_action = C_READ;
! 104: else player.t_action = C_USE;
! 105: return;
! 106: }
! 107:
! 108: /* We have waited our time, let's quaff the potion */
! 109: item = player.t_using;
! 110: player.t_using = NULL;
! 111: player.t_action = A_NIL;
! 112:
! 113: obj = OBJPTR(item);
! 114: /* remove it from the pack */
! 115: inpack--;
! 116: detach(pack, item);
! 117:
! 118: msg("As you read the scroll, it vanishes.");
! 119: cursed = (obj->o_flags & ISCURSED) != 0;
! 120: blessed = (obj->o_flags & ISBLESSED) != 0;
! 121:
! 122: which = obj->o_which;
! 123: }
! 124: else {
! 125: cursed = flag & ISCURSED;
! 126: blessed = flag & ISBLESSED;
! 127: }
! 128:
! 129:
! 130: switch (which) {
! 131: case S_CONFUSE:
! 132: /*
! 133: * Scroll of monster confusion. Give him that power.
! 134: */
! 135: msg("Your hands begin to glow red");
! 136: turn_on(player, CANHUH);
! 137: when S_CURING:
! 138: /*
! 139: * A cure disease spell
! 140: */
! 141: if (on(player, HASINFEST) ||
! 142: on(player, HASDISEASE)||
! 143: on(player, DOROT)) {
! 144: if (on(player, HASDISEASE)) {
! 145: extinguish(cure_disease);
! 146: cure_disease();
! 147: }
! 148: if (on(player, HASINFEST)) {
! 149: msg(terse ? "You feel yourself improving."
! 150: : "You begin to feel yourself improving again.");
! 151: turn_off(player, HASINFEST);
! 152: infest_dam = 0;
! 153: }
! 154: if (on(player, DOROT)) {
! 155: msg("You feel your skin returning to normal.");
! 156: turn_off(player, DOROT);
! 157: }
! 158: }
! 159: else {
! 160: msg(nothing);
! 161: break;
! 162: }
! 163: if (is_scroll) s_know[S_CURING] = TRUE;
! 164: when S_LIGHT:
! 165: if (blue_light(blessed, cursed) && is_scroll)
! 166: s_know[S_LIGHT] = TRUE;
! 167: when S_HOLD:
! 168: if (cursed) {
! 169: /*
! 170: * This scroll aggravates all the monsters on the current
! 171: * level and sets them running towards the hero
! 172: */
! 173: aggravate(TRUE, TRUE);
! 174: msg("You hear a high pitched humming noise.");
! 175: }
! 176: else if (blessed) { /* Hold all monsters on level */
! 177: if (mlist == NULL) msg(nothing);
! 178: else {
! 179: register struct linked_list *mon;
! 180: register struct thing *th;
! 181:
! 182: for (mon = mlist; mon != NULL; mon = next(mon)) {
! 183: th = THINGPTR(mon);
! 184: turn_off(*th, ISRUN);
! 185: turn_on(*th, ISHELD);
! 186: }
! 187: msg("A sudden peace comes over the dungeon.");
! 188: }
! 189: }
! 190: else {
! 191: /*
! 192: * Hold monster scroll. Stop all monsters within two spaces
! 193: * from chasing after the hero.
! 194: */
! 195: register int x,y;
! 196: register struct linked_list *mon;
! 197: bool gotone=FALSE;
! 198:
! 199: for (x = hero.x-2; x <= hero.x+2; x++) {
! 200: for (y = hero.y-2; y <= hero.y+2; y++) {
! 201: if (y < 1 || x < 0 || y > lines - 3 || x > cols - 1)
! 202: continue;
! 203: if (isalpha(mvwinch(mw, y, x))) {
! 204: if ((mon = find_mons(y, x)) != NULL) {
! 205: register struct thing *th;
! 206:
! 207: gotone = TRUE;
! 208: th = THINGPTR(mon);
! 209: turn_off(*th, ISRUN);
! 210: turn_on(*th, ISHELD);
! 211: }
! 212: }
! 213: }
! 214: }
! 215: if (gotone) msg("A sudden peace surrounds you.");
! 216: else msg(nothing);
! 217: }
! 218: when S_SLEEP:
! 219: /*
! 220: * if cursed, you fall asleep
! 221: */
! 222: if (is_scroll) s_know[S_SLEEP] = TRUE;
! 223: if (cursed) {
! 224: if (ISWEARING(R_ALERT))
! 225: msg("You feel drowsy for a moment.");
! 226: else {
! 227: msg("You fall asleep.");
! 228: player.t_no_move += movement(&player)*(4 + rnd(SLEEPTIME));
! 229: player.t_action = A_FREEZE;
! 230: }
! 231: }
! 232: else {
! 233: /*
! 234: * sleep monster scroll.
! 235: * puts all monsters within 2 spaces asleep
! 236: */
! 237: register int x,y;
! 238: register struct linked_list *mon;
! 239: bool gotone=FALSE;
! 240:
! 241: for (x = hero.x-2; x <= hero.x+2; x++) {
! 242: for (y = hero.y-2; y <= hero.y+2; y++) {
! 243: if (y < 1 || x < 0 || y > lines - 3 || x > cols - 1)
! 244: continue;
! 245: if (isalpha(mvwinch(mw, y, x))) {
! 246: if ((mon = find_mons(y, x)) != NULL) {
! 247: register struct thing *th;
! 248:
! 249: th = THINGPTR(mon);
! 250: if (on(*th, ISUNDEAD))
! 251: continue;
! 252: th->t_no_move += movement(th)*(SLEEPTIME+4);
! 253: th->t_action = A_FREEZE;
! 254: gotone = TRUE;
! 255: }
! 256: }
! 257: }
! 258: }
! 259: if (gotone)
! 260: msg("The monster(s) around you seem to have fallen asleep");
! 261: else
! 262: msg(nothing);
! 263: }
! 264: when S_CREATE:
! 265: /*
! 266: * Create a monster
! 267: * First look in a circle around him, next try his room
! 268: * otherwise give up
! 269: */
! 270: creat_mons(&player, (short) 0, TRUE);
! 271: light(&hero);
! 272: when S_IDENT:
! 273: /*
! 274: * if its blessed then identify everything in the pack
! 275: */
! 276: if (blessed) {
! 277: msg("You feel more Knowledgeable!");
! 278: idenpack();
! 279: }
! 280: else {
! 281: /*
! 282: * Identify, let the rogue figure something out
! 283: */
! 284: if (is_scroll && s_know[S_IDENT] != TRUE) {
! 285: msg("This scroll is an identify scroll");
! 286: }
! 287: whatis(NULL);
! 288: }
! 289: if (is_scroll) s_know[S_IDENT] = TRUE;
! 290: when S_MAP:
! 291: /*
! 292: * Scroll of magic mapping.
! 293: */
! 294: waddstr(msgw, morestr);
! 295: clearok(msgw, FALSE);
! 296: draw(msgw);
! 297: wait_for(' ');
! 298: msg("");
! 299: overwrite(stdscr, hw);
! 300: /*
! 301: * Take all the things we want to keep hidden out of the window
! 302: */
! 303: for (i = 1; i < lines-2; i++)
! 304: for (j = 0; j < cols; j++)
! 305: {
! 306: switch (nch = ch = CCHAR( mvwinch(hw, i, j) ))
! 307: {
! 308: case SECRETDOOR:
! 309: nch = secretdoor (i, j);
! 310: break;
! 311: case '-':
! 312: case '|':
! 313: case DOOR:
! 314: case PASSAGE:
! 315: case ' ':
! 316: case STAIRS:
! 317: if (mvwinch(mw, i, j) != ' ')
! 318: {
! 319: register struct thing *it;
! 320:
! 321: it = THINGPTR(find_mons(i, j));
! 322: if (it && it->t_oldch == ' ')
! 323: it->t_oldch = nch;
! 324: }
! 325: break;
! 326: default:
! 327: nch = ' ';
! 328: }
! 329: if (nch != ch)
! 330: waddch(hw, nch);
! 331: }
! 332: /*
! 333: * Copy in what he has discovered
! 334: */
! 335: overlay(cw, hw);
! 336: /*
! 337: * And set up for display
! 338: */
! 339: overwrite(hw, cw);
! 340: draw(cw);
! 341: if (is_scroll && s_know[S_MAP] != TRUE) {
! 342: msg("Oh, now this scroll has a map on it.");
! 343: s_know[S_MAP] = TRUE;
! 344: }
! 345: when S_GFIND:
! 346: /*
! 347: * Scroll of gold detection
! 348: */
! 349: {
! 350: int gtotal = 0;
! 351:
! 352: wclear(hw);
! 353: for (nitem = lvl_obj; nitem != NULL; nitem = next(nitem)) {
! 354: nobj = OBJPTR(nitem);
! 355: if (nobj->o_type == GOLD) {
! 356: gtotal += nobj->o_count;
! 357: mvwaddch(hw, nobj->o_pos.y, nobj->o_pos.x, GOLD);
! 358: }
! 359: }
! 360: for (nitem = mlist; nitem != NULL; nitem = next(nitem)) {
! 361: register struct linked_list *gitem;
! 362: register struct thing *th;
! 363:
! 364: th = THINGPTR(nitem);
! 365: if (on(*th, NODETECT)) continue;
! 366: for(gitem = th->t_pack; gitem != NULL; gitem = next(gitem)){
! 367: nobj = OBJPTR(gitem);
! 368: if (nobj->o_type == GOLD) {
! 369: gtotal += nobj->o_count;
! 370: mvwaddch(hw, th->t_pos.y, th->t_pos.x, GOLD);
! 371: }
! 372: }
! 373: }
! 374: if (gtotal) {
! 375: if (is_scroll) s_know[S_GFIND] = TRUE;
! 376: waddstr(msgw, morestr);
! 377: clearok(msgw, FALSE);
! 378: draw(msgw);
! 379: wait_for(' ');
! 380: msg("");
! 381: overlay(hw, cw);
! 382: draw(cw);
! 383: msg("You begin to feel greedy and you sense gold.");
! 384: break;
! 385: }
! 386: }
! 387: msg("You begin to feel a pull downward");
! 388: when S_TELEP:
! 389: /*
! 390: * Scroll of teleportation:
! 391: * Make him disappear and reappear
! 392: */
! 393: if (cursed) {
! 394: int old_max = cur_max;
! 395:
! 396: turns = (vlevel * 3) * LEVEL;
! 397: level = nfloors;
! 398: new_level(NORMLEV);
! 399: status(TRUE);
! 400: mpos = 0;
! 401: msg("You are banished to the lower regions.");
! 402: if (old_max == cur_max) /* if he's been here, make it harder */
! 403: aggravate(TRUE, TRUE);
! 404: }
! 405: else if (blessed) {
! 406: int old_level,
! 407: much = rnd(4) - 4;
! 408:
! 409: old_level = level;
! 410: if (much != 0) {
! 411: level += much;
! 412: if (level < 1)
! 413: level = 1;
! 414: mpos = 0;
! 415: cur_max = level;
! 416: turns += much*LEVEL;
! 417: if (turns < 0)
! 418: turns = 0;
! 419: new_level(NORMLEV); /* change levels */
! 420: if (level == old_level)
! 421: status(TRUE);
! 422: msg("You are whisked away to another region.");
! 423: }
! 424: }
! 425: else {
! 426: teleport();
! 427: }
! 428: if (is_scroll) s_know[S_TELEP] = TRUE;
! 429: when S_SCARE:
! 430: /*
! 431: * A monster will refuse to step on a scare monster scroll
! 432: * if it is dropped. Thus reading it is a mistake and produces
! 433: * laughter at the poor rogue's boo boo.
! 434: */
! 435: msg("You hear maniacal laughter in the distance.");
! 436: when S_REMOVE:
! 437: if (cursed) { /* curse all player's possessions */
! 438: for (nitem = pack; nitem != NULL; nitem = next(nitem)) {
! 439: nobj = OBJPTR(nitem);
! 440: if (nobj->o_flags & ISBLESSED)
! 441: nobj->o_flags &= ~ISBLESSED;
! 442: else
! 443: nobj->o_flags |= ISCURSED;
! 444: }
! 445: msg("The smell of fire and brimstone fills the air.");
! 446: }
! 447: else if (blessed) {
! 448: for (nitem = pack; nitem != NULL; nitem = next(nitem)) {
! 449: nobj = OBJPTR(nitem);
! 450: nobj->o_flags &= ~ISCURSED;
! 451: }
! 452: msg("Your pack glistens brightly");
! 453: }
! 454: else {
! 455: nitem = get_item(pack, "remove the curse on",ALL,FALSE,FALSE);
! 456: if (nitem != NULL) {
! 457: nobj = OBJPTR(nitem);
! 458: nobj->o_flags &= ~ISCURSED;
! 459: msg("Removed the curse from %s",inv_name(nobj,TRUE));
! 460: }
! 461: }
! 462: if (is_scroll) s_know[S_REMOVE] = TRUE;
! 463: when S_PETRIFY:
! 464: switch (mvinch(hero.y, hero.x)) {
! 465: case TRAPDOOR:
! 466: case DARTTRAP:
! 467: case TELTRAP:
! 468: case ARROWTRAP:
! 469: case SLEEPTRAP:
! 470: case BEARTRAP:
! 471: {
! 472: register int i;
! 473:
! 474: /* Find the right trap */
! 475: for (i=0; i<ntraps && !ce(traps[i].tr_pos, hero); i++);
! 476: ntraps--;
! 477:
! 478: if (!ce(traps[i].tr_pos, hero))
! 479: msg("What a strange trap!");
! 480: else {
! 481: while (i < ntraps) {
! 482: traps[i] = traps[i + 1];
! 483: i++;
! 484: }
! 485: }
! 486: }
! 487: goto pet_message;
! 488: case DOOR:
! 489: case SECRETDOOR:
! 490: case FLOOR:
! 491: case PASSAGE:
! 492: pet_message: msg("The dungeon begins to rumble and shake!");
! 493: addch(WALL);
! 494:
! 495: /* If the player is phased, unphase him */
! 496: if (on(player, CANINWALL)) {
! 497: extinguish(unphase);
! 498: turn_off(player, CANINWALL);
! 499: msg("Your dizzy feeling leaves you.");
! 500: }
! 501:
! 502: /* Mark the player as in a wall */
! 503: turn_on(player, ISINWALL);
! 504: break;
! 505: default:
! 506: msg(nothing);
! 507: }
! 508: when S_GENOCIDE:
! 509: msg("You have been granted the boon of genocide!--More--");
! 510: wait_for(' ');
! 511: msg("");
! 512: genocide();
! 513: if (is_scroll) s_know[S_GENOCIDE] = TRUE;
! 514: when S_PROTECT: {
! 515: struct linked_list *ll;
! 516: struct object *lb;
! 517: bool did_it = FALSE;
! 518: msg("You are granted the power of protection.");
! 519: if ((ll=get_item(pack,"protect",PROTECTABLE,FALSE,FALSE)) != NULL) {
! 520: lb = OBJPTR(ll);
! 521: mpos = 0;
! 522: if (cursed) {
! 523: switch(lb->o_type) { /* ruin it completely */
! 524: case RING: if (lb->o_ac > 0) {
! 525: if (is_current(lb)) {
! 526: switch (lb->o_which) {
! 527: case R_ADDWISDOM:
! 528: pstats.s_wisdom -= lb->o_ac;
! 529: when R_ADDINTEL:
! 530: pstats.s_intel -= lb->o_ac;
! 531: when R_ADDSTR:
! 532: pstats.s_str -= lb->o_ac;
! 533: when R_ADDHIT:
! 534: pstats.s_dext -= lb->o_ac;
! 535: }
! 536: }
! 537: did_it = TRUE;
! 538: lb->o_ac = 0;
! 539: }
! 540: when ARMOR: if (lb->o_ac > 10) {
! 541: did_it = TRUE;
! 542: lb->o_ac = 10;
! 543: }
! 544: when STICK: if (lb->o_charges > 0) {
! 545: did_it = TRUE;
! 546: lb->o_charges = 0;
! 547: }
! 548: when WEAPON:if (lb->o_hplus > 0) {
! 549: did_it = TRUE;
! 550: lb->o_hplus = 0;
! 551: }
! 552: if (lb->o_dplus > 0) {
! 553: did_it = TRUE;
! 554: lb->o_dplus = 0;
! 555: }
! 556: }
! 557: if (lb->o_flags & ISPROT) {
! 558: did_it = TRUE;
! 559: lb->o_flags &= ~ISPROT;
! 560: }
! 561: if (lb->o_flags & ISBLESSED) {
! 562: did_it = TRUE;
! 563: lb->o_flags &= ~ISBLESSED;
! 564: }
! 565: if (did_it)
! 566: msg("Your %s glows red for a moment",inv_name(lb,TRUE));
! 567: else {
! 568: msg(nothing);
! 569: break;
! 570: }
! 571: }
! 572: else {
! 573: lb->o_flags |= ISPROT;
! 574: msg("Protected %s.",inv_name(lb,TRUE));
! 575: }
! 576: }
! 577: if (is_scroll) s_know[S_PROTECT] = TRUE;
! 578: }
! 579: when S_MAKEIT:
! 580: msg("You have been endowed with the power of creation.");
! 581: if (is_scroll) s_know[S_MAKEIT] = TRUE;
! 582: create_obj(TRUE, 0, 0);
! 583: when S_ALLENCH: {
! 584: struct linked_list *ll;
! 585: struct object *lb;
! 586: int howmuch, flags;
! 587: if (is_scroll && s_know[S_ALLENCH] == FALSE) {
! 588: msg("You are granted the power of enchantment.");
! 589: msg("You may enchant anything(weapon,ring,armor,scroll,potion)");
! 590: }
! 591: if ((ll = get_item(pack, "enchant", ALL, FALSE, FALSE)) != NULL) {
! 592: lb = OBJPTR(ll);
! 593: lb->o_flags &= ~ISCURSED;
! 594: if (blessed) {
! 595: howmuch = 2;
! 596: flags = ISBLESSED;
! 597: }
! 598: else if (cursed) {
! 599: howmuch = -1;
! 600: flags = ISCURSED;
! 601: }
! 602: else {
! 603: howmuch = 1;
! 604: flags = ISBLESSED;
! 605: }
! 606: switch(lb->o_type) {
! 607: case RING:
! 608: if (lb->o_ac + howmuch > MAXENCHANT) {
! 609: msg("The enchantment doesn't seem to work!");
! 610: break;
! 611: }
! 612: lb->o_ac += howmuch;
! 613: if (lb==cur_ring[LEFT_1] || lb==cur_ring[LEFT_2] ||
! 614: lb==cur_ring[LEFT_3] || lb==cur_ring[LEFT_4] ||
! 615: lb==cur_ring[RIGHT_1] || lb==cur_ring[RIGHT_2] ||
! 616: lb==cur_ring[RIGHT_3] || lb==cur_ring[RIGHT_4]) {
! 617: switch (lb->o_which) {
! 618: case R_ADDWISDOM: pstats.s_wisdom += howmuch;
! 619: when R_ADDINTEL: pstats.s_intel += howmuch;
! 620: when R_ADDSTR: pstats.s_str += howmuch;
! 621: when R_ADDHIT: pstats.s_dext += howmuch;
! 622: }
! 623: }
! 624: msg("Enchanted %s.",inv_name(lb,TRUE));
! 625: when ARMOR:
! 626: if ((armors[lb->o_which].a_class - lb->o_ac) +
! 627: howmuch > MAXENCHANT) {
! 628: msg("The enchantment doesn't seem to work!");
! 629: break;
! 630: }
! 631: else
! 632: lb->o_ac -= howmuch;
! 633: msg("Enchanted %s.",inv_name(lb,TRUE));
! 634: when STICK:
! 635: lb->o_charges += (howmuch * 10) + rnd(5);
! 636: if (lb->o_charges < 0)
! 637: lb->o_charges = 0;
! 638: if (EQUAL(ws_type[lb->o_which], "staff")) {
! 639: if (lb->o_charges > 100)
! 640: lb->o_charges = 100;
! 641: }
! 642: else {
! 643: if (lb->o_charges > 50)
! 644: lb->o_charges = 50;
! 645: }
! 646: msg("Enchanted %s.",inv_name(lb,TRUE));
! 647: when WEAPON:
! 648: if(lb->o_hplus+lb->o_dplus+howmuch > MAXENCHANT * 2){
! 649: msg("The enchantment doesn't seem to work!");
! 650: break;
! 651: }
! 652: if (rnd(100) < 50)
! 653: lb->o_hplus += howmuch;
! 654: else
! 655: lb->o_dplus += howmuch;
! 656: msg("Enchanted %s.",inv_name(lb,TRUE));
! 657: when MM:
! 658: switch (lb->o_which) {
! 659: case MM_BRACERS:
! 660: if (lb->o_ac + howmuch > MAXENCHANT) {
! 661: msg("The enchantment doesn't seem to work!");
! 662: break;
! 663: }
! 664: else lb->o_ac += howmuch;
! 665: msg("Enchanted %s.",inv_name(lb,TRUE));
! 666: when MM_PROTECT:
! 667: if (lb->o_ac + howmuch > MAXENCHANT/2) {
! 668: msg("The enchantment doesn't seem to work!");
! 669: break;
! 670: }
! 671: else lb->o_ac += howmuch;
! 672: msg("Enchanted %s.",inv_name(lb,TRUE));
! 673: }
! 674: lb->o_flags |= flags;
! 675: when POTION:
! 676: case SCROLL:
! 677: default:
! 678: lb->o_flags |= flags;
! 679: msg("Enchanted %s.",inv_name(lb,TRUE));
! 680: }
! 681: }
! 682: if (is_scroll) s_know[S_ALLENCH] = TRUE;
! 683: if (!is_scroll) {
! 684: pstats.s_const--;
! 685: max_stats.s_const--;
! 686: if (pstats.s_const <= 0)
! 687: death(D_CONSTITUTION);
! 688: msg("You feel less healthy now");
! 689: }
! 690: }
! 691: when S_FINDTRAPS:
! 692: for (i=0; i<ntraps; i++) {
! 693: if (!(traps[i].tr_flags & ISFOUND)) {
! 694: traps[i].tr_flags |= ISFOUND;
! 695: if (cansee(traps[i].tr_pos.y, traps[i].tr_pos.x))
! 696: mvwaddch(cw,traps[i].tr_pos.y,traps[i].tr_pos.x,
! 697: traps[i].tr_type);
! 698: }
! 699: }
! 700: if (ntraps > 0) {
! 701: msg("You sense the presence of traps");
! 702: if (is_scroll) s_know[S_FINDTRAPS] = TRUE;
! 703: }
! 704: else
! 705: msg(nothing);
! 706:
! 707: when S_RUNES:
! 708: {
! 709: register struct linked_list *sitem;
! 710:
! 711: msg("The scroll explodes in a ball of fire!");
! 712: if (on(player, NOFIRE)) {
! 713: msg("The fire does not seem to affect you");
! 714: break;
! 715: }
! 716: explode(&player);
! 717: if (pstats.s_hpt <= 0)
! 718: death(D_SCROLL);
! 719: for (sitem = pack; sitem != NULL; sitem = nitem) {
! 720: nitem = next(sitem); /* in case we delete it */
! 721: nobj = OBJPTR(sitem);
! 722: /*
! 723: * check for loss of all scrolls and give them
! 724: * a save versus fire
! 725: */
! 726: if (nobj->o_type == SCROLL && roll(1,20) < 19) {
! 727: msg("%s burns up!", inv_name(nobj, TRUE));
! 728: inpack--;
! 729: detach(pack, sitem);
! 730: o_discard(sitem);
! 731: }
! 732: }
! 733: }
! 734:
! 735: when S_CHARM:
! 736: {
! 737: bool spots[9];
! 738: int x, y, spot, count, numcharmed, something, bonus;
! 739: struct linked_list *item;
! 740: register struct thing *tp;
! 741:
! 742: /* Initialize the places where we look around us */
! 743: for (i=0; i<9; i++) spots[i] = FALSE;
! 744: count = 0; /* No spots tried yet */
! 745: numcharmed = 0; /* Nobody charmed yet */
! 746: something = 0; /* Nothing has been seen yet */
! 747: bonus = 0; /* no bonus yet */
! 748:
! 749: /* Now look around us randomly for a charmee */
! 750: while (count < 9) {
! 751: do {
! 752: spot = rnd(9);
! 753: } while (spots[spot] == TRUE);
! 754:
! 755: /* We found a place */
! 756: count++;
! 757: spots[spot] = TRUE;
! 758: y = hero.y - 1 + (spot / 3);
! 759: x = hero.x - 1 + (spot % 3);
! 760:
! 761: /* Be sure to stay on the board! */
! 762: if (x < 0 || x >= cols || (y < 1) || (y >= lines - 2))
! 763: continue;
! 764:
! 765: /* Is there a monster here? */
! 766: if (!isalpha(mvwinch(mw, y, x))) continue;
! 767:
! 768: /* What kind is it? */
! 769: item = find_mons(y, x);
! 770: if (item == NULL) continue;
! 771:
! 772: tp = THINGPTR(item);
! 773: if (on(*tp,ISCHARMED) || on(*tp,ISUNIQUE) || on(*tp,ISUNDEAD))
! 774: continue;
! 775:
! 776: /* Will the monster be charmed? */
! 777: if (blessed) bonus -= 3;
! 778: bonus -= (pstats.s_charisma - 13) / 3;
! 779: if ((player.t_ctype==C_PALADIN || player.t_ctype==C_RANGER) &&
! 780: off(*tp, ISMEAN))
! 781: bonus -= 3;
! 782: if (save(VS_MAGIC, tp, bonus)) continue;
! 783:
! 784: /* We got him! */
! 785: numcharmed++;
! 786:
! 787: /* Let the player know (maybe) */
! 788: if ((off(*tp, ISINVIS) || on(player, CANSEE)) &&
! 789: (off(*tp, ISSHADOW) || on(player, CANSEE)) &&
! 790: cansee(y, x)) {
! 791: if (on(*tp, CANSURPRISE)) {
! 792: turn_off(*tp, CANSURPRISE);
! 793: msg("Woah!");
! 794: }
! 795: msg("The eyes of %s glaze over!",
! 796: prname(monster_name(tp), FALSE));
! 797: something++;
! 798: }
! 799:
! 800: /* Charm him and turn off any side effects */
! 801: turn_on(*tp, ISCHARMED);
! 802: runto(tp, &hero);
! 803: tp->t_action = A_NIL;
! 804:
! 805: /* If monster was suffocating us, stop it */
! 806: if (on(*tp, DIDSUFFOCATE)) {
! 807: turn_off(*tp, DIDSUFFOCATE);
! 808: extinguish(suffocate);
! 809: }
! 810:
! 811: /* If monster held us, stop it */
! 812: if (on(*tp, DIDHOLD) && (--hold_count == 0))
! 813: turn_off(player, ISHELD);
! 814: turn_off(*tp, DIDHOLD);
! 815:
! 816: /* If frightened of this monster, stop */
! 817: if (on(player, ISFLEE) &&
! 818: player.t_dest == &tp->t_pos) turn_off(player, ISFLEE);
! 819:
! 820: if ((blessed && numcharmed >= 2) || numcharmed > 0) break;
! 821: }
! 822:
! 823: if (something == 0) msg(nothing);
! 824: }
! 825:
! 826: otherwise:
! 827: msg("What a puzzling scroll!");
! 828: return;
! 829: }
! 830: look(TRUE, FALSE); /* put the result of the scroll on the screen */
! 831: status(FALSE);
! 832: if (is_scroll && item && s_know[which] && s_guess[which])
! 833: {
! 834: free(s_guess[which]);
! 835: s_guess[which] = NULL;
! 836: }
! 837: else if (is_scroll &&
! 838: !s_know[which] &&
! 839: item &&
! 840: askme &&
! 841: (obj->o_flags & ISKNOW) == 0 &&
! 842: (obj->o_flags & ISPOST) == 0 &&
! 843: s_guess[which] == NULL) {
! 844: nameitem(item, FALSE);
! 845: }
! 846: if (item != NULL) o_discard(item);
! 847: updpack(TRUE, &player);
! 848: }
CVSweb