Expand PMF_FN_* macros.
[netbsd-mini2440.git] / games / hack / hack.mhitu.c
blob5d9feaf21ea53b2d476887004a4f62c27747e5d9
1 /* $NetBSD: hack.mhitu.c,v 1.6 2003/04/02 18:36:37 jsm 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.mhitu.c,v 1.6 2003/04/02 18:36:37 jsm Exp $");
67 #endif /* not lint */
69 #include "hack.h"
70 #include "extern.h"
73 * mhitu: monster hits you
74 * returns 1 if monster dies (e.g. 'y', 'F'), 0 otherwise
76 int
77 mhitu(struct monst *mtmp)
79 const struct permonst *mdat = mtmp->data;
80 int tmp, ctmp;
82 nomul(0);
84 /* If swallowed, can only be affected by hissers and by u.ustuck */
85 if (u.uswallow) {
86 if (mtmp != u.ustuck) {
87 if (mdat->mlet == 'c' && !rn2(13)) {
88 pline("Outside, you hear %s's hissing!",
89 monnam(mtmp));
90 pline("%s gets turned to stone!",
91 Monnam(u.ustuck));
92 pline("And the same fate befalls you.");
93 done_in_by(mtmp);
94 /* "notreached": not return(1); */
96 return (0);
98 switch (mdat->mlet) { /* now mtmp == u.ustuck */
99 case ',':
100 youswld(mtmp, (u.uac > 0) ? u.uac + 4 : 4,
101 5, "The trapper");
102 break;
103 case '\'':
104 youswld(mtmp, rnd(6), 7, "The lurker above");
105 break;
106 case 'P':
107 youswld(mtmp, d(2, 4), 12, "The purple worm");
108 break;
109 default:
110 /* This is not impossible! */
111 pline("The mysterious monster totally digests you.");
112 u.uhp = 0;
114 if (u.uhp < 1)
115 done_in_by(mtmp);
116 return (0);
118 if (mdat->mlet == 'c' && Stoned)
119 return (0);
121 /* make eels visible the moment they hit/miss us */
122 if (mdat->mlet == ';' && mtmp->minvis && cansee(mtmp->mx, mtmp->my)) {
123 mtmp->minvis = 0;
124 pmon(mtmp);
126 if (!strchr("1&DuxynNF", mdat->mlet))
127 tmp = hitu(mtmp, d(mdat->damn, mdat->damd));
128 else
129 tmp = 0;
130 if (strchr(UNDEAD, mdat->mlet) && midnight())
131 tmp += hitu(mtmp, d(mdat->damn, mdat->damd));
133 ctmp = tmp && !mtmp->mcan &&
134 (!uarm || objects[uarm->otyp].a_can < rnd(3) || !rn2(50));
135 switch (mdat->mlet) {
136 case '1':
137 if (wiz_hit(mtmp))
138 return (1); /* he disappeared */
139 break;
140 case '&':
141 if (!mtmp->cham && !mtmp->mcan && !rn2(13)) {
142 (void) makemon(PM_DEMON, u.ux, u.uy);
143 } else {
144 (void) hitu(mtmp, d(2, 6));
145 (void) hitu(mtmp, d(2, 6));
146 (void) hitu(mtmp, rnd(3));
147 (void) hitu(mtmp, rnd(3));
148 (void) hitu(mtmp, rn1(4, 2));
150 break;
151 case ',':
152 if (tmp)
153 justswld(mtmp, "The trapper");
154 break;
155 case '\'':
156 if (tmp)
157 justswld(mtmp, "The lurker above");
158 break;
159 case ';':
160 if (ctmp) {
161 if (!u.ustuck && !rn2(10)) {
162 pline("%s swings itself around you!",
163 Monnam(mtmp));
164 u.ustuck = mtmp;
165 } else if (u.ustuck == mtmp &&
166 levl[mtmp->mx][mtmp->my].typ == POOL) {
167 pline("%s drowns you ...", Monnam(mtmp));
168 done("drowned");
171 break;
172 case 'A':
173 if (ctmp && rn2(2)) {
174 if (Poison_resistance)
175 pline("The sting doesn't seem to affect you.");
176 else {
177 pline("You feel weaker!");
178 losestr(1);
181 break;
182 case 'C':
183 (void) hitu(mtmp, rnd(6));
184 break;
185 case 'c':
186 if (!rn2(5)) {
187 pline("You hear %s's hissing!", monnam(mtmp));
188 if (ctmp || !rn2(20) || (flags.moonphase == NEW_MOON
189 && !carrying(DEAD_LIZARD))) {
190 Stoned = 5;
191 /* pline("You get turned to stone!"); */
192 /* done_in_by(mtmp); */
195 break;
196 case 'D':
197 if (rn2(6) || mtmp->mcan) {
198 (void) hitu(mtmp, d(3, 10));
199 (void) hitu(mtmp, rnd(8));
200 (void) hitu(mtmp, rnd(8));
201 break;
203 kludge("%s breathes fire!", "The dragon");
204 buzz(-1, mtmp->mx, mtmp->my, u.ux - mtmp->mx, u.uy - mtmp->my);
205 break;
206 case 'd':
207 (void) hitu(mtmp, d(2, (flags.moonphase == FULL_MOON) ? 3 : 4));
208 break;
209 case 'e':
210 (void) hitu(mtmp, d(3, 6));
211 break;
212 case 'F':
213 if (mtmp->mcan)
214 break;
215 kludge("%s explodes!", "The freezing sphere");
216 if (Cold_resistance)
217 pline("You don't seem affected by it.");
218 else {
219 xchar dn;
220 if (17 - (u.ulevel / 2) > rnd(20)) {
221 pline("You get blasted!");
222 dn = 6;
223 } else {
224 pline("You duck the blast...");
225 dn = 3;
227 losehp_m(d(dn, 6), mtmp);
229 mondead(mtmp);
230 return (1);
231 case 'g':
232 if (ctmp && multi >= 0 && !rn2(3)) {
233 kludge("You are frozen by %ss juices", "the cube'");
234 nomul(-rnd(10));
236 break;
237 case 'h':
238 if (ctmp && multi >= 0 && !rn2(5)) {
239 nomul(-rnd(10));
240 kludge("You are put to sleep by %ss bite!",
241 "the homunculus'");
243 break;
244 case 'j':
245 tmp = hitu(mtmp, rnd(3));
246 tmp &= hitu(mtmp, rnd(3));
247 if (tmp) {
248 (void) hitu(mtmp, rnd(4));
249 (void) hitu(mtmp, rnd(4));
251 break;
252 case 'k':
253 if ((hitu(mtmp, rnd(4)) || !rn2(3)) && ctmp) {
254 poisoned("bee's sting", mdat->mname);
256 break;
257 case 'L':
258 if (tmp)
259 stealgold(mtmp);
260 break;
261 case 'N':
262 if (mtmp->mcan && !Blind) {
263 pline("%s tries to seduce you, but you seem not interested.",
264 Amonnam(mtmp, "plain"));
265 if (rn2(3))
266 rloc(mtmp);
267 } else if (steal(mtmp)) {
268 rloc(mtmp);
269 mtmp->mflee = 1;
271 break;
272 case 'n':
273 if (!uwep && !uarm && !uarmh && !uarms && !uarmg) {
274 pline("%s hits! (I hope you don't mind)",
275 Monnam(mtmp));
276 u.uhp += rnd(7);
277 if (!rn2(7))
278 u.uhpmax++;
279 if (u.uhp > u.uhpmax)
280 u.uhp = u.uhpmax;
281 flags.botl = 1;
282 if (!rn2(50))
283 rloc(mtmp);
284 } else {
285 (void) hitu(mtmp, d(2, 6));
286 (void) hitu(mtmp, d(2, 6));
288 break;
289 case 'o':
290 tmp = hitu(mtmp, rnd(6));
291 if (hitu(mtmp, rnd(6)) && tmp && /* hits with both paws */
292 !u.ustuck && rn2(2)) {
293 u.ustuck = mtmp;
294 kludge("%s has grabbed you!", "The owlbear");
295 u.uhp -= d(2, 8);
296 } else if (u.ustuck == mtmp) {
297 u.uhp -= d(2, 8);
298 pline("You are being crushed.");
300 break;
301 case 'P':
302 if (ctmp && !rn2(4))
303 justswld(mtmp, "The purple worm");
304 else
305 (void) hitu(mtmp, d(2, 4));
306 break;
307 case 'Q':
308 (void) hitu(mtmp, rnd(2));
309 (void) hitu(mtmp, rnd(2));
310 break;
311 case 'R':
312 if (tmp && uarmh && !uarmh->rustfree &&
313 (int) uarmh->spe >= -1) {
314 pline("Your helmet rusts!");
315 uarmh->spe--;
316 } else if (ctmp && uarm && !uarm->rustfree && /* Mike Newton */
317 uarm->otyp < STUDDED_LEATHER_ARMOR &&
318 (int) uarm->spe >= -1) {
319 pline("Your armor rusts!");
320 uarm->spe--;
322 break;
323 case 'S':
324 if (ctmp && !rn2(8)) {
325 poisoned("snake's bite", mdat->mname);
327 break;
328 case 's':
329 if (tmp && !rn2(8)) {
330 poisoned("scorpion's sting", mdat->mname);
332 (void) hitu(mtmp, rnd(8));
333 (void) hitu(mtmp, rnd(8));
334 break;
335 case 'T':
336 (void) hitu(mtmp, rnd(6));
337 (void) hitu(mtmp, rnd(6));
338 break;
339 case 't':
340 if (!rn2(5))
341 rloc(mtmp);
342 break;
343 case 'u':
344 mtmp->mflee = 1;
345 break;
346 case 'U':
347 (void) hitu(mtmp, d(3, 4));
348 (void) hitu(mtmp, d(3, 4));
349 break;
350 case 'v':
351 if (ctmp && !u.ustuck)
352 u.ustuck = mtmp;
353 break;
354 case 'V':
355 if (tmp)
356 u.uhp -= 4;
357 if (ctmp)
358 losexp();
359 break;
360 case 'W':
361 if (ctmp)
362 losexp();
363 break;
364 #ifndef NOWORM
365 case 'w':
366 if (tmp)
367 wormhit(mtmp);
368 #endif /* NOWORM */
369 break;
370 case 'X':
371 (void) hitu(mtmp, rnd(5));
372 (void) hitu(mtmp, rnd(5));
373 (void) hitu(mtmp, rnd(5));
374 break;
375 case 'x':
377 long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
378 pline("%s pricks in your %s leg!",
379 Monnam(mtmp), (side == RIGHT_SIDE) ? "right" : "left");
380 set_wounded_legs(side, rnd(50));
381 losehp_m(2, mtmp);
382 break;
384 case 'y':
385 if (mtmp->mcan)
386 break;
387 mondead(mtmp);
388 if (!Blind) {
389 pline("You are blinded by a blast of light!");
390 Blind = d(4, 12);
391 seeoff(0);
393 return (1);
394 case 'Y':
395 (void) hitu(mtmp, rnd(6));
396 break;
398 if (u.uhp < 1)
399 done_in_by(mtmp);
400 return (0);
404 hitu(struct monst *mtmp, int dam)
406 int tmp, res;
408 nomul(0);
409 if (u.uswallow)
410 return (0);
412 if (mtmp->mhide && mtmp->mundetected) {
413 mtmp->mundetected = 0;
414 if (!Blind) {
415 struct obj *obj;
416 if ((obj = o_at(mtmp->mx, mtmp->my)) != NULL)
417 pline("%s was hidden under %s!",
418 Xmonnam(mtmp), doname(obj));
421 tmp = u.uac;
422 /* give people with Ac = -10 at least some vulnerability */
423 if (tmp < 0) {
424 dam += tmp; /* decrease damage */
425 if (dam <= 0)
426 dam = 1;
427 tmp = -rn2(-tmp);
429 tmp += mtmp->data->mlevel;
430 if (multi < 0)
431 tmp += 4;
432 if ((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee)
433 tmp -= 2;
434 if (mtmp->mtrapped)
435 tmp -= 2;
436 if (tmp <= rnd(20)) {
437 if (Blind)
438 pline("It misses.");
439 else
440 pline("%s misses.", Monnam(mtmp));
441 res = 0;
442 } else {
443 if (Blind)
444 pline("It hits!");
445 else
446 pline("%s hits!", Monnam(mtmp));
447 losehp_m(dam, mtmp);
448 res = 1;
450 stop_occupation();
451 return (res);