abstract
| - Below is the full text to makemon.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/makemon.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 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. }
|