games: Massive style(9) cleanup commit. Reduces differences to NetBSD.
[dragonfly.git] / games / hack / hack.mhitu.c
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.mhitu.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.mhitu.c,v 1.4 1999/11/16 10:26:36 marcel Exp $ */
4 /* $DragonFly: src/games/hack/hack.mhitu.c,v 1.4 2006/08/21 19:45:32 pavalos Exp $ */
5
6 #include "hack.h"
7
8 /*
9  * mhitu: monster hits you
10  *        returns 1 if monster dies (e.g. 'y', 'F'), 0 otherwise
11  */
12 bool
13 mhitu(struct monst *mtmp)
14 {
15         struct permonst *mdat = mtmp->data;
16         int tmp, ctmp;
17
18         nomul(0);
19
20         /* If swallowed, can only be affected by hissers and by u.ustuck */
21         if (u.uswallow) {
22                 if (mtmp != u.ustuck) {
23                         if (mdat->mlet == 'c' && !rn2(13)) {
24                                 pline("Outside, you hear %s's hissing!",
25                                       monnam(mtmp));
26                                 pline("%s gets turned to stone!",
27                                       Monnam(u.ustuck));
28                                 pline("And the same fate befalls you.");
29                                 done_in_by(mtmp);
30                                 /* "notreached": not return(1); */
31                         }
32                         return (0);
33                 }
34                 switch (mdat->mlet) {   /* now mtmp == u.ustuck */
35                 case ',':
36                         youswld(mtmp, (u.uac > 0) ? u.uac + 4 : 4,
37                                 5, "The trapper");
38                         break;
39                 case '\'':
40                         youswld(mtmp, rnd(6), 7, "The lurker above");
41                         break;
42                 case 'P':
43                         youswld(mtmp, d(2, 4), 12, "The purple worm");
44                         break;
45                 default:
46                         /* This is not impossible! */
47                         pline("The mysterious monster totally digests you.");
48                         u.uhp = 0;
49                 }
50                 if (u.uhp < 1)
51                         done_in_by(mtmp);
52                 return (0);
53         }
54
55         if (mdat->mlet == 'c' && Stoned)
56                 return (0);
57
58         /* make eels visible the moment they hit/miss us */
59         if (mdat->mlet == ';' && mtmp->minvis && cansee(mtmp->mx, mtmp->my)) {
60                 mtmp->minvis = 0;
61                 pmon(mtmp);
62         }
63         if (!strchr("1&DuxynNF", mdat->mlet))
64                 tmp = hitu(mtmp, d(mdat->damn, mdat->damd));
65         else
66                 tmp = 0;
67         if (strchr(UNDEAD, mdat->mlet) && midnight())
68                 tmp += hitu(mtmp, d(mdat->damn, mdat->damd));
69
70         ctmp = tmp && !mtmp->mcan &&
71             (!uarm || objects[uarm->otyp].a_can < rnd(3) || !rn2(50));
72         switch (mdat->mlet) {
73         case '1':
74                 if (wiz_hit(mtmp))      /* he disappeared */
75                         return (1);
76                 break;
77         case '&':
78                 if (!mtmp->cham && !mtmp->mcan && !rn2(13)) {
79                         makemon(PM_DEMON, u.ux, u.uy);
80                 } else {
81                         hitu(mtmp, d(2, 6));
82                         hitu(mtmp, d(2, 6));
83                         hitu(mtmp, rnd(3));
84                         hitu(mtmp, rnd(3));
85                         hitu(mtmp, rn1(4, 2));
86                 }
87                 break;
88         case ',':
89                 if (tmp)
90                         justswld(mtmp, "The trapper");
91                 break;
92         case '\'':
93                 if (tmp)
94                         justswld(mtmp, "The lurker above");
95                 break;
96         case ';':
97                 if (ctmp) {
98                         if (!u.ustuck && !rn2(10)) {
99                                 pline("%s swings itself around you!",
100                                       Monnam(mtmp));
101                                 u.ustuck = mtmp;
102                         } else if (u.ustuck == mtmp &&
103                                    levl[mtmp->mx][mtmp->my].typ == POOL) {
104                                 pline("%s drowns you ...", Monnam(mtmp));
105                                 done("drowned");
106                         }
107                 }
108                 break;
109         case 'A':
110                 if (ctmp && rn2(2)) {
111                         if (Poison_resistance)
112                                 pline("The sting doesn't seem to affect you.");
113                         else {
114                                 pline("You feel weaker!");
115                                 losestr(1);
116                         }
117                 }
118                 break;
119         case 'C':
120                 hitu(mtmp, rnd(6));
121                 break;
122         case 'c':
123                 if (!rn2(5)) {
124                         pline("You hear %s's hissing!", monnam(mtmp));
125                         if (ctmp || !rn2(20) || (flags.moonphase == NEW_MOON
126                             && !carrying(DEAD_LIZARD)))
127                                 Stoned = 5;
128                 }
129                 break;
130         case 'D':
131                 if (rn2(6) || mtmp->mcan) {
132                         hitu(mtmp, d(3, 10));
133                         hitu(mtmp, rnd(8));
134                         hitu(mtmp, rnd(8));
135                         break;
136                 }
137                 kludge("%s breathes fire!", "The dragon");
138                 buzz(-1, mtmp->mx, mtmp->my, u.ux - mtmp->mx, u.uy - mtmp->my);
139                 break;
140         case 'd':
141                 hitu(mtmp, d(2, (flags.moonphase == FULL_MOON) ? 3 : 4));
142                 break;
143         case 'e':
144                 hitu(mtmp, d(3, 6));
145                 break;
146         case 'F':
147                 if (mtmp->mcan)
148                         break;
149                 kludge("%s explodes!", "The freezing sphere");
150                 if (Cold_resistance)
151                         pline("You don't seem affected by it.");
152                 else {
153                         xchar dn;
154                         if (17 - (u.ulevel / 2) > rnd(20)) {
155                                 pline("You get blasted!");
156                                 dn = 6;
157                         } else {
158                                 pline("You duck the blast...");
159                                 dn = 3;
160                         }
161                         losehp_m(d(dn, 6), mtmp);
162                 }
163                 mondead(mtmp);
164                 return (1);
165         case 'g':
166                 if (ctmp && multi >= 0 && !rn2(3)) {
167                         kludge("You are frozen by %ss juices", "the cube'");
168                         nomul(-rnd(10));
169                 }
170                 break;
171         case 'h':
172                 if (ctmp && multi >= 0 && !rn2(5)) {
173                         nomul(-rnd(10));
174                         kludge("You are put to sleep by %ss bite!",
175                                "the homunculus'");
176                 }
177                 break;
178         case 'j':
179                 tmp = hitu(mtmp, rnd(3));
180                 tmp &= hitu(mtmp, rnd(3));
181                 if (tmp) {
182                         hitu(mtmp, rnd(4));
183                         hitu(mtmp, rnd(4));
184                 }
185                 break;
186         case 'k':
187                 if ((hitu(mtmp, rnd(4)) || !rn2(3)) && ctmp)
188                         poisoned("bee's sting", mdat->mname);
189                 break;
190         case 'L':
191                 if (tmp)
192                         stealgold(mtmp);
193                 break;
194         case 'N':
195                 if (mtmp->mcan && !Blind) {
196                         pline("%s tries to seduce you, but you seem not interested.",
197                             Amonnam(mtmp, "plain"));
198                         if (rn2(3))
199                                 rloc(mtmp);
200                 } else if (steal(mtmp)) {
201                         rloc(mtmp);
202                         mtmp->mflee = 1;
203                 }
204                 break;
205         case 'n':
206                 if (!uwep && !uarm && !uarmh && !uarms && !uarmg) {
207                         pline("%s hits! (I hope you don't mind)",
208                               Monnam(mtmp));
209                         u.uhp += rnd(7);
210                         if (!rn2(7))
211                                 u.uhpmax++;
212                         if (u.uhp > u.uhpmax)
213                                 u.uhp = u.uhpmax;
214                         flags.botl = 1;
215                         if (!rn2(50))
216                                 rloc(mtmp);
217                 } else {
218                         hitu(mtmp, d(2, 6));
219                         hitu(mtmp, d(2, 6));
220                 }
221                 break;
222         case 'o':
223                 tmp = hitu(mtmp, rnd(6));
224                 if (hitu(mtmp, rnd(6)) && tmp &&        /* hits with both paws */
225                     !u.ustuck && rn2(2)) {
226                         u.ustuck = mtmp;
227                         kludge("%s has grabbed you!", "The owlbear");
228                         u.uhp -= d(2, 8);
229                 } else if (u.ustuck == mtmp) {
230                         u.uhp -= d(2, 8);
231                         pline("You are being crushed.");
232                 }
233                 break;
234         case 'P':
235                 if (ctmp && !rn2(4))
236                         justswld(mtmp, "The purple worm");
237                 else
238                         hitu(mtmp, d(2, 4));
239                 break;
240         case 'Q':
241                 hitu(mtmp, rnd(2));
242                 hitu(mtmp, rnd(2));
243                 break;
244         case 'R':
245                 if (tmp && uarmh && !uarmh->rustfree &&
246                     (int)uarmh->spe >= -1) {
247                         pline("Your helmet rusts!");
248                         uarmh->spe--;
249                 } else if (ctmp && uarm && !uarm->rustfree &&   /* Mike Newton */
250                     uarm->otyp < STUDDED_LEATHER_ARMOR &&
251                     (int)uarm->spe >= -1) {
252                         pline("Your armor rusts!");
253                         uarm->spe--;
254                 }
255                 break;
256         case 'S':
257                 if (ctmp && !rn2(8))
258                         poisoned("snake's bite", mdat->mname);
259                 break;
260         case 's':
261                 if (tmp && !rn2(8))
262                         poisoned("scorpion's sting", mdat->mname);
263                 hitu(mtmp, rnd(8));
264                 hitu(mtmp, rnd(8));
265                 break;
266         case 'T':
267                 hitu(mtmp, rnd(6));
268                 hitu(mtmp, rnd(6));
269                 break;
270         case 't':
271                 if (!rn2(5))
272                         rloc(mtmp);
273                 break;
274         case 'u':
275                 mtmp->mflee = 1;
276                 break;
277         case 'U':
278                 hitu(mtmp, d(3, 4));
279                 hitu(mtmp, d(3, 4));
280                 break;
281         case 'v':
282                 if (ctmp && !u.ustuck)
283                         u.ustuck = mtmp;
284                 break;
285         case 'V':
286                 if (tmp)
287                         u.uhp -= 4;
288                 if (ctmp)
289                         losexp();
290                 break;
291         case 'W':
292                 if (ctmp)
293                         losexp();
294                 break;
295 #ifndef NOWORM
296         case 'w':
297                 if (tmp)
298                         wormhit(mtmp);
299 #endif /* NOWORM */
300                 break;
301         case 'X':
302                 hitu(mtmp, rnd(5));
303                 hitu(mtmp, rnd(5));
304                 hitu(mtmp, rnd(5));
305                 break;
306         case 'x':
307                 {
308                         long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
309                         pline("%s pricks in your %s leg!",
310                             Monnam(mtmp), (side == RIGHT_SIDE) ? "right" : "left");
311                         set_wounded_legs(side, rnd(50));
312                         losehp_m(2, mtmp);
313                         break;
314                 }
315         case 'y':
316                 if (mtmp->mcan)
317                         break;
318                 mondead(mtmp);
319                 if (!Blind) {
320                         pline("You are blinded by a blast of light!");
321                         Blind = d(4, 12);
322                         seeoff(0);
323                 }
324                 return (1);
325         case 'Y':
326                 hitu(mtmp, rnd(6));
327                 break;
328         }
329         if (u.uhp < 1)
330                 done_in_by(mtmp);
331         return (0);
332 }
333
334 bool
335 hitu(struct monst *mtmp, int dam)
336 {
337         bool res;
338         int tmp;
339
340         nomul(0);
341         if (u.uswallow)
342                 return (0);
343
344         if (mtmp->mhide && mtmp->mundetected) {
345                 mtmp->mundetected = 0;
346                 if (!Blind) {
347                         struct obj *obj;
348                         if ((obj = o_at(mtmp->mx, mtmp->my)) != NULL)
349                                 pline("%s was hidden under %s!",
350                                       Xmonnam(mtmp), doname(obj));
351                 }
352         }
353
354         tmp = u.uac;
355         /* give people with Ac = -10 at least some vulnerability */
356         if (tmp < 0) {
357                 dam += tmp;     /* decrease damage */
358                 if (dam <= 0)
359                         dam = 1;
360                 tmp = -rn2(-tmp);
361         }
362         tmp += mtmp->data->mlevel;
363         if (multi < 0)
364                 tmp += 4;
365         if ((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee)
366                 tmp -= 2;
367         if (mtmp->mtrapped)
368                 tmp -= 2;
369         if (tmp <= rnd(20)) {
370                 if (Blind)
371                         pline("It misses.");
372                 else
373                         pline("%s misses.", Monnam(mtmp));
374                 res = 0;
375         } else {
376                 if (Blind)
377                         pline("It hits!");
378                 else
379                         pline("%s hits!", Monnam(mtmp));
380                 losehp_m(dam, mtmp);
381                 res = 1;
382         }
383         stop_occupation();
384         return (res);
385 }