1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64: #include <sys/cdefs.h>
65: #ifndef lint
66: __RCSID("$NetBSD: hack.zap.c,v 1.7 2004/01/27 20:30:29 jsm Exp $");
67: #endif
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:
81:
82: void
83: bhitm(mtmp, otmp)
84: struct monst *mtmp;
85: struct obj *otmp;
86: {
87: wakeup(mtmp);
88: switch (otmp->otyp) {
89: case WAN_STRIKING:
90: if (u.uswallow || rnd(20) < 10 + mtmp->data->ac) {
91: int tmp = d(2, 12);
92: hit("wand", mtmp, exclam(tmp));
93: mtmp->mhp -= tmp;
94: if (mtmp->mhp < 1)
95: killed(mtmp);
96: } else
97: miss("wand", mtmp);
98: break;
99: case WAN_SLOW_MONSTER:
100: mtmp->mspeed = MSLOW;
101: break;
102: case WAN_SPEED_MONSTER:
103: mtmp->mspeed = MFAST;
104: break;
105: case WAN_UNDEAD_TURNING:
106: if (strchr(UNDEAD, mtmp->data->mlet)) {
107: mtmp->mhp -= rnd(8);
108: if (mtmp->mhp < 1)
109: killed(mtmp);
110: else
111: mtmp->mflee = 1;
112: }
113: break;
114: case WAN_POLYMORPH:
115: if (newcham(mtmp, &mons[rn2(CMNUM)]))
116: objects[otmp->otyp].oc_name_known = 1;
117: break;
118: case WAN_CANCELLATION:
119: mtmp->mcan = 1;
120: break;
121: case WAN_TELEPORTATION:
122: rloc(mtmp);
123: break;
124: case WAN_MAKE_INVISIBLE:
125: mtmp->minvis = 1;
126: break;
127: #ifdef WAN_PROBING
128: case WAN_PROBING:
129: mstatusline(mtmp);
130: break;
131: #endif
132: default:
133: impossible("What an interesting wand (%u)", otmp->otyp);
134: }
135: }
136:
137: int
138: bhito(obj, otmp)
139:
140: struct obj *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:
151:
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:
180: case WAN_SPEED_MONSTER:
181: #ifdef WAN_PROBING
182: case WAN_PROBING:
183: #endif
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()
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);
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:
259:
260:
261:
262:
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;
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, '*');
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);
323: Tmp_at(-1, -1);
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(force)
341: int force;
342: {
343:
344:
345:
346:
347:
348: return ((force < 0) ? "?" : (force <= 4) ? "." : "!");
349: }
350:
351: void
352: hit(str, mtmp, force)
353: const char *str;
354: struct monst *mtmp;
355: const char *force;
356: {
357: if (!cansee(mtmp->mx, mtmp->my))
358: pline("The %s hits it.", str);
359: else
360: pline("The %s hits %s%s", str, monnam(mtmp), force);
361: }
362:
363: void
364: miss(str, mtmp)
365: const char *str;
366: struct monst *mtmp;
367: {
368: if (!cansee(mtmp->mx, mtmp->my))
369: pline("The %s misses it.", str);
370: else
371: pline("The %s misses %s.", str, monnam(mtmp));
372: }
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384: struct monst *
385: bhit(ddx, ddy, range, sym, fhitm, fhito, obj)
386: int ddx, ddy, range;
387: char sym;
388:
389: void (*fhitm)(struct monst *, struct obj *);
390: int (*fhito)(struct obj *, struct obj *);
391: struct obj *obj;
392: {
393: struct monst *mtmp;
394: struct obj *otmp;
395: int typ;
396:
397: bhitpos.x = u.ux;
398: bhitpos.y = u.uy;
399:
400: if (sym)
401: tmp_at(-1, sym);
402: while (range-- > 0) {
403: bhitpos.x += ddx;
404: bhitpos.y += ddy;
405: typ = levl[bhitpos.x][bhitpos.y].typ;
406: if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != NULL) {
407: if (sym) {
408: tmp_at(-1, -1);
409: return (mtmp);
410: }
411: (*fhitm) (mtmp, obj);
412: range -= 3;
413: }
414: if (fhito && (otmp = o_at(bhitpos.x, bhitpos.y))) {
415: if ((*fhito) (otmp, obj))
416: range--;
417: }
418: if (!ZAP_POS(typ)) {
419: bhitpos.x -= ddx;
420: bhitpos.y -= ddy;
421: break;
422: }
423: if (sym)
424: tmp_at(bhitpos.x, bhitpos.y);
425: }
426:
427:
428: if (sym)
429: tmp_at(-1, (levl[bhitpos.x][bhitpos.y].typ == POOL) ? -1 : 0);
430: return (0);
431: }
432:
433: struct monst *
434: boomhit(int dx, int dy)
435: {
436: int i, ct;
437: struct monst *mtmp;
438: char sym = ')';
439:
440: bhitpos.x = u.ux;
441: bhitpos.y = u.uy;
442:
443: for (i = 0; i < 8; i++)
444: if (xdir[i] == dx && ydir[i] == dy)
445: break;
446: tmp_at(-1, sym);
447: for (ct = 0; ct < 10; ct++) {
448: if (i == 8)
449: i = 0;
450: sym = ')' + '(' - sym;
451: tmp_at(-2, sym);
452: dx = xdir[i];
453: dy = ydir[i];
454: bhitpos.x += dx;
455: bhitpos.y += dy;
456: if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != NULL) {
457: tmp_at(-1, -1);
458: return (mtmp);
459: }
460: if (!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ)) {
461: bhitpos.x -= dx;
462: bhitpos.y -= dy;
463: break;
464: }
465: if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
466: if (rn2(20) >= 10 + u.ulevel) {
467: (void) thitu(10, rnd(10), "boomerang");
468: break;
469: } else {
470: tmp_at(-1, -1);
471: pline("Skillfully, you catch the boomerang.");
472: return (&youmonst);
473: }
474: }
475: tmp_at(bhitpos.x, bhitpos.y);
476: if (ct % 5 != 0)
477: i++;
478: }
479: tmp_at(-1, -1);
480: return (0);
481: }
482:
483: char
484: dirlet(dx, dy)
485: int dx, dy;
486: {
487: return
488: (dx == dy) ? '\\' : (dx && dy) ? '/' : dx ? '-' : '|';
489: }
490:
491:
492:
493:
494: void
495: buzz(type, sx, sy, dx, dy)
496: int type;
497: xchar sx, sy;
498: int dx, dy;
499: {
500: int abstype = abs(type);
501: const char *fltxt = (type == -1) ? "blaze of fire" : fl[abstype];
502: struct rm *lev;
503: xchar range;
504: struct monst *mon;
505:
506: if (u.uswallow) {
507: int tmp;
508:
509: if (type < 0)
510: return;
511: tmp = zhit(u.ustuck, type);
512: pline("The %s rips into %s%s",
513: fltxt, monnam(u.ustuck), exclam(tmp));
514: return;
515: }
516: if (type < 0)
517: pru();
518: range = rn1(7, 7);
519: Tmp_at(-1, dirlet(dx, dy));
520: while (range-- > 0) {
521: sx += dx;
522: sy += dy;
523: if ((lev = &levl[sx][sy])->typ)
524: Tmp_at(sx, sy);
525: else {
526: int bounce = 0;
527: if (cansee(sx - dx, sy - dy))
528: pline("The %s bounces!", fltxt);
529: if (ZAP_POS(levl[sx][sy - dy].typ))
530: bounce = 1;
531: if (ZAP_POS(levl[sx - dx][sy].typ)) {
532: if (!bounce || rn2(2))
533: bounce = 2;
534: }
535: switch (bounce) {
536: case 0