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