abstract
| - Below is the full text to makemon.c from the source code of NetHack 1.4f. To link to a particular line, write [[NetHack 1.4f/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.4 87/08/08 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 mm; 144. register int cnt = rnd(10); 145. mm.x = x; 146. mm.y = y; 147. while(cnt--) { 148. enexto(&mm, mm.x, mm.y); 149. (void) makemon(ptr, mm.x, mm.y); 150. } 151. } 152. #ifdef DGKMOD 153. m_initinv(mtmp); 154. #endif 155. return(mtmp); 156. } 157. 158. #ifdef DGKMOD 159. /* Give some monsters an initial inventory to use */ 160. m_initinv(mtmp) 161. struct monst *mtmp; 162. { 163. struct obj *otmp; 164. 165. switch (mtmp->data->mlet) { 166. # ifdef KAA 167. case '9': 168. if (rn2(2)) { 169. otmp = mksobj(ENORMOUS_ROCK); 170. mpickobj(mtmp, otmp); 171. } 172. # endif 173. # ifdef KOPS 174. case 'K': /* create Keystone Kops with cream pies to 175. * throw. As suggested by KAA. [MRS] 176. */ 177. if (!rn2(4)) { 178. otmp = mksobj(CREAM_PIE); 179. otmp->quan = 2 + rnd(2); 180. mpickobj(mtmp, otmp); 181. } 182. break; 183. case 'O': 184. # else 185. case 'K': 186. # endif 187. if (!rn2(4)) { 188. otmp = mksobj(DART); 189. otmp->quan = 2 + rnd(12); 190. mpickobj(mtmp, otmp); 191. } 192. break; 193. case 'C': 194. if (rn2(2)) { 195. otmp = mksobj(CROSSBOW); 196. otmp->cursed = rn2(2); 197. mpickobj(mtmp, otmp); 198. otmp = mksobj(CROSSBOW_BOLT); 199. otmp->quan = 2 + rnd(12); 200. mpickobj(mtmp, otmp); 201. } 202. break; 203. default: 204. break; 205. } 206. } 207. #endif 208. 209. enexto(cc, xx,yy) 210. coord *cc; 211. register xchar xx,yy; 212. { 213. register xchar x,y; 214. coord foo[15], *tfoo; 215. int range; 216. 217. tfoo = foo; 218. range = 1; 219. do { /* full kludge action. */ 220. for(x = xx-range; x <= xx+range; x++) 221. if(goodpos(x, yy-range)) { 222. tfoo->x = x; 223. (tfoo++)->y = yy-range; 224. if(tfoo == &foo[15]) goto foofull; 225. } 226. for(x = xx-range; x <= xx+range; x++) 227. if(goodpos(x,yy+range)) { 228. tfoo->x = x; 229. (tfoo++)->y = yy+range; 230. if(tfoo == &foo[15]) goto foofull; 231. } 232. for(y = yy+1-range; y < yy+range; y++) 233. if(goodpos(xx-range,y)) { 234. tfoo->x = xx-range; 235. (tfoo++)->y = y; 236. if(tfoo == &foo[15]) goto foofull; 237. } 238. for(y = yy+1-range; y < yy+range; y++) 239. if(goodpos(xx+range,y)) { 240. tfoo->x = xx+range; 241. (tfoo++)->y = y; 242. if(tfoo == &foo[15]) goto foofull; 243. } 244. range++; 245. } while(tfoo == foo); 246. foofull: 247. cc->x = foo[rn2(tfoo-foo)].x; 248. cc->y = foo[rn2(tfoo-foo)].y; 249. return(0); 250. } 251. 252. goodpos(x,y) /* used only in mnexto and rloc */ 253. { 254. return( 255. ! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 || 256. m_at(x,y) || !ACCESSIBLE(levl[x][y].typ) 257. || (x == u.ux && y == u.uy) 258. || sobj_at(ENORMOUS_ROCK, x, y) 259. )); 260. } 261. 262. rloc(mtmp) 263. struct monst *mtmp; 264. { 265. register tx,ty; 266. register char ch = mtmp->data->mlet; 267. 268. #ifndef NOWORM 269. if(ch == 'w' && mtmp->mx) return; /* do not relocate worms */ 270. #endif 271. do { 272. tx = rn1(COLNO-3,2); 273. ty = rn2(ROWNO); 274. } while(!goodpos(tx,ty)); 275. mtmp->mx = tx; 276. mtmp->my = ty; 277. if(u.ustuck == mtmp){ 278. if(u.uswallow) { 279. u.ux = tx; 280. u.uy = ty; 281. docrt(); 282. } else u.ustuck = 0; 283. } 284. pmon(mtmp); 285. } 286. 287. struct monst * 288. mkmon_at(let,x,y) 289. char let; 290. register int x,y; 291. { 292. register int ct; 293. register struct permonst *ptr; 294. 295. for(ct = 0; ct < CMNUM; ct++) { 296. ptr = &mons[ct]; 297. if(ptr->mlet == let) 298. return(makemon(ptr,x,y)); 299. } 300. return(0); 301. }
|