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