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