]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.zap.c
ANSIfy function declarations. All object file diffs inspected.
[bsdgames-darwin.git] / hack / hack.zap.c
1 /* $NetBSD: hack.zap.c,v 1.8 2009/06/07 18:30:39 dholland Exp $ */
2
3 /*
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 * Amsterdam
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
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.
18 *
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.
23 *
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.
35 */
36
37 /*
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
40 *
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.
51 *
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.
62 */
63
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 */
68
69 #include "hack.h"
70 #include "extern.h"
71
72 const char *const fl[] = {
73 "magic missile",
74 "bolt of fire",
75 "sleep ray",
76 "bolt of cold",
77 "death ray"
78 };
79
80 /* Routines for IMMEDIATE wands. */
81 /* bhitm: monster mtmp was hit by the effect of wand otmp */
82 void
83 bhitm(struct monst *mtmp, struct obj *otmp)
84 {
85 wakeup(mtmp);
86 switch (otmp->otyp) {
87 case WAN_STRIKING:
88 if (u.uswallow || rnd(20) < 10 + mtmp->data->ac) {
89 int tmp = d(2, 12);
90 hit("wand", mtmp, exclam(tmp));
91 mtmp->mhp -= tmp;
92 if (mtmp->mhp < 1)
93 killed(mtmp);
94 } else
95 miss("wand", mtmp);
96 break;
97 case WAN_SLOW_MONSTER:
98 mtmp->mspeed = MSLOW;
99 break;
100 case WAN_SPEED_MONSTER:
101 mtmp->mspeed = MFAST;
102 break;
103 case WAN_UNDEAD_TURNING:
104 if (strchr(UNDEAD, mtmp->data->mlet)) {
105 mtmp->mhp -= rnd(8);
106 if (mtmp->mhp < 1)
107 killed(mtmp);
108 else
109 mtmp->mflee = 1;
110 }
111 break;
112 case WAN_POLYMORPH:
113 if (newcham(mtmp, &mons[rn2(CMNUM)]))
114 objects[otmp->otyp].oc_name_known = 1;
115 break;
116 case WAN_CANCELLATION:
117 mtmp->mcan = 1;
118 break;
119 case WAN_TELEPORTATION:
120 rloc(mtmp);
121 break;
122 case WAN_MAKE_INVISIBLE:
123 mtmp->minvis = 1;
124 break;
125 #ifdef WAN_PROBING
126 case WAN_PROBING:
127 mstatusline(mtmp);
128 break;
129 #endif /* WAN_PROBING */
130 default:
131 impossible("What an interesting wand (%u)", otmp->otyp);
132 }
133 }
134
135 /*
136 * object obj was hit by the effect of wand otmp
137 * returns TRUE if sth was done
138 */
139 int
140 bhito(struct obj *obj, struct obj *otmp)
141 {
142 int res = TRUE;
143
144 if (obj == uball || obj == uchain)
145 res = FALSE;
146 else
147 switch (otmp->otyp) {
148 case WAN_POLYMORPH:
149 /*
150 * preserve symbol and quantity, but turn rocks into
151 * gems
152 */
153 mkobj_at((obj->otyp == ROCK || obj->otyp == ENORMOUS_ROCK)
154 ? GEM_SYM : obj->olet,
155 obj->ox, obj->oy)->quan = obj->quan;
156 delobj(obj);
157 break;
158 case WAN_STRIKING:
159 if (obj->otyp == ENORMOUS_ROCK)
160 fracture_rock(obj);
161 else
162 res = FALSE;
163 break;
164 case WAN_CANCELLATION:
165 if (obj->spe && obj->olet != AMULET_SYM) {
166 obj->known = 0;
167 obj->spe = 0;
168 }
169 break;
170 case WAN_TELEPORTATION:
171 rloco(obj);
172 break;
173 case WAN_MAKE_INVISIBLE:
174 obj->oinvis = 1;
175 break;
176 case WAN_UNDEAD_TURNING:
177 res = revive(obj);
178 break;
179 case WAN_SLOW_MONSTER: /* no effect on objects */
180 case WAN_SPEED_MONSTER:
181 #ifdef WAN_PROBING
182 case WAN_PROBING:
183 #endif /* WAN_PROBING */
184 res = FALSE;
185 break;
186 default:
187 impossible("What an interesting wand (%u)", otmp->otyp);
188 }
189 return (res);
190 }
191
192 int
193 dozap(void)
194 {
195 struct obj *obj;
196 xchar zx, zy;
197
198 obj = getobj("/", "zap");
199 if (!obj)
200 return (0);
201 if (obj->spe < 0 || (obj->spe == 0 && rn2(121))) {
202 pline("Nothing Happens.");
203 return (1);
204 }
205 if (obj->spe == 0)
206 pline("You wrest one more spell from the worn-out wand.");
207 if (!(objects[obj->otyp].bits & NODIR) && !getdir(1))
208 return (1); /* make him pay for knowing !NODIR */
209 obj->spe--;
210 if (objects[obj->otyp].bits & IMMEDIATE) {
211 if (u.uswallow)
212 bhitm(u.ustuck, obj);
213 else if (u.dz) {
214 if (u.dz > 0) {
215 struct obj *otmp = o_at(u.ux, u.uy);
216 if (otmp)
217 (void) bhito(otmp, obj);
218 }
219 } else
220 (void) bhit(u.dx, u.dy, rn1(8, 6), 0, bhitm, bhito, obj);
221 } else {
222 switch (obj->otyp) {
223 case WAN_LIGHT:
224 litroom(TRUE);
225 break;
226 case WAN_SECRET_DOOR_DETECTION:
227 if (!findit())
228 return (1);
229 break;
230 case WAN_CREATE_MONSTER:
231 {
232 int cnt = 1;
233 if (!rn2(23))
234 cnt += rn2(7) + 1;
235 while (cnt--)
236 (void) makemon((struct permonst *) 0, u.ux, u.uy);
237 }
238 break;
239 case WAN_WISHING:
240 {
241 char buf[BUFSZ];
242 struct obj *otmp;
243 if (u.uluck + rn2(5) < 0) {
244 pline("Unfortunately, nothing happens.");
245 break;
246 }
247 pline("You may wish for an object. What do you want? ");
248 getlin(buf);
249 if (buf[0] == '\033')
250 buf[0] = 0;
251 otmp = readobjnam(buf);
252 otmp = addinv(otmp);
253 prinv(otmp);
254 break;
255 }
256 case WAN_DIGGING:
257 /*
258 * Original effect (approximately): from CORR: dig
259 * until we pierce a wall from ROOM: piece wall and
260 * dig until we reach an ACCESSIBLE place. Currently:
261 * dig for digdepth positions; also down on request
262 * of Lennart Augustsson.
263 */
264 {
265 struct rm *room;
266 int digdepth;
267 if (u.uswallow) {
268 struct monst *mtmp = u.ustuck;
269
270 pline("You pierce %s's stomach wall!",
271 monnam(mtmp));
272 mtmp->mhp = 1; /* almost dead */
273 unstuck(mtmp);
274 mnexto(mtmp);
275 break;
276 }
277 if (u.dz) {
278 if (u.dz < 0) {
279 pline("You loosen a rock from the ceiling.");
280 pline("It falls on your head!");
281 losehp(1, "falling rock");
282 mksobj_at(ROCK, u.ux, u.uy);
283 fobj->quan = 1;
284 stackobj(fobj);
285 if (Invisible)
286 newsym(u.ux, u.uy);
287 } else {
288 dighole();
289 }
290 break;
291 }
292 zx = u.ux + u.dx;
293 zy = u.uy + u.dy;
294 digdepth = 8 + rn2(18);
295 Tmp_at(-1, '*'); /* open call */
296 while (--digdepth >= 0) {
297 if (!isok(zx, zy))
298 break;
299 room = &levl[zx][zy];
300 Tmp_at(zx, zy);
301 if (!xdnstair) {
302 if (zx < 3 || zx > COLNO - 3 ||
303 zy < 3 || zy > ROWNO - 3)
304 break;
305 if (room->typ == HWALL ||
306 room->typ == VWALL) {
307 room->typ = ROOM;
308 break;
309 }
310 } else if (room->typ == HWALL || room->typ == VWALL ||
311 room->typ == SDOOR || room->typ == LDOOR) {
312 room->typ = DOOR;
313 digdepth -= 2;
314 } else if (room->typ == SCORR || !room->typ) {
315 room->typ = CORR;
316 digdepth--;
317 }
318 mnewsym(zx, zy);
319 zx += u.dx;
320 zy += u.dy;
321 }
322 mnewsym(zx, zy); /* not always necessary */
323 Tmp_at(-1, -1); /* closing call */
324 break;
325 }
326 default:
327 buzz((int) obj->otyp - WAN_MAGIC_MISSILE,
328 u.ux, u.uy, u.dx, u.dy);
329 break;
330 }
331 if (!objects[obj->otyp].oc_name_known) {
332 objects[obj->otyp].oc_name_known = 1;
333 more_experienced(0, 10);
334 }
335 }
336 return (1);
337 }
338
339 const char *
340 exclam(int force)
341 {
342 /* force == 0 occurs e.g. with sleep ray */
343 /*
344 * note that large force is usual with wands so that !! would require
345 * information about hand/weapon/wand
346 */
347 return ((force < 0) ? "?" : (force <= 4) ? "." : "!");
348 }
349
350 void
351 hit(const char *str, struct monst *mtmp, const char *force)
352 {
353 /* force is usually either "." or "!" */
354
355 if (!cansee(mtmp->mx, mtmp->my))
356 pline("The %s hits it.", str);
357 else
358 pline("The %s hits %s%s", str, monnam(mtmp), force);
359 }
360
361 void
362 miss(const char *str, struct monst *mtmp)
363 {
364 if (!cansee(mtmp->mx, mtmp->my))
365 pline("The %s misses it.", str);
366 else
367 pline("The %s misses %s.", str, monnam(mtmp));
368 }
369
370 /*
371 * bhit: called when a weapon is thrown (sym = obj->olet) or when an
372 * IMMEDIATE wand is zapped (sym = 0); the weapon falls down at end of range
373 * or when a monster is hit; the monster is returned, and bhitpos is set to
374 * the final position of the weapon thrown; the ray of a wand may affect
375 * several objects and monsters on its path - for each of these an argument
376 * function is called.
377 */
378 /* check !u.uswallow before calling bhit() */
379
380 struct monst *
381 bhit(int ddx, int ddy, int range, /* direction and range */
382 int sym, /* symbol displayed on path */
383 /* fns called when mon/obj hit */
384 void (*fhitm)(struct monst *, struct obj *),
385 int (*fhito)(struct obj *, struct obj *),
386 struct obj *obj) /* 2nd arg to fhitm/fhito */
387 {
388 struct monst *mtmp;
389 struct obj *otmp;
390 int typ;
391
392 bhitpos.x = u.ux;
393 bhitpos.y = u.uy;
394
395 if (sym)
396 tmp_at(-1, sym);/* open call */
397 while (range-- > 0) {
398 bhitpos.x += ddx;
399 bhitpos.y += ddy;
400 typ = levl[bhitpos.x][bhitpos.y].typ;
401 if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != NULL) {
402 if (sym) {
403 tmp_at(-1, -1); /* close call */
404 return (mtmp);
405 }
406 (*fhitm) (mtmp, obj);
407 range -= 3;
408 }
409 if (fhito && (otmp = o_at(bhitpos.x, bhitpos.y))) {
410 if ((*fhito) (otmp, obj))
411 range--;
412 }
413 if (!ZAP_POS(typ)) {
414 bhitpos.x -= ddx;
415 bhitpos.y -= ddy;
416 break;
417 }
418 if (sym)
419 tmp_at(bhitpos.x, bhitpos.y);
420 }
421
422 /* leave last symbol unless in a pool */
423 if (sym)
424 tmp_at(-1, (levl[bhitpos.x][bhitpos.y].typ == POOL) ? -1 : 0);
425 return (0);
426 }
427
428 struct monst *
429 boomhit(int dx, int dy)
430 {
431 int i, ct;
432 struct monst *mtmp;
433 char sym = ')';
434
435 bhitpos.x = u.ux;
436 bhitpos.y = u.uy;
437
438 for (i = 0; i < 8; i++)
439 if (xdir[i] == dx && ydir[i] == dy)
440 break;
441 tmp_at(-1, sym); /* open call */
442 for (ct = 0; ct < 10; ct++) {
443 if (i == 8)
444 i = 0;
445 sym = ')' + '(' - sym;
446 tmp_at(-2, sym);/* change let call */
447 dx = xdir[i];
448 dy = ydir[i];
449 bhitpos.x += dx;
450 bhitpos.y += dy;
451 if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != NULL) {
452 tmp_at(-1, -1);
453 return (mtmp);
454 }
455 if (!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ)) {
456 bhitpos.x -= dx;
457 bhitpos.y -= dy;
458 break;
459 }
460 if (bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */
461 if (rn2(20) >= 10 + u.ulevel) { /* we hit ourselves */
462 (void) thitu(10, rnd(10), "boomerang");
463 break;
464 } else {/* we catch it */
465 tmp_at(-1, -1);
466 pline("Skillfully, you catch the boomerang.");
467 return (&youmonst);
468 }
469 }
470 tmp_at(bhitpos.x, bhitpos.y);
471 if (ct % 5 != 0)
472 i++;
473 }
474 tmp_at(-1, -1); /* do not leave last symbol */
475 return (0);
476 }
477
478 char
479 dirlet(int dx, int dy)
480 {
481 return
482 (dx == dy) ? '\\' : (dx && dy) ? '/' : dx ? '-' : '|';
483 }
484
485 /* type == -1: monster spitting fire at you */
486 /* type == -1,-2,-3: bolts sent out by wizard */
487 /* called with dx = dy = 0 with vertical bolts */
488 void
489 buzz(int type, xchar sx, xchar sy, int dx, int dy)
490 {
491 int abstype = abs(type);
492 const char *fltxt = (type == -1) ? "blaze of fire" : fl[abstype];
493 struct rm *lev;
494 xchar range;
495 struct monst *mon;
496
497 if (u.uswallow) {
498 int tmp;
499
500 if (type < 0)
501 return;
502 tmp = zhit(u.ustuck, type);
503 pline("The %s rips into %s%s",
504 fltxt, monnam(u.ustuck), exclam(tmp));
505 return;
506 }
507 if (type < 0)
508 pru();
509 range = rn1(7, 7);
510 Tmp_at(-1, dirlet(dx, dy)); /* open call */
511 while (range-- > 0) {
512 sx += dx;
513 sy += dy;
514 if ((lev = &levl[sx][sy])->typ)
515 Tmp_at(sx, sy);
516 else {
517 int bounce = 0;
518 if (cansee(sx - dx, sy - dy))
519 pline("The %s bounces!", fltxt);
520 if (ZAP_POS(levl[sx][sy - dy].typ))
521 bounce = 1;
522 if (ZAP_POS(levl[sx - dx][sy].typ)) {
523 if (!bounce || rn2(2))
524 bounce = 2;
525 }
526 switch (bounce) {
527 case 0:
528 dx = -dx;
529 dy = -dy;
530 continue;
531 case 1:
532 dy = -dy;
533 sx -= dx;
534 break;
535 case 2:
536 dx = -dx;
537 sy -= dy;
538 break;
539 }
540 Tmp_at(-2, dirlet(dx, dy));
541 continue;
542 }
543 if (lev->typ == POOL && abstype == 1 /* fire */ ) {
544 range -= 3;
545 lev->typ = ROOM;
546 if (cansee(sx, sy)) {
547 mnewsym(sx, sy);
548 pline("The water evaporates.");
549 } else
550 pline("You hear a hissing sound.");
551 }
552 if ((mon = m_at(sx, sy)) &&
553 (type != -1 || mon->data->mlet != 'D')) {
554 wakeup(mon);
555 if (rnd(20) < 18 + mon->data->ac) {
556 int tmp = zhit(mon, abstype);
557 if (mon->mhp < 1) {
558 if (type < 0) {
559 if (cansee(mon->mx, mon->my))
560 pline("%s is killed by the %s!",
561 Monnam(mon), fltxt);
562 mondied(mon);
563 } else
564 killed(mon);
565 } else
566 hit(fltxt, mon, exclam(tmp));
567 range -= 2;
568 } else
569 miss(fltxt, mon);
570 } else if (sx == u.ux && sy == u.uy) {
571 nomul(0);
572 if (rnd(20) < 18 + u.uac) {
573 int dam = 0;
574 range -= 2;
575 pline("The %s hits you!", fltxt);
576 switch (abstype) {
577 case 0:
578 dam = d(2, 6);
579 break;
580 case 1:
581 if (Fire_resistance)
582 pline("You don't feel hot!");
583 else
584 dam = d(6, 6);
585 if (!rn2(3))
586 burn_scrolls();
587 break;
588 case 2:
589 nomul(-rnd(25)); /* sleep ray */
590 break;
591 case 3:
592 if (Cold_resistance)
593 pline("You don't feel cold!");
594 else
595 dam = d(6, 6);
596 break;
597 case 4:
598 u.uhp = -1;
599 }
600 losehp(dam, fltxt);
601 } else
602 pline("The %s whizzes by you!", fltxt);
603 stop_occupation();
604 }
605 if (!ZAP_POS(lev->typ)) {
606 int bounce = 0, rmn;
607 if (cansee(sx, sy))
608 pline("The %s bounces!", fltxt);
609 range--;
610 if (!dx || !dy || !rn2(20)) {
611 dx = -dx;
612 dy = -dy;
613 } else {
614 if (ZAP_POS(rmn = levl[sx][sy - dy].typ) &&
615 (IS_ROOM(rmn) || ZAP_POS(levl[sx + dx][sy - dy].typ)))
616 bounce = 1;
617 if (ZAP_POS(rmn = levl[sx - dx][sy].typ) &&
618 (IS_ROOM(rmn) || ZAP_POS(levl[sx - dx][sy + dy].typ)))
619 if (!bounce || rn2(2))
620 bounce = 2;
621
622 switch (bounce) {
623 case 0:
624 dy = -dy;
625 dx = -dx;
626 break;
627 case 1:
628 dy = -dy;
629 break;
630 case 2:
631 dx = -dx;
632 break;
633 }
634 Tmp_at(-2, dirlet(dx, dy));
635 }
636 }
637 }
638 Tmp_at(-1, -1);
639 }
640
641 int
642 zhit(struct monst *mon, int type) /* returns damage to mon */
643 {
644 int tmp = 0;
645
646 switch (type) {
647 case 0: /* magic missile */
648 tmp = d(2, 6);
649 break;
650 case -1: /* Dragon blazing fire */
651 case 1: /* fire */
652 if (strchr("Dg", mon->data->mlet))
653 break;
654 tmp = d(6, 6);
655 if (strchr("YF", mon->data->mlet))
656 tmp += 7;
657 break;
658 case 2: /* sleep */
659 mon->mfroz = 1;
660 break;
661 case 3: /* cold */
662 if (strchr("YFgf", mon->data->mlet))
663 break;
664 tmp = d(6, 6);
665 if (mon->data->mlet == 'D')
666 tmp += 7;
667 break;
668 case 4: /* death */
669 if (strchr(UNDEAD, mon->data->mlet))
670 break;
671 tmp = mon->mhp + 1;
672 break;
673 }
674 mon->mhp -= tmp;
675 return (tmp);
676 }
677
678 #define CORPSE_I_TO_C(otyp) (char) ((otyp >= DEAD_ACID_BLOB)\
679 ? 'a' + (otyp - DEAD_ACID_BLOB)\
680 : '@' + (otyp - DEAD_HUMAN))
681 int
682 revive(struct obj *obj)
683 {
684 struct monst *mtmp = NULL;
685
686 if (obj->olet == FOOD_SYM && obj->otyp > CORPSE) {
687 /* do not (yet) revive shopkeepers */
688 /*
689 * Note: this might conceivably produce two monsters at the
690 * same position - strange, but harmless
691 */
692 mtmp = mkmon_at(CORPSE_I_TO_C(obj->otyp), obj->ox, obj->oy);
693 delobj(obj);
694 }
695 return (!!mtmp); /* TRUE if some monster created */
696 }
697
698 void
699 rloco(struct obj *obj)
700 {
701 int tx, ty, otx, oty;
702
703 otx = obj->ox;
704 oty = obj->oy;
705 do {
706 tx = rn1(COLNO - 3, 2);
707 ty = rn2(ROWNO);
708 } while (!goodpos(tx, ty));
709 obj->ox = tx;
710 obj->oy = ty;
711 if (cansee(otx, oty))
712 newsym(otx, oty);
713 }
714
715 /* fractured by pick-axe or wand of striking */
716 /* no texts here! */
717 void
718 fracture_rock(struct obj *obj)
719 {
720 /* unpobj(obj); */
721 obj->otyp = ROCK;
722 obj->quan = 7 + rn2(60);
723 obj->owt = weight(obj);
724 obj->olet = WEAPON_SYM;
725 if (cansee(obj->ox, obj->oy))
726 prl(obj->ox, obj->oy);
727 }
728
729 void
730 burn_scrolls(void)
731 {
732 struct obj *obj, *obj2;
733 int cnt = 0;
734
735 for (obj = invent; obj; obj = obj2) {
736 obj2 = obj->nobj;
737 if (obj->olet == SCROLL_SYM) {
738 cnt++;
739 useup(obj);
740 }
741 }
742 if (cnt > 1) {
743 pline("Your scrolls catch fire!");
744 losehp(cnt, "burning scrolls");
745 } else if (cnt) {
746 pline("Your scroll catches fire!");
747 losehp(1, "burning scroll");
748 }
749 }