abstract
| - Below is the full text to monmove.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/monmove.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)monmove.c 3.1 92/12/06 */ 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. #include "artifact.h" 8. 9. #ifdef OVL0 10. 11. static int FDECL(disturb,(struct monst *)); 12. static void FDECL(distfleeck,(struct monst *,int *,int *,int *)); 13. 14. #endif /* OVL0 */ 15. #ifdef OVL1 16. 17. STATIC_OVL boolean FDECL(mdig_tunnel,(struct monst *)); 18. 19. #endif /* OVL1 */ 20. #ifdef OVLB 21. 22. boolean /* TRUE : mtmp died */ 23. mb_trapped(mtmp) 24. register struct monst *mtmp; 25. { 26. if (flags.verbose) { 27. if (cansee(mtmp->mx, mtmp->my)) 28. pline("KABOOM!! You see a door explode."); 29. else if (flags.soundok) 30. You("hear a distant explosion."); 31. } 32. mtmp->mstun = 1; 33. mtmp->mhp -= rnd(15); 34. if(mtmp->mhp <= 0) { 35. mondied(mtmp); 36. return(TRUE); 37. } 38. return(FALSE); 39. } 40. 41. #endif /* OVLB */ 42. #ifdef OVL1 43. 44. /* Return TRUE if monster died, FALSE otherwise. */ 45. STATIC_OVL boolean 46. mdig_tunnel(mtmp) 47. register struct monst *mtmp; 48. { 49. register struct rm *here; 50. register int pile; 51. 52. here = &levl[mtmp->mx][mtmp->my]; 53. if (here->typ == SDOOR) here->typ = DOOR; 54. 55. /* Eats away door if present & closed or locked */ 56. if(closed_door(mtmp->mx, mtmp->my)) { 57. if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE)) 58. add_damage(mtmp->mx, mtmp->my, 0L); 59. unblock_point(mtmp->mx,mtmp->my); /* vision */ 60. if(here->doormask & D_TRAPPED) { 61. here->doormask = D_NODOOR; 62. if(mb_trapped(mtmp)) { /* mtmp is killed */ 63. newsym(mtmp->mx,mtmp->my); 64. return TRUE; 65. } 66. } else { 67. if(!rn2(3) && flags.verbose) /* not too often.. */ 68. You("feel an unexpected draft of air."); 69. here->doormask = D_BROKEN; 70. } 71. newsym(mtmp->mx,mtmp->my); 72. return FALSE; 73. } else 74. if (!IS_ROCK(here->typ)) /* no dig */ 75. return(FALSE); 76. 77. /* Only rock and walls fall through to this point. */ 78. if ((here->diggable & W_NONDIGGABLE)) { 79. impossible("mdig_tunnel: %s at (%d,%d) is undiggable", 80. (IS_WALL(here->typ) ? "wall" : "stone"), 81. (int) mtmp->mx, (int) mtmp->my); 82. return FALSE; /* still alive */ 83. } 84. 85. if(IS_WALL(here->typ)) { 86. if(flags.soundok && flags.verbose && !rn2(5)) 87. You("hear the sound of crashing rock."); 88. if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE)) 89. add_damage(mtmp->mx, mtmp->my, 0L); 90. if (level.flags.is_maze_lev) { 91. here->typ = ROOM; 92. } else if (level.flags.is_cavernous_lev) { 93. here->typ = CORR; 94. } else { 95. here->typ = DOOR; 96. here->doormask = D_NODOOR; 97. } 98. } else 99. here->typ = CORR; 100. 101. pile = rnd(12); 102. if(pile < 5) /* leave behind some rocks? */ 103. (void) mksobj_at((pile == 1)? BOULDER : ROCK, 104. mtmp->mx, mtmp->my, TRUE); 105. newsym(mtmp->mx,mtmp->my); 106. if(sobj_at(BOULDER, mtmp->mx, mtmp->my) == (struct obj *)0) 107. unblock_point(mtmp->mx,mtmp->my); /* vision */ 108. return FALSE ; 109. } 110. 111. int 112. dochugw(mtmp) 113. register struct monst *mtmp; 114. { 115. register int x = mtmp->mx; 116. register int y = mtmp->my; 117. register int rd = dochug(mtmp); 118. register int dd; 119. 120. if(Warning && !rd && !mtmp->mpeaceful && 121. (dd = distu(mtmp->mx,mtmp->my)) < distu(x,y) && 122. dd < 100 && !canseemon(mtmp)) { 123. /* Note: this assumes we only want to warn against the monster to 124. * which the weapon does extra damage, as there is no "monster 125. * which the weapon warns against" field. 126. */ 127. if(spec_ability(uwep,SPFX_WARN) && spec_dbon(uwep,mtmp->data,1)) 128. warnlevel = 100; 129. else if ((int) (mtmp->m_lev / 4) > warnlevel) 130. warnlevel = (mtmp->m_lev / 4); 131. } 132. /* check whether hero notices monster and stops current activity */ 133. if (occupation && !rd && !Confusion && 134. (!mtmp->mpeaceful || Hallucination) && 135. canseemon(mtmp) && !cansee(x,y) && 136. distu(mtmp->mx,mtmp->my) <= (BOLT_LIM+1)*(BOLT_LIM+1)) 137. stop_occupation(); 138. 139. return(rd); 140. } 141. 142. #endif /* OVL1 */ 143. #ifdef OVL2 144. 145. boolean 146. onscary(x, y, mtmp) 147. int x, y; 148. struct monst *mtmp; 149. { 150. if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee || 151. is_lminion(mtmp->data) || is_rider(mtmp->data) || 152. mtmp->data->mlet == S_HUMAN || mtmp->mpeaceful || 153. mtmp->data == &mons[PM_MINOTAUR]) 154. return(FALSE); 155. return( 156. #ifdef ELBERETH 157. sengr_at("Elbereth", x, y) || 158. #endif 159. sobj_at(SCR_SCARE_MONSTER, x, y) != (struct obj *)0); 160. } 161. 162. #endif /* OVL2 */ 163. #ifdef OVL0 164. 165. /* 166. * Possibly awaken the given monster. Return a 1 if the monster has been 167. * jolted awake. 168. */ 169. static int 170. disturb(mtmp) 171. register struct monst *mtmp; 172. { 173. /* 174. * + Ettins are hard to surprise. 175. * + Nymphs, jabberwocks, and leprechauns do not easily wake up. 176. * 177. * Wake up if: 178. * in direct LOS AND 179. * within 10 squares AND 180. * not stealthy or (mon is an ettin and 9/10) AND 181. * (mon is not a nymph, jabberwock, or leprechaun) or 1/50 AND 182. * Aggravate or mon is (dog or human) or 183. * (1/7 and mon is not mimicing furniture or object) 184. */ 185. if(couldsee(mtmp->mx,mtmp->my) && 186. distu(mtmp->mx,mtmp->my) <= 100 && 187. (!Stealth || (mtmp->data == &mons[PM_ETTIN] && rn2(10))) && 188. (!(mtmp->data->mlet == S_NYMPH 189. || mtmp->data == &mons[PM_JABBERWOCK] 190. || mtmp->data->mlet == S_LEPRECHAUN) || !rn2(50)) && 191. (Aggravate_monster 192. || (mtmp->data->mlet == S_DOG || 193. mtmp->data->mlet == S_HUMAN) 194. || (!rn2(7) && mtmp->m_ap_type != M_AP_FURNITURE && 195. mtmp->m_ap_type != M_AP_OBJECT) )) { 196. 197. mtmp->msleep = 0; 198. return(1); 199. } 200. return(0); 201. } 202. 203. static void 204. distfleeck(mtmp,inrange,nearby,scared) 205. register struct monst *mtmp; 206. int *inrange, *nearby, *scared; 207. { 208. int seescaryx, seescaryy; 209. 210. *inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 211. (BOLT_LIM * BOLT_LIM)); 212. *nearby = *inrange && monnear(mtmp, mtmp->mux, mtmp->muy); 213. 214. /* Note: if your image is displaced, the monster sees the Elbereth 215. * at your displaced position, thus never attacking your displaced 216. * position, but possibly attacking you by accident. If you are 217. * invisible, it sees the Elbereth at your real position, thus never 218. * running into you by accident but possibly attacking the spot 219. * where it guesses you are. 220. */ 221. if (Invis && !perceives(mtmp->data)) { 222. seescaryx = mtmp->mux; 223. seescaryy = mtmp->muy; 224. } else { 225. seescaryx = u.ux; 226. seescaryy = u.uy; 227. } 228. *scared = (*nearby && (onscary(seescaryx, seescaryy, mtmp) || 229. (!mtmp->mpeaceful && 230. in_your_sanctuary(mtmp->mx, mtmp->my)))); 231. 232. if(*scared && !mtmp->mflee) { 233. #ifdef POLYSELF 234. if (!sticks(uasmon)) 235. #endif 236. unstuck(mtmp); /* monster lets go when fleeing */ 237. mtmp->mflee = 1; 238. #ifdef STUPID 239. if (rn2(7)) 240. mtmp->mfleetim = rnd(10); 241. else 242. mtmp->mfleetim = rnd(100); 243. #else 244. mtmp->mfleetim = rnd(rn2(7) ? 10 : 100); 245. #endif 246. } 247. 248. } 249. 250. /* returns 1 if monster died moving, 0 otherwise */ 251. /* The whole dochugw/m_move/distfleeck/mfndpos section is serious spaghetti 252. * code. --KAA 253. */ 254. int 255. dochug(mtmp) 256. register struct monst *mtmp; 257. { 258. register struct permonst *mdat = mtmp->data; 259. register int tmp=0; 260. int inrange, nearby, scared; 261. 262. /* Pre-movement adjustments */ 263. 264. if(mtmp->cham && !rn2(6)) /* polymorph chameleons */ 265. (void) newcham(mtmp, (struct permonst *)0); 266. 267. /* regenerate monsters */ 268. if (mtmp->mhp < mtmp->mhpmax && (!(moves%20) || regenerates(mdat))) 269. mtmp->mhp++; 270. if(mtmp->mspec_used) mtmp->mspec_used--; 271. 272. /* polymorph lycanthropes */ 273. were_change(mtmp); 274. 275. /* check for waitmask status change */ 276. if((mtmp->data->mflags3 & M3_WAITFORU) && 277. (m_canseeu(mtmp) || mtmp->mhp < mtmp->mhpmax)) 278. mtmp->data->mflags3 &= ~M3_WAITFORU; 279. 280. #ifdef MULDGN 281. /* update quest status flags */ 282. quest_stat_check(mtmp); 283. #endif 284. 285. if(!mtmp->mcanmove || (mtmp->data->mflags3 & M3_WAITMASK)) { 286. if (Hallucination) newsym(mtmp->mx,mtmp->my); 287. #ifdef MULDGN 288. if(mtmp->mcanmove && (mtmp->data->mflags3 & M3_CLOSE) && 289. !mtmp->msleep && monnear(mtmp, u.ux, u.uy)) 290. quest_talk(mtmp); /* give the leaders a chance to speak */ 291. #endif 292. return(0); /* other frozen monsters can't do anything */ 293. } 294. 295. /* there is a chance we will wake it */ 296. if(mtmp->msleep && !disturb(mtmp)) { 297. if (Hallucination) newsym(mtmp->mx,mtmp->my); 298. return(0); 299. } 300. 301. /* not frozen or sleeping: wipe out texts written in the dust */ 302. wipe_engr_at(mtmp->mx, mtmp->my, 1); 303. 304. /* confused monsters get unconfused with small probability */ 305. if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0; 306. 307. /* stunned monsters get un-stunned with larger probability */ 308. if(mtmp->mstun && !rn2(10)) mtmp->mstun = 0; 309. 310. /* some monsters teleport */ 311. if(mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz) { 312. rloc(mtmp); 313. return(0); 314. } 315. if(mdat->msound == MS_SHRIEK && !um_dist(mtmp->mx, mtmp->my, 1)) 316. m_respond(mtmp); 317. if(mdat->mmove < rnd(6)) return(0); 318. 319. /* fleeing monsters might regain courage */ 320. if(mtmp->mflee && !mtmp->mfleetim 321. && mtmp->mhp == mtmp->mhpmax && !rn2(25)) mtmp->mflee = 0; 322. 323. set_apparxy(mtmp); 324. /* Must be done after you move and before the monster does. The 325. * set_apparxy() call in m_move() doesn't suffice since the variables 326. * inrange, etc. all depend on stuff set by set_apparxy(). 327. */ 328. 329. /* Monsters that want to acquire things */ 330. /* may teleport, so do it before inrange is set */ 331. if(is_covetous(mtmp->data)) (void) tactics(mtmp); 332. 333. /* check distance and scariness of attacks */ 334. distfleeck(mtmp,&inrange,&nearby,&scared); 335. 336. #ifdef MUSE 337. if(find_defensive(mtmp)) { 338. if (use_defensive(mtmp) != 0) 339. return 1; 340. } else if(find_misc(mtmp)) { 341. if (use_misc(mtmp) != 0) 342. return 1; 343. } 344. #endif 345. 346. /* Demonic Blackmail! */ 347. if(nearby && mdat->msound == MS_BRIBE && 348. mtmp->mpeaceful && !mtmp->mtame) { 349. if (mtmp->mux != u.ux || mtmp->muy != u.uy) { 350. pline("%s whispers something to thin air.", 351. cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It"); 352. #ifdef POLYSELF 353. if (is_demon(uasmon)) rloc(mtmp); 354. /* "Good hunting, brother" */ 355. else { 356. #endif 357. mtmp->minvis = 0; 358. /* Why? For the same reason in real demon talk */ 359. pline("%s gets angry.", Amonnam(mtmp)); 360. mtmp->mpeaceful = 0; 361. /* since no way is an image going to pay it off */ 362. #ifdef POLYSELF 363. } 364. #endif 365. } else if(demon_talk(mtmp)) return(1); /* you paid it off */ 366. } 367. 368. if (mdat == &mons[PM_MIND_FLAYER] && !rn2(20)) { 369. struct monst *m2, *nmon = (struct monst *)0; 370. 371. if (canseemon(mtmp)) 372. pline("%s concentrates.", Monnam(mtmp)); 373. if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM) { 374. You("sense a faint wave of psychic energy."); 375. goto toofar; 376. } 377. You("sense a wave of psychic energy pouring over you!"); 378. if (mtmp->mpeaceful && 379. (!Conflict || resist(mtmp, RING_CLASS, 0, 0))) 380. pline("It seems quite soothing."); 381. else { 382. register boolean m_sen = sensemon(mtmp); 383. 384. if (m_sen || (Telepat && rn2(2)) || !rn2(10)) { 385. int dmg; 386. pline("It locks in on your %s!", 387. m_sen ? "telepathy" : 388. Telepat ? "latent telepathy" : "mind"); 389. dmg = rnd(15); 390. if (Half_spell_damage) dmg = (dmg+1) / 2; 391. losehp(dmg, "psychic blast", KILLED_BY_AN); 392. } 393. } 394. for(m2=fmon; m2; m2 = nmon) { 395. nmon = m2->nmon; 396. if (m2->mpeaceful != mtmp->mpeaceful) continue; 397. if (mindless(m2->data)) continue; 398. if (m2 == mtmp) continue; 399. if ((telepathic(m2->data) && 400. (rn2(2) || m2->mblinded)) || !rn2(10)) { 401. if (cansee(m2->mx, m2->my)) 402. pline("It locks in on %s.", mon_nam(m2)); 403. m2->mhp -= rnd(15); 404. if (m2->mhp <= 0) 405. monkilled(m2, "", AD_DRIN); 406. } 407. } 408. } 409. toofar: 410. #ifdef MUSE 411. /* If monster is nearby you, and has to wield a weapon, do so. This 412. * costs the monster a move, of course. 413. */ 414. if((!mtmp->mpeaceful || Conflict) && inrange && 415. dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8 416. && attacktype(mdat, AT_WEAP)) { 417. if (mtmp->weapon_check == NEED_WEAPON || !MON_WEP(mtmp)) { 418. mtmp->weapon_check = NEED_HTH_WEAPON; 419. if (mon_wield_item(mtmp) != 0) return(0); 420. } 421. } 422. #endif 423. /* Now the actual movement phase */ 424. 425. if(!nearby || mtmp->mflee || scared || 426. mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) || 427. (mdat->mlet == S_LEPRECHAUN && !u.ugold && (mtmp->mgold || rn2(2))) || 428. (is_wanderer(mdat) && !rn2(4)) || (Conflict && !mtmp->iswiz) || 429. (!mtmp->mcansee && !rn2(4)) || mtmp->mpeaceful) { 430. 431. tmp = m_move(mtmp, 0); 432. distfleeck(mtmp,&inrange,&nearby,&scared); /* recalc */ 433. 434. switch (tmp) { 435. 436. case 0: /* no movement, but it can still attack you */ 437. case 3: /* absolutely no movement */ 438. /* for pets, case 0 and 3 are equivalent */ 439. /* During hallucination, monster appearance should 440. * still change - even if it doesn't move. 441. */ 442. if(Hallucination) newsym(mtmp->mx,mtmp->my); 443. break; 444. case 1: /* monster moved */ 445. /* Maybe it stepped on a trap and fell asleep... */ 446. if(mtmp->msleep || !mtmp->mcanmove) return(0); 447. if(!nearby && ranged_attk(mdat)) break; 448. else if(mdat->mmove <= 12) { 449. /* a monster that's digesting you can move at the 450. * same time -dlc 451. */ 452. if(u.uswallow && mtmp == u.ustuck) 453. return(mattacku(mtmp)); 454. return(0); 455. } 456. break; 457. case 2: /* monster died */ 458. return(1); 459. } 460. } 461. 462. /* Now, attack the player if possible - one attack set per monst */ 463. 464. if (!mtmp->mpeaceful || 465. (Conflict && !resist(mtmp, RING_CLASS, 0, 0))) { 466. if(inrange && !noattacks(mdat) && u.uhp > 0 && !scared && tmp != 3) 467. if(mattacku(mtmp)) return(1); /* monster died (e.g. exploded) */ 468. 469. if(mtmp->wormno) wormhitu(mtmp); 470. } 471. #ifdef MULDGN 472. /* special speeches for quest monsters */ 473. if(!mtmp->msleep && mtmp->mcanmove && nearby) 474. quest_talk(mtmp); 475. else 476. #endif 477. /* extra emotional attack for vile monsters */ 478. if(inrange && mtmp->data->msound == MS_CUSS && !mtmp->mpeaceful && 479. couldsee(mtmp->mx, mtmp->my) && !mtmp->minvis && !rn2(5)) 480. cuss(mtmp); 481. 482. /* extra movement for fast monsters */ 483. if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp, 1); 484. return(tmp == 2); 485. } 486. 487. static const char NEARDATA practical[] = { WEAPON_CLASS, ARMOR_CLASS, GEM_CLASS, FOOD_CLASS, 0 }; 488. static const char NEARDATA magical[] = { 489. AMULET_CLASS, POTION_CLASS, SCROLL_CLASS, WAND_CLASS, RING_CLASS, 490. SPBOOK_CLASS, 0 }; 491. static const char NEARDATA indigestion[] = { BALL_CLASS, ROCK_CLASS, 0 }; 492. 493. #ifdef POLYSELF 494. boolean 495. itsstuck(mtmp) 496. register struct monst *mtmp; 497. { 498. if (sticks(uasmon) && mtmp==u.ustuck && !u.uswallow) { 499. pline("%s cannot escape from you!", Monnam(mtmp)); 500. return(TRUE); 501. } 502. return(FALSE); 503. } 504. #endif 505. 506. int 507. m_move(mtmp, after) 508. register struct monst *mtmp; 509. register int after; 510. { 511. register int appr; 512. xchar gx,gy,nix,niy,chcnt; 513. int chi; /* could be schar except for stupid Sun-2 compiler */ 514. boolean likegold=0, likegems=0, likeobjs=0, likemagic=0, conceals=0; 515. boolean likerock=0, can_tunnel=0; 516. boolean can_open=0, can_unlock=0, doorbuster=0; 517. #ifdef MUSE 518. boolean uses_items=0; 519. #endif 520. struct permonst *ptr; 521. schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */ 522. long info[9]; 523. long flag; 524. int omx = mtmp->mx, omy = mtmp->my; 525. #ifdef MUSE 526. struct obj *mw_tmp; 527. #endif 528. 529. if(mtmp->mtrapped) { 530. int i = mintrap(mtmp); 531. if(i >= 2) { newsym(mtmp->mx,mtmp->my); return(2); }/* it died */ 532. if(i == 1) return(0); /* still in trap, so didn't move */ 533. } 534. ptr = mtmp->data; /* mintrap() can change mtmp->data -dlc */ 535. if(hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) && rn2(10)) 536. return(0); /* do not leave hiding place */ 537. if(mtmp->meating) { 538. mtmp->meating--; 539. return(3); /* still eating */ 540. } 541. 542. set_apparxy(mtmp); 543. /* where does mtmp think you are? */ 544. /* Not necessary if m_move called from this file, but necessary in 545. * other calls of m_move (ex. leprechauns dodging) 546. */ 547. can_tunnel = tunnels(ptr) && 548. #ifdef REINCARNATION 549. !Is_rogue_level(&u.uz) && 550. #endif 551. #ifdef MUSE 552. (!needspick(ptr) || 553. (m_carrying(mtmp, PICK_AXE) && 554. (mtmp->weapon_check != NO_WEAPON_WANTED || 555. !(mw_tmp = MON_WEP(mtmp)) || mw_tmp->otyp == PICK_AXE))); 556. #else 557. (!needspick(ptr) || m_carrying(mtmp, PICK_AXE)); 558. #endif 559. can_open = !(nohands(ptr) || verysmall(ptr)); 560. can_unlock = ((can_open && m_carrying(mtmp, SKELETON_KEY)) || mtmp->iswiz); 561. doorbuster = is_giant(ptr); 562. if(mtmp->wormno) goto not_special; 563. /* my dog gets special treatment */ 564. if(mtmp->mtame) { 565. mmoved = dog_move(mtmp, after); 566. goto postmov; 567. } 568. 569. /* likewise for shopkeeper */ 570. if(mtmp->isshk) { 571. mmoved = shk_move(mtmp); 572. if(mmoved == -2) return(2); 573. if(mmoved >= 0) goto postmov; 574. mmoved = 0; /* follow player outside shop */ 575. } 576. 577. /* and for the guard */ 578. if(mtmp->isgd) { 579. mmoved = gd_move(mtmp); 580. if(mmoved == -2) return(2); 581. if(mmoved >= 0) goto postmov; 582. mmoved = 0; 583. } 584. 585. /* and the acquisitive monsters get special treatment */ 586. if(is_covetous(ptr)) { 587. xchar tx = (xchar)((mtmp->mstrategy >> 16) & 0xff), 588. ty = (xchar)((mtmp->mstrategy >> 8) & 0xff); 589. struct monst *intruder = m_at(tx, ty); 590. /* 591. * if there's a monster on the object or in possesion of it, 592. * attack it. 593. */ 594. if((dist2(mtmp->mx, mtmp->my, tx, ty) < 2) && 595. intruder && (intruder != mtmp)) { 596. 597. if(mattackm(mtmp, intruder) == 2) return(2); 598. mmoved = 1; 599. } else mmoved = 0; 600. goto postmov; 601. } 602. 603. /* and for the priest */ 604. if(mtmp->ispriest) { 605. mmoved = pri_move(mtmp); 606. if(mmoved == -2) return(2); 607. if(mmoved >= 0) goto postmov; 608. mmoved = 0; 609. } 610. 611. #ifdef MAIL 612. if(ptr == &mons[PM_MAIL_DAEMON]) { 613. if(flags.soundok && canseemon(mtmp)) 614. verbalize("I'm late!"); 615. mongone(mtmp); 616. return(2); 617. } 618. #endif 619. 620. /* teleport if that lies in our nature */ 621. if(ptr == &mons[PM_TENGU] && !rn2(5) && !mtmp->mcan) { 622. if(mtmp->mhp < 7 || mtmp->mpeaceful || rn2(2)) 623. rloc(mtmp); 624. else 625. mnexto(mtmp); 626. mmoved = 1; 627. goto postmov; 628. } 629. not_special: 630. if(u.uswallow && !mtmp->mflee && u.ustuck != mtmp) return(1); 631. appr = 1; 632. omx = mtmp->mx; 633. omy = mtmp->my; 634. gx = mtmp->mux; 635. gy = mtmp->muy; 636. if(mtmp->mflee) appr = -1; 637. if (mtmp->mconf || (u.uswallow && mtmp == u.ustuck)) 638. appr = 0; 639. else { 640. boolean should_see = (couldsee(omx, omy) && 641. (levl[gx][gy].lit || 642. !levl[omx][omy].lit) && 643. (dist2(omx, omy, gx, gy) <= 36)); 644. 645. if (!mtmp->mcansee || 646. (should_see && Invis && !perceives(ptr)) || 647. #ifdef POLYSELF 648. (u.usym == S_MIMIC_DEF) || u.uundetected || 649. #endif 650. (mtmp->mpeaceful && !mtmp->isshk) || /* allow shks to follow */ 651. ((ptr->mlet == S_STALKER || ptr->mlet == S_BAT || 652. ptr->mlet == S_LIGHT) && !rn2(3))) 653. appr = 0; 654. 655. if(monsndx(ptr) == PM_LEPRECHAUN && (appr == 1) && 656. (mtmp->mgold > u.ugold)) 657. appr = -1; 658. 659. if (!should_see && can_track(ptr)) { 660. register coord *cp; 661. 662. cp = gettrack(omx,omy); 663. if (cp) { 664. gx = cp->x; 665. gy = cp->y; 666. } 667. } 668. } 669. 670. #ifdef REINCARNATION 671. if (!Is_rogue_level(&u.uz)) 672. #endif 673. { 674. register int pctload = (curr_mon_load(mtmp) * 100) / 675. max_mon_load(mtmp); 676. 677. /* look for gold or jewels nearby */ 678. likegold = (likes_gold(ptr) && pctload < 95); 679. likegems = (likes_gems(ptr) && pctload < 85); 680. #ifdef MUSE 681. uses_items = (!mindless(ptr) && !is_animal(ptr) 682. && pctload < 75); 683. #endif 684. likeobjs = (likes_objs(ptr) && pctload < 75); 685. likemagic = (likes_magic(ptr) && pctload < 85); 686. likerock = (throws_rocks(ptr) && pctload < 50); 687. conceals = hides_under(ptr); 688. } 689. 690. #define SQSRCHRADIUS 5 691. 692. { register int minr = SQSRCHRADIUS; /* not too far away */ 693. register struct obj *otmp; 694. register int xx, yy; 695. int oomx, oomy, lmx, lmy; 696. 697. /* cut down the search radius if it thinks character is closer. */ 698. if(distmin(mtmp->mux, mtmp->muy, omx, omy) < SQSRCHRADIUS && 699. !mtmp->mpeaceful) minr--; 700. /* guards shouldn't get too distracted */ 701. if(!mtmp->mpeaceful && is_mercenary(ptr)) minr = 1; 702. 703. if((likegold || likegems || likeobjs || likemagic || likerock || conceals) 704. && (!*in_rooms(omx, omy, SHOPBASE) || (!rn2(25) && !mtmp->isshk))) { 705. look_for_obj: 706. oomx = min(COLNO-1, omx+minr); 707. oomy = min(ROWNO-1, omy+minr); 708. lmx = max(1, omx-minr); 709. lmy = max(0, omy-minr); 710. for(otmp = fobj; otmp; otmp = otmp->nobj) { 711. xx = otmp->ox; 712. yy = otmp->oy; 713. if(xx >= lmx && xx <= oomx && yy >= lmy && yy <= oomy) { 714. if(((likegold && otmp->otyp == GOLD_PIECE) || 715. (likeobjs && index(practical, otmp->oclass)) || 716. (likemagic && index(magical, otmp->oclass)) || 717. #ifdef MUSE 718. (uses_items && searches_for_item(mtmp, otmp)) || 719. #endif 720. (likerock && otmp->otyp == BOULDER) || 721. (likegems && otmp->oclass == GEM_CLASS && 722. objects[otmp->otyp].oc_material != MINERAL) || 723. (conceals && !cansee(otmp->ox,otmp->oy)) || 724. (ptr == &mons[PM_GELATINOUS_CUBE] && 725. !index(indigestion, otmp->oclass) && 726. !(otmp->otyp == CORPSE && 727. otmp->corpsenm == PM_COCKATRICE)) 728. ) && touch_artifact(otmp,mtmp)) { 729. if(can_carry(mtmp,otmp) && 730. (throws_rocks(ptr) || 731. !sobj_at(BOULDER,xx,yy)) && 732. (ptr->mlet != S_UNICORN || 733. objects[otmp->otyp].oc_material == GEMSTONE)) { 734. minr = distmin(omx,omy,xx,yy); 735. oomx = min(COLNO-1, omx+minr); 736. oomy = min(ROWNO-1, omy+minr); 737. lmx = max(1, omx-minr); 738. lmy = max(0, omy-minr); 739. gx = otmp->ox; 740. gy = otmp->oy; 741. } 742. } 743. } 744. } 745. } else if(likegold) { 746. /* don't try to pick up anything else, but use the same loop */ 747. #ifdef MUSE 748. uses_items = 749. #endif 750. likegems = likeobjs = likemagic = likerock = conceals = 0; 751. goto look_for_obj; 752. } 753. 754. if(minr < SQSRCHRADIUS && appr == -1) { 755. if(distmin(omx,omy,mtmp->mux,mtmp->muy) <= 3) { 756. gx = mtmp->mux; 757. gy = mtmp->muy; 758. } else 759. appr = 1; 760. } 761. } 762. nix = omx; 763. niy = omy; 764. flag = ALLOW_TRAPS; 765. if (mtmp->mpeaceful && (!Conflict || resist(mtmp, RING_CLASS, 0, 0))) 766. flag |= (ALLOW_SANCT | ALLOW_SSM); 767. else flag |= ALLOW_U; 768. if (ptr->mlet == S_UNICORN) flag |= NOTONL; 769. if (passes_walls(ptr)) flag |= (ALLOW_WALL | ALLOW_ROCK); 770. if (can_tunnel) flag |= ALLOW_DIG; 771. if (is_human(ptr) || ptr == &mons[PM_MINOTAUR]) flag |= ALLOW_SSM; 772. if (is_undead(ptr)) flag |= NOGARLIC; 773. if (throws_rocks(ptr)) flag |= ALLOW_ROCK; 774. if (can_open) flag |= OPENDOOR; 775. if (can_unlock) flag |= UNLOCKDOOR; 776. if (doorbuster) flag |= BUSTDOOR; 777. { 778. register int i, j, nx, ny, nearer; 779. int jcnt, cnt; 780. int ndist, nidist; 781. register coord *mtrk; 782. coord poss[9]; 783. 784. cnt = mfndpos(mtmp, poss, info, flag); 785. chcnt = 0; 786. jcnt = min(MTSZ, cnt-1); 787. chi = -1; 788. nidist = dist2(nix,niy,gx,gy); 789. /* allow monsters be shortsighted on some levels for balance */ 790. if(!mtmp->mpeaceful && level.flags.shortsighted && 791. nidist > (couldsee(nix,niy) ? 144 : 36) && appr == 1) appr = 0; 792. 793. for(i=0; i < cnt; i++) { 794. nx = poss[i].x; 795. ny = poss[i].y; 796. 797. if (appr != 0) { 798. mtrk = &mtmp->mtrack[0]; 799. for(j=0; j < jcnt; mtrk++, j++) 800. if(nx == mtrk->x && ny == mtrk->y) 801. if(rn2(4*(cnt-j))) 802. goto nxti; 803. } 804. 805. nearer = ((ndist = dist2(nx,ny,gx,gy)) < nidist); 806. 807. if((appr == 1 && nearer) || (appr == -1 && !nearer) || 808. (!appr && !rn2(++chcnt)) || !mmoved) { 809. nix = nx; 810. niy = ny; 811. nidist = ndist; 812. chi = i; 813. mmoved = 1; 814. } 815. nxti: ; 816. } 817. } 818. 819. if(mmoved) { 820. register int j; 821. #ifdef POLYSELF 822. if (mmoved==1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp)) 823. return(3); 824. #endif 825. #ifdef MUSE 826. if (mmoved==1 && can_tunnel && needspick(ptr) && 827. (!(mw_tmp = MON_WEP(mtmp)) || mw_tmp->otyp != PICK_AXE)) { 828. mtmp->weapon_check = NEED_PICK_AXE; 829. (void)mon_wield_item(mtmp); 830. } 831. #endif 832. /* If ALLOW_U is set, either it's trying to attack you, or it 833. * thinks it is. In either case, attack this spot in preference to 834. * all others. 835. */ 836. if(info[chi] & ALLOW_U) { 837. nix = mtmp->mux; 838. niy = mtmp->muy; 839. } 840. if (nix == u.ux && niy == u.uy) { 841. mtmp->mux = u.ux; 842. mtmp->muy = u.uy; 843. return(0); 844. } 845. /* The monster may attack another based on 1 of 2 conditions: 846. * 1 - It may be confused. 847. * 2 - It may mistake the monster for your (displaced) image. 848. * Pets get taken care of above and shouldn't reach this code. 849. * Conflict gets handled even farther away (movemon()). 850. */ 851. if((info[chi] & ALLOW_M) || 852. (nix == mtmp->mux && niy == mtmp->muy)) { 853. struct monst *mtmp2; 854. int stat; 855. mtmp2 = m_at(nix,niy); 856. 857. stat = mattackm(mtmp, mtmp2); 858. 859. if (stat & MM_AGR_DIED) /* aggressor died */ 860. return 2; 861. 862. if ((stat & MM_HIT) && !(stat & MM_DEF_DIED) && 863. rn2(4) && mtmp2->mlstmv != monstermoves) { 864. stat = mattackm(mtmp2, mtmp); /* return attack */ 865. if (stat & MM_DEF_DIED) 866. return 2; 867. } 868. return 3; 869. } 870. 871. remove_monster(omx, omy); 872. place_monster(mtmp, nix, niy); 873. for(j = MTSZ-1; j > 0; j--) 874. mtmp->mtrack[j] = mtmp->mtrack[j-1]; 875. mtmp->mtrack[0].x = omx; 876. mtmp->mtrack[0].y = omy; 877. /* Place a segment at the old position. */ 878. if (mtmp->wormno) worm_move(mtmp); 879. } else { 880. if(ptr->mlet == S_UNICORN && rn2(2)) { 881. rloc(mtmp); 882. return(1); 883. } 884. if(mtmp->wormno) worm_nomove(mtmp); 885. } 886. postmov: 887. if(mmoved == 1) { 888. boolean canseeit = cansee(mtmp->mx, mtmp->my); 889. boolean abstain = (mtmp->mpeaceful && !mtmp->mtame); 890. 891. newsym(omx,omy); /* update the old position */ 892. if (mintrap(mtmp) >= 2) { 893. if(mtmp->mx) newsym(mtmp->mx,mtmp->my); 894. return(2); /* it died */ 895. } 896. ptr = mtmp->data; 897. 898. /* open a door, or crash through it, if you can */ 899. if(IS_DOOR(levl[mtmp->mx][mtmp->my].typ) 900. && !passes_walls(ptr) /* doesn't need to open doors */ 901. && !can_tunnel /* taken care of below */ 902. ) { 903. struct rm *here = &levl[mtmp->mx][mtmp->my]; 904. boolean btrapped = (here->doormask & D_TRAPPED); 905. 906. if(here->doormask & (D_LOCKED|D_CLOSED) && amorphous(ptr)) { 907. if (flags.verbose && canseeit) 908. pline("%s %ss under the door.", Monnam(mtmp), 909. (ptr == &mons[PM_FOG_CLOUD] || 910. ptr == &mons[PM_YELLOW_LIGHT]) 911. ? "flow" : "ooze"); 912. } else if(here->doormask & D_LOCKED && can_unlock) { 913. if(btrapped) { 914. here->doormask = D_NODOOR; 915. newsym(mtmp->mx, mtmp->my); 916. unblock_point(mtmp->mx,mtmp->my); /* vision */ 917. if(mb_trapped(mtmp)) return(2); 918. } else { 919. if (flags.verbose) { 920. if (canseeit) 921. You("see a door being unlocked and opened."); 922. else if (flags.soundok) 923. You("hear a door being unlocked and opened."); 924. } 925. here->doormask = D_ISOPEN; 926. /* newsym(mtmp->mx, mtmp->my); */ 927. unblock_point(mtmp->mx,mtmp->my); /* vision */ 928. } 929. } else if (here->doormask == D_CLOSED && can_open) { 930. if(btrapped) { 931. here->doormask = D_NODOOR; 932. newsym(mtmp->mx, mtmp->my); 933. unblock_point(mtmp->mx,mtmp->my); /* vision */ 934. if(mb_trapped(mtmp)) return(2); 935. } else { 936. if (flags.verbose) { 937. if (canseeit) 938. You("see a door being opened."); 939. else if (flags.soundok) 940. You("hear the sound of a door opening."); 941. } 942. here->doormask = D_ISOPEN; 943. /* newsym(mtmp->mx, mtmp->my); */ /* done below */ 944. unblock_point(mtmp->mx,mtmp->my); /* vision */ 945. } 946. } else if (here->doormask & (D_LOCKED|D_CLOSED)) { 947. /* mfndpos guarantees this must be a doorbuster */ 948. if(btrapped) { 949. here->doormask = D_NODOOR; 950. newsym(mtmp->mx, mtmp->my); 951. unblock_point(mtmp->mx,mtmp->my); /* vision */ 952. if(mb_trapped(mtmp)) return(2); 953. } else { 954. if (flags.verbose) { 955. if (canseeit) 956. You("see a door crash open."); 957. else if (flags.soundok) 958. You("hear the sound of a door crashing open."); 959. } 960. if (here->doormask & D_LOCKED && !rn2(2)) 961. here->doormask = D_NODOOR; 962. else here->doormask = D_BROKEN; 963. /* newsym(mtmp->mx, mtmp->my); */ /* done below */ 964. unblock_point(mtmp->mx,mtmp->my); /* vision */ 965. } 966. } 967. } 968. 969. /* possibly dig */ 970. if (can_tunnel && mdig_tunnel(mtmp)) 971. return(2); /* mon died (position already updated) */ 972. 973. /* set also in domove(), hack.c */ 974. if (u.uswallow && mtmp == u.ustuck && 975. (mtmp->mx != omx || mtmp->my != omy)) { 976. /* If the monster moved, then update */ 977. u.ux0 = u.ux; 978. u.uy0 = u.uy; 979. u.ux = mtmp->mx; 980. u.uy = mtmp->my; 981. swallowed(0); 982. } else 983. newsym(mtmp->mx,mtmp->my); 984. 985. if(OBJ_AT(mtmp->mx, mtmp->my) && mtmp->mcanmove) { 986. /* Maybe a rock mole just ate some metal object */ 987. if(metallivorous(ptr)) meatgold(mtmp); 988. 989. if(g_at(mtmp->mx,mtmp->my) && likegold && 990. (!abstain || !rn2(10))) mpickgold(mtmp); 991. 992. /* Maybe a cube ate just about anything */ 993. if(ptr == &mons[PM_GELATINOUS_CUBE]) meatobj(mtmp); 994. 995. if((!abstain || !rn2(10)) && 996. (!*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || !rn2(25))) { 997. if(likeobjs) mpickstuff(mtmp, practical); 998. if(likemagic) mpickstuff(mtmp, magical); 999. if(likerock || likegems) mpickgems(mtmp); 1000. #ifdef MUSE 1001. if(uses_items) mpickstuff(mtmp, (char *)0); 1002. #endif 1003. } 1004. 1005. if(mtmp->minvis) { 1006. newsym(mtmp->mx, mtmp->my); 1007. if (mtmp->wormno) see_wsegs(mtmp); 1008. } 1009. } 1010. 1011. if(hides_under(ptr)) { 1012. mtmp->mundetected = OBJ_AT(mtmp->mx, mtmp->my); 1013. newsym(mtmp->mx, mtmp->my); 1014. } 1015. } 1016. return(mmoved); 1017. } 1018. 1019. #endif /* OVL0 */ 1020. #ifdef OVL2 1021. 1022. boolean 1023. closed_door(x, y) 1024. register int x, y; 1025. { 1026. return(IS_DOOR(levl[x][y].typ) && 1027. (levl[x][y].doormask & (D_LOCKED | D_CLOSED))); 1028. } 1029. 1030. boolean 1031. accessible(x, y) 1032. register int x, y; 1033. { 1034. return(ACCESSIBLE(levl[x][y].typ) && !closed_door(x, y)); 1035. } 1036. 1037. #endif /* OVL2 */ 1038. #ifdef OVL0 1039. 1040. void 1041. set_apparxy(mtmp) /* where does mtmp think you are standing? */ 1042. register struct monst *mtmp; 1043. { 1044. #define notseen (Invis && !perceives(mtmp->data)) 1045. /* add cases as required. eg. Displacement ... */ 1046. register int disp = (Underwater ? 3 : notseen ? 1 : Displaced ? 2 : 0); 1047. 1048. /* without something like the following, invis. and displ. are too */ 1049. /* powerful. */ 1050. register boolean gotu = 1051. (notseen ? !rn2(3) : Displaced ? !rn2(4) : FALSE); 1052. 1053. /* Monsters which know where you are don't suddenly forget, if you 1054. didn't move away. */ 1055. if (mtmp->mux==u.ux && mtmp->muy==u.uy) gotu = 1; 1056. 1057. /* your dog follows your smell */ 1058. if(!disp || mtmp->mtame || gotu || 1059. /* Monsters touching you know where you are */ 1060. mtmp == u.ustuck || 1061. /* If invisible but not displaced, staying around gets you 'discovered' */ 1062. (!Displaced && u.dx == 0 && u.dy == 0)) { 1063. mtmp->mux = u.ux; 1064. mtmp->muy = u.uy; 1065. } 1066. else do { 1067. mtmp->mux = u.ux - disp + rn2(2*disp+1); 1068. mtmp->muy = u.uy - disp + rn2(2*disp+1); 1069. } while((mtmp->mux != u.ux || mtmp->muy != u.uy) && 1070. ( (!passes_walls(mtmp->data) && 1071. (!ACCESSIBLE(levl[mtmp->mux][mtmp->muy].typ) || 1072. (closed_door(mtmp->mux, mtmp->muy) && 1073. !amorphous(mtmp->data) 1074. ) 1075. ) 1076. ) || 1077. (disp==1 && mtmp->mux == mtmp->mx && mtmp->muy == mtmp->my) 1078. ) 1079. ); 1080. } 1081. 1082. #endif /* OVL0 */ 1083. 1084. /*monmove.c*/
|