comparison arogue7/scrolls.c @ 125:adfa37e67084

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