Expand PMF_FN_* macros.
[netbsd-mini2440.git] / games / hack / hack.zap.c
blob6391977798a0182ba141187b485105cb48243bc3
1 /* $NetBSD: hack.zap.c,v 1.8 2009/06/07 18:30:39 dholland Exp $ */
3 /*
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 * Amsterdam
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * - Neither the name of the Stichting Centrum voor Wiskunde en
20 * Informatica, nor the names of its contributors may be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 #include <sys/cdefs.h>
65 #ifndef lint
66 __RCSID("$NetBSD: hack.zap.c,v 1.8 2009/06/07 18:30:39 dholland Exp $");
67 #endif /* not lint */
69 #include "hack.h"
70 #include "extern.h"
72 static const char *const fl[] = {
73 "magic missile",
74 "bolt of fire",
75 "sleep ray",
76 "bolt of cold",
77 "death ray"
80 static void bhitm(struct monst *, struct obj *);
81 static int bhito(struct obj *, struct obj *);
82 static char dirlet(int, int);
83 static int zhit(struct monst *, int);
84 static int revive(struct obj *);
85 static void rloco(struct obj *);
86 static void burn_scrolls(void);
88 /* Routines for IMMEDIATE wands. */
89 /* bhitm: monster mtmp was hit by the effect of wand otmp */
90 static void
91 bhitm(struct monst *mtmp, struct obj *otmp)
93 wakeup(mtmp);
94 switch (otmp->otyp) {
95 case WAN_STRIKING:
96 if (u.uswallow || rnd(20) < 10 + mtmp->data->ac) {
97 int tmp = d(2, 12);
98 hit("wand", mtmp, exclam(tmp));
99 mtmp->mhp -= tmp;
100 if (mtmp->mhp < 1)
101 killed(mtmp);
102 } else
103 miss("wand", mtmp);
104 break;
105 case WAN_SLOW_MONSTER:
106 mtmp->mspeed = MSLOW;
107 break;
108 case WAN_SPEED_MONSTER:
109 mtmp->mspeed = MFAST;
110 break;
111 case WAN_UNDEAD_TURNING:
112 if (strchr(UNDEAD, mtmp->data->mlet)) {
113 mtmp->mhp -= rnd(8);
114 if (mtmp->mhp < 1)
115 killed(mtmp);
116 else
117 mtmp->mflee = 1;
119 break;
120 case WAN_POLYMORPH:
121 if (newcham(mtmp, &mons[rn2(CMNUM)]))
122 objects[otmp->otyp].oc_name_known = 1;
123 break;
124 case WAN_CANCELLATION:
125 mtmp->mcan = 1;
126 break;
127 case WAN_TELEPORTATION:
128 rloc(mtmp);
129 break;
130 case WAN_MAKE_INVISIBLE:
131 mtmp->minvis = 1;
132 break;
133 #ifdef WAN_PROBING
134 case WAN_PROBING:
135 mstatusline(mtmp);
136 break;
137 #endif /* WAN_PROBING */
138 default:
139 impossible("What an interesting wand (%u)", otmp->otyp);
144 * object obj was hit by the effect of wand otmp
145 * returns TRUE if sth was done
147 static int
148 bhito(struct obj *obj, struct obj *otmp)
150 int res = TRUE;
152 if (obj == uball || obj == uchain)
153 res = FALSE;
154 else
155 switch (otmp->otyp) {
156 case WAN_POLYMORPH:
158 * preserve symbol and quantity, but turn rocks into
159 * gems
161 mkobj_at((obj->otyp == ROCK || obj->otyp == ENORMOUS_ROCK)
162 ? GEM_SYM : obj->olet,
163 obj->ox, obj->oy)->quan = obj->quan;
164 delobj(obj);
165 break;
166 case WAN_STRIKING:
167 if (obj->otyp == ENORMOUS_ROCK)
168 fracture_rock(obj);
169 else
170 res = FALSE;
171 break;
172 case WAN_CANCELLATION:
173 if (obj->spe && obj->olet != AMULET_SYM) {
174 obj->known = 0;
175 obj->spe = 0;
177 break;
178 case WAN_TELEPORTATION:
179 rloco(obj);
180 break;
181 case WAN_MAKE_INVISIBLE:
182 obj->oinvis = 1;
183 break;
184 case WAN_UNDEAD_TURNING:
185 res = revive(obj);
186 break;
187 case WAN_SLOW_MONSTER: /* no effect on objects */
188 case WAN_SPEED_MONSTER:
189 #ifdef WAN_PROBING
190 case WAN_PROBING:
191 #endif /* WAN_PROBING */
192 res = FALSE;
193 break;
194 default:
195 impossible("What an interesting wand (%u)", otmp->otyp);
197 return (res);
201 dozap(void)
203 struct obj *obj;
204 xchar zx, zy;
206 obj = getobj("/", "zap");
207 if (!obj)
208 return (0);
209 if (obj->spe < 0 || (obj->spe == 0 && rn2(121))) {
210 pline("Nothing Happens.");
211 return (1);
213 if (obj->spe == 0)
214 pline("You wrest one more spell from the worn-out wand.");
215 if (!(objects[obj->otyp].bits & NODIR) && !getdir(1))
216 return (1); /* make him pay for knowing !NODIR */
217 obj->spe--;
218 if (objects[obj->otyp].bits & IMMEDIATE) {
219 if (u.uswallow)
220 bhitm(u.ustuck, obj);
221 else if (u.dz) {
222 if (u.dz > 0) {
223 struct obj *otmp = o_at(u.ux, u.uy);
224 if (otmp)
225 (void) bhito(otmp, obj);
227 } else
228 (void) bhit(u.dx, u.dy, rn1(8, 6), 0, bhitm, bhito, obj);
229 } else {
230 switch (obj->otyp) {
231 case WAN_LIGHT:
232 litroom(TRUE);
233 break;
234 case WAN_SECRET_DOOR_DETECTION:
235 if (!findit())
236 return (1);
237 break;
238 case WAN_CREATE_MONSTER:
240 int cnt = 1;
241 if (!rn2(23))
242 cnt += rn2(7) + 1;
243 while (cnt--)
244 (void) makemon((struct permonst *) 0, u.ux, u.uy);
246 break;
247 case WAN_WISHING:
249 char buf[BUFSZ];
250 struct obj *otmp;
251 if (u.uluck + rn2(5) < 0) {
252 pline("Unfortunately, nothing happens.");
253 break;
255 pline("You may wish for an object. What do you want? ");
256 getlin(buf);
257 if (buf[0] == '\033')
258 buf[0] = 0;
259 otmp = readobjnam(buf);
260 otmp = addinv(otmp);
261 prinv(otmp);
262 break;
264 case WAN_DIGGING:
266 * Original effect (approximately): from CORR: dig
267 * until we pierce a wall from ROOM: piece wall and
268 * dig until we reach an ACCESSIBLE place. Currently:
269 * dig for digdepth positions; also down on request
270 * of Lennart Augustsson.
273 struct rm *room;
274 int digdepth;
275 if (u.uswallow) {
276 struct monst *mtmp = u.ustuck;
278 pline("You pierce %s's stomach wall!",
279 monnam(mtmp));
280 mtmp->mhp = 1; /* almost dead */
281 unstuck(mtmp);
282 mnexto(mtmp);
283 break;
285 if (u.dz) {
286 if (u.dz < 0) {
287 pline("You loosen a rock from the ceiling.");
288 pline("It falls on your head!");
289 losehp(1, "falling rock");
290 mksobj_at(ROCK, u.ux, u.uy);
291 fobj->quan = 1;
292 stackobj(fobj);
293 if (Invisible)
294 newsym(u.ux, u.uy);
295 } else {
296 dighole();
298 break;
300 zx = u.ux + u.dx;
301 zy = u.uy + u.dy;
302 digdepth = 8 + rn2(18);
303 Tmp_at(-1, '*'); /* open call */
304 while (--digdepth >= 0) {
305 if (!isok(zx, zy))
306 break;
307 room = &levl[zx][zy];
308 Tmp_at(zx, zy);
309 if (!xdnstair) {
310 if (zx < 3 || zx > COLNO - 3 ||
311 zy < 3 || zy > ROWNO - 3)
312 break;
313 if (room->typ == HWALL ||
314 room->typ == VWALL) {
315 room->typ = ROOM;
316 break;
318 } else if (room->typ == HWALL || room->typ == VWALL ||
319 room->typ == SDOOR || room->typ == LDOOR) {
320 room->typ = DOOR;
321 digdepth -= 2;
322 } else if (room->typ == SCORR || !room->typ) {
323 room->typ = CORR;
324 digdepth--;
326 mnewsym(zx, zy);
327 zx += u.dx;
328 zy += u.dy;
330 mnewsym(zx, zy); /* not always necessary */
331 Tmp_at(-1, -1); /* closing call */
332 break;
334 default:
335 buzz((int) obj->otyp - WAN_MAGIC_MISSILE,
336 u.ux, u.uy, u.dx, u.dy);
337 break;
339 if (!objects[obj->otyp].oc_name_known) {
340 objects[obj->otyp].oc_name_known = 1;
341 more_experienced(0, 10);
344 return (1);
347 const char *
348 exclam(int force)
350 /* force == 0 occurs e.g. with sleep ray */
352 * note that large force is usual with wands so that !! would require
353 * information about hand/weapon/wand
355 return ((force < 0) ? "?" : (force <= 4) ? "." : "!");
358 void
359 hit(const char *str, struct monst *mtmp, const char *force)
361 /* force is usually either "." or "!" */
363 if (!cansee(mtmp->mx, mtmp->my))
364 pline("The %s hits it.", str);
365 else
366 pline("The %s hits %s%s", str, monnam(mtmp), force);
369 void
370 miss(const char *str, struct monst *mtmp)
372 if (!cansee(mtmp->mx, mtmp->my))
373 pline("The %s misses it.", str);
374 else
375 pline("The %s misses %s.", str, monnam(mtmp));
379 * bhit: called when a weapon is thrown (sym = obj->olet) or when an
380 * IMMEDIATE wand is zapped (sym = 0); the weapon falls down at end of range
381 * or when a monster is hit; the monster is returned, and bhitpos is set to
382 * the final position of the weapon thrown; the ray of a wand may affect
383 * several objects and monsters on its path - for each of these an argument
384 * function is called.
386 /* check !u.uswallow before calling bhit() */
388 struct monst *
389 bhit(int ddx, int ddy, int range, /* direction and range */
390 int sym, /* symbol displayed on path */
391 /* fns called when mon/obj hit */
392 void (*fhitm)(struct monst *, struct obj *),
393 int (*fhito)(struct obj *, struct obj *),
394 struct obj *obj) /* 2nd arg to fhitm/fhito */
396 struct monst *mtmp;
397 struct obj *otmp;
398 int typ;
400 bhitpos.x = u.ux;
401 bhitpos.y = u.uy;
403 if (sym)
404 tmp_at(-1, sym);/* open call */
405 while (range-- > 0) {
406 bhitpos.x += ddx;
407 bhitpos.y += ddy;
408 typ = levl[bhitpos.x][bhitpos.y].typ;
409 if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != NULL) {
410 if (sym) {
411 tmp_at(-1, -1); /* close call */
412 return (mtmp);
414 (*fhitm) (mtmp, obj);
415 range -= 3;
417 if (fhito && (otmp = o_at(bhitpos.x, bhitpos.y))) {
418 if ((*fhito) (otmp, obj))
419 range--;
421 if (!ZAP_POS(typ)) {
422 bhitpos.x -= ddx;
423 bhitpos.y -= ddy;
424 break;
426 if (sym)
427 tmp_at(bhitpos.x, bhitpos.y);
430 /* leave last symbol unless in a pool */
431 if (sym)
432 tmp_at(-1, (levl[bhitpos.x][bhitpos.y].typ == POOL) ? -1 : 0);
433 return (0);
436 struct monst *
437 boomhit(int dx, int dy)
439 int i, ct;
440 struct monst *mtmp;
441 char sym = ')';
443 bhitpos.x = u.ux;
444 bhitpos.y = u.uy;
446 for (i = 0; i < 8; i++)
447 if (xdir[i] == dx && ydir[i] == dy)
448 break;
449 tmp_at(-1, sym); /* open call */
450 for (ct = 0; ct < 10; ct++) {
451 if (i == 8)
452 i = 0;
453 sym = ')' + '(' - sym;
454 tmp_at(-2, sym);/* change let call */
455 dx = xdir[i];
456 dy = ydir[i];
457 bhitpos.x += dx;
458 bhitpos.y += dy;
459 if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != NULL) {
460 tmp_at(-1, -1);
461 return (mtmp);
463 if (!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ)) {
464 bhitpos.x -= dx;
465 bhitpos.y -= dy;
466 break;
468 if (bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */
469 if (rn2(20) >= 10 + u.ulevel) { /* we hit ourselves */
470 (void) thitu(10, rnd(10), "boomerang");
471 break;
472 } else {/* we catch it */
473 tmp_at(-1, -1);
474 pline("Skillfully, you catch the boomerang.");
475 return (&youmonst);
478 tmp_at(bhitpos.x, bhitpos.y);
479 if (ct % 5 != 0)
480 i++;
482 tmp_at(-1, -1); /* do not leave last symbol */
483 return (0);
486 static char
487 dirlet(int dx, int dy)
489 return
490 (dx == dy) ? '\\' : (dx && dy) ? '/' : dx ? '-' : '|';
493 /* type == -1: monster spitting fire at you */
494 /* type == -1,-2,-3: bolts sent out by wizard */
495 /* called with dx = dy = 0 with vertical bolts */
496 void
497 buzz(int type, xchar sx, xchar sy, int dx, int dy)
499 int abstype = abs(type);
500 const char *fltxt = (type == -1) ? "blaze of fire" : fl[abstype];
501 struct rm *lev;
502 xchar range;
503 struct monst *mon;
505 if (u.uswallow) {
506 int tmp;
508 if (type < 0)
509 return;
510 tmp = zhit(u.ustuck, type);
511 pline("The %s rips into %s%s",
512 fltxt, monnam(u.ustuck), exclam(tmp));
513 return;
515 if (type < 0)
516 pru();
517 range = rn1(7, 7);
518 Tmp_at(-1, dirlet(dx, dy)); /* open call */
519 while (range-- > 0) {
520 sx += dx;
521 sy += dy;
522 if ((lev = &levl[sx][sy])->typ)
523 Tmp_at(sx, sy);
524 else {
525 int bounce = 0;
526 if (cansee(sx - dx, sy - dy))
527 pline("The %s bounces!", fltxt);
528 if (ZAP_POS(levl[sx][sy - dy].typ))
529 bounce = 1;
530 if (ZAP_POS(levl[sx - dx][sy].typ)) {
531 if (!bounce || rn2(2))
532 bounce = 2;
534 switch (bounce) {
535 case 0:
536 dx = -dx;
537 dy = -dy;
538 continue;
539 case 1:
540 dy = -dy;
541 sx -= dx;
542 break;
543 case 2:
544 dx = -dx;
545 sy -= dy;
546 break;
548 Tmp_at(-2, dirlet(dx, dy));
549 continue;
551 if (lev->typ == POOL && abstype == 1 /* fire */ ) {
552 range -= 3;
553 lev->typ = ROOM;
554 if (cansee(sx, sy)) {
555 mnewsym(sx, sy);
556 pline("The water evaporates.");
557 } else
558 pline("You hear a hissing sound.");
560 if ((mon = m_at(sx, sy)) &&
561 (type != -1 || mon->data->mlet != 'D')) {
562 wakeup(mon);
563 if (rnd(20) < 18 + mon->data->ac) {
564 int tmp = zhit(mon, abstype);
565 if (mon->mhp < 1) {
566 if (type < 0) {
567 if (cansee(mon->mx, mon->my))
568 pline("%s is killed by the %s!",
569 Monnam(mon), fltxt);
570 mondied(mon);
571 } else
572 killed(mon);
573 } else
574 hit(fltxt, mon, exclam(tmp));
575 range -= 2;
576 } else
577 miss(fltxt, mon);
578 } else if (sx == u.ux && sy == u.uy) {
579 nomul(0);
580 if (rnd(20) < 18 + u.uac) {
581 int dam = 0;
582 range -= 2;
583 pline("The %s hits you!", fltxt);
584 switch (abstype) {
585 case 0:
586 dam = d(2, 6);
587 break;
588 case 1:
589 if (Fire_resistance)
590 pline("You don't feel hot!");
591 else
592 dam = d(6, 6);
593 if (!rn2(3))
594 burn_scrolls();
595 break;
596 case 2:
597 nomul(-rnd(25)); /* sleep ray */
598 break;
599 case 3:
600 if (Cold_resistance)
601 pline("You don't feel cold!");
602 else
603 dam = d(6, 6);
604 break;
605 case 4:
606 u.uhp = -1;
608 losehp(dam, fltxt);
609 } else
610 pline("The %s whizzes by you!", fltxt);
611 stop_occupation();
613 if (!ZAP_POS(lev->typ)) {
614 int bounce = 0, rmn;
615 if (cansee(sx, sy))
616 pline("The %s bounces!", fltxt);
617 range--;
618 if (!dx || !dy || !rn2(20)) {
619 dx = -dx;
620 dy = -dy;
621 } else {
622 if (ZAP_POS(rmn = levl[sx][sy - dy].typ) &&
623 (IS_ROOM(rmn) || ZAP_POS(levl[sx + dx][sy - dy].typ)))
624 bounce = 1;
625 if (ZAP_POS(rmn = levl[sx - dx][sy].typ) &&
626 (IS_ROOM(rmn) || ZAP_POS(levl[sx - dx][sy + dy].typ)))
627 if (!bounce || rn2(2))
628 bounce = 2;
630 switch (bounce) {
631 case 0:
632 dy = -dy;
633 dx = -dx;
634 break;
635 case 1:
636 dy = -dy;
637 break;
638 case 2:
639 dx = -dx;
640 break;
642 Tmp_at(-2, dirlet(dx, dy));
646 Tmp_at(-1, -1);
649 static int
650 zhit(struct monst *mon, int type) /* returns damage to mon */
652 int tmp = 0;
654 switch (type) {
655 case 0: /* magic missile */
656 tmp = d(2, 6);
657 break;
658 case -1: /* Dragon blazing fire */
659 case 1: /* fire */
660 if (strchr("Dg", mon->data->mlet))
661 break;
662 tmp = d(6, 6);
663 if (strchr("YF", mon->data->mlet))
664 tmp += 7;
665 break;
666 case 2: /* sleep */
667 mon->mfroz = 1;
668 break;
669 case 3: /* cold */
670 if (strchr("YFgf", mon->data->mlet))
671 break;
672 tmp = d(6, 6);
673 if (mon->data->mlet == 'D')
674 tmp += 7;
675 break;
676 case 4: /* death */
677 if (strchr(UNDEAD, mon->data->mlet))
678 break;
679 tmp = mon->mhp + 1;
680 break;
682 mon->mhp -= tmp;
683 return (tmp);
686 #define CORPSE_I_TO_C(otyp) (char) ((otyp >= DEAD_ACID_BLOB)\
687 ? 'a' + (otyp - DEAD_ACID_BLOB)\
688 : '@' + (otyp - DEAD_HUMAN))
689 static int
690 revive(struct obj *obj)
692 struct monst *mtmp = NULL;
694 if (obj->olet == FOOD_SYM && obj->otyp > CORPSE) {
695 /* do not (yet) revive shopkeepers */
697 * Note: this might conceivably produce two monsters at the
698 * same position - strange, but harmless
700 mtmp = mkmon_at(CORPSE_I_TO_C(obj->otyp), obj->ox, obj->oy);
701 delobj(obj);
703 return (!!mtmp); /* TRUE if some monster created */
706 static void
707 rloco(struct obj *obj)
709 int tx, ty, otx, oty;
711 otx = obj->ox;
712 oty = obj->oy;
713 do {
714 tx = rn1(COLNO - 3, 2);
715 ty = rn2(ROWNO);
716 } while (!goodpos(tx, ty));
717 obj->ox = tx;
718 obj->oy = ty;
719 if (cansee(otx, oty))
720 newsym(otx, oty);
723 /* fractured by pick-axe or wand of striking */
724 /* no texts here! */
725 void
726 fracture_rock(struct obj *obj)
728 /* unpobj(obj); */
729 obj->otyp = ROCK;
730 obj->quan = 7 + rn2(60);
731 obj->owt = weight(obj);
732 obj->olet = WEAPON_SYM;
733 if (cansee(obj->ox, obj->oy))
734 prl(obj->ox, obj->oy);
737 static void
738 burn_scrolls(void)
740 struct obj *obj, *obj2;
741 int cnt = 0;
743 for (obj = invent; obj; obj = obj2) {
744 obj2 = obj->nobj;
745 if (obj->olet == SCROLL_SYM) {
746 cnt++;
747 useup(obj);
750 if (cnt > 1) {
751 pline("Your scrolls catch fire!");
752 losehp(cnt, "burning scrolls");
753 } else if (cnt) {
754 pline("Your scroll catches fire!");
755 losehp(1, "burning scroll");