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