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