File: | src/games/hack/hack.fight.c |
Warning: | line 123, column 38 Although the value stored to 'pa' is used in the enclosing expression, the value is never actually read from 'pa' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: hack.fight.c,v 1.10 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 <stdio.h> |
65 | |
66 | #include "hack.h" |
67 | |
68 | extern struct permonst li_dog, dog, la_dog; |
69 | |
70 | static boolean far_noise; |
71 | static long noisetime; |
72 | |
73 | static void monstone(struct monst *); |
74 | |
75 | /* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */ |
76 | int |
77 | hitmm(struct monst * magr, struct monst * mdef) |
78 | { |
79 | struct permonst *pa = magr->data, *pd = mdef->data; |
80 | int hit; |
81 | schar tmp; |
82 | boolean vis; |
83 | |
84 | if(strchr("Eauy", pa->mlet)) return(0); |
85 | if(magr->mfroz) return(0); /* riv05!a3 */ |
86 | tmp = pd->ac + pa->mlevel; |
87 | if(mdef->mconf || mdef->mfroz || mdef->msleep){ |
88 | tmp += 4; |
89 | if(mdef->msleep) mdef->msleep = 0; |
90 | } |
91 | hit = (tmp > rnd(20)); |
92 | if(hit) mdef->msleep = 0; |
93 | vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my)); |
94 | if(vis){ |
95 | char buf[BUFSZ256]; |
96 | if(mdef->mimic) seemimic(mdef); |
97 | if(magr->mimic) seemimic(magr); |
98 | (void) snprintf(buf,sizeof buf,"%s %s", Monnam(magr), |
99 | hit ? "hits" : "misses"); |
100 | pline("%s %s.", buf, monnam(mdef)); |
101 | } else { |
102 | boolean far = (dist(magr->mx, magr->my) > 15); |
103 | if(far != far_noise || moves-noisetime > 10) { |
104 | far_noise = far; |
105 | noisetime = moves; |
106 | pline("You hear some noises%s.", |
107 | far ? " in the distance" : ""); |
108 | } |
109 | } |
110 | if(hit){ |
111 | if(magr->data->mlet == 'c' && !magr->cham) { |
112 | magr->mhpmax += 3; |
113 | if(vis) pline("%s is turned to stone!", Monnam(mdef)); |
114 | else if(mdef->mtame) |
115 | pline("You have a peculiarly sad feeling for a moment, then it passes."); |
116 | monstone(mdef); |
117 | hit = 2; |
118 | } else |
119 | if((mdef->mhp -= d(pa->damn,pa->damd)) < 1) { |
120 | magr->mhpmax += 1 + rn2(pd->mlevel+1); |
121 | if(magr->mtame && magr->mhpmax > 8*pa->mlevel){ |
122 | if(pa == &li_dog) magr->data = pa = &dog; |
123 | else if(pa == &dog) magr->data = pa = &la_dog; |
Although the value stored to 'pa' is used in the enclosing expression, the value is never actually read from 'pa' | |
124 | } |
125 | if(vis) pline("%s is killed!", Monnam(mdef)); |
126 | else if(mdef->mtame) |
127 | pline("You have a sad feeling for a moment, then it passes."); |
128 | mondied(mdef); |
129 | hit = 2; |
130 | } |
131 | } |
132 | return(hit); |
133 | } |
134 | |
135 | /* drop (perhaps) a cadaver and remove monster */ |
136 | void |
137 | mondied(struct monst *mdef) |
138 | { |
139 | struct permonst *pd = mdef->data; |
140 | |
141 | if(letter(pd->mlet) && rn2(3)){ |
142 | (void) mkobj_at(pd->mlet,mdef->mx,mdef->my); |
143 | if(cansee(mdef->mx,mdef->my)){ |
144 | unpmon(mdef); |
145 | atl(mdef->mx,mdef->my,fobj->olet); |
146 | } |
147 | stackobj(fobj); |
148 | } |
149 | mondead(mdef); |
150 | } |
151 | |
152 | /* drop a rock and remove monster */ |
153 | static void |
154 | monstone(struct monst *mdef) |
155 | { |
156 | extern char mlarge[]; |
157 | if(strchr(mlarge, mdef->data->mlet)) |
158 | mksobj_at(ENORMOUS_ROCK97, mdef->mx, mdef->my); |
159 | else |
160 | mksobj_at(ROCK75, mdef->mx, mdef->my); |
161 | if(cansee(mdef->mx, mdef->my)){ |
162 | unpmon(mdef); |
163 | atl(mdef->mx,mdef->my,fobj->olet); |
164 | } |
165 | mondead(mdef); |
166 | } |
167 | |
168 | int |
169 | fightm(struct monst *mtmp) |
170 | { |
171 | struct monst *mon; |
172 | |
173 | for(mon = fmon; mon; mon = mon->nmon) if(mon != mtmp) { |
174 | if(DIST(mon->mx,mon->my,mtmp->mx,mtmp->my)(((mon->mx)-(mtmp->mx))*((mon->mx)-(mtmp->mx)) + ( (mon->my)-(mtmp->my))*((mon->my)-(mtmp->my))) < 3) |
175 | if(rn2(4)) |
176 | return(hitmm(mtmp,mon)); |
177 | } |
178 | return(-1); |
179 | } |
180 | |
181 | /* u is hit by sth, but not a monster */ |
182 | int |
183 | thitu(int tlev, int dam, char *name) |
184 | { |
185 | char buf[BUFSZ256]; |
186 | |
187 | setan(name,buf,sizeof buf); |
188 | if(u.uac + tlev <= rnd(20)) { |
189 | if(Blindu.uprops[(19 +7)].p_flgs) pline("It misses."); |
190 | else pline("You are almost hit by %s!", buf); |
191 | return(0); |
192 | } else { |
193 | if(Blindu.uprops[(19 +7)].p_flgs) pline("You are hit!"); |
194 | else pline("You are hit by %s!", buf); |
195 | losehp(dam,name); |
196 | return(1); |
197 | } |
198 | } |
199 | |
200 | char mlarge[] = "bCDdegIlmnoPSsTUwY',&"; |
201 | |
202 | /* return TRUE if mon still alive */ |
203 | boolean |
204 | hmon(struct monst *mon, struct obj *obj, int thrown) |
205 | { |
206 | int tmp; |
207 | boolean hittxt = FALSE0; |
208 | |
209 | if(!obj){ |
210 | tmp = rnd(2); /* attack with bare hands */ |
211 | if(mon->data->mlet == 'c' && !uarmg){ |
212 | pline("You hit the cockatrice with your bare hands."); |
213 | pline("You turn to stone ..."); |
214 | done_in_by(mon); |
215 | } |
216 | } else if(obj->olet == WEAPON_SYM')' || obj->otyp == PICK_AXE93) { |
217 | if(obj == uwep && (obj->otyp > SPEAR85 || obj->otyp < BOOMERANG76)) |
218 | tmp = rnd(2); |
219 | else { |
220 | if(strchr(mlarge, mon->data->mlet)) { |
221 | tmp = rnd(objects[obj->otyp].wldamoc_oc1); |
222 | if(obj->otyp == TWO_HANDED_SWORD81) tmp += d(2,6); |
223 | else if(obj->otyp == FLAIL79) tmp += rnd(4); |
224 | } else { |
225 | tmp = rnd(objects[obj->otyp].wsdamoc_oc2); |
226 | } |
227 | tmp += obj->spe; |
228 | if(!thrown && obj == uwep && obj->otyp == BOOMERANG76 |
229 | && !rn2(3)){ |
230 | pline("As you hit %s, the boomerang breaks into splinters.", |
231 | monnam(mon)); |
232 | freeinv(obj); |
233 | setworn((struct obj *) 0, obj->owornmask); |
234 | obfree(obj, (struct obj *) 0); |
235 | tmp++; |
236 | } |
237 | } |
238 | if(mon->data->mlet == 'O' && obj->otyp == TWO_HANDED_SWORD81 && |
239 | !strcmp(ONAME(obj)((char *) obj->oextra), "Orcrist")) |
240 | tmp += rnd(10); |
241 | } else switch(obj->otyp) { |
242 | case HEAVY_IRON_BALL95: |
243 | tmp = rnd(25); break; |
244 | case EXPENSIVE_CAMERA91: |
245 | pline("You succeed in destroying your camera. Congratulations!"); |
246 | freeinv(obj); |
247 | if(obj->owornmask) |
248 | setworn((struct obj *) 0, obj->owornmask); |
249 | obfree(obj, (struct obj *) 0); |
250 | return(TRUE1); |
251 | case DEAD_COCKATRICE47: |
252 | pline("You hit %s with the cockatrice corpse.", |
253 | monnam(mon)); |
254 | if(mon->data->mlet == 'c') { |
255 | tmp = 1; |
256 | hittxt = TRUE1; |
257 | break; |
258 | } |
259 | pline("%s is turned to stone!", Monnam(mon)); |
260 | killed(mon); |
261 | return(FALSE0); |
262 | case CLOVE_OF_GARLIC16: /* no effect against demons */ |
263 | if(strchr(UNDEAD"ZVW ", mon->data->mlet)) |
264 | mon->mflee = 1; |
265 | tmp = 1; |
266 | break; |
267 | default: |
268 | /* non-weapons can damage because of their weight */ |
269 | /* (but not too much) */ |
270 | tmp = obj->owt/10; |
271 | if(tmp < 1) tmp = 1; |
272 | else tmp = rnd(tmp); |
273 | if(tmp > 6) tmp = 6; |
274 | } |
275 | |
276 | /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) */ |
277 | |
278 | tmp += u.udaminc + dbon(); |
279 | if(u.uswallow) { |
280 | if((tmp -= u.uswldtim) <= 0) { |
281 | pline("Your arms are no longer able to hit."); |
282 | return(TRUE1); |
283 | } |
284 | } |
285 | if(tmp < 1) tmp = 1; |
286 | mon->mhp -= tmp; |
287 | if(mon->mhp < 1) { |
288 | killed(mon); |
289 | return(FALSE0); |
290 | } |
291 | if(mon->mtame && (!mon->mflee || mon->mfleetim)) { |
292 | mon->mflee = 1; /* Rick Richardson */ |
293 | mon->mfleetim += 10*rnd(tmp); |
294 | } |
295 | |
296 | if(!hittxt) { |
297 | if(thrown) |
298 | /* this assumes that we cannot throw plural things */ |
299 | hit( xname(obj) /* or: objects[obj->otyp].oc_name */, |
300 | mon, exclam(tmp) ); |
301 | else if(Blindu.uprops[(19 +7)].p_flgs) |
302 | pline("You hit it."); |
303 | else |
304 | pline("You hit %s%s", monnam(mon), exclam(tmp)); |
305 | } |
306 | |
307 | if(u.umconf && !thrown) { |
308 | if(!Blindu.uprops[(19 +7)].p_flgs) { |
309 | pline("Your hands stop glowing blue."); |
310 | if(!mon->mfroz && !mon->msleep) |
311 | pline("%s appears confused.",Monnam(mon)); |
312 | } |
313 | mon->mconf = 1; |
314 | u.umconf = 0; |
315 | } |
316 | return(TRUE1); /* mon still alive */ |
317 | } |
318 | |
319 | /* try to attack; return FALSE if monster evaded */ |
320 | /* u.dx and u.dy must be set */ |
321 | boolean |
322 | attack(struct monst *mtmp) |
323 | { |
324 | schar tmp; |
325 | boolean malive = TRUE1; |
326 | struct permonst *mdat; |
327 | mdat = mtmp->data; |
328 | |
329 | u_wipe_engr(3); /* andrew@orca: prevent unlimited pick-axe attacks */ |
330 | |
331 | if(mdat->mlet == 'L' && !mtmp->mfroz && !mtmp->msleep && |
332 | !mtmp->mconf && mtmp->mcansee && !rn2(7) && |
333 | (m_move(mtmp, 0) == 2 /* he died */ || /* he moved: */ |
334 | mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) |
335 | return(FALSE0); |
336 | |
337 | if(mtmp->mimic){ |
338 | if(!u.ustuck && !mtmp->mflee) u.ustuck = mtmp; |
339 | switch(levl[u.ux+u.dx][u.uy+u.dy].scrsym){ |
340 | case '+': |
341 | pline("The door actually was a Mimic."); |
342 | break; |
343 | case '$': |
344 | pline("The chest was a Mimic!"); |
345 | break; |
346 | default: |
347 | pline("Wait! That's a Mimic!"); |
348 | } |
349 | wakeup(mtmp); /* clears mtmp->mimic */ |
350 | return(TRUE1); |
351 | } |
352 | |
353 | wakeup(mtmp); |
354 | |
355 | if(mtmp->mhide && mtmp->mundetected){ |
356 | struct obj *obj; |
357 | |
358 | mtmp->mundetected = 0; |
359 | if((obj = o_at(mtmp->mx,mtmp->my)) && !Blindu.uprops[(19 +7)].p_flgs) |
360 | pline("Wait! There's a %s hiding under %s!", |
361 | mdat->mname, doname(obj)); |
362 | return(TRUE1); |
363 | } |
364 | |
365 | tmp = u.uluck + u.ulevel + mdat->ac + abon(); |
366 | if(uwep) { |
367 | if(uwep->olet == WEAPON_SYM')' || uwep->otyp == PICK_AXE93) |
368 | tmp += uwep->spe; |
369 | if(uwep->otyp == TWO_HANDED_SWORD81) tmp -= 1; |
370 | else if(uwep->otyp == DAGGER82) tmp += 2; |
371 | else if(uwep->otyp == CRYSKNIFE84) tmp += 3; |
372 | else if(uwep->otyp == SPEAR85 && |
373 | strchr("XDne", mdat->mlet)) tmp += 2; |
374 | } |
375 | if(mtmp->msleep) { |
376 | mtmp->msleep = 0; |
377 | tmp += 2; |
378 | } |
379 | if(mtmp->mfroz) { |
380 | tmp += 4; |
381 | if(!rn2(10)) mtmp->mfroz = 0; |
382 | } |
383 | if(mtmp->mflee) tmp += 2; |
384 | if(u.utrap) tmp -= 3; |
385 | |
386 | /* with a lot of luggage, your agility diminishes */ |
387 | tmp -= (inv_weight() + 40)/20; |
388 | |
389 | if(tmp <= rnd(20) && !u.uswallow){ |
390 | if(Blindu.uprops[(19 +7)].p_flgs) pline("You miss it."); |
391 | else pline("You miss %s.",monnam(mtmp)); |
392 | } else { |
393 | /* we hit the monster; be careful: it might die! */ |
394 | |
395 | if((malive = hmon(mtmp,uwep,0)) == TRUE1) { |
396 | /* monster still alive */ |
397 | if(!rn2(25) && mtmp->mhp < mtmp->mhpmax/2) { |
398 | mtmp->mflee = 1; |
399 | if(!rn2(3)) mtmp->mfleetim = rnd(100); |
400 | if(u.ustuck == mtmp && !u.uswallow) |
401 | u.ustuck = 0; |
402 | } |
403 | #ifndef NOWORM |
404 | if(mtmp->wormno) |
405 | cutworm(mtmp, u.ux+u.dx, u.uy+u.dy, |
406 | uwep ? uwep->otyp : 0); |
407 | #endif /* NOWORM */ |
408 | } |
409 | if(mdat->mlet == 'a') { |
410 | if(rn2(2)) { |
411 | pline("You are splashed by the blob's acid!"); |
412 | losehp_m(rnd(6), mtmp); |
413 | if(!rn2(30)) corrode_armor(); |
414 | } |
415 | if(!rn2(6)) corrode_weapon(); |
416 | } |
417 | } |
418 | if(malive && mdat->mlet == 'E' && canseemon(mtmp) |
419 | && !mtmp->mcan && rn2(3)) { |
420 | if(mtmp->mcansee) { |
421 | pline("You are frozen by the floating eye's gaze!"); |
422 | nomul((u.ulevel > 6 || rn2(4)) ? rn1(20,-21) : -200); |
423 | } else { |
424 | pline("The blinded floating eye cannot defend itself."); |
425 | if(!rn2(500)) if((int)u.uluck > LUCKMIN(-10)) u.uluck--; |
426 | } |
427 | } |
428 | return(TRUE1); |
429 | } |