abstract
| - Below is the full text to makemon.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/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 2.3 87/12/12 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include "hack.h" 5. extern char fut_geno[]; 6. extern char *index(); 7. extern struct obj *mkobj_at(), *mksobj(), *mkobj(); 8. struct monst zeromonst; 9. extern boolean in_mklev; 10. 11. #ifdef HARD /* used in hell for bigger, badder demons! */ 12. 13. struct permonst d_lord = { "demon lord", '&',12,13,-5,50,1,5,0 }, 14. d_prince = { "demon prince", '&',14,14,-6,70,1,6,0 }; 15. #endif 16. #ifdef KJSMODS 17. # ifdef KOPS 18. struct permonst kobold = { "kobold",'K',1,6,7,0,1,4,0 }; 19. # endif 20. # ifdef ROCKMOLE 21. struct permonst giant_rat = { "giant rat",'r',0,12,7,0,1,3,0 }; 22. # endif 23. #endif /* KJSMODS /**/ 24. 25. struct permonst grey_dragon = { "grey dragon", 'D',10,9,-1,20,3,8,0 }; 26. struct permonst red_dragon = { "red dragon", 'D',10,9,-1,20,3,8,0 }; 27. struct permonst orange_dragon = { "orange dragon",'D',10,9,-1,20,3,8,0 }; 28. struct permonst white_dragon = { "white dragon", 'D',10,9,-1,20,3,8,0 }; 29. struct permonst black_dragon = { "black dragon", 'D',10,9,-1,20,3,8,0 }; 30. struct permonst blue_dragon = { "blue dragon", 'D',10,9,-1,20,3,8,0 }; 31. struct permonst green_dragon = { "green dragon", 'D',10,9,-1,20,3,8,0 }; 32. struct permonst yellow_dragon = { "yellow dragon",'D',10,9,-1,20,3,8,0 }; 33. extern struct permonst pm_gremlin; 34. 35. /* 36. * called with [x,y] = coordinates; 37. * [0,0] means anyplace 38. * [u.ux,u.uy] means: call mnexto (if !in_mklev) 39. * 40. * In case we make an Orc or killer bee, we make an entire horde 41. * (swarm); note that in this case we return only one of them 42. * (the one at [x,y]). 43. */ 44. struct monst * 45. makemon(ptr,x,y) 46. register struct permonst *ptr; 47. { 48. register struct monst *mtmp; 49. register nleft, deep, ct; 50. boolean anything = (!ptr); 51. int zlevel = dlevel; 52. #ifdef BVH 53. if(has_amulet()) zlevel = MAXLEVEL; 54. #endif 55. /* if a monster already exists at the position, return */ 56. if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0); 57. if(ptr){ 58. /* if you are to make a specific monster and it has 59. already been genocided, return */ 60. if(index(fut_geno, ptr->mlet)) return((struct monst *) 0); 61. } else { 62. /* make a random (common) monster. */ 63. nleft = CMNUM - strlen(fut_geno); 64. if(index(fut_geno, 'm')) nleft++; /* only 1 minotaur */ 65. if(index(fut_geno, '@')) nleft++; 66. if(nleft <= 0) 67. return((struct monst *) 0); /* no more monsters! */ 68. 69. /* determine the strongest monster to make. */ 70. #ifdef ROCKMOLE 71. deep = rn2(nleft*zlevel/24 + 6); 72. #else 73. deep = rn2(nleft*zlevel/24 + 7); 74. #endif 75. if(deep < zlevel - 4) deep = rn2(nleft*zlevel/24 + 12); 76. /* if deep is greater than the number of monsters left 77. to create, set deep to a random number between half 78. the number left and the number left. */ 79. if(deep >= nleft) deep = rn1(nleft - nleft/2, nleft/2); 80. 81. for(ct = 0 ; ct < CMNUM ; ct++){ 82. ptr = &mons[ct]; 83. if(index(fut_geno, ptr->mlet)) continue; 84. #ifdef KOPS 85. if(ptr->mlet == 'K') { 86. # ifdef KJSMODS 87. /* since this is a random monster, make 88. a Kobold instead of a Kop. */ 89. ptr = &kobold; 90. # else 91. deep--; 92. # endif 93. continue; 94. } 95. #endif /* KOPS /**/ 96. if(deep-- <= 0) goto gotmon; 97. } 98. /* this can happen if you are deep in the dungeon and 99. mostly weak monsters have been genocided. */ 100. return((struct monst *) 0); 101. } 102. gotmon: 103. #if defined(KJSMODS) && defined(ROCKMOLE) 104. /* make a giant rat */ 105. if((zlevel < 4 && ptr->mlet == 'r') 106. || (zlevel == 1 && (ptr->mlet == 'h' || ptr->mlet == 'i')) 107. || (zlevel == 2 && (ptr->mlet == 'o' || ptr->mlet == 'y')) 108. ) ptr = &giant_rat; 109. #endif 110. mtmp = newmonst(ptr->pxlth); 111. *mtmp = zeromonst; /* clear all entries in structure */ 112. for(ct = 0; ct < ptr->pxlth; ct++) 113. ((char *) &(mtmp->mextra[0]))[ct] = 0; 114. mtmp->nmon = fmon; 115. fmon = mtmp; 116. mtmp->m_id = flags.ident++; 117. mtmp->data = ptr; 118. mtmp->mxlth = ptr->pxlth; 119. if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80; 120. else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4); 121. else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8); 122. mtmp->mx = x; 123. mtmp->my = y; 124. mtmp->mcansee = 1; 125. if(ptr->mlet == 'D') { 126. mtmp->dragon = rn2(8); 127. switch(mtmp->dragon) { 128. case 0: mtmp->data = &grey_dragon; break; 129. case 1: mtmp->data = &red_dragon; break; 130. case 2: mtmp->data = &orange_dragon; break; 131. case 3: mtmp->data = &white_dragon; break; 132. case 4: mtmp->data = &black_dragon; break; 133. case 5: mtmp->data = &blue_dragon; break; 134. case 6: mtmp->data = &green_dragon; break; 135. case 7: mtmp->data = &yellow_dragon; break; 136. } 137. } 138. /* if gnome, make a gremlin or if gremlin make sure it stays gremlin */ 139. if((ptr->mlet == 'G' && zlevel >= 10 && rn2(4)) || 140. !strcmp(ptr->mname, "gremlin")) { 141. ptr = PM_GREMLIN; 142. mtmp->data = PM_GREMLIN; 143. mtmp->isgremlin = 1; 144. } 145. if(ptr->mlet == 'M'){ 146. mtmp->mimic = 1; 147. mtmp->mappearance = ']'; 148. } 149. if(!in_mklev) { 150. if(x == u.ux && y == u.uy && ptr->mlet != ' ') 151. mnexto(mtmp); 152. if(x == 0 && y == 0) 153. rloc(mtmp); 154. } 155. if(ptr->mlet == 's' || ptr->mlet == 'S') { 156. mtmp->mhide = mtmp->mundetected = 1; 157. if(in_mklev) 158. if(mtmp->mx && mtmp->my) 159. (void) mkobj_at(0, mtmp->mx, mtmp->my); 160. } 161. if(ptr->mlet == ':') { 162. #ifdef DGKMOD 163. /* If you're protected with a ring, don't create 164. * any shape-changing chameleons -dgk 165. */ 166. if (Protection_from_shape_changers) 167. mtmp->cham = 0; 168. else { 169. mtmp->cham = 1; 170. (void) newcham(mtmp, 171. # ifndef RPH 172. &mons[zlevel+14+rn2(CMNUM-14-zlevel)]); 173. # else 174. (struct permonst *)0); 175. # endif 176. } 177. #else 178. mtmp->cham = 1; 179. (void) newcham (mtmp, 180. # ifndef RPH 181. &mons[zlevel+14+rn2(CMNUM-14-zlevel)]); 182. # else 183. 0); 184. # endif 185. #endif 186. } 187. if(ptr->mlet == 'I' || ptr->mlet == ';') 188. mtmp->minvis = 1; 189. if(ptr->mlet == 'L' || ptr->mlet == 'N' 190. || (in_mklev && index("&w;", ptr->mlet) && rn2(5)) 191. ) mtmp->msleep = 1; 192. #ifdef HARD 193. if(ptr->mlet == '&' && (Inhell || u.udemigod)) { 194. 195. if(!rn2(3 + !Inhell + !u.udemigod)) { 196. if (rn2(3 + Inhell)) mtmp->data = &d_lord; 197. else { 198. mtmp->data = &d_prince; 199. mtmp->mpeaceful = 1; 200. mtmp->minvis = 1; 201. } 202. } 203. #ifdef RPH 204. if(uwep) 205. if(!strcmp(ONAME(uwep), "Excalibur")) 206. mtmp->mpeaceful = mtmp->mtame = 0; 207. #endif 208. } 209. #endif /* HARD /**/ 210. #ifndef NOWORM 211. if(ptr->mlet == 'w' && getwn(mtmp)) initworm(mtmp); 212. #endif 213. 214. if(anything) 215. if(ptr->mlet == 'O' || ptr->mlet == 'k' 216. #ifdef SAC 217. || ptr->mlet == '3' 218. #endif /* SAC /**/ 219. || (ptr->mlet == 'G' && mtmp->isgremlin) 220. ) { 221. 222. coord mm; 223. register int cnt = rnd(10); 224. mm.x = x; 225. mm.y = y; 226. while(cnt--) { 227. enexto(&mm, mm.x, mm.y); 228. (void) makemon(ptr, mm.x, mm.y); 229. } 230. } 231. #ifdef DGKMOD 232. m_initinv(mtmp); 233. #endif 234. return(mtmp); 235. } 236. 237. #ifdef DGKMOD 238. /* Give some monsters an initial inventory to use */ 239. m_initinv(mtmp) 240. struct monst *mtmp; 241. { 242. struct obj *otmp; 243. 244. switch (mtmp->data->mlet) { 245. # ifdef KAA 246. case '9': 247. if (rn2(2)) { 248. otmp = mksobj(ENORMOUS_ROCK); 249. mpickobj(mtmp, otmp); 250. } 251. # endif 252. # ifdef SAC 253. case '3': /* Outfit the troops */ 254. if (!rn2(5)) { 255. otmp = mksobj(HELMET); 256. mpickobj(mtmp, otmp); } 257. if (!rn2(5)) { 258. otmp = mksobj(CHAIN_MAIL); 259. mpickobj(mtmp, otmp); } 260. if (!rn2(4)) { 261. otmp = mksobj(DAGGER); 262. mpickobj(mtmp, otmp); } 263. if (!rn2(7)) { 264. otmp = mksobj(SPEAR); 265. mpickobj(mtmp, otmp); } 266. if (!rn2(3)) { 267. otmp = mksobj(K_RATION); 268. mpickobj(mtmp, otmp); } 269. if (!rn2(2)) { 270. otmp = mksobj(C_RATION); 271. mpickobj(mtmp, otmp); } 272. # endif /* SAC /**/ 273. # ifdef KOPS 274. case 'K': /* create Keystone Kops with cream pies to 275. * throw. As suggested by KAA. [MRS] 276. */ 277. if (!rn2(4) 278. # ifdef KJSMODS 279. && !strcmp(mtmp->data->mname, "Keystone Kop") 280. # endif 281. ) { 282. otmp = mksobj(CREAM_PIE); 283. otmp->quan = 2 + rnd(2); 284. otmp->owt = weight(otmp); 285. mpickobj(mtmp, otmp); 286. } 287. break; 288. case 'O': 289. # else 290. case 'K': 291. # endif 292. if (!rn2(4)) { 293. otmp = mksobj(DART); 294. otmp->quan = 2 + rnd(12); 295. otmp->owt = weight(otmp); 296. mpickobj(mtmp, otmp); 297. } 298. break; 299. 300. case 'C': 301. if (rn2(2)) { 302. otmp = mksobj(CROSSBOW); 303. otmp->cursed = rn2(2); 304. mpickobj(mtmp, otmp); 305. otmp = mksobj(CROSSBOW_BOLT); 306. otmp->quan = 2 + rnd(12); 307. otmp->owt = weight(otmp); 308. mpickobj(mtmp, otmp); 309. } 310. break; 311. default: 312. break; 313. } 314. } 315. #endif 316. 317. enexto(cc, xx,yy) 318. coord *cc; 319. register xchar xx,yy; 320. { 321. register xchar x,y; 322. coord foo[15], *tfoo; 323. int range, i; 324. 325. tfoo = foo; 326. range = 1; 327. do { /* full kludge action. */ 328. for(x = xx-range; x <= xx+range; x++) 329. if(goodpos(x, yy-range)) { 330. tfoo->x = x; 331. (tfoo++)->y = yy-range; 332. if(tfoo == &foo[15]) goto foofull; 333. } 334. for(x = xx-range; x <= xx+range; x++) 335. if(goodpos(x,yy+range)) { 336. tfoo->x = x; 337. (tfoo++)->y = yy+range; 338. if(tfoo == &foo[15]) goto foofull; 339. } 340. for(y = yy+1-range; y < yy+range; y++) 341. if(goodpos(xx-range,y)) { 342. tfoo->x = xx-range; 343. (tfoo++)->y = y; 344. if(tfoo == &foo[15]) goto foofull; 345. } 346. for(y = yy+1-range; y < yy+range; y++) 347. if(goodpos(xx+range,y)) { 348. tfoo->x = xx+range; 349. (tfoo++)->y = y; 350. if(tfoo == &foo[15]) goto foofull; 351. } 352. range++; 353. } while(tfoo == foo); 354. foofull: 355. i = rn2(tfoo - foo); 356. cc->x = foo[i].x; 357. cc->y = foo[i].y; 358. return(0); 359. } 360. 361. goodpos(x,y) /* used only in mnexto and rloc */ 362. { 363. return( 364. ! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 || 365. m_at(x,y) || !ACCESSIBLE(levl[x][y].typ) 366. || (x == u.ux && y == u.uy) 367. || sobj_at(ENORMOUS_ROCK, x, y) 368. )); 369. } 370. 371. rloc(mtmp) 372. struct monst *mtmp; 373. { 374. register tx,ty; 375. register char ch = mtmp->data->mlet; 376. 377. #ifndef NOWORM 378. if(ch == 'w' && mtmp->mx) return; /* do not relocate worms */ 379. #endif 380. do { 381. tx = rn1(COLNO-3,2); 382. ty = rn2(ROWNO); 383. } while(!goodpos(tx,ty)); 384. mtmp->mx = tx; 385. mtmp->my = ty; 386. if(u.ustuck == mtmp){ 387. if(u.uswallow) { 388. u.ux = tx; 389. u.uy = ty; 390. docrt(); 391. } else u.ustuck = 0; 392. } 393. pmon(mtmp); 394. } 395. 396. struct monst * 397. mkmon_at(let,x,y) 398. char let; 399. register int x,y; 400. { 401. register int ct; 402. register struct permonst *ptr; 403. 404. for(ct = 0; ct < CMNUM; ct++) { 405. ptr = &mons[ct]; 406. if(ptr->mlet == let) 407. return(makemon(ptr,x,y)); 408. } 409. return((struct monst *)0); 410. }
|