Source:NetHack 2.3e/mkshop.c
Jump to navigation
Jump to search
Below is the full text to mkshop.c from the source code of NetHack 2.3e.
Warning! This is the source code from an old release. For newer releases, see Source code
Screenshots and source code from Hack are used under the CWI license.
1. /* SCCS Id: @(#)mkshop.c 2.3 87/12/12 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. /* 5. * Entry points: 6. * mkroom() -- make and stock a room of a given type 7. * nexttodoor() -- return TRUE if adjacent to a door 8. * has_dnstairs() -- return TRUE if given room has a down staircase 9. * has_upstairs() -- return TRUE if given room has an up staircase 10. * dist2() -- Euclidean square-of-distance function 11. * courtmon() -- generate a court monster 12. * 13. * (note: this module should become mkroom.c in the next major release) 14. */ 15. #ifndef QUEST 16. #include "hack.h" 17. #include "mkroom.h" 18. extern struct monst *makemon(); 19. extern struct permonst pm_soldier; 20. extern struct obj *mkobj_at(), *mksobj_at(); 21. extern void stock_room(); 22. extern int nroom; 23. 24. static boolean 25. isbig(sroom) 26. register struct mkroom *sroom; 27. { 28. register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly); 29. return( area > 20 ); 30. } 31. 32. void 33. mkroom(roomtype) 34. /* make and stock a room of a given type */ 35. int roomtype; 36. { 37. void mkshop(), mkzoo(), mkswamp(); 38. 39. if (roomtype >= SHOPBASE) 40. mkshop(); /* someday, we should be able to specify shop type */ 41. else switch(roomtype) 42. { 43. case COURT: mkzoo(COURT); break; 44. case ZOO: mkzoo(ZOO); break; 45. case BEEHIVE: mkzoo(BEEHIVE); break; 46. case MORGUE: mkzoo(MORGUE); break; 47. case BARRACKS: mkzoo(BARRACKS); break; 48. case SWAMP: mkswamp(); break; 49. default: impossible("Tried to make a room of type %d.", roomtype); 50. } 51. } 52. 53. static void 54. mkshop(){ 55. register struct mkroom *sroom; 56. int roomno, i = -1; 57. #ifdef WIZARD 58. extern char *getenv(); 59. 60. /* first determine shoptype */ 61. if(wizard){ 62. register char *ep = getenv("SHOPTYPE"); 63. if(ep){ 64. if(*ep == 'z' || *ep == 'Z'){ 65. mkzoo(ZOO); 66. return; 67. } 68. if(*ep == 'm' || *ep == 'M'){ 69. mkzoo(MORGUE); 70. return; 71. } 72. if(*ep == 'b' || *ep == 'B'){ 73. mkzoo(BEEHIVE); 74. return; 75. } 76. #ifdef NEWCLASS 77. if(*ep == 't' || *ep == 'T'){ 78. mkzoo(COURT); 79. return; 80. } 81. #endif 82. #ifdef SAC 83. if(*ep == '3'){ 84. mkzoo(BARRACKS); 85. return; 86. } 87. #endif /* SAC */ 88. if(*ep == 's' || *ep == 'S'){ 89. mkswamp(); 90. return; 91. } 92. for(i=0; shtypes[i].name; i++) 93. if(*ep == shtypes[i].symb) goto gottype; 94. i = -1; 95. } 96. } 97. gottype: 98. #endif 99. for(sroom = &rooms[0], roomno = 0; ; sroom++, roomno++){ 100. if(sroom->hx < 0) return; 101. if(sroom - rooms >= nroom) { 102. pline("rooms not closed by -1?"); 103. return; 104. } 105. if(sroom->rtype != OROOM) continue; 106. if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom)) 107. continue; 108. if( 109. #ifdef WIZARD 110. (wizard && getenv("SHOPTYPE") && sroom->doorct != 0) || 111. #endif 112. sroom->doorct == 1) break; 113. } 114. 115. if(i < 0) { /* shoptype not yet determined */ 116. register int j; 117. 118. /* pick a shop type at random */ 119. for(j = rn2(100), i = 0; j -= shtypes[i].prob; i++) 120. if (j < 0) break; 121. 122. /* big rooms cannot be wand or book shops, 123. * - so make them general stores 124. */ 125. if(isbig(sroom) && (shtypes[i].symb == WAND_SYM 126. #ifdef SPELLS 127. || shtypes[i].symb == SPBOOK_SYM 128. #endif 129. )) i = 0; 130. } 131. sroom->rtype = SHOPBASE + i; 132. 133. /* stock the room with a shopkeeper and artifacts */ 134. stock_room(&(shtypes[i]), sroom); 135. } 136. 137. static void 138. mkzoo(type) 139. int type; 140. { 141. register struct mkroom *sroom; 142. register struct monst *mon; 143. register int sh,sx,sy,i; 144. int goldlim = 500 * dlevel; 145. int moct = 0; 146. struct permonst *morguemon(); 147. #ifdef NEWCLASS 148. struct permonst *courtmon(); 149. #endif 150. 151. i = nroom; 152. for(sroom = &rooms[rn2(nroom)]; ; sroom++) { 153. if(sroom == &rooms[nroom]) 154. sroom = &rooms[0]; 155. if(!i-- || sroom->hx < 0) 156. return; 157. if(sroom->rtype != OROOM) continue; 158. if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3))) 159. continue; 160. if(sroom->doorct == 1 || !rn2(5)) 161. break; 162. } 163. sroom->rtype = type; 164. sh = sroom->fdoor; 165. for(sx = sroom->lx; sx <= sroom->hx; sx++) 166. for(sy = sroom->ly; sy <= sroom->hy; sy++){ 167. if((sx == sroom->lx && doors[sh].x == sx-1) || 168. (sx == sroom->hx && doors[sh].x == sx+1) || 169. (sy == sroom->ly && doors[sh].y == sy-1) || 170. (sy == sroom->hy && doors[sh].y == sy+1)) continue; 171. mon = makemon( 172. #ifdef NEWCLASS 173. (type == COURT) ? courtmon() : 174. #endif 175. #ifdef SAC 176. (type == BARRACKS) ? PM_SOLDIER : 177. #endif 178. (type == MORGUE) ? morguemon() : 179. (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0, 180. sx, sy); 181. if(mon) mon->msleep = 1; 182. switch(type) { 183. case ZOO: 184. i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y)); 185. if(i >= goldlim) i = 5*dlevel; 186. goldlim -= i; 187. mkgold((long)(10 + rn2(i)), sx, sy); 188. break; 189. case MORGUE: 190. /* Usually there is one dead body in the morgue */ 191. if(!moct && rn2(3)) { 192. mksobj_at(CORPSE, sx, sy); 193. moct++; 194. } 195. break; 196. case BEEHIVE: 197. if(!rn2(3)) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy); 198. break; 199. } 200. } 201. #ifdef NEWCLASS 202. if(type == COURT) { 203. 204. sx = sroom->lx + (rn2(sroom->hx - sroom->lx)); 205. sy = sroom->ly + (rn2(sroom->hy - sroom->ly)); 206. levl[sx][sy].typ = THRONE; 207. levl[sx][sy].scrsym = THRONE_SYM; 208. mkgold((long) rn1(50 * dlevel,10), sx, sy); 209. } 210. #endif 211. 212. } 213. 214. static struct permonst * 215. morguemon() 216. { 217. extern struct permonst pm_ghost; 218. register int i = rn2(100), hd = rn2(dlevel); 219. 220. if(hd > 10 && i < 10) return(PM_DEMON); 221. if(hd > 8 && i > 85) return(PM_VAMPIRE); 222. return((i < 40) ? PM_GHOST : (i < 60) ? PM_WRAITH : PM_ZOMBIE); 223. } 224. 225. static void 226. mkswamp() /* Michiel Huisjes & Fred de Wilde */ 227. { 228. register struct mkroom *sroom; 229. register int sx,sy,i,eelct = 0; 230. extern struct permonst pm_eel; 231. 232. for(i=0; i<5; i++) { /* 5 tries */ 233. sroom = &rooms[rn2(nroom)]; 234. if(sroom->hx < 0 || sroom->rtype != OROOM || 235. has_upstairs(sroom) || has_dnstairs(sroom)) 236. continue; 237. 238. /* satisfied; make a swamp */ 239. sroom->rtype = SWAMP; 240. for(sx = sroom->lx; sx <= sroom->hx; sx++) 241. for(sy = sroom->ly; sy <= sroom->hy; sy++) 242. if((sx+sy)%2 && !o_at(sx,sy) && !t_at(sx,sy) 243. && !m_at(sx,sy) && !nexttodoor(sx,sy)){ 244. levl[sx][sy].typ = POOL; 245. levl[sx][sy].scrsym = POOL_SYM; 246. if(!eelct || !rn2(4)) { 247. (void) makemon(PM_EEL, sx, sy); 248. eelct++; 249. } 250. } 251. } 252. } 253. 254. boolean 255. nexttodoor(sx,sy) 256. register sx,sy; 257. { 258. register dx,dy; 259. register struct rm *lev; 260. for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++) 261. if((lev = &levl[sx+dx][sy+dy])->typ == DOOR || 262. lev->typ == SDOOR || lev->typ == LDOOR) 263. return(TRUE); 264. return(FALSE); 265. } 266. 267. boolean 268. has_dnstairs(sroom) 269. register struct mkroom *sroom; 270. { 271. return(sroom->lx <= xdnstair && xdnstair <= sroom->hx && 272. sroom->ly <= ydnstair && ydnstair <= sroom->hy); 273. } 274. 275. boolean 276. has_upstairs(sroom) 277. register struct mkroom *sroom; 278. { 279. return(sroom->lx <= xupstair && xupstair <= sroom->hx && 280. sroom->ly <= yupstair && yupstair <= sroom->hy); 281. } 282. 283. int 284. dist2(x0,y0,x1,y1){ 285. return((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1)); 286. } 287. 288. static int 289. sq(a) int a; { 290. return(a*a); 291. } 292. #endif /* QUEST /**/ 293. 294. #ifdef NEWCLASS 295. struct permonst * 296. courtmon() 297. { 298. int i = rn2(60) + rn2(3*dlevel); 299. 300. if (i > 100) return(PM_DRAGON); 301. else if (i > 95) return(PM_XORN); 302. else if (i > 85) return(PM_TROLL); 303. else if (i > 75) return(PM_ETTIN); 304. else if (i > 60) return(PM_CENTAUR); 305. else if (i > 45) return(PM_ORC); 306. else if (i > 30) return(PM_HOBGOBLIN); 307. #ifdef KOPS 308. else return(PM_GNOME); 309. #else 310. else if (i > 15) return(PM_GNOME); 311. else return(PM_KOBOLD); 312. #endif 313. } 314. #endif /* NEWCLASS /**/