Source:NetHack 1.3d/makemon.c
Jump to navigation
Jump to search
Below is the full text to makemon.c from the source code of NetHack 1.3d.
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: @(#)makemon.c 1.3 87/07/14 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* makemon.c - version 1.0.2 */ 4. 5. #include "hack.h" 6. extern char fut_geno[]; 7. extern char *index(); 8. extern struct obj *mkobj_at(), *mksobj(), *mkobj(); 9. struct monst zeromonst; 10. extern boolean in_mklev; 11. 12. #ifdef HARD /* used in hell for bigger, badder demons! */ 13. 14. struct permonst d_lord = { "demon lord", '&',12,13,-5,50,1,5,0 }, 15. d_prince = { "demon prince", '&',14,14,-6,70,1,6,0 }; 16. #endif 17. 18. /* 19. * called with [x,y] = coordinates; 20. * [0,0] means anyplace 21. * [u.ux,u.uy] means: call mnexto (if !in_mklev) 22. * 23. * In case we make an Orc or killer bee, we make an entire horde 24. * (swarm); note that in this case we return only one of them 25. * (the one at [x,y]). 26. */ 27. struct monst * 28. makemon(ptr,x,y) 29. register struct permonst *ptr; 30. { 31. register struct monst *mtmp; 32. register tmp, ct; 33. boolean anything = (!ptr); 34. 35. if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0); 36. if(ptr){ 37. if(index(fut_geno, ptr->mlet)) return((struct monst *) 0); 38. } else { 39. ct = CMNUM - strlen(fut_geno); 40. if(index(fut_geno, 'm')) ct++; /* make only 1 minotaur */ 41. if(index(fut_geno, '@')) ct++; 42. if(ct <= 0) return(0); /* no more monsters! */ 43. tmp = 7; 44. #ifdef KOPS 45. tmp--; 46. #endif 47. #ifdef ROCKMOLE 48. if(dlevel<4) tmp--; 49. #endif 50. tmp = rn2(ct*dlevel/24 + 7); 51. if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12); 52. if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2); 53. ct = 0; 54. #ifdef KOPS 55. ct++; 56. #endif 57. while(!(tmp + 1 <= CMNUM - ct)) tmp--; 58. for(; ct < CMNUM; ct++){ 59. ptr = &mons[ct]; 60. #ifdef KOPS 61. if(ptr->mlet == 'K') { 62. tmp--; 63. continue; 64. } 65. #endif 66. if(index(fut_geno, ptr->mlet)) continue; 67. if(tmp-- <= 0) goto gotmon; 68. } 69. panic("makemon?"); 70. } 71. gotmon: 72. mtmp = newmonst(ptr->pxlth); 73. *mtmp = zeromonst; /* clear all entries in structure */ 74. for(ct = 0; ct < ptr->pxlth; ct++) 75. ((char *) &(mtmp->mextra[0]))[ct] = 0; 76. mtmp->nmon = fmon; 77. fmon = mtmp; 78. mtmp->m_id = flags.ident++; 79. mtmp->data = ptr; 80. mtmp->mxlth = ptr->pxlth; 81. if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80; 82. else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4); 83. else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8); 84. mtmp->mx = x; 85. mtmp->my = y; 86. mtmp->mcansee = 1; 87. if(ptr->mlet == 'M'){ 88. mtmp->mimic = 1; 89. mtmp->mappearance = ']'; 90. } 91. if(!in_mklev) { 92. if(x == u.ux && y == u.uy && ptr->mlet != ' ') 93. mnexto(mtmp); 94. if(x == 0 && y == 0) 95. rloc(mtmp); 96. } 97. if(ptr->mlet == 's' || ptr->mlet == 'S') { 98. mtmp->mhide = mtmp->mundetected = 1; 99. if(in_mklev) 100. if(mtmp->mx && mtmp->my) 101. (void) mkobj_at(0, mtmp->mx, mtmp->my); 102. } 103. if(ptr->mlet == ':') { 104. #ifdef DGKMOD 105. /* If you're protected with a ring, don't create 106. * any shape-changing chameleons -dgk 107. */ 108. if (Protection_from_shape_changers) 109. mtmp->cham = 0; 110. else { 111. mtmp->cham = 1; 112. (void) newcham(mtmp, 113. &mons[dlevel+14+rn2(CMNUM-14-dlevel)]); 114. } 115. #else 116. mtmp->cham = 1; 117. (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]); 118. #endif 119. } 120. if(ptr->mlet == 'I' || ptr->mlet == ';') 121. mtmp->minvis = 1; 122. if(ptr->mlet == 'L' || ptr->mlet == 'N' 123. || (in_mklev && index("&w;", ptr->mlet) && rn2(5)) 124. ) mtmp->msleep = 1; 125. #ifdef HARD 126. if(ptr->mlet == '&' && (Inhell || u.udemigod)) { 127. 128. if(!rn2(5 + !Inhell)) { 129. if (rn2(3 + Inhell)) mtmp->data = &d_lord; 130. else { 131. mtmp->data = &d_prince; 132. mtmp->mpeaceful = 1; 133. mtmp->minvis = 1; 134. } 135. } 136. } 137. #endif /* HARD /**/ 138. #ifndef NOWORM 139. if(ptr->mlet == 'w' && getwn(mtmp)) initworm(mtmp); 140. #endif 141. 142. if(anything) if(ptr->mlet == 'O' || ptr->mlet == 'k') { 143. coord enexto(); 144. coord mm; 145. register int cnt = rnd(10); 146. mm.x = x; 147. mm.y = y; 148. while(cnt--) { 149. mm = enexto(mm.x, mm.y); 150. (void) makemon(ptr, mm.x, mm.y); 151. } 152. } 153. #ifdef DGKMOD 154. m_initinv(mtmp); 155. #endif 156. return(mtmp); 157. } 158. 159. #ifdef DGKMOD 160. /* Give some monsters an initial inventory to use */ 161. m_initinv(mtmp) 162. struct monst *mtmp; 163. { 164. struct obj *otmp; 165. 166. switch (mtmp->data->mlet) { 167. # ifdef KAA 168. case '9': 169. if (rn2(2)) { 170. otmp = mksobj(ENORMOUS_ROCK); 171. mpickobj(mtmp, otmp); 172. } 173. # endif 174. # ifdef KOPS 175. case 'K': /* create Keystone Kops with cream pies to 176. * throw. As suggested by KAA. [MRS] 177. */ 178. if (!rn2(4)) { 179. otmp = mksobj(CREAM_PIE); 180. otmp->quan = 2 + rnd(2); 181. mpickobj(mtmp, otmp); 182. } 183. break; 184. case 'O': 185. # else 186. case 'K': 187. # endif 188. if (!rn2(4)) { 189. otmp = mksobj(DART); 190. otmp->quan = 2 + rnd(12); 191. mpickobj(mtmp, otmp); 192. } 193. break; 194. case 'C': 195. if (rn2(2)) { 196. otmp = mksobj(CROSSBOW); 197. otmp->cursed = rn2(2); 198. mpickobj(mtmp, otmp); 199. otmp = mksobj(CROSSBOW_BOLT); 200. otmp->quan = 2 + rnd(12); 201. mpickobj(mtmp, otmp); 202. } 203. break; 204. default: 205. break; 206. } 207. } 208. #endif 209. 210. coord 211. enexto(xx,yy) 212. register xchar xx,yy; 213. { 214. register xchar x,y; 215. coord foo[15], *tfoo; 216. int range; 217. 218. tfoo = foo; 219. range = 1; 220. do { /* full kludge action. */ 221. for(x = xx-range; x <= xx+range; x++) 222. if(goodpos(x, yy-range)) { 223. tfoo->x = x; 224. (tfoo++)->y = yy-range; 225. if(tfoo == &foo[15]) goto foofull; 226. } 227. for(x = xx-range; x <= xx+range; x++) 228. if(goodpos(x,yy+range)) { 229. tfoo->x = x; 230. (tfoo++)->y = yy+range; 231. if(tfoo == &foo[15]) goto foofull; 232. } 233. for(y = yy+1-range; y < yy+range; y++) 234. if(goodpos(xx-range,y)) { 235. tfoo->x = xx-range; 236. (tfoo++)->y = y; 237. if(tfoo == &foo[15]) goto foofull; 238. } 239. for(y = yy+1-range; y < yy+range; y++) 240. if(goodpos(xx+range,y)) { 241. tfoo->x = xx+range; 242. (tfoo++)->y = y; 243. if(tfoo == &foo[15]) goto foofull; 244. } 245. range++; 246. } while(tfoo == foo); 247. foofull: 248. return( foo[rn2(tfoo-foo)] ); 249. } 250. 251. goodpos(x,y) /* used only in mnexto and rloc */ 252. { 253. return( 254. ! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 || 255. m_at(x,y) || !ACCESSIBLE(levl[x][y].typ) 256. || (x == u.ux && y == u.uy) 257. || sobj_at(ENORMOUS_ROCK, x, y) 258. )); 259. } 260. 261. rloc(mtmp) 262. struct monst *mtmp; 263. { 264. register tx,ty; 265. register char ch = mtmp->data->mlet; 266. 267. #ifndef NOWORM 268. if(ch == 'w' && mtmp->mx) return; /* do not relocate worms */ 269. #endif 270. do { 271. tx = rn1(COLNO-3,2); 272. ty = rn2(ROWNO); 273. } while(!goodpos(tx,ty)); 274. mtmp->mx = tx; 275. mtmp->my = ty; 276. if(u.ustuck == mtmp){ 277. if(u.uswallow) { 278. u.ux = tx; 279. u.uy = ty; 280. docrt(); 281. } else u.ustuck = 0; 282. } 283. pmon(mtmp); 284. } 285. 286. struct monst * 287. mkmon_at(let,x,y) 288. char let; 289. register int x,y; 290. { 291. register int ct; 292. register struct permonst *ptr; 293. 294. for(ct = 0; ct < CMNUM; ct++) { 295. ptr = &mons[ct]; 296. if(ptr->mlet == let) 297. return(makemon(ptr,x,y)); 298. } 299. return(0); 300. }