Bug Summary

File:src/games/hack/hack.mklev.c
Warning:line 777, column 8
Assigned value is garbage or undefined

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.mklev.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.mklev.c
1/* $OpenBSD: hack.mklev.c,v 1.9 2021/01/26 20:42:49 millert 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#include <stdlib.h>
66
67#include "hack.h"
68
69#define somex()((random()%(croom->hx-croom->lx+1))+croom->lx) ((random()%(croom->hx-croom->lx+1))+croom->lx)
70#define somey()((random()%(croom->hy-croom->ly+1))+croom->ly) ((random()%(croom->hy-croom->ly+1))+croom->ly)
71
72#define XLIM4 4 /* define minimum required space around a room */
73#define YLIM3 3
74boolean secret; /* TRUE while making a vault: increase [XY]LIM */
75int smeq[MAXNROFROOMS15+1];
76int doorindex;
77struct rm zerorm;
78schar nxcor;
79boolean goldseen;
80int nroom;
81
82/* Definitions used by makerooms() and addrs() */
83#define MAXRS50 50 /* max lth of temp rectangle table - arbitrary */
84struct rectangle {
85 xchar rlx,rly,rhx,rhy;
86} rs[MAXRS50+1];
87int rscnt,rsmax; /* 0..rscnt-1: currently under consideration */
88 /* rscnt..rsmax: discarded */
89
90static void addrs(int, int, int, int);
91static void addrsx(int, int, int, int, boolean);
92int comp(const void *, const void *);
93static coord finddpos(int, int, int, int);
94static int okdoor(int, int);
95static void dodoor(int, int, struct mkroom *);
96static void dosdoor(int, int, struct mkroom *, int);
97static int maker(schar, schar, schar, schar);
98static void makecorridors(void);
99static void join(int, int);
100static void make_niches(void);
101static void makevtele(void);
102static void makeniche(boolean);
103
104void
105makelevel(void)
106{
107 struct mkroom *croom, *troom;
108 unsigned tryct;
109 int x,y;
110
111 nroom = 0;
112 doorindex = 0;
113 rooms[0].hx = -1; /* in case we are in a maze */
114
115 for(x=0; x<COLNO80; x++) for(y=0; y<ROWNO22; y++)
116 levl[x][y] = zerorm;
117
118 oinit(); /* assign level dependent obj probabilities */
119
120 if(dlevel >= rn1(3, 26)) { /* there might be several mazes */
121 makemaz();
122 return;
123 }
124
125 /* construct the rooms */
126 nroom = 0;
127 secret = FALSE0;
128 (void) makerooms();
129
130 /* construct stairs (up and down in different rooms if possible) */
131 croom = &rooms[rn2(nroom)];
132 xdnstair = somex()((random()%(croom->hx-croom->lx+1))+croom->lx);
133 ydnstair = somey()((random()%(croom->hy-croom->ly+1))+croom->ly);
134 levl[(int)xdnstair][(int)ydnstair].scrsym ='>';
135 levl[(int)xdnstair][(int)ydnstair].typ = STAIRS10;
136 if(nroom > 1) {
137 troom = croom;
138 croom = &rooms[rn2(nroom-1)];
139 if(croom >= troom) croom++;
140 }
141 xupstair = somex()((random()%(croom->hx-croom->lx+1))+croom->lx); /* %% < and > might be in the same place */
142 yupstair = somey()((random()%(croom->hy-croom->ly+1))+croom->ly);
143 levl[(int)xupstair][(int)yupstair].scrsym ='<';
144 levl[(int)xupstair][(int)yupstair].typ = STAIRS10;
145
146 /* for each room: put things inside */
147 for(croom = rooms; croom->hx > 0; croom++) {
148
149 /* put a sleeping monster inside */
150 /* Note: monster may be on the stairs. This cannot be
151 avoided: maybe the player fell through a trapdoor
152 while a monster was on the stairs. Conclusion:
153 we have to check for monsters on the stairs anyway. */
154 if(!rn2(3)) (void)
155 makemon((struct permonst *) 0, somex()((random()%(croom->hx-croom->lx+1))+croom->lx), somey()((random()%(croom->hy-croom->ly+1))+croom->ly));
156
157 /* put traps and mimics inside */
158 goldseen = FALSE0;
159 while(!rn2(8-(dlevel/6))) mktrap(0,0,croom);
160 if(!goldseen && !rn2(3)) mkgold(0L,somex()((random()%(croom->hx-croom->lx+1))+croom->lx),somey()((random()%(croom->hy-croom->ly+1))+croom->ly));
161 if(!rn2(3)) {
162 (void) mkobj_at(0, somex()((random()%(croom->hx-croom->lx+1))+croom->lx), somey()((random()%(croom->hy-croom->ly+1))+croom->ly));
163 tryct = 0;
164 while(!rn2(5)) {
165 if(++tryct > 100){
166 printf("tryct overflow4\n");
167 break;
168 }
169 (void) mkobj_at(0, somex()((random()%(croom->hx-croom->lx+1))+croom->lx), somey()((random()%(croom->hy-croom->ly+1))+croom->ly));
170 }
171 }
172 }
173
174 qsort((char *) rooms, nroom, sizeof(struct mkroom), comp);
175 makecorridors();
176 make_niches();
177
178 /* make a secret treasure vault, not connected to the rest */
179 if(nroom <= (2*MAXNROFROOMS15/3)) if(rn2(3)) {
180 troom = &rooms[nroom];
181 secret = TRUE1;
182 if(makerooms()) {
183 troom->rtype = VAULT4; /* treasure vault */
184 for(x = troom->lx; x <= troom->hx; x++)
185 for(y = troom->ly; y <= troom->hy; y++)
186 mkgold((long)(rnd(dlevel*100) + 50), x, y);
187 if(!rn2(3))
188 makevtele();
189 }
190 }
191
192#ifndef QUEST
193#ifdef WIZARD"bruno"
194 if(wizardflags.debug && getenv("SHOPTYPE")) mkshop(); else
195#endif /* WIZARD */
196 if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3) mkshop();
197 else
198 if(dlevel > 6 && !rn2(7)) mkzoo(ZOO7);
199 else
200 if(dlevel > 9 && !rn2(5)) mkzoo(BEEHIVE5);
201 else
202 if(dlevel > 11 && !rn2(6)) mkzoo(MORGUE6);
203 else
204 if(dlevel > 18 && !rn2(6)) mkswamp();
205#endif /* QUEST */
206}
207
208int
209makerooms(void)
210{
211 struct rectangle *rsp;
212 int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy;
213 int tryct = 0, xlim, ylim;
214
215 /* init */
216 xlim = XLIM4 + secret;
217 ylim = YLIM3 + secret;
218 if(nroom == 0) {
219 rsp = rs;
220 rsp->rlx = rsp->rly = 0;
221 rsp->rhx = COLNO80-1;
222 rsp->rhy = ROWNO22-1;
223 rsmax = 1;
224 }
225 rscnt = rsmax;
226
227 /* make rooms until satisfied */
228 while(rscnt > 0 && nroom < MAXNROFROOMS15-1) {
229 if(!secret && nroom > (MAXNROFROOMS15/3) &&
230 !rn2((MAXNROFROOMS15-nroom)*(MAXNROFROOMS15-nroom)))
231 return(0);
232
233 /* pick a rectangle */
234 rsp = &rs[rn2(rscnt)];
235 hx = rsp->rhx;
236 hy = rsp->rhy;
237 lx = rsp->rlx;
238 ly = rsp->rly;
239
240 /* find size of room */
241 if(secret)
242 dx = dy = 1;
243 else {
244 dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8);
245 dy = 2 + rn2(4);
246 if(dx*dy > 50)
247 dy = 50/dx;
248 }
249
250 /* look whether our room will fit */
251 if(hx-lx < dx + dx/2 + 2*xlim || hy-ly < dy + dy/3 + 2*ylim) {
252 /* no, too small */
253 /* maybe we throw this area out */
254 if(secret || !rn2(MAXNROFROOMS15+1-nroom-tryct)) {
255 rscnt--;
256 rs[rsmax] = *rsp;
257 *rsp = rs[rscnt];
258 rs[rscnt] = rs[rsmax];
259 tryct = 0;
260 } else
261 tryct++;
262 continue;
263 }
264
265 lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1);
266 lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1);
267 hix = lowx + dx;
268 hiy = lowy + dy;
269
270 if(maker(lowx, dx, lowy, dy)) {
271 if(secret)
272 return(1);
273 addrs(lowx-1, lowy-1, hix+1, hiy+1);
274 tryct = 0;
275 } else
276 if(tryct++ > 100)
277 break;
278 }
279 return(0); /* failed to make vault - very strange */
280}
281
282static void
283addrs(int lowx, int lowy, int hix, int hiy)
284{
285 struct rectangle *rsp;
286 int lx,ly,hx,hy,xlim,ylim;
287 boolean discarded;
288
289 xlim = XLIM4 + secret;
290 ylim = YLIM3 + secret;
291
292 /* walk down since rscnt and rsmax change */
293 for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) {
294
295 if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||
296 (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy)
297 continue;
298 if((discarded = (rsp >= &rs[rscnt]))) {
299 *rsp = rs[--rsmax];
300 } else {
301 rsmax--;
302 rscnt--;
303 *rsp = rs[rscnt];
304 if(rscnt != rsmax)
305 rs[rscnt] = rs[rsmax];
306 }
307 if(lowy - ly > 2*ylim + 4)
308 addrsx(lx,ly,hx,lowy-2,discarded);
309 if(lowx - lx > 2*xlim + 4)
310 addrsx(lx,ly,lowx-2,hy,discarded);
311 if(hy - hiy > 2*ylim + 4)
312 addrsx(lx,hiy+2,hx,hy,discarded);
313 if(hx - hix > 2*xlim + 4)
314 addrsx(hix+2,ly,hx,hy,discarded);
315 }
316}
317
318static void
319addrsx(int lx, int ly, int hx, int hy, boolean discarded)
320/* boolean discarded; piece of a discarded area */
321{
322 struct rectangle *rsp;
323
324 /* check inclusions */
325 for(rsp = rs; rsp < &rs[rsmax]; rsp++) {
326 if(lx >= rsp->rlx && hx <= rsp->rhx &&
327 ly >= rsp->rly && hy <= rsp->rhy)
328 return;
329 }
330
331 /* make a new entry */
332 if(rsmax >= MAXRS50) {
333#ifdef WIZARD"bruno"
334 if(wizardflags.debug) pline("MAXRS may be too small.");
335#endif /* WIZARD */
336 return;
337 }
338 rsmax++;
339 if(!discarded) {
340 *rsp = rs[rscnt];
341 rsp = &rs[rscnt];
342 rscnt++;
343 }
344 rsp->rlx = lx;
345 rsp->rly = ly;
346 rsp->rhx = hx;
347 rsp->rhy = hy;
348}
349
350int
351comp(const void *x, const void *y)
352{
353 if(((struct mkroom *)x)->lx < ((struct mkroom *)y)->lx)
354 return(-1);
355 return(((struct mkroom *)x)->lx > ((struct mkroom *)y)->lx);
356}
357
358static coord
359finddpos(int xl, int yl, int xh, int yh)
360{
361 coord ff;
362 int x,y;
363
364 x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
365 y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
366 if(okdoor(x, y))
367 goto gotit;
368
369 for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
370 if(okdoor(x, y))
371 goto gotit;
372
373 for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
374 if(levl[x][y].typ == DOOR7 || levl[x][y].typ == SDOOR3)
375 goto gotit;
376 /* cannot find something reasonable -- strange */
377 x = xl;
378 y = yh;
379gotit:
380 ff.x = x;
381 ff.y = y;
382 return(ff);
383}
384
385/* see whether it is allowable to create a door at [x,y] */
386static int
387okdoor(int x, int y)
388{
389 if(levl[x-1][y].typ == DOOR7 || levl[x+1][y].typ == DOOR7 ||
390 levl[x][y+1].typ == DOOR7 || levl[x][y-1].typ == DOOR7 ||
391 levl[x-1][y].typ == SDOOR3 || levl[x+1][y].typ == SDOOR3 ||
392 levl[x][y-1].typ == SDOOR3 || levl[x][y+1].typ == SDOOR3 ||
393 (levl[x][y].typ != HWALL1 && levl[x][y].typ != VWALL2) ||
394 doorindex >= DOORMAX100)
395 return(0);
396 return(1);
397}
398
399static void
400dodoor(int x, int y, struct mkroom *aroom)
401{
402 if(doorindex >= DOORMAX100) {
403 impossible("DOORMAX exceeded?");
404 return;
405 }
406 if(!okdoor(x,y) && nxcor)
407 return;
408 dosdoor(x,y,aroom,rn2(8) ? DOOR7 : SDOOR3);
409}
410
411static void
412dosdoor(int x, int y, struct mkroom *aroom, int type)
413{
414 struct mkroom *broom;
415 int tmp;
416
417 if(!IS_WALL(levl[x][y].typ)((levl[x][y].typ) <= 2)) /* avoid SDOORs with '+' as scrsym */
418 type = DOOR7;
419 levl[x][y].typ = type;
420 if(type == DOOR7)
421 levl[x][y].scrsym = '+';
422 aroom->doorct++;
423 broom = aroom+1;
424 if(broom->hx < 0) tmp = doorindex; else
425 for(tmp = doorindex; tmp > broom->fdoor; tmp--)
426 doors[tmp] = doors[tmp-1];
427 doorindex++;
428 doors[tmp].x = x;
429 doors[tmp].y = y;
430 for( ; broom->hx >= 0; broom++) broom->fdoor++;
431}
432
433/* Only called from makerooms() */
434static int
435maker(schar lowx, schar ddx, schar lowy, schar ddy)
436{
437 struct mkroom *croom;
438 int x, y, hix = lowx+ddx, hiy = lowy+ddy;
439 int xlim = XLIM4 + secret, ylim = YLIM3 + secret;
440
441 if(nroom >= MAXNROFROOMS15) return(0);
442 if(lowx < XLIM4) lowx = XLIM4;
443 if(lowy < YLIM3) lowy = YLIM3;
444 if(hix > COLNO80-XLIM4-1) hix = COLNO80-XLIM4-1;
445 if(hiy > ROWNO22-YLIM3-1) hiy = ROWNO22-YLIM3-1;
446chk:
447 if(hix <= lowx || hiy <= lowy) return(0);
448
449 /* check area around room (and make room smaller if necessary) */
450 for(x = lowx - xlim; x <= hix + xlim; x++) {
451 for(y = lowy - ylim; y <= hiy + ylim; y++) {
452 if(levl[x][y].typ) {
453#ifdef WIZARD"bruno"
454 if(wizardflags.debug && !secret)
455 pline("Strange area [%d,%d] in maker().",x,y);
456#endif /* WIZARD */
457 if(!rn2(3)) return(0);
458 if(x < lowx)
459 lowx = x+xlim+1;
460 else
461 hix = x-xlim-1;
462 if(y < lowy)
463 lowy = y+ylim+1;
464 else
465 hiy = y-ylim-1;
466 goto chk;
467 }
468 }
469 }
470
471 croom = &rooms[nroom];
472
473 /* on low levels the room is lit (usually) */
474 /* secret vaults are always lit */
475 if((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1)) {
476 for(x = lowx-1; x <= hix+1; x++)
477 for(y = lowy-1; y <= hiy+1; y++)
478 levl[x][y].lit = 1;
479 croom->rlit = 1;
480 } else
481 croom->rlit = 0;
482 croom->lx = lowx;
483 croom->hx = hix;
484 croom->ly = lowy;
485 croom->hy = hiy;
486 croom->rtype = croom->doorct = croom->fdoor = 0;
487
488 for(x = lowx-1; x <= hix+1; x++)
489 for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
490 levl[x][y].scrsym = '-';
491 levl[x][y].typ = HWALL1;
492 }
493 for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
494 for(y = lowy; y <= hiy; y++) {
495 levl[x][y].scrsym = '|';
496 levl[x][y].typ = VWALL2;
497 }
498 for(x = lowx; x <= hix; x++)
499 for(y = lowy; y <= hiy; y++) {
500 levl[x][y].scrsym = '.';
501 levl[x][y].typ = ROOM9;
502 }
503
504 smeq[nroom] = nroom;
505 croom++;
506 croom->hx = -1;
507 nroom++;
508 return(1);
509}
510
511static void
512makecorridors(void)
513{
514 int a,b;
515
516 nxcor = 0;
517 for(a = 0; a < nroom-1; a++)
518 join(a, a+1);
519 for(a = 0; a < nroom-2; a++)
520 if(smeq[a] != smeq[a+2])
521 join(a, a+2);
522 for(a = 0; a < nroom; a++)
523 for(b = 0; b < nroom; b++)
524 if(smeq[a] != smeq[b])
525 join(a, b);
526 if(nroom > 2)
527 for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) {
528 a = rn2(nroom);
529 b = rn2(nroom-2);
530 if(b >= a) b += 2;
531 join(a, b);
532 }
533}
534
535static void
536join(int a, int b)
537{
538 coord cc,tt;
539 int tx, ty, xx, yy;
540 struct rm *crm;
541 struct mkroom *croom, *troom;
542 int dx, dy, dix, diy, cct;
543
544 croom = &rooms[a];
545 troom = &rooms[b];
546
547 /* find positions cc and tt for doors in croom and troom
548 and direction for a corridor between them */
549
550 if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX100) return;
551 if(troom->lx > croom->hx) {
552 dx = 1;
553 dy = 0;
554 xx = croom->hx+1;
555 tx = troom->lx-1;
556 cc = finddpos(xx,croom->ly,xx,croom->hy);
557 tt = finddpos(tx,troom->ly,tx,troom->hy);
558 } else if(troom->hy < croom->ly) {
559 dy = -1;
560 dx = 0;
561 yy = croom->ly-1;
562 cc = finddpos(croom->lx,yy,croom->hx,yy);
563 ty = troom->hy+1;
564 tt = finddpos(troom->lx,ty,troom->hx,ty);
565 } else if(troom->hx < croom->lx) {
566 dx = -1;
567 dy = 0;
568 xx = croom->lx-1;
569 tx = troom->hx+1;
570 cc = finddpos(xx,croom->ly,xx,croom->hy);
571 tt = finddpos(tx,troom->ly,tx,troom->hy);
572 } else {
573 dy = 1;
574 dx = 0;
575 yy = croom->hy+1;
576 ty = troom->ly-1;
577 cc = finddpos(croom->lx,yy,croom->hx,yy);
578 tt = finddpos(troom->lx,ty,troom->hx,ty);
579 }
580 xx = cc.x;
581 yy = cc.y;
582 tx = tt.x - dx;
583 ty = tt.y - dy;
584 if(nxcor && levl[xx+dx][yy+dy].typ)
585 return;
586 dodoor(xx,yy,croom);
587
588 cct = 0;
589 while(xx != tx || yy != ty) {
590 xx += dx;
591 yy += dy;
592
593 /* loop: dig corridor at [xx,yy] and find new [xx,yy] */
594 if(cct++ > 500 || (nxcor && !rn2(35)))
595 return;
596
597 if(xx == COLNO80-1 || xx == 0 || yy == 0 || yy == ROWNO22-1)
598 return; /* impossible */
599
600 crm = &levl[xx][yy];
601 if(!(crm->typ)) {
602 if(rn2(100)) {
603 crm->typ = CORR8;
604 crm->scrsym = CORR_SYM'#';
605 if(nxcor && !rn2(50))
606 (void) mkobj_at(ROCK_SYM'`', xx, yy);
607 } else {
608 crm->typ = SCORR4;
609 crm->scrsym = ' ';
610 }
611 } else
612 if(crm->typ != CORR8 && crm->typ != SCORR4) {
613 /* strange ... */
614 return;
615 }
616
617 /* find next corridor position */
618 dix = abs(xx-tx);
619 diy = abs(yy-ty);
620
621 /* do we have to change direction ? */
622 if(dy && dix > diy) {
623 int ddx = (xx > tx) ? -1 : 1;
624
625 crm = &levl[xx+ddx][yy];
626 if(!crm->typ || crm->typ == CORR8 || crm->typ == SCORR4) {
627 dx = ddx;
628 dy = 0;
629 continue;
630 }
631 } else if(dx && diy > dix) {
632 int ddy = (yy > ty) ? -1 : 1;
633
634 crm = &levl[xx][yy+ddy];
635 if(!crm->typ || crm->typ == CORR8 || crm->typ == SCORR4) {
636 dy = ddy;
637 dx = 0;
638 continue;
639 }
640 }
641
642 /* continue straight on? */
643 crm = &levl[xx+dx][yy+dy];
644 if(!crm->typ || crm->typ == CORR8 || crm->typ == SCORR4)
645 continue;
646
647 /* no, what must we do now?? */
648 if(dx) {
649 dx = 0;
650 dy = (ty < yy) ? -1 : 1;
651 crm = &levl[xx+dx][yy+dy];
652 if(!crm->typ || crm->typ == CORR8 || crm->typ == SCORR4)
653 continue;
654 dy = -dy;
655 continue;
656 } else {
657 dy = 0;
658 dx = (tx < xx) ? -1 : 1;
659 crm = &levl[xx+dx][yy+dy];
660 if(!crm->typ || crm->typ == CORR8 || crm->typ == SCORR4)
661 continue;
662 dx = -dx;
663 continue;
664 }
665 }
666
667 /* we succeeded in digging the corridor */
668 dodoor(tt.x, tt.y, troom);
669
670 if(smeq[a] < smeq[b])
671 smeq[b] = smeq[a];
672 else
673 smeq[a] = smeq[b];
674}
675
676static void
677make_niches(void)
678{
679 int ct = rnd(nroom/2 + 1);
680 while(ct--) makeniche(FALSE0);
681}
682
683static void
684makevtele(void)
685{
686 makeniche(TRUE1);
687}
688
689static void
690makeniche(boolean with_trap)
691{
692 struct mkroom *aroom;
693 struct rm *rm;
694 int vct = 8;
695 coord dd;
696 int dy,xx,yy;
697 struct trap *ttmp;
698
699 if(doorindex < DOORMAX100)
700 while(vct--) {
701 aroom = &rooms[rn2(nroom-1)];
702 if(aroom->rtype != 0) continue; /* not an ordinary room */
703 if(aroom->doorct == 1 && rn2(5)) continue;
704 if(rn2(2)) {
705 dy = 1;
706 dd = finddpos(aroom->lx,aroom->hy+1,aroom->hx,aroom->hy+1);
707 } else {
708 dy = -1;
709 dd = finddpos(aroom->lx,aroom->ly-1,aroom->hx,aroom->ly-1);
710 }
711 xx = dd.x;
712 yy = dd.y;
713 if((rm = &levl[xx][yy+dy])->typ) continue;
714 if(with_trap || !rn2(4)) {
715 rm->typ = SCORR4;
716 rm->scrsym = ' ';
717 if(with_trap) {
718 ttmp = maketrap(xx, yy+dy, TELEP_TRAP4);
719 ttmp->once = 1;
720 make_engr_at(xx, yy-dy, "ad ae?ar um");
721 }
722 dosdoor(xx, yy, aroom, SDOOR3);
723 } else {
724 rm->typ = CORR8;
725 rm->scrsym = CORR_SYM'#';
726 if(rn2(7))
727 dosdoor(xx, yy, aroom, rn2(5) ? SDOOR3 : DOOR7);
728 else {
729 mksobj_at(SCR_TELEPORTATION143, xx, yy+dy);
730 if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy);
731 }
732 }
733 return;
734 }
735}
736
737/* make a trap somewhere (in croom if mazeflag = 0) */
738void
739mktrap(int num, int mazeflag, struct mkroom *croom)
740{
741 struct trap *ttmp;
742 int kind,nopierc,nomimic,fakedoor,fakegold,tryct = 0;
743 xchar mx,my;
744 extern char fut_geno[];
745
746 if(!num || num >= TRAPNUM9) {
1
Assuming 'num' is not equal to 0
2
Assuming 'num' is < TRAPNUM
3
Taking false branch
747 nopierc = (dlevel < 4) ? 1 : 0;
748 nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
749 if(strchr(fut_geno, 'M')) nomimic = 1;
750 kind = rn2(TRAPNUM9 - nopierc - nomimic);
751 /* note: PIERC = 7, MIMIC = 8, TRAPNUM = 9 */
752 } else kind = num;
753
754 if(kind == MIMIC8) {
4
Assuming 'kind' is equal to MIMIC
5
Taking true branch
755 struct monst *mtmp;
756
757 fakedoor = (!rn2(3) && !mazeflag);
6
Assuming the condition is false
758 fakegold = (!fakedoor
6.1
'fakedoor' is 0
&& !rn2(2));
7
Assuming the condition is false
759 if(fakegold
7.1
'fakegold' is 0
) goldseen = TRUE1;
8
Taking false branch
760 do {
761 if(++tryct > 200) return;
9
Taking false branch
762 if(fakedoor
9.1
'fakedoor' is 0
) {
10
Taking false branch
763 /* note: fakedoor maybe on actual door */
764 if(rn2(2)){
765 if(rn2(2))
766 mx = croom->hx+1;
767 else mx = croom->lx-1;
768 my = somey()((random()%(croom->hy-croom->ly+1))+croom->ly);
769 } else {
770 if(rn2(2))
771 my = croom->hy+1;
772 else my = croom->ly-1;
773 mx = somex()((random()%(croom->hx-croom->lx+1))+croom->lx);
774 }
775 } else if(mazeflag) {
11
Assuming 'mazeflag' is not equal to 0
12
Taking true branch
776 coord mm;
777 mx = mm.x;
13
Assigned value is garbage or undefined
778 my = mm.y;
779 } else {
780 mx = somex()((random()%(croom->hx-croom->lx+1))+croom->lx);
781 my = somey()((random()%(croom->hy-croom->ly+1))+croom->ly);
782 }
783 } while(m_at(mx,my) || levl[(int)mx][(int)my].typ == STAIRS10);
784 if ((mtmp = makemon(PM_MIMIC&mons[37],mx,my))) {
785 mtmp->mimic = 1;
786 mtmp->mappearance =
787 fakegold ? '$' : fakedoor ? '+' :
788 (mazeflag && rn2(2)) ? AMULET_SYM'"' :
789 "=/)%?![<>" [ rn2(9) ];
790 }
791 return;
792 }
793
794 do {
795 if(++tryct > 200)
796 return;
797 if(mazeflag){
798 extern coord mazexy();
799 coord mm;
800 mm = mazexy();
801 mx = mm.x;
802 my = mm.y;
803 } else {
804 mx = somex()((random()%(croom->hx-croom->lx+1))+croom->lx);
805 my = somey()((random()%(croom->hy-croom->ly+1))+croom->ly);
806 }
807 } while(t_at(mx, my) || levl[(int)mx][(int)my].typ == STAIRS10);
808 ttmp = maketrap(mx, my, kind);
809 if(mazeflag && !rn2(10) && ttmp->ttyp < PIERC7)
810 ttmp->tseen = 1;
811}