Source:NetHack 2.2a/monmove.c
Revision as of 02:23, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 2.2a/monmove.c moved to Source:NetHack 2.2a/monmove.c: Robot: moved page)
Below is the full text to monmove.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/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 2.1 87/10/18 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 int warnlevel; /* defined in mon.c */ 9. 10. dochugw(mtmp) register struct monst *mtmp; { 11. register x = mtmp->mx; 12. register y = mtmp->my; 13. register d = dochug(mtmp); 14. register dd; 15. if(!d) /* monster still alive */ 16. if(Warning) 17. if(!mtmp->mpeaceful) 18. if(mtmp->data->mlevel > warnlevel) 19. if((dd = dist(mtmp->mx,mtmp->my)) < dist(x,y)) 20. if(dd < 100) 21. if(!canseemon(mtmp)) 22. warnlevel = mtmp->data->mlevel; 23. return(d); 24. } 25. 26. /* returns 1 if monster died moving, 0 otherwise */ 27. dochug(mtmp) 28. register struct monst *mtmp; 29. { 30. register struct permonst *mdat; 31. register tmp, nearby, scared, onscary; 32. 33. if(mtmp->cham && !rn2(6)) 34. (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]); 35. mdat = mtmp->data; 36. if(mdat->mlevel < 0) 37. panic("bad monster %c (%d)",mdat->mlet,mdat->mlevel); 38. 39. /* regenerate monsters */ 40. if((!(moves%20) || index(MREGEN, mdat->mlet)) && 41. mtmp->mhp < mtmp->mhpmax) 42. mtmp->mhp++; 43. 44. if(mtmp->mfroz) { 45. if (Hallucination) pmon(mtmp); 46. return(0); /* frozen monsters don't do anything */ 47. } 48. 49. if(mtmp->msleep) /* there is a chance we will wake it */ 50. if(!disturb(mtmp)) return(0); 51. 52. /* not frozen or sleeping: wipe out texts written in the dust */ 53. wipe_engr_at(mtmp->mx, mtmp->my, 1); 54. 55. /* confused monsters get unconfused with small probability */ 56. if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0; 57. 58. /* some monsters teleport */ 59. if(mtmp->mflee && index("tNL", mdat->mlet) && !rn2(40)){ 60. rloc(mtmp); 61. return(0); 62. } 63. if(mdat->mmove < rnd(6)) return(0); 64. 65. /* fleeing monsters might regain courage */ 66. if(mtmp->mflee && !mtmp->mfleetim 67. && mtmp->mhp == mtmp->mhpmax && !rn2(25)) 68. mtmp->mflee = 0; 69. 70. nearby = (dist(mtmp->mx, mtmp->my) < 3); 71. onscary = (sengr_at("Elbereth", u.ux, u.uy) || 72. sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy)); 73. scared = (nearby && onscary && !mtmp->mtame && mtmp->mcansee) 74. && (mdat->mlet != '1'); /* RPH: the wiz is never scared */ 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. #ifdef RPH 232. if (msym == '8' && canseemon(mtmp)) { 233. if (mtmp->mcan) 234. pline ("You notice that %s isn't all that ugly.",monnam(mtmp)); 235. else if (rn2(3)) 236. pline ("You see the ugly back of %s.", monnam(mtmp)); 237. else { 238. pline ("You look upon %s.", monnam(mtmp)); 239. pline ("You turn to stone."); 240. done_in_by(mtmp); 241. } 242. } 243. #endif 244. not_special: 245. if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1); 246. appr = 1; 247. if(mtmp->mflee) appr = -1; 248. if(mtmp->mconf || Invis || !mtmp->mcansee || 249. (index("BIy", msym) && !rn2(3))) 250. appr = 0; 251. omx = mtmp->mx; 252. omy = mtmp->my; 253. gx = u.ux; 254. gy = u.uy; 255. if(msym == 'L' && appr == 1 && mtmp->mgold > u.ugold) 256. appr = -1; 257. 258. /* random criterion for 'smell' or track finding ability 259. should use mtmp->msmell or sth 260. */ 261. if(msym == '@' || 262. #ifdef RPH 263. uwep && !strcmp(ONAME(uwep), "Excalibur") || 264. #endif 265. ('a' <= msym && msym <= 'z')) { 266. extern coord *gettrack(); 267. register coord *cp; 268. schar mroom; 269. mroom = inroom(omx,omy); 270. if(mroom < 0 || mroom != inroom(u.ux,u.uy)){ 271. cp = gettrack(omx,omy); 272. if(cp){ 273. gx = cp->x; 274. gy = cp->y; 275. } 276. } 277. } 278. 279. /* look for gold or jewels nearby */ 280. #ifdef ROCKMOLE 281. likegold = (index("LODr", msym) != NULL); 282. likegems = (index("ODu", msym) != NULL); 283. # ifdef KJSMODS 284. likeobjs = (mtmp->mhide || (msym == 'r' && dlevel > 3)); 285. # else 286. likeobjs = (mtmp->mhide || msym == 'r'); 287. # endif 288. #else 289. likegold = (index("LOD", msym) != NULL); 290. likegems = (index("ODu", msym) != NULL); 291. likeobjs = mtmp->mhide; 292. #endif 293. #ifdef KAA 294. likerock = (msym == '9'); 295. #endif 296. #define SRCHRADIUS 25 297. { xchar mind = SRCHRADIUS; /* not too far away */ 298. register int dd; 299. if(likegold){ 300. register struct gold *gold; 301. for(gold = fgold; gold; gold = gold->ngold) 302. if((dd = DIST(omx,omy,gold->gx,gold->gy)) < mind){ 303. mind = dd; 304. gx = gold->gx; 305. gy = gold->gy; 306. } 307. } 308. if(likegems || likeobjs 309. #ifdef KAA 310. || likerock 311. #endif 312. ) { 313. register struct obj *otmp; 314. for(otmp = fobj; otmp; otmp = otmp->nobj) 315. if(likeobjs 316. || (likegems && otmp->olet == GEM_SYM) 317. #ifdef KAA 318. || (likerock && otmp->olet == ROCK_SYM) 319. #endif 320. ) { 321. if(msym != 'u' || objects[otmp->otyp].g_val != 0) 322. if((dd = DIST(omx,omy,otmp->ox,otmp->oy)) < mind){ 323. mind = dd; 324. gx = otmp->ox; 325. gy = otmp->oy; 326. } 327. } 328. } 329. if(mind < SRCHRADIUS && appr == -1) { 330. if(dist(omx,omy) < 10) { 331. gx = u.ux; 332. gy = u.uy; 333. } else 334. appr = 1; 335. } 336. } 337. nix = omx; 338. niy = omy; 339. cnt = mfndpos(mtmp,poss,info, 340. msym == 'u' ? NOTONL : 341. #ifdef ROCKMOLE 342. # ifdef KJSMODS 343. (msym == 'r' && dlevel > 3) ? ALLOW_WALL : 344. # else 345. msym == 'r' ? ALLOW_WALL : 346. # endif 347. #endif 348. (msym == '@' || msym == '1') ? (ALLOW_SSM | ALLOW_TRAPS) : 349. index(UNDEAD, msym) ? NOGARLIC : 350. #ifdef KAA 351. (msym == '9') ? (ALLOW_ROCK | ALLOW_TRAPS) : ALLOW_TRAPS); 352. #else 353. ALLOW_TRAPS); 354. #endif 355. chcnt = 0; 356. chi = -1; 357. for(i=0; i<cnt; i++) { 358. nx = poss[i].x; 359. ny = poss[i].y; 360. for(j=0; j<MTSZ && j<cnt-1; j++) 361. if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y) 362. if(rn2(4*(cnt-j))) goto nxti; 363. #ifdef STUPID 364. /* some stupid compilers think that this is too complicated */ 365. { int d1 = DIST(nx,ny,gx,gy); 366. int d2 = DIST(nix,niy,gx,gy); 367. nearer = (d1 < d2); 368. } 369. #else 370. nearer = (DIST(nx,ny,gx,gy) < DIST(nix,niy,gx,gy)); 371. #endif 372. if((appr == 1 && nearer) || (appr == -1 && !nearer) || 373. !mmoved || 374. (!appr && !rn2(++chcnt))){ 375. nix = nx; 376. niy = ny; 377. chi = i; 378. mmoved = 1; 379. } 380. nxti: ; 381. } 382. if(mmoved){ 383. if(info[chi] & ALLOW_M){ 384. mtmp2 = m_at(nix,niy); 385. if(hitmm(mtmp,mtmp2) == 1 && rn2(4) && 386. hitmm(mtmp2,mtmp) == 2) return(2); 387. return(0); 388. } 389. if(info[chi] & ALLOW_U){ 390. (void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd)+1); 391. return(0); 392. } 393. mtmp->mx = nix; 394. mtmp->my = niy; 395. for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1]; 396. mtmp->mtrack[0].x = omx; 397. mtmp->mtrack[0].y = omy; 398. #ifndef NOWORM 399. if(mtmp->wormno) worm_move(mtmp); 400. #endif 401. } else { 402. if(msym == 'u' && rn2(2)){ 403. rloc(mtmp); 404. return(0); 405. } 406. #ifndef NOWORM 407. if(mtmp->wormno) worm_nomove(mtmp); 408. #endif 409. } 410. postmov: 411. if(mmoved == 1) { 412. if(mintrap(mtmp) == 2) /* he died */ 413. return(2); 414. #ifdef ROCKMOLE 415. /* Maybe a rock mole just ate something? */ 416. if(msym == 'r' 417. # ifdef KJSMODS 418. && dlevel > 3 419. #endif 420. && IS_ROCK(levl[mtmp->mx][mtmp->my].typ) && 421. levl[mtmp->mx][mtmp->my].typ != POOL){ 422. register int pile = rnd(25); 423. /* Just ate something. */ 424. if(levl[mtmp->mx][mtmp->my].typ == 0) 425. levl[mtmp->mx][mtmp->my].typ = CORR; 426. else if(IS_WALL(levl[mtmp->mx][mtmp->my].typ)) 427. levl[mtmp->mx][mtmp->my].typ = DOOR; 428. mnewsym(mtmp->mx,mtmp->my); 429. /* Left behind a pile? */ 430. if(pile < 5) { 431. if(pile == 1) 432. mksobj_at(ENORMOUS_ROCK, mtmp->mx, mtmp->my); 433. else 434. mksobj_at(ROCK, mtmp->mx, mtmp->my); 435. } 436. if(cansee(mtmp->mx, mtmp->my)) 437. if(fobj) atl(mtmp->mx,mtmp->my,fobj->olet); 438. } 439. /* Maybe a rock mole just ate some gold or armor? */ 440. if(msym == 'r') meatgold(mtmp); 441. #endif /* ROCKMOLE /**/ 442. if(likegold) mpickgold(mtmp); 443. #ifdef KAA 444. if(likerock || likegems) mpickgems(mtmp); 445. #else 446. if(likegems) mpickgems(mtmp); 447. #endif 448. if(mtmp->mhide) mtmp->mundetected = 1; 449. } 450. pmon(mtmp); 451. return(mmoved); 452. } 453.