Source:NetHack 1.3d/monmove.c
Jump to navigation
Jump to search
Below is the full text to monmove.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/monmove.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: @(#)monmove.c 1.3 87/07/14 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* monmove.c - version 1.0 */ 4. 5. #include "hack.h" 6. #include "mfndpos.h" 7. #define NULL (char *) 0 8. 9. extern int warnlevel; /* defined in mon.c */ 10. 11. dochugw(mtmp) register struct monst *mtmp; { 12. register x = mtmp->mx; 13. register y = mtmp->my; 14. register d = dochug(mtmp); 15. register dd; 16. if(!d) /* monster still alive */ 17. if(Warning) 18. if(!mtmp->mpeaceful) 19. if(mtmp->data->mlevel > warnlevel) 20. if((dd = dist(mtmp->mx,mtmp->my)) < dist(x,y)) 21. if(dd < 100) 22. if(!canseemon(mtmp)) 23. warnlevel = mtmp->data->mlevel; 24. return(d); 25. } 26. 27. /* returns 1 if monster died moving, 0 otherwise */ 28. dochug(mtmp) 29. register struct monst *mtmp; 30. { 31. register struct permonst *mdat; 32. register tmp, nearby, scared, onscary; 33. 34. if(mtmp->cham && !rn2(6)) 35. (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]); 36. mdat = mtmp->data; 37. if(mdat->mlevel < 0) 38. panic("bad monster %c (%d)",mdat->mlet,mdat->mlevel); 39. 40. /* regenerate monsters */ 41. if((!(moves%20) || index(MREGEN, mdat->mlet)) && 42. mtmp->mhp < mtmp->mhpmax) 43. mtmp->mhp++; 44. 45. if(mtmp->mfroz) { 46. if (Hallucination) pmon(mtmp); 47. return(0); /* frozen monsters don't do anything */ 48. } 49. 50. if(mtmp->msleep) /* there is a chance we will wake it */ 51. if(!disturb(mtmp)) return(0); 52. 53. /* not frozen or sleeping: wipe out texts written in the dust */ 54. wipe_engr_at(mtmp->mx, mtmp->my, 1); 55. 56. /* confused monsters get unconfused with small probability */ 57. if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0; 58. 59. /* some monsters teleport */ 60. if(mtmp->mflee && index("tNL", mdat->mlet) && !rn2(40)){ 61. rloc(mtmp); 62. return(0); 63. } 64. if(mdat->mmove < rnd(6)) return(0); 65. 66. /* fleeing monsters might regain courage */ 67. if(mtmp->mflee && !mtmp->mfleetim 68. && mtmp->mhp == mtmp->mhpmax && !rn2(25)) 69. mtmp->mflee = 0; 70. 71. nearby = (dist(mtmp->mx, mtmp->my) < 3); 72. onscary = (sengr_at("Elbereth", u.ux, u.uy) || 73. sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy)); 74. scared = (nearby && onscary && !mtmp->mtame && mtmp->mcansee); 75. if(scared && !mtmp->mflee) { 76. mtmp->mflee = 1; 77. mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100)); 78. } 79. 80. if(!nearby || 81. mtmp->mflee || scared || 82. mtmp->mconf || 83. (mtmp->minvis && !rn2(3)) || 84. #ifndef KOPS 85. (index("BIuy", mdat->mlet) && !rn2(4)) || 86. #else 87. (index("KBIuy", mdat->mlet) && !rn2(4)) || 88. #endif 89. (mdat->mlet == 'L' && !u.ugold && (mtmp->mgold || rn2(2))) || 90. (!mtmp->mcansee && !rn2(4)) || 91. mtmp->mpeaceful 92. ) { 93. tmp = m_move(mtmp,0); /* 2: monster died moving */ 94. if(tmp == 2 || (tmp && mdat->mmove <= 12)) 95. return(tmp == 2); 96. 97. if(Hallucination && tmp==0) pmon(mtmp); 98. /* If 0, this means the monster didn't move. During hallucination, its 99. appearance should still change. */ 100. 101. #ifdef HARD 102. /* Without this line, fast monsters don't hit you when they've 103. * caught up to you. -dgk 104. */ 105. nearby = (dist(mtmp->mx, mtmp->my) < 3); 106. scared = (nearby && onscary); 107. if(scared && !mtmp->mflee) { 108. mtmp->mflee = 1; 109. mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100)); 110. } 111. #endif 112. } 113. #ifdef HARD /* Demonic Blackmail!!! */ 114. if(mdat->mlet == '&' && mtmp->mpeaceful && !mtmp->mtame) 115. if(demon_talk(mtmp)) 116. return(1); /* you paid it off */ 117. #endif 118. if(!index("Ea", mdat->mlet) && nearby && 119. !mtmp->mpeaceful && u.uhp > 0 && !scared) { 120. if(mhitu(mtmp)) 121. return(1); /* monster died (e.g. 'y' or 'F') */ 122. } 123. /* extra movement for fast monsters */ 124. if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp,1); 125. return(tmp == 2); 126. } 127. 128. m_move(mtmp,after) 129. register struct monst *mtmp; 130. { 131. #ifndef REGBUG 132. register 133. #endif 134. struct monst *mtmp2; 135. #ifndef REGBUG 136. register 137. #endif 138. int nx,ny,omx,omy,appr,nearer,cnt,i,j; 139. xchar gx,gy,nix,niy,chcnt; 140. schar chi; 141. boolean likegold, likegems, likeobjs; 142. #ifdef KAA 143. boolean likerock; 144. #endif 145. char msym = mtmp->data->mlet; 146. schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */ 147. coord poss[9]; 148. long info[9]; 149. 150. if(mtmp->mfroz || mtmp->msleep) 151. return(0); 152. if(mtmp->mtrapped) { 153. i = mintrap(mtmp); 154. if(i == 2) return(2); /* he died */ 155. if(i == 1) return(0); /* still in trap, so didnt move */ 156. } 157. if(mtmp->mhide && o_at(mtmp->mx,mtmp->my) && rn2(10)) 158. return(0); /* do not leave hiding place */ 159. 160. #ifndef NOWORM 161. if(mtmp->wormno) 162. goto not_special; 163. #endif 164. 165. /* my dog gets a special treatment */ 166. if(mtmp->mtame) { 167. return( dog_move(mtmp, after) ); 168. } 169. 170. /* likewise for shopkeeper */ 171. if(mtmp->isshk) { 172. mmoved = shk_move(mtmp); 173. if(mmoved >= 0) 174. goto postmov; 175. mmoved = 0; /* follow player outside shop */ 176. } 177. 178. /* and for the guard */ 179. if(mtmp->isgd) { 180. mmoved = gd_move(); 181. goto postmov; 182. } 183. 184. /* teleport if that lies in our nature ('t') or when badly wounded ('1') */ 185. if((msym == 't' && !rn2(5)) 186. || (msym == '1' && (mtmp->mhp < 7 || (!xdnstair && !rn2(5)) 187. || levl[u.ux][u.uy].typ == STAIRS))) { 188. if(mtmp->mhp < 7 || (msym == 't' && rn2(2))) 189. rloc(mtmp); 190. else 191. mnexto(mtmp); 192. mmoved = 1; 193. goto postmov; 194. } 195. 196. /* spit fire ('D') or use a wand ('1') when appropriate */ 197. #ifdef DGKMOD 198. /* Add arrow and bolt throwing monsters */ 199. if (index( 200. # ifdef KAA 201. # ifdef KOPS 202. "D1OKC9", 203. # else 204. "D1KC9", 205. # endif 206. # else 207. # ifdef KOPS 208. "D1OKC", 209. # else 210. "D1KC", 211. # endif 212. # endif 213. msym)) 214. 215. if (!inrange(mtmp)) /* inrange returns 1 if OK for mon */ 216. return(0); /* to move after it zaps or throws */ 217. #else 218. if(index("D1", msym)) 219. inrange(mtmp); 220. #endif 221. 222. if(msym == 'U' && !mtmp->mcan && canseemon(mtmp) && 223. mtmp->mcansee && rn2(5)) { 224. if(!Confusion) 225. pline("%s's gaze has confused you!", Monnam(mtmp)); 226. else 227. pline("You are getting more and more confused."); 228. if(rn2(3)) mtmp->mcan = 1; 229. HConfusion += d(3,4); /* timeout */ 230. } 231. not_special: 232. if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1); 233. appr = 1; 234. if(mtmp->mflee) appr = -1; 235. if(mtmp->mconf || Invis || !mtmp->mcansee || 236. (index("BIy", msym) && !rn2(3))) 237. appr = 0; 238. omx = mtmp->mx; 239. omy = mtmp->my; 240. gx = u.ux; 241. gy = u.uy; 242. if(msym == 'L' && appr == 1 && mtmp->mgold > u.ugold) 243. appr = -1; 244. 245. /* random criterion for 'smell' or track finding ability 246. should use mtmp->msmell or sth 247. */ 248. if(msym == '@' || 249. ('a' <= msym && msym <= 'z')) { 250. extern coord *gettrack(); 251. register coord *cp; 252. schar mroom; 253. mroom = inroom(omx,omy); 254. if(mroom < 0 || mroom != inroom(u.ux,u.uy)){ 255. cp = gettrack(omx,omy); 256. if(cp){ 257. gx = cp->x; 258. gy = cp->y; 259. } 260. } 261. } 262. 263. /* look for gold or jewels nearby */ 264. #ifdef ROCKMOLE 265. likegold = (index("LODr", msym) != NULL); 266. likegems = (index("ODu", msym) != NULL); 267. likeobjs = (mtmp->mhide || msym == 'r'); 268. #else 269. likegold = (index("LOD", msym) != NULL); 270. likegems = (index("ODu", msym) != NULL); 271. likeobjs = mtmp->mhide; 272. #endif 273. #ifdef KAA 274. likerock = (msym == '9'); 275. #endif 276. #define SRCHRADIUS 25 277. { xchar mind = SRCHRADIUS; /* not too far away */ 278. register int dd; 279. if(likegold){ 280. register struct gold *gold; 281. for(gold = fgold; gold; gold = gold->ngold) 282. if((dd = DIST(omx,omy,gold->gx,gold->gy)) < mind){ 283. mind = dd; 284. gx = gold->gx; 285. gy = gold->gy; 286. } 287. } 288. if(likegems || likeobjs 289. #ifdef KAA 290. || likerock 291. #endif 292. ) { 293. register struct obj *otmp; 294. for(otmp = fobj; otmp; otmp = otmp->nobj) 295. if(likeobjs 296. || (likegems && otmp->olet == GEM_SYM) 297. #ifdef KAA 298. || (likerock && otmp->olet == ROCK_SYM) 299. #endif 300. ) { 301. if(msym != 'u' || objects[otmp->otyp].g_val != 0) 302. if((dd = DIST(omx,omy,otmp->ox,otmp->oy)) < mind){ 303. mind = dd; 304. gx = otmp->ox; 305. gy = otmp->oy; 306. } 307. } 308. } 309. if(mind < SRCHRADIUS && appr == -1) { 310. if(dist(omx,omy) < 10) { 311. gx = u.ux; 312. gy = u.uy; 313. } else 314. appr = 1; 315. } 316. } 317. nix = omx; 318. niy = omy; 319. cnt = mfndpos(mtmp,poss,info, 320. msym == 'u' ? NOTONL : 321. #ifdef ROCKMOLE 322. msym == 'r' ? ALLOW_WALL : 323. #endif 324. (msym == '@' || msym == '1') ? (ALLOW_SSM | ALLOW_TRAPS) : 325. index(UNDEAD, msym) ? NOGARLIC : 326. #ifdef KAA 327. (msym == '9') ? (ALLOW_ROCK | ALLOW_TRAPS) : ALLOW_TRAPS); 328. #else 329. ALLOW_TRAPS); 330. #endif 331. chcnt = 0; 332. chi = -1; 333. for(i=0; i<cnt; i++) { 334. nx = poss[i].x; 335. ny = poss[i].y; 336. for(j=0; j<MTSZ && j<cnt-1; j++) 337. if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y) 338. if(rn2(4*(cnt-j))) goto nxti; 339. #ifdef STUPID 340. /* some stupid compilers think that this is too complicated */ 341. { int d1 = DIST(nx,ny,gx,gy); 342. int d2 = DIST(nix,niy,gx,gy); 343. nearer = (d1 < d2); 344. } 345. #else 346. nearer = (DIST(nx,ny,gx,gy) < DIST(nix,niy,gx,gy)); 347. #endif 348. if((appr == 1 && nearer) || (appr == -1 && !nearer) || 349. !mmoved || 350. (!appr && !rn2(++chcnt))){ 351. nix = nx; 352. niy = ny; 353. chi = i; 354. mmoved = 1; 355. } 356. nxti: ; 357. } 358. if(mmoved){ 359. if(info[chi] & ALLOW_M){ 360. mtmp2 = m_at(nix,niy); 361. if(hitmm(mtmp,mtmp2) == 1 && rn2(4) && 362. hitmm(mtmp2,mtmp) == 2) return(2); 363. return(0); 364. } 365. if(info[chi] & ALLOW_U){ 366. (void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd)+1); 367. return(0); 368. } 369. mtmp->mx = nix; 370. mtmp->my = niy; 371. for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1]; 372. mtmp->mtrack[0].x = omx; 373. mtmp->mtrack[0].y = omy; 374. #ifndef NOWORM 375. if(mtmp->wormno) worm_move(mtmp); 376. #endif 377. } else { 378. if(msym == 'u' && rn2(2)){ 379. rloc(mtmp); 380. return(0); 381. } 382. #ifndef NOWORM 383. if(mtmp->wormno) worm_nomove(mtmp); 384. #endif 385. } 386. postmov: 387. if(mmoved == 1) { 388. if(mintrap(mtmp) == 2) /* he died */ 389. return(2); 390. #ifdef ROCKMOLE 391. /* Maybe a rock mole just ate something? */ 392. if(msym == 'r' && IS_ROCK(levl[mtmp->mx][mtmp->my].typ) && 393. levl[mtmp->mx][mtmp->my].typ != POOL){ 394. register int pile = rnd(25); 395. /* Just ate something. */ 396. if(levl[mtmp->mx][mtmp->my].typ == 0) 397. levl[mtmp->mx][mtmp->my].typ = CORR; 398. else if(IS_WALL(levl[mtmp->mx][mtmp->my].typ)) 399. levl[mtmp->mx][mtmp->my].typ = DOOR; 400. mnewsym(mtmp->mx,mtmp->my); 401. /* Left behind a pile? */ 402. if(pile < 5) { 403. if(pile == 1) 404. mksobj_at(ENORMOUS_ROCK, mtmp->mx, mtmp->my); 405. else 406. mksobj_at(ROCK, mtmp->mx, mtmp->my); 407. } 408. if(cansee(mtmp->mx, mtmp->my)) 409. atl(mtmp->mx,mtmp->my,fobj->olet); 410. } 411. /* Maybe a rock mole just ate some gold or armor? */ 412. if(msym == 'r') meatgold(mtmp); 413. #endif /* ROCKMOLE /**/ 414. if(likegold) mpickgold(mtmp); 415. #ifdef KAA 416. if(likerock || likegems) mpickgems(mtmp); 417. #else 418. if(likegems) mpickgems(mtmp); 419. #endif 420. if(mtmp->mhide) mtmp->mundetected = 1; 421. } 422. pmon(mtmp); 423. return(mmoved); 424. } 425.