Annotation of early-roguelike/arogue7/scrolls.c, Revision 1.1.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