Bug Summary

File:src/games/hack/hack.fight.c
Warning:line 122, column 36
Although the value stored to 'pa' is used in the enclosing expression, the value is never actually read from 'pa'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name hack.fight.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/games/hack/obj -resource-dir /usr/local/lib/clang/13.0.0 -I . -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/games/hack/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/games/hack/hack.fight.c
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
68extern struct permonst li_dog, dog, la_dog;
69
70static boolean far_noise;
71static long noisetime;
72
73static void monstone(struct monst *);
74
75/* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */
76int
77hitmm(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;
Although the value stored to 'pa' is used in the enclosing expression, the value is never actually read from 'pa'
123 else if(pa == &dog) magr->data = pa = &la_dog;
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 */
136void
137mondied(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 */
153static void
154monstone(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
168int
169fightm(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 */
182int
183thitu(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
200char mlarge[] = "bCDdegIlmnoPSsTUwY',&";
201
202/* return TRUE if mon still alive */
203boolean
204hmon(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 */
321boolean
322attack(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}