abstract
| - Below is the full text to mklev.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/mklev.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ 2. 3. #include 4. #include "mklev.h" 5. #include "def.trap.h" 6. 7. extern char *getlogin(); 8. extern struct monst *makemon(); 9. 10. char *tfile,*tspe,**args; 11. char nul[40]; 12. 13. #include "savelev.h" 14. 15. #ifdef WIZARD 16. boolean wizard; 17. #endif WIZARD 18. 19. 20. #define somex() ((rand()%(croom->hx-croom->lx+1))+croom->lx) 21. #define somey() ((rand()%(croom->hy-croom->ly+1))+croom->ly) 22. 23. struct rm levl[COLNO][ROWNO]; 24. struct monst *fmon; 25. struct obj *fobj; 26. struct gen *fgold, *ftrap; 27. 28. char *fut_geno; /* monsters that should not be created anymore */ 29. 30. struct mkroom rooms[MAXNROFROOMS+1], *croom, *troom; 31. coord doors[DOORMAX]; 32. int doorindex = 0; 33. int comp(); 34. 35. xchar dlevel; 36. schar nxcor,xx,yy,dx,dy,tx,ty; /* for corridors and other things... */ 37. boolean goldseen; 38. int nroom; 39. 40. xchar xdnstair,xupstair,ydnstair,yupstair; 41. 42. 43. main(argc,argv) 44. char *argv[]; 45. { 46. register unsigned tryct; 47. 48. if(argc < 6) panic("Too few arguments!!"); 49. args = argv; 50. tfile = argv[1]; 51. tspe = argv[2]; 52. dlevel = atoi(argv[3]); 53. if(dlevel < 1) panic("Bad level"); 54. fut_geno = argv[4]; 55. #ifdef WIZARD 56. wizard = (argv[5][0] == 'w'); 57. #endif WIZARD 58. (void) srand(getpid()); 59. init_objects(); 60. rooms[0].hx = -1; /* in case we are in a maze */ 61. 62. /* a: normal; b: maze */ 63. if(*tspe == 'b') { 64. makemaz(); 65. savelev(); 66. exit(0); 67. } 68. 69. /* construct the rooms */ 70. while(nroom < (MAXNROFROOMS/3)) { 71. croom = rooms; 72. nroom = 0; 73. (void) makerooms(0); /* not secret */ 74. } 75. 76. /* for each room: put things inside */ 77. for(croom = rooms; croom->hx > 0; croom++) { 78. 79. /* put a sleeping monster inside */ 80. if(!rn2(3)) (void) 81. makemon((struct permonst *) 0, somex(), somey()); 82. 83. /* put traps and mimics inside */ 84. goldseen = FALSE; 85. while(!rn2(8-(dlevel/6))) mktrap(0,0); 86. if(!goldseen && !rn2(3)) mkgold(0,somex(),somey()); 87. if(!rn2(3)) { 88. mkobj_at(0, somex(), somey()); 89. tryct = 0; 90. while(!rn2(5)) { 91. if(++tryct > 100){ 92. printf("tryct overflow4
"); 93. break; 94. } 95. mkobj_at(0, somex(), somey()); 96. } 97. } 98. } 99. tryct = 0; 100. do { 101. if(++tryct > 1000) panic("Cannot make dnstairs
"); 102. croom = &rooms[rn2(nroom)]; 103. xdnstair = somex(); 104. ydnstair = somey(); 105. } while((*tspe =='n' && (!(xdnstair%2) || !(ydnstair%2))) || 106. g_at(xdnstair,ydnstair,ftrap)); 107. levl[xdnstair][ydnstair].scrsym ='>'; 108. levl[xdnstair][ydnstair].typ = STAIRS; 109. troom = croom; 110. do { 111. if(++tryct > 2000) panic("Cannot make upstairs
"); 112. croom = &rooms[rn2(nroom)]; 113. xupstair = somex(); 114. yupstair = somey(); 115. } while(croom == troom || m_at(xupstair,yupstair) || 116. g_at(xupstair,yupstair,ftrap)); 117. levl[xupstair][yupstair].scrsym ='<'; 118. levl[xupstair][yupstair].typ = STAIRS; 119. 120. qsort((char *) rooms, nroom, sizeof(struct mkroom), comp); 121. croom = rooms; 122. troom = croom+1; 123. nxcor = 0; 124. mkpos(); 125. do makecor(); 126. while (croom->hx > 0 && troom->hx > 0); 127. 128. /* make a secret treasure vault, not connected to the rest */ 129. if(nroom < (2*MAXNROFROOMS/3)) if(!rn2(3)) { 130. register int x,y; 131. troom = croom = &rooms[nroom]; 132. if(makerooms(1)) { /* make secret room */ 133. troom->rtype = 6; /* treasure vault */ 134. for(x = troom->lx; x <= troom->hx; x++) 135. for(y = troom->ly; y <= troom->hy; y++) 136. mkgold(rnd(dlevel*100) + 50, x, y); 137. } 138. } 139. 140. #ifdef WIZARD 141. if(wizard){ 142. if(rn2(3)) mkshop(); else mkzoo(); 143. } else 144. #endif WIZARD 145. if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 2) mkshop(); 146. else 147. if(dlevel > 6 && (!rn2(7) || !strcmp("david", getlogin()))) 148. mkzoo(); 149. savelev(); 150. exit(0); 151. } 152. 153. makerooms(secret) int secret; { 154. register int lowx, lowy; 155. register int tryct = 0; 156. while(nroom < (MAXNROFROOMS/2) || secret) 157. for(lowy = rn1(3,3); lowy < ROWNO-7; lowy += rn1(2,4)) { 158. for(lowx = rn1(3,4); lowx < COLNO-10; lowx += rn1(2,7)) { 159. if(tryct++ > 10000) return(0); 160. if((lowy += (rn2(5)-2)) < 3) lowy = 3; 161. else if(lowy > ROWNO-6) lowy = ROWNO-6; 162. if(levl[lowx][lowy].typ) continue; 163. if((secret && maker(lowx, 1, lowy, 1)) || 164. (!secret && maker(lowx,rn1(9,2),lowy,rn1(4,2)) 165. && nroom+2 > MAXNROFROOMS)) return(1); 166. } 167. } 168. return(1); 169. } 170. 171. comp(x,y) 172. register struct mkroom *x,*y; 173. { 174. if(x->lx < y->lx) return(-1); 175. return(x->lx > y->lx); 176. } 177. 178. coord 179. finddpos(xl,yl,xh,yh) { 180. coord ff; 181. register x,y; 182. ff.x = (xl == xh) ? xl : (xl + rn2(xh-xl+1)); 183. ff.y = (yl == yh) ? yl : (yl + rn2(yh-yl+1)); 184. if(okdoor(ff.x, ff.y)) return(ff); 185. if(xl < xh) for(x = xl; x <= xh; x++) 186. if(okdoor(x, ff.y)){ 187. ff.x = x; 188. return(ff); 189. } 190. if(yl < yh) for(y = yl; y <= yh; y++) 191. if(okdoor(ff.x, y)){ 192. ff.y = y; 193. return(ff); 194. } 195. return(ff); 196. } 197. 198. /* when croom and troom exist, find position for a door in croom 199. and direction for a corridor towards position [tx,ty] in the wall 200. of troom */ 201. mkpos() 202. { 203. coord cc,tt; 204. if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return; 205. if(troom->lx > croom->hx) { 206. dx = 1; 207. dy = 0; 208. xx = croom->hx+1; 209. tx = troom->lx-1; 210. cc = finddpos(xx,croom->ly,xx,croom->hy); 211. tt = finddpos(tx,troom->ly,tx,troom->hy); 212. } else if(troom->hy < croom->ly) { 213. dy = -1; 214. dx = 0; 215. yy = croom->ly-1; 216. cc = finddpos(croom->lx,yy,croom->hx,yy); 217. ty = troom->hy+1; 218. tt = finddpos(troom->lx,ty,troom->hx,ty); 219. } else if(troom->hx < croom->lx) { 220. dx = -1; 221. dy = 0; 222. xx = croom->lx-1; 223. tx = troom->hx+1; 224. cc = finddpos(xx,croom->ly,xx,croom->hy); 225. tt = finddpos(tx,troom->ly,tx,troom->hy); 226. } else { 227. dy = 1; 228. dx = 0; 229. yy = croom->hy+1; 230. ty = troom->ly-1; 231. cc = finddpos(croom->lx,yy,croom->hx,yy); 232. tt = finddpos(troom->lx,ty,troom->hx,ty); 233. } 234. xx = cc.x; 235. yy = cc.y; 236. tx = tt.x; 237. ty = tt.y; 238. if(levl[xx+dx][yy+dy].typ) { 239. if(nxcor) newloc(); 240. else { 241. dodoor(xx,yy,croom); 242. xx += dx; 243. yy += dy; 244. } 245. return; 246. } 247. dodoor(xx,yy,croom); 248. } 249. 250. /* if allowable, create a door at [x,y] */ 251. okdoor(x,y) 252. register x,y; 253. { 254. if(levl[x-1][y].typ == DOOR || levl[x+1][y].typ == DOOR || 255. levl[x][y+1].typ == DOOR || levl[x][y-1].typ == DOOR || 256. levl[x-1][y].typ == SDOOR || levl[x+1][y].typ == SDOOR || 257. levl[x][y-1].typ == SDOOR || levl[x][y+1].typ == SDOOR || 258. (levl[x][y].typ != HWALL && levl[x][y].typ != VWALL) || 259. doorindex >= DOORMAX) 260. return(0); 261. return(1); 262. } 263. 264. dodoor(x,y,aroom) 265. register x,y; 266. register struct mkroom *aroom; 267. { 268. register struct mkroom *broom; 269. register tmp; 270. if(doorindex >= DOORMAX) panic("DOORMAX exceeded?"); 271. if(!okdoor(x,y) && nxcor) return; 272. if(!rn2(8)) levl[x][y].typ = SDOOR; 273. else { 274. levl[x][y].scrsym ='+'; 275. levl[x][y].typ = DOOR; 276. } 277. aroom->doorct++; 278. broom = aroom+1; 279. if(broom->hx < 0) tmp = doorindex; else 280. for(tmp = doorindex; tmp > broom->fdoor; tmp--) 281. doors[tmp] = doors[tmp-1]; 282. doorindex++; 283. doors[tmp].x = x; 284. doors[tmp].y = y; 285. for( ; broom->hx >= 0; broom++) broom->fdoor++; 286. } 287. 288. newloc() 289. { 290. register a,b; 291. register int tryct = 0; 292. 293. ++croom; 294. ++troom; 295. if(nxcor || croom->hx < 0 || troom->hx < 0) { 296. if(nxcor++ > rn1(nroom,4)) { 297. croom = &rooms[nroom]; 298. return; 299. } 300. do { 301. if(++tryct > 100){ 302. printf("tryct overflow5
"); 303. croom = &rooms[nroom]; 304. return; 305. } 306. a = rn2(nroom); 307. b = rn2(nroom); 308. croom = &rooms[a]; 309. troom = &rooms[b]; 310. } while(croom == troom || (troom == croom+1 && !rn2(3))); 311. } 312. mkpos(); 313. } 314. 315. /* make a trap somewhere (in croom if mazeflag = 0) */ 316. mktrap(num,mazeflag) 317. register num,mazeflag; 318. { 319. register struct gen *gtmp; 320. register int kind,nopierc,nomimic,fakedoor,fakegold,tryct = 0; 321. register xchar mx,my; 322. 323. if(!num || num >= TRAPNUM) { 324. nopierc = (dlevel < 4) ? 1 : 0; 325. nomimic = (dlevel < 9 || goldseen ) ? 1 : 0; 326. if(index(fut_geno, 'M')) nomimic = 1; 327. kind = rn2(TRAPNUM - nopierc - nomimic); 328. /* note: PIERC = 7, MIMIC = 8, TRAPNUM = 9 */ 329. } else kind = num; 330. 331. if(kind == MIMIC) { 332. register struct monst *mtmp; 333. 334. fakedoor = (!rn2(3) && !mazeflag); 335. fakegold = (!fakedoor && !rn2(2)); 336. if(fakegold) goldseen = TRUE; 337. do { 338. if(++tryct > 200) return; 339. if(fakedoor) { 340. /* note: fakedoor maybe on actual door */ 341. if(rn2(2)){ 342. if(rn2(2)) 343. mx = croom->hx+1; 344. else mx = croom->lx-1; 345. my = somey(); 346. } else { 347. if(rn2(2)) 348. my = croom->hy+1; 349. else my = croom->ly-1; 350. mx = somex(); 351. } 352. } else if(mazeflag) { 353. extern coord mazexy(); 354. coord mm; 355. mm = mazexy(); 356. mx = mm.x; 357. my = mm.y; 358. } else { 359. mx = somex(); 360. my = somey(); 361. } 362. } while(m_at(mx,my)); 363. if(mtmp = makemon(PM_MIMIC,mx,my)) 364. mtmp->mimic = 365. fakegold ? '$' : fakedoor ? '+' : 366. (mazeflag && rn2(2)) ? AMULET_SYM : 367. "=/)%?![<>" [ rn2(9) ]; 368. return; 369. } 370. gtmp = newgen(); 371. gtmp->gflag = kind; 372. do { 373. if(++tryct > 200){ 374. printf("tryct overflow7
"); 375. free((char *) gtmp); 376. return; 377. } 378. if(mazeflag){ 379. extern coord mazexy(); 380. coord mm; 381. mm = mazexy(); 382. gtmp->gx = mm.x; 383. gtmp->gy = mm.y; 384. } else { 385. gtmp->gx = somex(); 386. gtmp->gy = somey(); 387. } 388. } while(g_at(gtmp->gx, gtmp->gy, ftrap)); 389. gtmp->ngen = ftrap; 390. ftrap = gtmp; 391. if(mazeflag && !rn2(10) && gtmp->gflag < PIERC) gtmp->gflag |= SEEN; 392. } 393. 394. /*VARARGS1*/ 395. panic(str,arg1,arg2,arg3) 396. char *str,*arg1,*arg2,*arg3; 397. { 398. char bufr[BUFSZ]; 399. extern char *sprintf(); 400. (void) sprintf(bufr,str,arg1,arg2,arg3); 401. (void) write(1,"
MKLEV ERROR: ",15); 402. puts(bufr); 403. (void) fflush(stdout); 404. exit(1); 405. } 406. 407. maker(lowx,ddx,lowy,ddy) 408. schar lowx,ddx,lowy,ddy; 409. { 410. register x, y, hix = lowx+ddx, hiy = lowy+ddy; 411. 412. if(nroom >= MAXNROFROOMS) return(0); 413. if(hix > COLNO-5) hix = COLNO-5; 414. if(hiy > ROWNO-4) hiy = ROWNO-4; 415. chk: 416. if(hix <= lowx || hiy <= lowy) return(0); 417. 418. /* check area around room (and make room smaller if necessary) */ 419. for(x = lowx-4; x <= hix+4; x++) 420. for(y = lowy-3; y <= hiy+3; y++) 421. if(levl[x][y].typ) { 422. if(rn2(3)) return(0); 423. lowx = x+5; 424. lowy = y+4; 425. goto chk; 426. } 427. 428. /* on low levels the room is lit (usually) */ 429. /* secret vaults are always lit */ 430. if((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1)) 431. for(x = lowx-1; x <= hix+1; x++) 432. for(y = lowy-1; y <= hiy+1; y++) 433. levl[x][y].lit = 1; 434. croom->lx = lowx; 435. croom->hx = hix; 436. croom->ly = lowy; 437. croom->hy = hiy; 438. croom->rtype = croom->doorct = croom->fdoor = 0; 439. for(x = lowx-1; x <= hix+1; x++) 440. for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) { 441. levl[x][y].scrsym = '-'; 442. levl[x][y].typ = HWALL; 443. } 444. for(x = lowx-1; x <= hix+1; x += (hix-lowx+2)) 445. for(y = lowy; y <= hiy; y++) { 446. levl[x][y].scrsym = '|'; 447. levl[x][y].typ = VWALL; 448. } 449. for(x = lowx; x <= hix; x++) 450. for(y = lowy; y <= hiy; y++) { 451. levl[x][y].scrsym = '.'; 452. levl[x][y].typ = ROOM; 453. } 454. croom++; 455. croom->hx = -1; 456. nroom++; 457. return(1); 458. } 459. 460. makecor() { 461. register nx, ny; 462. register struct rm *crm; 463. register dix, diy, secondtry = 0; 464. 465. tryagain: 466. nx = xx + dx; 467. ny = yy + dy; 468. 469. if(nxcor && !rn2(35)) { 470. newloc(); 471. return; 472. } 473. if(nx == COLNO-1 || nx == 0 || ny == 0 || ny == ROWNO-1) { 474. if(nxcor) { 475. newloc(); 476. return; 477. } else { 478. printf("something went wrong. we try again...
"); 479. execl("./mklev",args[0],tfile,tspe,args[3],args[4],args[5],0); 480. panic("cannot execute ./mklev
"); 481. } 482. } 483. 484. dix = abs(nx-tx); 485. diy = abs(ny-ty); 486. if(dy && dix > diy) { 487. dy = 0; 488. dx = (nx > tx) ? -1 : 1; 489. } else if(dx && diy > dix) { 490. dx = 0; 491. dy = (ny > ty) ? -1 : 1; 492. } 493. 494. crm = &levl[nx][ny]; 495. if(!(crm->typ)) { 496. if(rn2(100)) { 497. crm->typ = CORR; 498. crm->scrsym = CORR_SYM; 499. } else { 500. crm->typ = SCORR; 501. crm->scrsym = ' '; 502. } 503. xx = nx; 504. yy = ny; 505. if(nxcor && !rn2(50)) { 506. mkobj_at(ROCK_SYM, nx, ny); 507. } 508. return; 509. } 510. if(crm->typ == CORR || crm->typ == SCORR) { 511. xx = nx; 512. yy = ny; 513. return; 514. } 515. if(nx == tx && ny == ty) { 516. dodoor(nx,ny,troom); 517. newloc(); 518. return; 519. } 520. if(!secondtry++ && (nx != xx+dx || ny != yy+dy)) 521. goto tryagain; 522. if(dx) { 523. if(ty < ny) dy = -1; 524. else dy = levl[nx+dx][ny-1].typ == ROOM?1:-1; 525. dx = 0; 526. } else { 527. if(tx < nx) dx = -1; 528. else dx = levl[nx-1][ny+dy].typ == ROOM?1:-1; 529. dy = 0; 530. } 531. } 532. 533. struct monst * 534. m_at(x,y) 535. register x,y; 536. { 537. register struct monst *mtmp; 538. 539. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 540. if(mtmp->mx == x && mtmp->my == y) return(mtmp); 541. return(0); 542. } 543. 544. struct gen * 545. g_at(x,y,ptr) 546. register x,y; 547. register struct gen *ptr; 548. { 549. while(ptr) { 550. if(ptr->gx == x && ptr->gy == y) return(ptr); 551. ptr = ptr->ngen; 552. } 553. return(0); 554. }
|