Source:NetHack 3.0.0/mkroom.c
Jump to navigation
Jump to search
Below is the full text to mkroom.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/mkroom.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)mkroom.c 3.0 88/11/24 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* 6. * Entry points: 7. * mkroom() -- make and stock a room of a given type 8. * nexttodoor() -- return TRUE if adjacent to a door 9. * has_dnstairs() -- return TRUE if given room has a down staircase 10. * has_upstairs() -- return TRUE if given room has an up staircase 11. * dist2() -- Euclidean square-of-distance function 12. * courtmon() -- generate a court monster 13. */ 14. #include "hack.h" 15. 16. static void mkshop(), mkzoo(), mkswamp(); 17. #ifdef ORACLE 18. static void mkdelphi(); 19. #endif 20. #if defined(ALTARS) && defined(THEOLOGY) 21. static void mktemple(); 22. #endif 23. 24. static struct permonst *morguemon(); 25. #ifdef ARMY 26. static struct permonst *squadmon(); 27. #endif 28. 29. #define sq(x) ((x)*(x)) 30. 31. static boolean 32. isbig(sroom) 33. register struct mkroom *sroom; 34. { 35. register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly); 36. return( area > 20 ); 37. } 38. 39. void 40. mkroom(roomtype) 41. /* make and stock a room of a given type */ 42. int roomtype; 43. { 44. 45. if (roomtype >= SHOPBASE) 46. mkshop(); /* someday, we should be able to specify shop type */ 47. else switch(roomtype) { 48. #ifdef THRONES 49. case COURT: mkzoo(COURT); break; 50. #endif 51. case ZOO: mkzoo(ZOO); break; 52. case BEEHIVE: mkzoo(BEEHIVE); break; 53. case MORGUE: mkzoo(MORGUE); break; 54. case BARRACKS: mkzoo(BARRACKS); break; 55. case SWAMP: mkswamp(); break; 56. #ifdef ORACLE 57. case DELPHI: mkdelphi(); break; 58. #endif 59. #if defined(ALTARS) && defined(THEOLOGY) 60. case TEMPLE: mktemple(); break; 61. #endif 62. default: impossible("Tried to make a room of type %d.", roomtype); 63. } 64. } 65. 66. static void 67. mkshop() 68. { 69. register struct mkroom *sroom; 70. int i = -1; 71. #ifdef WIZARD 72. register char *ep; 73. 74. /* first determine shoptype */ 75. if(wizard){ 76. ep = getenv("SHOPTYPE"); 77. if(ep){ 78. if(*ep == 'z' || *ep == 'Z'){ 79. mkzoo(ZOO); 80. return; 81. } 82. if(*ep == 'm' || *ep == 'M'){ 83. mkzoo(MORGUE); 84. return; 85. } 86. if(*ep == 'b' || *ep == 'B'){ 87. mkzoo(BEEHIVE); 88. return; 89. } 90. #ifdef THRONES 91. if(*ep == 't' || *ep == 'T'){ 92. mkzoo(COURT); 93. return; 94. } 95. #endif 96. #ifdef ARMY 97. if(*ep == 's' || *ep == 'S'){ 98. mkzoo(BARRACKS); 99. return; 100. } 101. #endif /* ARMY */ 102. #if defined(ALTARS) && defined(THEOLOGY) 103. if(*ep == '_'){ 104. mktemple(); 105. return; 106. } 107. #endif 108. if(*ep == '}'){ 109. mkswamp(); 110. return; 111. } 112. for(i=0; shtypes[i].name; i++) 113. if(*ep == shtypes[i].symb) goto gottype; 114. i = -1; 115. } 116. } 117. gottype: 118. #endif 119. for(sroom = &rooms[0]; ; sroom++){ 120. if(sroom->hx < 0) return; 121. if(sroom - rooms >= nroom) { 122. pline("rooms not closed by -1?"); 123. return; 124. } 125. if(sroom->rtype != OROOM) continue; 126. if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom)) 127. continue; 128. if( 129. #ifdef WIZARD 130. (wizard && ep && sroom->doorct != 0) || 131. #endif 132. sroom->doorct == 1) break; 133. } 134. 135. if(i < 0) { /* shoptype not yet determined */ 136. register int j; 137. 138. /* pick a shop type at random */ 139. for(j = rn2(100), i = 0; j -= shtypes[i].prob; i++) 140. if (j < 0) break; 141. 142. /* big rooms cannot be wand or book shops, 143. * - so make them general stores 144. */ 145. if(isbig(sroom) && (shtypes[i].symb == WAND_SYM 146. #ifdef SPELLS 147. || shtypes[i].symb == SPBOOK_SYM 148. #endif 149. )) i = 0; 150. } 151. sroom->rtype = SHOPBASE + i; 152. 153. /* stock the room with a shopkeeper and artifacts */ 154. stock_room(&(shtypes[i]), sroom); 155. } 156. 157. static struct mkroom * 158. pick_room() 159. /* pick an unused room, preferably with only one door */ 160. { 161. register struct mkroom *sroom; 162. register int i = nroom; 163. 164. for(sroom = &rooms[rn2(nroom)]; i--; sroom++) { 165. if(sroom == &rooms[nroom]) 166. sroom = &rooms[0]; 167. if(sroom->hx < 0) 168. return (struct mkroom *)0; 169. if(sroom->rtype != OROOM) continue; 170. if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3))) 171. continue; 172. if(sroom->doorct == 1 || !rn2(5)) 173. return sroom; 174. } 175. return (struct mkroom *)0; 176. } 177. 178. static void 179. mkzoo(type) 180. int type; 181. { 182. register struct mkroom *sroom; 183. struct monst *mon; 184. register int sx,sy,i; 185. int sh, tx, ty, goldlim = 500 * dlevel; 186. 187. if(!(sroom = pick_room())) return; 188. 189. sroom->rtype = type; 190. sh = sroom->fdoor; 191. switch(type) { 192. case COURT: 193. tx = somex(sroom); ty = somey(sroom); break; 194. /* TODO: try to ensure the enthroned monster is an M2_PRINCE */ 195. case BEEHIVE: 196. tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2; 197. ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2; 198. break; 199. } 200. for(sx = sroom->lx; sx <= sroom->hx; sx++) 201. for(sy = sroom->ly; sy <= sroom->hy; sy++){ 202. if((sx == sroom->lx && doors[sh].x == sx-1) || 203. (sx == sroom->hx && doors[sh].x == sx+1) || 204. (sy == sroom->ly && doors[sh].y == sy-1) || 205. (sy == sroom->hy && doors[sh].y == sy+1)) continue; 206. mon = makemon( 207. #ifdef THRONES 208. (type == COURT) ? courtmon() : 209. #endif 210. #ifdef ARMY 211. (type == BARRACKS) ? squadmon() : 212. #endif 213. (type == MORGUE) ? morguemon() : 214. (type == BEEHIVE) ? 215. (sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] : 216. &mons[PM_KILLER_BEE]) : 217. (struct permonst *) 0, 218. sx, sy); 219. if(mon) { 220. mon->msleep = 1; 221. #ifdef THRONES 222. if (type==COURT && mon->mpeaceful) { 223. mon->mpeaceful = 0; 224. mon->malign = max(3,abs(mon->data->maligntyp)); 225. } 226. #endif 227. } 228. switch(type) { 229. case ZOO: 230. i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y)); 231. if(i >= goldlim) i = 5*dlevel; 232. goldlim -= i; 233. mkgold((long)(10 + rn2(i)), sx, sy); 234. break; 235. case MORGUE: 236. if(!rn2(5)) 237. (void) mk_tt_corpse(sx, sy); 238. if(!rn2(10)) /* lots of treasure buried with dead */ 239. (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy); 240. break; 241. case BEEHIVE: 242. if(!rn2(3)) 243. (void) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy); 244. break; 245. case BARRACKS: 246. if(!rn2(20)) /* the payroll and some loot */ 247. (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy); 248. break; 249. } 250. } 251. #ifdef THRONES 252. if(type == COURT) { 253. levl[tx][ty].typ = THRONE; 254. levl[tx][ty].scrsym = THRONE_SYM; 255. 256. tx = somex(sroom); 257. ty = somey(sroom); 258. mkgold((long) rn1(50 * dlevel,10), sx, sy); 259. (void) mksobj_at(CHEST, sx, sy); /* the royal coffers */ 260. } 261. #endif 262. 263. } 264. 265. static struct permonst * 266. morguemon() 267. { 268. register int i = rn2(100), hd = rn2(dlevel); 269. 270. if(hd > 10 && i < 10) 271. return((Inhell) ? mkclass(S_DEMON) : &mons[ndemon()]); 272. if(hd > 8 && i > 85) 273. return(mkclass(S_VAMPIRE)); 274. 275. return((i < 20) ? &mons[PM_GHOST] 276. : (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE)); 277. } 278. 279. static void 280. mkswamp() /* Michiel Huisjes & Fred de Wilde */ 281. { 282. register struct mkroom *sroom; 283. register int sx,sy,i,eelct = 0; 284. 285. for(i=0; i<5; i++) { /* 5 tries */ 286. sroom = &rooms[rn2(nroom)]; 287. if(sroom->hx < 0 || sroom->rtype != OROOM || 288. has_upstairs(sroom) || has_dnstairs(sroom)) 289. continue; 290. 291. /* satisfied; make a swamp */ 292. sroom->rtype = SWAMP; 293. for(sx = sroom->lx; sx <= sroom->hx; sx++) 294. for(sy = sroom->ly; sy <= sroom->hy; sy++) 295. if(levl[sx][sy].omask == 0 && levl[sx][sy].gmask == 0 && 296. levl[sx][sy].mmask == 0 && 297. !t_at(sx,sy) && !nexttodoor(sx,sy)) { 298. if((sx+sy)%2) { 299. levl[sx][sy].typ = POOL; 300. levl[sx][sy].scrsym = POOL_SYM; 301. if(!eelct || !rn2(4)) { 302. (void) makemon(mkclass(S_EEL), sx, sy); 303. eelct++; 304. } 305. } else if(!rn2(4)) /* swamps tend to be moldy */ 306. (void) makemon(mkclass(S_FUNGUS), sx, sy); 307. } 308. } 309. } 310. 311. #ifdef ORACLE 312. static void 313. mkdelphi() 314. { 315. register struct mkroom *sroom; 316. register struct monst *oracl; 317. int dy,xx,yy; 318. 319. if(doorindex >= DOORMAX) return; 320. if(!(sroom = pick_room())) return; 321. 322. if(!place_oracle(sroom,&dy,&xx,&yy)) return; 323. 324. /* set up Oracle and environment */ 325. if(!(oracl = makemon(&mons[PM_ORACLE],xx,yy))) return; 326. sroom->rtype = DELPHI; 327. oracl->mpeaceful = 1; 328. 329. yy -= dy; 330. if(ACCESSIBLE(levl[xx-1][yy].typ)) 331. (void) mkstatue(&mons[PM_FOREST_CENTAUR], xx-1, yy); 332. if(ACCESSIBLE(levl[xx][yy].typ)) 333. (void) mkstatue(&mons[PM_MOUNTAIN_CENTAUR], xx, yy); 334. if(ACCESSIBLE(levl[xx+1][yy].typ)) 335. (void) mkstatue(&mons[PM_PLAINS_CENTAUR], xx+1, yy); 336. # ifdef FOUNTAINS 337. mkfount(0,sroom); 338. # endif 339. } 340. #endif 341. 342. #if defined(ALTARS) && defined(THEOLOGY) 343. void 344. shrine_pos(sx,sy,troom) 345. int *sx,*sy; 346. struct mkroom *troom; 347. { 348. *sx = troom->lx + ((troom->hx - troom->lx) / 2); 349. *sy = troom->ly + ((troom->hy - troom->ly) / 2); 350. } 351. 352. static void 353. mktemple() 354. { 355. register struct mkroom *sroom; 356. int sx,sy; 357. 358. if(!(sroom = pick_room())) return; 359. 360. /* set up Priest and shrine */ 361. sroom->rtype = TEMPLE; 362. shrine_pos(&sx,&sy,sroom); 363. /* 364. * In temples, shrines are blessed altars 365. * located in the center of the room 366. */ 367. levl[sx][sy].typ = ALTAR; 368. levl[sx][sy].scrsym = ALTAR_SYM; 369. levl[sx][sy].altarmask = rn2((int)A_LAW+1) | A_SHRINE; 370. priestini(dlevel, sx, sy, (int) levl[sx][sy].altarmask); 371. } 372. #endif 373. 374. boolean 375. nexttodoor(sx,sy) 376. register int sx, sy; 377. { 378. register int dx, dy; 379. register struct rm *lev; 380. for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++) 381. if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) || 382. lev->typ == SDOOR) 383. return(TRUE); 384. return(FALSE); 385. } 386. 387. boolean 388. has_dnstairs(sroom) 389. register struct mkroom *sroom; 390. { 391. return(sroom->lx <= xdnstair && xdnstair <= sroom->hx && 392. sroom->ly <= ydnstair && ydnstair <= sroom->hy); 393. } 394. 395. boolean 396. has_upstairs(sroom) 397. register struct mkroom *sroom; 398. { 399. return(sroom->lx <= xupstair && xupstair <= sroom->hx && 400. sroom->ly <= yupstair && yupstair <= sroom->hy); 401. } 402. 403. int 404. dist2(x0,y0,x1,y1) 405. int x0, y0, x1, y1; 406. { 407. register int dx = x0 - x1, dy = y0 - y1; 408. return sq(dx) + sq(dy); 409. } 410. 411. #ifdef THRONES 412. struct permonst * 413. courtmon() 414. { 415. int i = rn2(60) + rn2(3*dlevel); 416. if (i > 100) return(mkclass(S_DRAGON)); 417. else if (i > 95) return(mkclass(S_GIANT)); 418. else if (i > 85) return(mkclass(S_TROLL)); 419. else if (i > 75) return(mkclass(S_CENTAUR)); 420. else if (i > 60) return(mkclass(S_ORC)); 421. else if (i > 45) return(&mons[PM_BUGBEAR]); 422. else if (i > 30) return(&mons[PM_HOBGOBLIN]); 423. else if (i > 15) return(mkclass(S_GNOME)); 424. else return(mkclass(S_KOBOLD)); 425. } 426. #endif /* THRONES /**/ 427. 428. #ifdef ARMY 429. #define NSTYPES (PM_CAPTAIN-PM_SOLDIER+1) 430. 431. struct { 432. unsigned pm; 433. unsigned prob; 434. } squadprob[NSTYPES] = { 435. PM_SOLDIER, 80, PM_SERGEANT, 15, PM_LIEUTENANT, 4, PM_CAPTAIN, 1 436. }; 437. 438. static struct permonst * 439. squadmon() { /* return soldier types. */ 440. 441. register struct permonst *ptr; 442. register int i, cpro, sel = rnd(80+dlevel); 443. 444. for(cpro = i = 0; i < NSTYPES; i++) 445. if((cpro += squadprob[i].prob) > sel) { 446. 447. ptr = &mons[squadprob[i].pm]; 448. goto gotone; 449. } 450. ptr = &mons[squadprob[rn2(NSTYPES)].pm]; 451. gotone: 452. if(!(ptr->geno & G_GENOD)) return(ptr); 453. else return((struct permonst *) 0); 454. } 455. #endif /* ARMY /* */