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