Difference between revisions of "Source:NetHack 3.0.0/monmove.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (NetHack 3.0.0/monmove.c moved to Source:NetHack 3.0.0/monmove.c: Robot: moved page) |
(No difference)
|
Latest revision as of 05:01, 4 March 2008
Below is the full text to monmove.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/monmove.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)monmove.c 3.0 88/11/10 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "mfndpos.h" 7. #ifdef NAMED_ITEMS 8. # include "artifact.h" 9. #endif 10. 11. static boolean /* TRUE : mtmp died */ 12. mb_trapped(mtmp) 13. register struct monst *mtmp; 14. { 15. if (flags.verbose) { 16. if (cansee(mtmp->mx, mtmp->my)) 17. pline("KABOOM!! You see a door explode."); 18. else if (flags.soundok) 19. You("hear a distant explosion."); 20. } 21. mtmp->mstun = 1; 22. mtmp->mhp -= rnd(15); 23. if(mtmp->mhp <= 0) { 24. mondied(mtmp); 25. return(TRUE); 26. } 27. return(FALSE); 28. } 29. 30. boolean 31. mdig_tunnel(mtmp) /* FALSE: monster died */ 32. register struct monst *mtmp; 33. { 34. register struct rm *here; 35. register int pile = rnd(12); 36. boolean canseeit = cansee(mtmp->mx, mtmp->my); 37. here = &levl[mtmp->mx][mtmp->my]; 38. 39. if(IS_ROCK(here->typ)) { 40. /* Just ate something. */ 41. if(here->typ == STONE) here->typ = CORR; 42. else if(IS_WALL(here->typ) && 43. !(here->diggable & W_NONDIGGABLE)) { 44. if(flags.soundok && flags.verbose && !rn2(5)) 45. You("hear the sound of crashing rock."); 46. here->typ = DOOR; 47. here->doormask = D_NODOOR; 48. } 49. } 50. /* Eats away door if present & closed or locked */ 51. else if(IS_DOOR(here->typ) && 52. (here->doormask & (D_LOCKED | D_CLOSED))) { 53. if(here->doormask & D_TRAPPED) { 54. here->doormask = D_NODOOR; 55. if(mb_trapped(mtmp)) return(FALSE); 56. } else { 57. if(!rn2(3) && flags.verbose) /* not too often.. */ 58. You("feel an unexpected draft of air."); 59. here->doormask = D_BROKEN; 60. } 61. } 62. else pile = 12; /* it doesn't leave rocks if it didn't dig */ 63. 64. /* Left behind a pile? */ 65. if(pile < 5) { 66. if(pile == 1) 67. (void) mksobj_at(BOULDER, mtmp->mx, mtmp->my); 68. else 69. (void) mksobj_at(ROCK, mtmp->mx, mtmp->my); 70. } 71. if(canseeit) { 72. here->seen = TRUE; 73. newsym(mtmp->mx,mtmp->my); 74. } else 75. mnewsym(mtmp->mx,mtmp->my); 76. return(TRUE); 77. } 78. 79. int 80. dochugw(mtmp) 81. register struct monst *mtmp; 82. { 83. register int x = mtmp->mx; 84. register int y = mtmp->my; 85. register int rd = dochug(mtmp); 86. register int dd; 87. 88. if(!rd && !mtmp->mpeaceful && 89. (dd = dist(mtmp->mx,mtmp->my)) < dist(x,y) && 90. dd < 100 && !canseemon(mtmp)) { 91. #ifdef NAMED_ITEMS 92. /* Note: this assumes we only want to warn against the monster which 93. * the weapon does extra damage to, as there is no "monster which 94. * the weapon warns against" field. 95. */ 96. if(spec_ability(uwep,SPFX_WARN) && spec_dbon(uwep,mtmp->data,1)) 97. warnlevel = 100; 98. else 99. #endif 100. if (Warning && mtmp->m_lev > warnlevel) 101. warnlevel = mtmp->m_lev; 102. } 103. return(rd); 104. } 105. 106. boolean 107. onscary(x, y, mtmp) 108. int x, y; 109. struct monst *mtmp; 110. { 111. if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee || 112. mtmp->data->mlet == S_HUMAN || mtmp->mpeaceful) 113. return(FALSE); 114. return( 115. #ifdef ELBERETH 116. sengr_at("Elbereth", x, y) || 117. #endif 118. sobj_at(SCR_SCARE_MONSTER, x, y) != (struct obj *)0); 119. } 120. 121. /* returns 1 if monster died moving, 0 otherwise */ 122. int 123. dochug(mtmp) 124. register struct monst *mtmp; 125. { 126. register struct permonst *mdat = mtmp->data; 127. register int tmp=0, inrange, nearby, scared, seescaryx, 128. seescaryy; 129. 130. /* Pre-movement adjustments */ 131. 132. if(mtmp->cham && !rn2(6)) /* polymorph chameleons */ 133. (void) newcham(mtmp, (struct permonst *)0); 134. 135. /* regenerate monsters */ 136. if((!(moves%20) || regenerates(mdat)) && mtmp->mhp < mtmp->mhpmax) 137. mtmp->mhp++; 138. if(mtmp->mspec_used) mtmp->mspec_used--; 139. 140. /* polymorph lycanthropes */ 141. were_change(mtmp); 142. 143. if(mtmp->mfroz) { 144. if (Hallucination) pmon(mtmp); 145. return(0); /* frozen monsters don't do anything */ 146. } 147. 148. if(mtmp->msleep) /* there is a chance we will wake it */ 149. if(!disturb(mtmp)) return(0); 150. 151. /* not frozen or sleeping: wipe out texts written in the dust */ 152. wipe_engr_at(mtmp->mx, mtmp->my, 1); 153. 154. /* confused monsters get unconfused with small probability */ 155. if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0; 156. 157. /* stunned monsters get un-stunned with larger probability */ 158. if(mtmp->mstun && !rn2(10)) mtmp->mstun = 0; 159. 160. /* some monsters teleport */ 161. if(mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz) { 162. rloc(mtmp); 163. return(0); 164. } 165. if(mdat->mmove < rnd(6)) return(0); 166. 167. /* fleeing monsters might regain courage */ 168. if(mtmp->mflee && !mtmp->mfleetim 169. && mtmp->mhp == mtmp->mhpmax && !rn2(25)) mtmp->mflee = 0; 170. 171. set_apparxy(mtmp); 172. /* Must be done after you move and before the monster does. The 173. * set_apparxy() call in m_move() doesn't suffice since the variables 174. * inrange, etc... all depend on stuff set by set_apparxy(). 175. */ 176. 177. /* The Wizard's prime directive */ 178. /* may teleport, so do it before inrange is set */ 179. if(mtmp->iswiz) 180. (void) wiz_get_amulet(mtmp); 181. 182. inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 183. (BOLT_LIM * BOLT_LIM)); 184. nearby = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) < 3); 185. /* Note: if your image is displaced, the monster sees the Elbereth 186. * at your displaced position, thus never attacking your displaced 187. * position, but possibly attacking you by accident. If you are 188. * invisible, it sees the Elbereth at your real position, thus never 189. * running into you by accident but possibly attacking the spot 190. * where it guesses you are. 191. */ 192. if (Invis && !perceives(mdat)) { 193. seescaryx = mtmp->mux; 194. seescaryy = mtmp->muy; 195. } else { 196. seescaryx = u.ux; 197. seescaryy = u.uy; 198. } 199. scared = (nearby && onscary(seescaryx, seescaryy, mtmp)); 200. 201. if(scared && !mtmp->mflee) { 202. #ifdef POLYSELF 203. if (!sticks(uasmon)) 204. #endif 205. unstuck(mtmp); /* monster lets go when fleeing */ 206. mtmp->mflee = 1; 207. mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100)); 208. } 209. 210. #ifdef HARD /* Demonic Blackmail!!! */ 211. if(nearby && is_demon(mdat) && mtmp->mpeaceful && !mtmp->mtame) { 212. if (mtmp->mux != u.ux || mtmp->muy != u.uy) { 213. pline("%s whispers something to thin air.", 214. cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It"); 215. #ifdef POLYSELF 216. if (is_demon(uasmon)) rloc(mtmp); 217. /* "Good hunting, brother" */ 218. else 219. #endif 220. if (is_lord(mdat) || is_prince(mdat)) { 221. /* use is_lord instead of is_dlord */ 222. mtmp->minvis = 0; 223. /* Why? For the same reason in real demon talk */ 224. pline("%s gets angry.", Xmonnam(mtmp)); 225. mtmp->mpeaceful = 0; 226. /* since no way is an image going to pay it off */ 227. } 228. } else if(demon_talk(mtmp)) return(1); /* you paid it off */ 229. } 230. #endif 231. 232. /* Now the actual movement phase */ 233. 234. if(!nearby || mtmp->mflee || scared || 235. mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) || 236. (mdat->mlet == S_LEPRECHAUN && !u.ugold && (mtmp->mgold || rn2(2))) || 237. (is_wanderer(mdat) && !rn2(4)) || (Conflict && !mtmp->iswiz) || 238. (!mtmp->mcansee && !rn2(4)) || mtmp->mpeaceful) { 239. 240. tmp = m_move(mtmp, 0); 241. nearby = (dist(mtmp->mx, mtmp->my) < 3); /* recalc */ 242. scared = (nearby && onscary(seescaryx, seescaryy, mtmp)); 243. switch (tmp) { 244. 245. case 0: /* no movement, but it can still attack you */ 246. case 3: /* absolutely no movement */ 247. /* for pets, case 0 and 3 are equivalent */ 248. /* During hallucination, monster appearance should 249. * still change - even if it doesn't move. 250. */ 251. if(Hallucination) pmon(mtmp); 252. break; 253. case 1: /* monster moved */ 254. if(!nearby && ranged_attk(mdat)) break; 255. else if(mdat->mmove <= 12) return(0); 256. break; 257. case 2: /* monster died */ 258. return(1); 259. } 260. 261. inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 262. (BOLT_LIM * BOLT_LIM)); 263. if(scared && !mtmp->mflee) { 264. mtmp->mflee = 1; 265. mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100)); 266. } 267. } 268. 269. /* Now, attack the player if possible - one attack set per monst */ 270. 271. if(inrange && !noattacks(mdat) && 272. !mtmp->mpeaceful && !mtmp->mtame && u.uhp > 0 && !scared && tmp != 3) 273. if(mattacku(mtmp)) return(1); /* monster died (e.g. exploded) */ 274. 275. #ifdef WORM 276. if(mtmp->wormno && !mtmp->mtame) wormhit(mtmp); 277. #endif 278. 279. /* extra movement for fast monsters */ 280. if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp, 1); 281. return(tmp == 2); 282. } 283. 284. static const char practical[] = { WEAPON_SYM, GEM_SYM, FOOD_SYM, 0 }; 285. static const char magical[] = { 286. AMULET_SYM, POTION_SYM, SCROLL_SYM, WAND_SYM, RING_SYM, 287. #ifdef SPELLS 288. SPBOOK_SYM, 289. #endif 290. 0 }; 291. static const char indigestion[] = { BALL_SYM, ROCK_SYM, 0 }; 292. 293. #ifdef POLYSELF 294. static boolean 295. itsstuck(mtmp) 296. register struct monst *mtmp; 297. { 298. if (sticks(uasmon) && mtmp==u.ustuck && !u.uswallow) { 299. kludge("%s cannot escape from you!", Monnam(mtmp)); 300. return(TRUE); 301. } 302. return(FALSE); 303. } 304. #endif 305. 306. int 307. m_move(mtmp, after) 308. register struct monst *mtmp; 309. register int after; 310. { 311. register struct monst *mtmp2; 312. register int nx,ny,omx,omy,appr,nearer,cnt,i,j; 313. xchar gx,gy,nix,niy,chcnt; 314. schar chi; 315. boolean likegold=0, likegems=0, likeobjs=0, likemagic=0, conceals=0; 316. boolean likerock=0, can_tunnel=0; 317. struct permonst *ptr = mtmp->data; 318. schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */ 319. coord poss[9]; 320. long info[9]; 321. long flag; 322. 323. if(mtmp->mtrapped) { 324. i = mintrap(mtmp); 325. if(i == 2) return(2); /* it died */ 326. if(i == 1) return(0); /* still in trap, so didn't move */ 327. } 328. if(mtmp->mhide && 329. (levl[mtmp->mx][mtmp->my].omask || levl[mtmp->mx][mtmp->my].gmask) && 330. rn2(10)) 331. return(0); /* do not leave hiding place */ 332. if(mtmp->meating) { 333. mtmp->meating--; 334. return(3); /* still eating */ 335. } 336. 337. set_apparxy(mtmp); 338. /* where does mtmp think you are? */ 339. /* Not necessary if m_move called from here, but necessary in 340. * other calls of m_move (i.e. leprechauns dodging) 341. */ 342. can_tunnel = tunnels(ptr) && 343. #ifdef REINCARNATION 344. dlevel != rogue_level && 345. #endif 346. (!needspick(ptr) || m_carrying(mtmp, PICK_AXE)); 347. #ifdef WORM 348. if(mtmp->wormno) goto not_special; 349. #endif 350. /* my dog gets a special treatment */ 351. if(mtmp->mtame) return( dog_move(mtmp, after) ); 352. 353. /* likewise for shopkeeper */ 354. if(mtmp->isshk) { 355. mmoved = shk_move(mtmp); 356. if(mmoved == -2) return(2); 357. if(mmoved >= 0) goto postmov; 358. mmoved = 0; /* follow player outside shop */ 359. } 360. 361. /* and for the guard */ 362. if(mtmp->isgd) { 363. mmoved = gd_move(); 364. goto postmov; 365. } 366. 367. /* and the wiz already got special treatment */ 368. if(mtmp->iswiz) { 369. mmoved = 0; 370. goto postmov; 371. } 372. #if defined(ALTARS) && defined(THEOLOGY) 373. /* and for the priest */ 374. if(mtmp->ispriest) { 375. mmoved = pri_move(mtmp); 376. if(mmoved == -2) return(2); 377. if(mmoved >= 0) goto postmov; 378. mmoved = 0; 379. } 380. #endif 381. #ifdef MAIL 382. if(ptr == &mons[PM_MAIL_DAEMON]) { 383. if(flags.soundok && canseemon(mtmp)) 384. pline("\"I'm late!\""); 385. mongone(mtmp); 386. return(2); 387. } 388. #endif 389. 390. /* teleport if that lies in our nature */ 391. if(ptr == &mons[PM_TENGU] && !rn2(5)) { 392. if(mtmp->mhp < 7 || mtmp->mpeaceful || rn2(2)) 393. rloc(mtmp); 394. else 395. mnexto(mtmp); 396. mmoved = 1; 397. goto postmov; 398. } 399. #ifdef WORM 400. not_special: 401. #endif 402. if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1); 403. appr = 1; 404. if(mtmp->mflee) appr = -1; 405. if(mtmp->mconf || (Invis && !perceives(ptr)) || !mtmp->mcansee || 406. (mtmp->mpeaceful && !mtmp->isshk) || /* allow shks to follow */ 407. ((ptr->mlet == S_STALKER || ptr->mlet == S_BAT || 408. ptr->mlet == S_YLIGHT) && !rn2(3))) 409. appr = 0; 410. omx = mtmp->mx; 411. omy = mtmp->my; 412. gx = mtmp->mux; 413. gy = mtmp->muy; 414. if(ptr == &mons[PM_LEPRECHAUN] && appr == 1 && mtmp->mgold > u.ugold) 415. appr = -1; 416. 417. if(can_track(ptr)) { 418. register coord *cp; 419. schar mroom; 420. 421. mroom = inroom(omx,omy); 422. if(mroom < 0 || mroom != inroom(u.ux,u.uy)){ 423. cp = gettrack(omx,omy); 424. if(cp){ 425. gx = cp->x; 426. gy = cp->y; 427. } 428. } 429. } 430. 431. #ifdef REINCARNATION 432. if (dlevel != rogue_level) 433. #endif 434. { 435. register int pctload = (curr_mon_load(mtmp) * 100) / 436. max_mon_load(mtmp); 437. 438. /* look for gold or jewels nearby */ 439. likegold = (likes_gold(ptr) && pctload < 95); 440. likegems = (likes_gems(ptr) && pctload < 85); 441. likeobjs = (likes_objs(ptr) && pctload < 75); 442. likemagic = (likes_magic(ptr) && pctload < 85); 443. likerock = (throws_rocks(ptr) && pctload < 50); 444. conceals = hides_under(ptr); 445. } 446. 447. #define SRCHRADIUS 25 448. 449. { xchar mind = SRCHRADIUS; /* not too far away */ 450. register int dd; 451. 452. /* cut down the search radius if it thinks character is closer. */ 453. if(dist2(mtmp->mux, mtmp->muy, omx, omy) < SRCHRADIUS && 454. !mtmp->mtame && !mtmp->mpeaceful) mind /= 2; 455. 456. if(likegold){ 457. register struct gold *gold; 458. 459. for(gold = fgold; gold; gold = gold->ngold) 460. if((dd = dist2(omx,omy,gold->gx,gold->gy)) < mind){ 461. mind = dd; 462. gx = gold->gx; 463. gy = gold->gy; 464. } 465. } 466. if((likegems || likeobjs || likemagic || likerock || conceals) 467. && (!in_shop(omx, omy) || (!rn2(25) && !mtmp->isshk))) { 468. register struct obj *otmp; 469. 470. for(otmp = fobj; otmp; otmp = otmp->nobj) 471. if((likeobjs && index(practical, otmp->olet)) || 472. (likemagic && index(magical, otmp->olet)) || 473. (likerock && otmp->otyp == BOULDER) || 474. (likegems && otmp->olet == GEM_SYM && 475. otmp->otyp < LAST_GEM + 5) || 476. (conceals && !cansee(otmp->ox,otmp->oy)) || 477. (ptr == &mons[PM_GELATINOUS_CUBE] && 478. !index(indigestion, otmp->olet)) 479. ) { 480. if(can_carry(mtmp,otmp)) 481. if(ptr->mlet != S_UNICORN || 482. objects[otmp->otyp].g_val != 0) 483. if((dd = dist2(omx,omy,otmp->ox,otmp->oy)) < mind){ 484. mind = dd; 485. gx = otmp->ox; 486. gy = otmp->oy; 487. } 488. } 489. } 490. if(mind < SRCHRADIUS && appr == -1) { 491. if(dist2(omx,omy,mtmp->mux,mtmp->muy) < 10) { 492. gx = mtmp->mux; 493. gy = mtmp->muy; 494. } else 495. appr = 1; 496. } 497. } 498. nix = omx; 499. niy = omy; 500. flag = ALLOW_TRAPS; 501. if (mtmp->mpeaceful) flag |= (ALLOW_SANCT | ALLOW_SSM); 502. else flag |= ALLOW_U; 503. if (ptr->mlet == S_UNICORN) flag |= NOTONL; 504. if (passes_walls(ptr)) flag |= (ALLOW_WALL | ALLOW_ROCK); 505. if (can_tunnel) flag |= ALLOW_DIG; 506. if (is_human(ptr)) flag |= ALLOW_SSM; 507. if (is_undead(ptr)) flag |= NOGARLIC; 508. if (throws_rocks(ptr)) flag |= ALLOW_ROCK; 509. cnt = mfndpos(mtmp, poss, info, flag); 510. chcnt = 0; 511. chi = -1; 512. 513. for(i=0; i < cnt; i++) { 514. nx = poss[i].x; 515. ny = poss[i].y; 516. 517. for(j=0; j < MTSZ && j < cnt-1; j++) 518. if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y) 519. if(rn2(4*(cnt-j))) goto nxti; 520. 521. nearer = (dist2(nx,ny,gx,gy) < dist2(nix,niy,gx,gy)); 522. 523. if((appr == 1 && nearer) || (appr == -1 && !nearer) || 524. !mmoved || (!appr && !rn2(++chcnt))) { 525. nix = nx; 526. niy = ny; 527. chi = i; 528. mmoved = 1; 529. } 530. nxti: ; 531. } 532. 533. if(mmoved) { 534. #ifdef POLYSELF 535. if (mmoved==1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp)) 536. return(3); 537. #endif 538. if((info[chi] & ALLOW_U) || (nix == u.ux && niy == u.uy)) { 539. mtmp->mux = u.ux; 540. mtmp->muy = u.uy; 541. return(0); 542. } 543. /* The monster may attack another based on 1 of 2 conditions: 544. * 1 - He may be under the "conflict" influence. 545. * 2 - He may mistake the monster for your (displaced) image. 546. * Pets get taken care of above and shouldn't reach this code. 547. */ 548. if((info[chi] & ALLOW_M) || 549. (nix == mtmp->mux && niy == mtmp->muy)) { 550. mtmp2 = 551. (levl[nix][niy].mmask ? m_at(nix,niy) : (struct monst *)0); 552. if(mattackm(mtmp, mtmp2) == 1 && rn2(4) && 553. mtmp2->mlstmv != moves && mattackm(mtmp2, mtmp) == 2) 554. return(2); 555. return(3); 556. } 557. #ifdef WORM 558. /* The square now has a worm segment and must keep its mmask */ 559. if (!mtmp->wormno) 560. #endif 561. levl[omx][omy].mmask = 0; 562. levl[nix][niy].mmask = 1; 563. mtmp->mx = nix; 564. mtmp->my = niy; 565. for(j = MTSZ-1; j > 0; j--) 566. mtmp->mtrack[j] = mtmp->mtrack[j-1]; 567. mtmp->mtrack[0].x = omx; 568. mtmp->mtrack[0].y = omy; 569. #ifdef WORM 570. if(mtmp->wormno) worm_move(mtmp); 571. #endif 572. } else { 573. if(ptr->mlet == S_UNICORN && rn2(2)) { 574. rloc(mtmp); 575. return(1); 576. } 577. #ifdef WORM 578. if(mtmp->wormno) worm_nomove(mtmp); 579. #endif 580. } 581. postmov: 582. if(mmoved == 1) { 583. boolean canseeit = cansee(mtmp->mx, mtmp->my); 584. boolean abstain = (mtmp->mpeaceful && !mtmp->mtame); 585. 586. if(mintrap(mtmp) == 2) return(2); /* he died */ 587. 588. /* open a door, or crash through it, if you can */ 589. if(IS_DOOR(levl[mtmp->mx][mtmp->my].typ) 590. && !passes_walls(ptr) /* doesn't need to open doors */ 591. && !amorphous(ptr) /* ditto */ 592. && !can_tunnel /* taken care of below */ 593. ) { 594. struct rm *here = &levl[mtmp->mx][mtmp->my]; 595. boolean btrapped = (here->doormask & D_TRAPPED); 596. 597. if(here->doormask & D_LOCKED && mtmp->isshk) { 598. /* can't lock out shk */ 599. if(btrapped) { 600. here->doormask = D_NODOOR; 601. if(mb_trapped(mtmp)) return(2); 602. } else { 603. if (flags.verbose) { 604. if (canseeit) 605. You("see a door being unlocked and opened."); 606. else if (flags.soundok) 607. You("hear a door being unlocked and opened."); 608. } 609. here->doormask = D_ISOPEN; 610. } 611. } else if (here->doormask == D_CLOSED && 612. !nohands(mtmp->data)) { 613. if(btrapped) { 614. here->doormask = D_NODOOR; 615. if(mb_trapped(mtmp)) return(2); 616. } else { 617. if (flags.verbose) { 618. if (canseeit) 619. You("see a door being opened."); 620. else if (flags.soundok) 621. You("hear the sound of a door opening."); 622. } 623. here->doormask = D_ISOPEN; 624. } 625. } else if(here->doormask & (D_LOCKED | D_CLOSED)) { 626. /* mfndpos guarantees monster is a giant */ 627. if(btrapped) { 628. here->doormask = D_NODOOR; 629. if(mb_trapped(mtmp)) return(2); 630. } else { 631. if (flags.verbose) { 632. if (canseeit) 633. You("see a door crash open."); 634. else if (flags.soundok) 635. You("hear the sound of a door crashing open."); 636. } 637. if (here->doormask & D_LOCKED && !rn2(2)) 638. here->doormask = D_NODOOR; 639. else here->doormask = D_BROKEN; 640. } 641. } 642. } 643. /* Maybe a rock mole just ate something? */ 644. if(can_tunnel) if(!mdig_tunnel(mtmp)) return(2); /* died? */ 645. 646. if(levl[mtmp->mx][mtmp->my].gmask == 1) { 647. /* Maybe a rock mole just ate some gold */ 648. if(ptr == &mons[PM_ROCK_MOLE]) meatgold(mtmp); 649. if(likegold && (!abstain || !rn2(10))) mpickgold(mtmp); 650. } 651. if(levl[mtmp->mx][mtmp->my].omask == 1) { 652. /* Maybe a rock mole just ate some metal object */ 653. if(ptr == &mons[PM_ROCK_MOLE]) meatgold(mtmp); 654. /* Maybe a cube ate just about anything */ 655. if(ptr == &mons[PM_GELATINOUS_CUBE]) meatobj(mtmp); 656. 657. if ((!abstain || !rn2(10)) 658. && (!in_shop(mtmp->mx, mtmp->my) || !rn2(25))) { 659. if(likeobjs) mpickstuff(mtmp, practical); 660. if(likemagic) mpickstuff(mtmp, magical); 661. if(likerock || likegems) mpickgems(mtmp); 662. } 663. } 664. if(mtmp->mhide) mtmp->mundetected = (levl[mtmp->mx][mtmp->my].omask 665. || levl[mtmp->mx][mtmp->my].gmask); 666. 667. /* set also in domove(), hack.c */ 668. if(u.uswallow && mtmp == u.ustuck) { 669. u.ux = mtmp->mx; 670. u.uy = mtmp->my; 671. if(mtmp->mx != mtmp->mdx || mtmp->my != mtmp->mdy) { 672. swallowed(0); 673. mtmp->mdx = mtmp->mx; 674. mtmp->mdy = mtmp->my; 675. } 676. } 677. } 678. pmon(mtmp); 679. return(mmoved); 680. } 681. 682. void 683. set_apparxy(mtmp) /* where does mtmp think you are standing? */ 684. register struct monst *mtmp; 685. { 686. #define notseen (Invis && !perceives(mtmp->data)) 687. /* add cases as required. eg. Displacement ... */ 688. register int disp = (notseen ? 1 : Displaced ? 2 : 0); 689. 690. /* without something like the following, invis. and displ. are too */ 691. /* powerful. */ 692. register boolean gotu = 693. (notseen ? !rn2(3) : Displaced ? !rn2(4) : FALSE); 694. 695. /* Monsters which know where you are don't suddenly forget, if you 696. didn't move away. */ 697. if (mtmp->mux==u.ux && mtmp->muy==u.uy) gotu = 1; 698. 699. /* your dog follows your smell */ 700. if(!disp || mtmp->mtame || gotu || 701. /* If invisible but not displaced, staying around gets you 'discovered' */ 702. (!Displaced && u.dx == 0 && u.dy == 0)) { 703. mtmp->mux = u.ux; 704. mtmp->muy = u.uy; 705. } 706. else do { 707. mtmp->mux = u.ux - disp + rn2(2*disp+1); 708. mtmp->muy = u.uy - disp + rn2(2*disp+1); 709. } while((mtmp->mux != u.ux || mtmp->muy != u.uy) && 710. ( (!passes_walls(mtmp->data) && 711. (!ACCESSIBLE(levl[mtmp->mux][mtmp->muy].typ) || 712. (IS_DOOR(levl[mtmp->mux][mtmp->muy].typ) && 713. (levl[mtmp->mux][mtmp->muy].doormask & (D_LOCKED | D_CLOSED)) && 714. !amorphous(mtmp->data) 715. )) 716. ) || 717. (disp==1 && mtmp->mux == mtmp->mx && mtmp->muy == mtmp->my) 718. ) 719. ); 720. }