About: Source:NetHack 3.4.0/monmove.c   Sponge Permalink

An Entity of Type : owl:Thing, within Data Space : 134.155.108.49:8890 associated with source dataset(s)

Below is the full text to monmove.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.0/monmove.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code

AttributesValues
rdfs:label
  • Source:NetHack 3.4.0/monmove.c
rdfs:comment
  • Below is the full text to monmove.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.0/monmove.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code
dcterms:subject
dbkwik:nethack/pro...iPageUsesTemplate
abstract
  • Below is the full text to monmove.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.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.4 2000/08/16 */ 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. extern boolean notonhead; 10. 11. #ifdef OVL0 12. 13. STATIC_DCL int FDECL(disturb,(struct monst *)); 14. STATIC_DCL void FDECL(distfleeck,(struct monst *,int *,int *,int *)); 15. STATIC_DCL int FDECL(m_arrival, (struct monst *)); 16. STATIC_DCL void FDECL(watch_on_duty,(struct monst *)); 17. 18. #endif /* OVL0 */ 19. #ifdef OVLB 20. 21. boolean /* TRUE : mtmp died */ 22. mb_trapped(mtmp) 23. register struct monst *mtmp; 24. { 25. if (flags.verbose) { 26. if (cansee(mtmp->mx, mtmp->my)) 27. pline("KABOOM!! You see a door explode."); 28. else if (flags.soundok) 29. You_hear("a distant explosion."); 30. } 31. wake_nearto(mtmp->mx, mtmp->my, 7*7); 32. mtmp->mstun = 1; 33. mtmp->mhp -= rnd(15); 34. if(mtmp->mhp <= 0) { 35. mondied(mtmp); 36. if (mtmp->mhp > 0) /* lifesaved */ 37. return(FALSE); 38. else 39. return(TRUE); 40. } 41. return(FALSE); 42. } 43. 44. #endif /* OVLB */ 45. #ifdef OVL0 46. 47. STATIC_OVL void 48. watch_on_duty(mtmp) 49. register struct monst *mtmp; 50. { 51. register s_level *slev = Is_special(&u.uz); 52. int x, y; 53. 54. if(slev && slev->flags.town && mtmp->mpeaceful && 55. mtmp->mcansee && m_canseeu(mtmp) && !rn2(3)) { 56. 57. if(picking_lock(&x, &y) && IS_DOOR(levl[x][y].typ) && 58. (levl[x][y].doormask & D_LOCKED)) { 59. 60. if(couldsee(mtmp->mx, mtmp->my)) { 61. 62. pline("%s yells:", Amonnam(mtmp)); 63. if(levl[x][y].looted & D_WARNED) { 64. verbalize("Halt, thief! You're under arrest!"); 65. (void) angry_guards(!(flags.soundok)); 66. } else { 67. verbalize("Hey, stop picking that lock!"); 68. levl[x][y].looted |= D_WARNED; 69. } 70. stop_occupation(); 71. } 72. } else if (is_digging()) { 73. /* chewing, wand/spell of digging are checked elsewhere */ 74. watch_dig(mtmp, digging.pos.x, digging.pos.y, FALSE); 75. } 76. } 77. } 78. 79. #endif /* OVL0 */ 80. #ifdef OVL1 81. 82. int 83. dochugw(mtmp) 84. register struct monst *mtmp; 85. { 86. register int x = mtmp->mx, y = mtmp->my; 87. boolean already_saw_mon = !occupation ? 0 : canspotmon(mtmp); 88. int rd = dochug(mtmp); 89. #if 0 90. /* part of the original warning code which was replaced in 3.3.1 */ 91. int dd; 92. 93. if(Warning && !rd && !mtmp->mpeaceful && 94. (dd = distu(mtmp->mx,mtmp->my)) < distu(x,y) && 95. dd < 100 && !canseemon(mtmp)) { 96. /* Note: this assumes we only want to warn against the monster to 97. * which the weapon does extra damage, as there is no "monster 98. * which the weapon warns against" field. 99. */ 100. if (spec_ability(uwep, SPFX_WARN) && spec_dbon(uwep, mtmp, 1)) 101. warnlevel = 100; 102. else if ((int) (mtmp->m_lev / 4) > warnlevel) 103. warnlevel = (mtmp->m_lev / 4); 104. } 105. #endif /* 0 */ 106. 107. /* a similar check is in monster_nearby() in hack.c */ 108. /* check whether hero notices monster and stops current activity */ 109. if (occupation && !rd && !Confusion && 110. (!mtmp->mpeaceful || Hallucination) && 111. /* it's close enough to be a threat */ 112. distu(mtmp->mx,mtmp->my) <= (BOLT_LIM+1)*(BOLT_LIM+1) && 113. /* and either couldn't see it before, or it was too far away */ 114. (!already_saw_mon || !couldsee(x,y) || 115. distu(x,y) > (BOLT_LIM+1)*(BOLT_LIM+1)) && 116. /* can see it now, or sense it and would normally see it */ 117. (canseemon(mtmp) || 118. (sensemon(mtmp) && couldsee(mtmp->mx,mtmp->my))) && 119. !noattacks(mtmp->data) && !onscary(u.ux, u.uy, mtmp)) 120. stop_occupation(); 121. 122. return(rd); 123. } 124. 125. #endif /* OVL1 */ 126. #ifdef OVL2 127. 128. boolean 129. onscary(x, y, mtmp) 130. int x, y; 131. struct monst *mtmp; 132. { 133. if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee || 134. mtmp->mpeaceful || mtmp->data->mlet == S_HUMAN || 135. is_lminion(mtmp->data) || is_rider(mtmp->data) || 136. mtmp->data == &mons[PM_MINOTAUR]) 137. return(FALSE); 138. 139. return (boolean)(sobj_at(SCR_SCARE_MONSTER, x, y) 140. #ifdef ELBERETH 141. || sengr_at("Elbereth", x, y) 142. #endif 143. || (mtmp->data->mlet == S_VAMPIRE 144. && IS_ALTAR(levl[x][y].typ))); 145. } 146. 147. #endif /* OVL2 */ 148. #ifdef OVL0 149. 150. /* regenerate lost hit points */ 151. void 152. mon_regen(mon, digest_meal) 153. struct monst *mon; 154. boolean digest_meal; 155. { 156. if (mon->mhp < mon->mhpmax && 157. (moves % 20 == 0 || regenerates(mon->data))) mon->mhp++; 158. if (mon->mspec_used) mon->mspec_used--; 159. if (digest_meal) { 160. if (mon->meating) mon->meating--; 161. } 162. } 163. 164. /* 165. * Possibly awaken the given monster. Return a 1 if the monster has been 166. * jolted awake. 167. */ 168. STATIC_OVL int 169. disturb(mtmp) 170. register struct monst *mtmp; 171. { 172. /* 173. * + Ettins are hard to surprise. 174. * + Nymphs, jabberwocks, and leprechauns do not easily wake up. 175. * 176. * Wake up if: 177. * in direct LOS AND 178. * within 10 squares AND 179. * not stealthy or (mon is an ettin and 9/10) AND 180. * (mon is not a nymph, jabberwock, or leprechaun) or 1/50 AND 181. * Aggravate or mon is (dog or human) or 182. * (1/7 and mon is not mimicing furniture or object) 183. */ 184. if(couldsee(mtmp->mx,mtmp->my) && 185. distu(mtmp->mx,mtmp->my) <= 100 && 186. (!Stealth || (mtmp->data == &mons[PM_ETTIN] && rn2(10))) && 187. (!(mtmp->data->mlet == S_NYMPH 188. || mtmp->data == &mons[PM_JABBERWOCK] 189. #if 0 /* DEFERRED */ 190. || mtmp->data == &mons[PM_VORPAL_JABBERWOCK] 191. #endif 192. || mtmp->data->mlet == S_LEPRECHAUN) || !rn2(50)) && 193. (Aggravate_monster 194. || (mtmp->data->mlet == S_DOG || 195. mtmp->data->mlet == S_HUMAN) 196. || (!rn2(7) && mtmp->m_ap_type != M_AP_FURNITURE && 197. mtmp->m_ap_type != M_AP_OBJECT) )) { 198. mtmp->msleeping = 0; 199. return(1); 200. } 201. return(0); 202. } 203. 204. /* monster begins fleeing for the specified time, 0 means untimed flee 205. * if first, only adds fleetime if monster isn't already fleeing 206. * if fleemsg, prints a message about new flight, otherwise, caller should */ 207. void 208. monflee(mtmp, fleetime, first, fleemsg) 209. struct monst *mtmp; 210. int fleetime; 211. boolean first; 212. boolean fleemsg; 213. { 214. if (u.ustuck == mtmp) { 215. if (u.uswallow) 216. expels(mtmp, mtmp->data, TRUE); 217. else if (!sticks(youmonst.data)) { 218. unstuck(mtmp); /* monster lets go when fleeing */ 219. You("get released!"); 220. } 221. } 222. 223. if (!first || !mtmp->mflee) { 224. /* don't lose untimed scare */ 225. if (!fleetime) 226. mtmp->mfleetim = 0; 227. else if (!mtmp->mflee || mtmp->mfleetim) { 228. fleetime += mtmp->mfleetim; 229. /* ensure monster flees long enough to visibly stop fighting */ 230. if (fleetime == 1) fleetime++; 231. mtmp->mfleetim = min(fleetime, 127); 232. } 233. if (!mtmp->mflee && fleemsg && canseemon(mtmp)) 234. pline("%s turns to flee!", (Monnam(mtmp))); 235. mtmp->mflee = 1; 236. } 237. } 238. 239. STATIC_OVL void 240. distfleeck(mtmp,inrange,nearby,scared) 241. register struct monst *mtmp; 242. int *inrange, *nearby, *scared; 243. { 244. int seescaryx, seescaryy; 245. 246. *inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 247. (BOLT_LIM * BOLT_LIM)); 248. *nearby = *inrange && monnear(mtmp, mtmp->mux, mtmp->muy); 249. 250. /* Note: if your image is displaced, the monster sees the Elbereth 251. * at your displaced position, thus never attacking your displaced 252. * position, but possibly attacking you by accident. If you are 253. * invisible, it sees the Elbereth at your real position, thus never 254. * running into you by accident but possibly attacking the spot 255. * where it guesses you are. 256. */ 257. if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) { 258. seescaryx = mtmp->mux; 259. seescaryy = mtmp->muy; 260. } else { 261. seescaryx = u.ux; 262. seescaryy = u.uy; 263. } 264. *scared = (*nearby && (onscary(seescaryx, seescaryy, mtmp) || 265. (!mtmp->mpeaceful && 266. in_your_sanctuary(mtmp, 0, 0)))); 267. 268. if(*scared) { 269. if (rn2(7)) 270. monflee(mtmp, rnd(10), TRUE, TRUE); 271. else 272. monflee(mtmp, rnd(100), TRUE, TRUE); 273. } 274. 275. } 276. 277. /* perform a special one-time action for a monster; returns -1 if nothing 278. special happened, 0 if monster uses up its turn, 1 if monster is killed */ 279. STATIC_OVL int 280. m_arrival(mon) 281. struct monst *mon; 282. { 283. mon->mstrategy &= ~STRAT_ARRIVE; /* always reset */ 284. 285. return -1; 286. } 287. 288. /* returns 1 if monster died moving, 0 otherwise */ 289. /* The whole dochugw/m_move/distfleeck/mfndpos section is serious spaghetti 290. * code. --KAA 291. */ 292. int 293. dochug(mtmp) 294. register struct monst *mtmp; 295. { 296. register struct permonst *mdat; 297. register int tmp=0; 298. int inrange, nearby, scared; 299. #ifdef GOLDOBJ 300. struct obj *ygold = 0, *lepgold = 0; 301. #endif 302. 303. /* Pre-movement adjustments */ 304. 305. mdat = mtmp->data; 306. 307. if (mtmp->mstrategy & STRAT_ARRIVE) { 308. int res = m_arrival(mtmp); 309. if (res >= 0) return res; 310. } 311. 312. /* check for waitmask status change */ 313. if ((mtmp->mstrategy & STRAT_WAITFORU) && 314. (m_canseeu(mtmp) || mtmp->mhp < mtmp->mhpmax)) 315. mtmp->mstrategy &= ~STRAT_WAITFORU; 316. 317. /* update quest status flags */ 318. quest_stat_check(mtmp); 319. 320. if (!mtmp->mcanmove || (mtmp->mstrategy & STRAT_WAITMASK)) { 321. if (Hallucination) newsym(mtmp->mx,mtmp->my); 322. if (mtmp->mcanmove && (mtmp->mstrategy & STRAT_CLOSE) && 323. !mtmp->msleeping && monnear(mtmp, u.ux, u.uy)) 324. quest_talk(mtmp); /* give the leaders a chance to speak */ 325. return(0); /* other frozen monsters can't do anything */ 326. } 327. 328. /* there is a chance we will wake it */ 329. if (mtmp->msleeping && !disturb(mtmp)) { 330. if (Hallucination) newsym(mtmp->mx,mtmp->my); 331. return(0); 332. } 333. 334. /* not frozen or sleeping: wipe out texts written in the dust */ 335. wipe_engr_at(mtmp->mx, mtmp->my, 1); 336. 337. /* confused monsters get unconfused with small probability */ 338. if (mtmp->mconf && !rn2(50)) mtmp->mconf = 0; 339. 340. /* stunned monsters get un-stunned with larger probability */ 341. if (mtmp->mstun && !rn2(10)) mtmp->mstun = 0; 342. 343. /* some monsters teleport */ 344. if (mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz && 345. !level.flags.noteleport) { 346. rloc(mtmp); 347. return(0); 348. } 349. if (mdat->msound == MS_SHRIEK && !um_dist(mtmp->mx, mtmp->my, 1)) 350. m_respond(mtmp); 351. if (mdat == &mons[PM_MEDUSA] && couldsee(mtmp->mx, mtmp->my)) 352. m_respond(mtmp); 353. if (mtmp->mhp <= 0) return(1); /* m_respond gaze can kill medusa */ 354. 355. /* fleeing monsters might regain courage */ 356. if (mtmp->mflee && !mtmp->mfleetim 357. && mtmp->mhp == mtmp->mhpmax && !rn2(25)) mtmp->mflee = 0; 358. 359. set_apparxy(mtmp); 360. /* Must be done after you move and before the monster does. The 361. * set_apparxy() call in m_move() doesn't suffice since the variables 362. * inrange, etc. all depend on stuff set by set_apparxy(). 363. */ 364. 365. /* Monsters that want to acquire things */ 366. /* may teleport, so do it before inrange is set */ 367. if(is_covetous(mdat)) (void) tactics(mtmp); 368. 369. /* check distance and scariness of attacks */ 370. distfleeck(mtmp,&inrange,&nearby,&scared); 371. 372. if(find_defensive(mtmp)) { 373. if (use_defensive(mtmp) != 0) 374. return 1; 375. } else if(find_misc(mtmp)) { 376. if (use_misc(mtmp) != 0) 377. return 1; 378. } 379. 380. /* Demonic Blackmail! */ 381. if(nearby && mdat->msound == MS_BRIBE && 382. mtmp->mpeaceful && !mtmp->mtame && !u.uswallow) { 383. if (mtmp->mux != u.ux || mtmp->muy != u.uy) { 384. pline("%s whispers at thin air.", 385. cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It"); 386. 387. if (is_demon(youmonst.data)) { 388. /* "Good hunting, brother" */ 389. if (!tele_restrict(mtmp)) rloc(mtmp); 390. } else { 391. mtmp->minvis = mtmp->perminvis = 0; 392. /* Why? For the same reason in real demon talk */ 393. pline("%s gets angry!", Amonnam(mtmp)); 394. mtmp->mpeaceful = 0; 395. /* since no way is an image going to pay it off */ 396. } 397. } else if(demon_talk(mtmp)) return(1); /* you paid it off */ 398. } 399. 400. /* the watch will look around and see if you are up to no good :-) */ 401. if (mdat == &mons[PM_WATCHMAN] || mdat == &mons[PM_WATCH_CAPTAIN]) 402. watch_on_duty(mtmp); 403. 404. else if (is_mind_flayer(mdat) && !rn2(20)) { 405. struct monst *m2, *nmon = (struct monst *)0; 406. 407. if (canseemon(mtmp)) 408. pline("%s concentrates.", Monnam(mtmp)); 409. if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM) { 410. You("sense a faint wave of psychic energy."); 411. goto toofar; 412. } 413. pline("A wave of psychic energy pours over you!"); 414. if (mtmp->mpeaceful && 415. (!Conflict || resist(mtmp, RING_CLASS, 0, 0))) 416. pline("It feels quite soothing."); 417. else { 418. register boolean m_sen = sensemon(mtmp); 419. 420. if (m_sen || (Blind_telepat && rn2(2)) || !rn2(10)) { 421. int dmg; 422. pline("It locks on to your %s!", 423. m_sen ? "telepathy" : 424. Blind_telepat ? "latent telepathy" : "mind"); 425. dmg = rnd(15); 426. if (Half_spell_damage) dmg = (dmg+1) / 2; 427. losehp(dmg, "psychic blast", KILLED_BY_AN); 428. } 429. } 430. for(m2=fmon; m2; m2 = nmon) { 431. nmon = m2->nmon; 432. if (DEADMONSTER(m2)) continue; 433. if (m2->mpeaceful == mtmp->mpeaceful) continue; 434. if (mindless(m2->data)) continue; 435. if (m2 == mtmp) continue; 436. if ((telepathic(m2->data) && 437. (rn2(2) || m2->mblinded)) || !rn2(10)) { 438. if (cansee(m2->mx, m2->my)) 439. pline("It locks on to %s.", mon_nam(m2)); 440. m2->mhp -= rnd(15); 441. if (m2->mhp <= 0) 442. monkilled(m2, "", AD_DRIN); 443. else 444. m2->msleeping = 0; 445. } 446. } 447. } 448. toofar: 449. 450. /* If monster is nearby you, and has to wield a weapon, do so. This 451. * costs the monster a move, of course. 452. */ 453. if((!mtmp->mpeaceful || Conflict) && inrange && 454. dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8 455. && attacktype(mdat, AT_WEAP)) { 456. struct obj *mw_tmp; 457. 458. /* The scared check is necessary. Otherwise a monster that is 459. * one square near the player but fleeing into a wall would keep 460. * switching between pick-axe and weapon. 461. */ 462. mw_tmp = MON_WEP(mtmp); 463. if (!(scared && mw_tmp && is_pick(mw_tmp)) && 464. mtmp->weapon_check == NEED_WEAPON) { 465. mtmp->weapon_check = NEED_HTH_WEAPON; 466. if (mon_wield_item(mtmp) != 0) return(0); 467. } 468. } 469. 470. /* Now the actual movement phase */ 471. 472. #ifndef GOLDOBJ 473. if(!nearby || mtmp->mflee || scared || 474. mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) || 475. (mdat->mlet == S_LEPRECHAUN && !u.ugold && (mtmp->mgold || rn2(2))) || 476. #else 477. if (mdat->mlet == S_LEPRECHAUN) { 478. ygold = findgold(invent); 479. lepgold = findgold(mtmp->minvent); 480. } 481. 482. if(!nearby || mtmp->mflee || scared || 483. mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) || 484. (mdat->mlet == S_LEPRECHAUN && !ygold && (lepgold || rn2(2))) || 485. #endif 486. (is_wanderer(mdat) && !rn2(4)) || (Conflict && !mtmp->iswiz) || 487. (!mtmp->mcansee && !rn2(4)) || mtmp->mpeaceful) { 488. /* Possibly cast an undirected spell if not attacking you */ 489. /* note that most of the time castmu() will pick a directed 490. spell and do nothing, so the monster moves normally */ 491. /* arbitrary distance restriction to keep monster far away 492. from you from having cast dozens of sticks-to-snakes 493. or similar spells by the time you reach it */ 494. if (dist2(mtmp->mx, mtmp->my, u.ux, u.uy) <= 64 && !mtmp->mspec_used) { 495. struct attack *a; 496. 497. for (a = &mdat->mattk[0]; a < &mdat->mattk[NATTK]; a++) { 498. if (a->aatyp == AT_MAGC && (a->adtyp == AD_SPEL || a->adtyp == AD_CLRC)) { 499. if (castmu(mtmp, a, FALSE, FALSE)) { 500. tmp = 3; 501. break; 502. } 503. } 504. } 505. } 506. 507. tmp = m_move(mtmp, 0); 508. distfleeck(mtmp,&inrange,&nearby,&scared); /* recalc */ 509. 510. switch (tmp) { 511. case 0: /* no movement, but it can still attack you */ 512. case 3: /* absolutely no movement */ 513. /* for pets, case 0 and 3 are equivalent */ 514. /* vault guard might have vanished */ 515. if (mtmp->isgd && (mtmp->mhp < 1 || 516. (mtmp->mx == 0 && mtmp->my == 0))) 517. return 1; /* behave as if it died */ 518. /* During hallucination, monster appearance should 519. * still change - even if it doesn't move. 520. */ 521. if(Hallucination) newsym(mtmp->mx,mtmp->my); 522. break; 523. case 1: /* monster moved */ 524. /* Maybe it stepped on a trap and fell asleep... */ 525. if (mtmp->msleeping || !mtmp->mcanmove) return(0); 526. if(!nearby && 527. (ranged_attk(mdat) || find_offensive(mtmp))) 528. break; 529. else if(u.uswallow && mtmp == u.ustuck) { 530. /* a monster that's digesting you can move at the 531. * same time -dlc 532. */ 533. return(mattacku(mtmp)); 534. } else 535. return(0); 536. /*NOTREACHED*/ 537. break; 538. case 2: /* monster died */ 539. return(1); 540. } 541. } 542. 543. /* Now, attack the player if possible - one attack set per monst */ 544. 545. if (!mtmp->mpeaceful || 546. (Conflict && !resist(mtmp, RING_CLASS, 0, 0))) { 547. if(inrange && !noattacks(mdat) && u.uhp > 0 && !scared && tmp != 3) 548. if(mattacku(mtmp)) return(1); /* monster died (e.g. exploded) */ 549. 550. if(mtmp->wormno) wormhitu(mtmp); 551. } 552. /* special speeches for quest monsters */ 553. if (!mtmp->msleeping && mtmp->mcanmove && nearby) 554. quest_talk(mtmp); 555. /* extra emotional attack for vile monsters */ 556. if (inrange && mtmp->data->msound == MS_CUSS && !mtmp->mpeaceful && 557. couldsee(mtmp->mx, mtmp->my) && !mtmp->minvis && !rn2(5)) 558. cuss(mtmp); 559. 560. return(tmp == 2); 561. } 562. 563. static NEARDATA const char practical[] = { WEAPON_CLASS, ARMOR_CLASS, GEM_CLASS, FOOD_CLASS, 0 }; 564. static NEARDATA const char magical[] = { 565. AMULET_CLASS, POTION_CLASS, SCROLL_CLASS, WAND_CLASS, RING_CLASS, 566. SPBOOK_CLASS, 0 }; 567. static NEARDATA const char indigestion[] = { BALL_CLASS, ROCK_CLASS, 0 }; 568. static NEARDATA const char boulder_class[] = { ROCK_CLASS, 0 }; 569. static NEARDATA const char gem_class[] = { GEM_CLASS, 0 }; 570. 571. boolean 572. itsstuck(mtmp) 573. register struct monst *mtmp; 574. { 575. if (sticks(youmonst.data) && mtmp==u.ustuck && !u.uswallow) { 576. pline("%s cannot escape from you!", Monnam(mtmp)); 577. return(TRUE); 578. } 579. return(FALSE); 580. } 581. 582. /* Return values: 583. * 0: did not move, but can still attack and do other stuff. 584. * 1: moved, possibly can attack. 585. * 2: monster died. 586. * 3: did not move, and can't do anything else either. 587. */ 588. int 589. m_move(mtmp, after) 590. register struct monst *mtmp; 591. register int after; 592. { 593. register int appr; 594. xchar gx,gy,nix,niy,chcnt; 595. int chi; /* could be schar except for stupid Sun-2 compiler */ 596. boolean likegold=0, likegems=0, likeobjs=0, likemagic=0, conceals=0; 597. boolean likerock=0, can_tunnel=0; 598. boolean can_open=0, can_unlock=0, doorbuster=0; 599. boolean uses_items=0, setlikes=0; 600. boolean avoid=FALSE; 601. struct permonst *ptr; 602. struct monst *mtoo; 603. schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */ 604. long info[9]; 605. long flag; 606. int omx = mtmp->mx, omy = mtmp->my; 607. struct obj *mw_tmp; 608. 609. if(mtmp->mtrapped) { 610. int i = mintrap(mtmp); 611. if(i >= 2) { newsym(mtmp->mx,mtmp->my); return(2); }/* it died */ 612. if(i == 1) return(0); /* still in trap, so didn't move */ 613. } 614. ptr = mtmp->data; /* mintrap() can change mtmp->data -dlc */ 615. 616. if (mtmp->meating) { 617. mtmp->meating--; 618. return 3; /* still eating */ 619. } 620. if (hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) && rn2(10)) 621. return 0; /* do not leave hiding place */ 622. 623. set_apparxy(mtmp); 624. /* where does mtmp think you are? */ 625. /* Not necessary if m_move called from this file, but necessary in 626. * other calls of m_move (ex. leprechauns dodging) 627. */ 628. can_tunnel = tunnels(ptr) && 629. #ifdef REINCARNATION 630. !Is_rogue_level(&u.uz) && 631. #endif 632. (!needspick(ptr) || m_carrying(mtmp, PICK_AXE) || 633. (m_carrying(mtmp, DWARVISH_MATTOCK) && !which_armor(mtmp, W_ARMS))); 634. can_open = !(nohands(ptr) || verysmall(ptr)); 635. can_unlock = ((can_open && m_carrying(mtmp, SKELETON_KEY)) || 636. mtmp->iswiz || is_rider(ptr)); 637. doorbuster = is_giant(ptr); 638. if(mtmp->wormno) goto not_special; 639. /* my dog gets special treatment */ 640. if(mtmp->mtame) { 641. mmoved = dog_move(mtmp, after); 642. goto postmov; 643. } 644. 645. /* likewise for shopkeeper */ 646. if(mtmp->isshk) { 647. mmoved = shk_move(mtmp); 648. if(mmoved == -2) return(2); 649. if(mmoved >= 0) goto postmov; 650. mmoved = 0; /* follow player outside shop */ 651. } 652. 653. /* and for the guard */ 654. if(mtmp->isgd) { 655. mmoved = gd_move(mtmp); 656. if(mmoved == -2) return(2); 657. if(mmoved >= 0) goto postmov; 658. mmoved = 0; 659. } 660. 661. /* and the acquisitive monsters get special treatment */ 662. if(is_covetous(ptr)) { 663. xchar tx = STRAT_GOALX(mtmp->mstrategy), 664. ty = STRAT_GOALY(mtmp->mstrategy); 665. struct monst *intruder = m_at(tx, ty); 666. /* 667. * if there's a monster on the object or in possesion of it, 668. * attack it. 669. */ 670. if((dist2(mtmp->mx, mtmp->my, tx, ty) < 2) && 671. intruder && (intruder != mtmp)) { 672. 673. notonhead = (intruder->mx != tx || intruder->my != ty); 674. if(mattackm(mtmp, intruder) == 2) return(2); 675. mmoved = 1; 676. } else mmoved = 0; 677. goto postmov; 678. } 679. 680. /* and for the priest */ 681. if(mtmp->ispriest) { 682. mmoved = pri_move(mtmp); 683. if(mmoved == -2) return(2); 684. if(mmoved >= 0) goto postmov; 685. mmoved = 0; 686. } 687. 688. #ifdef MAIL 689. if(ptr == &mons[PM_MAIL_DAEMON]) { 690. if(flags.soundok && canseemon(mtmp)) 691. verbalize("I'm late!"); 692. mongone(mtmp); 693. return(2); 694. } 695. #endif 696. 697. /* teleport if that lies in our nature */ 698. if(ptr == &mons[PM_TENGU] && !rn2(5) && !mtmp->mcan && 699. !tele_restrict(mtmp)) { 700. if(mtmp->mhp < 7 || mtmp->mpeaceful || rn2(2)) 701. rloc(mtmp); 702. else 703. mnexto(mtmp); 704. mmoved = 1; 705. goto postmov; 706. } 707. not_special: 708. if(u.uswallow && !mtmp->mflee && u.ustuck != mtmp) return(1); 709. omx = mtmp->mx; 710. omy = mtmp->my; 711. gx = mtmp->mux; 712. gy = mtmp->muy; 713. appr = mtmp->mflee ? -1 : 1; 714. if (mtmp->mconf || (u.uswallow && mtmp == u.ustuck)) 715. appr = 0; 716. else { 717. #ifdef GOLDOBJ 718. struct obj *lepgold, *ygold; 719. #endif 720. boolean should_see = (couldsee(omx, omy) && 721. (levl[gx][gy].lit || 722. !levl[omx][omy].lit) && 723. (dist2(omx, omy, gx, gy) <= 36)); 724. 725. if (!mtmp->mcansee || 726. (should_see && Invis && !perceives(ptr) && rn2(11)) || 727. (youmonst.m_ap_type == M_AP_OBJECT && youmonst.mappearance == STRANGE_OBJECT) || u.uundetected || 728. (youmonst.m_ap_type == M_AP_OBJECT && youmonst.mappearance == GOLD_PIECE && !likes_gold(ptr)) || 729. (mtmp->mpeaceful && !mtmp->isshk) || /* allow shks to follow */ 730. ((monsndx(ptr) == PM_STALKER || ptr->mlet == S_BAT || 731. ptr->mlet == S_LIGHT) && !rn2(3))) 732. appr = 0; 733. 734. if(monsndx(ptr) == PM_LEPRECHAUN && (appr == 1) && 735. #ifndef GOLDOBJ 736. (mtmp->mgold > u.ugold)) 737. #else 738. ( (lepgold = findgold(mtmp->minvent)) && 739. (lepgold->quan > ((ygold = findgold(invent)) ? ygold->quan : 0L)) )) 740. #endif 741. appr = -1; 742. 743. if (!should_see && can_track(ptr)) { 744. register coord *cp; 745. 746. cp = gettrack(omx,omy); 747. if (cp) { 748. gx = cp->x; 749. gy = cp->y; 750. } 751. } 752. } 753. 754. if ((!mtmp->mpeaceful || !rn2(10)) 755. #ifdef REINCARNATION 756. && (!Is_rogue_level(&u.uz)) 757. #endif 758. ) { 759. boolean in_line = lined_up(mtmp) && 760. (distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 761. (throws_rocks(youmonst.data) ? 20 : ACURRSTR/2+1) 762. ); 763. 764. if (appr != 1 || !in_line) { 765. /* Monsters in combat won't pick stuff up, avoiding the 766. * situation where you toss arrows at it and it has nothing 767. * better to do than pick the arrows up. 768. */ 769. register int pctload = (curr_mon_load(mtmp) * 100) / 770. max_mon_load(mtmp); 771. 772. /* look for gold or jewels nearby */ 773. likegold = (likes_gold(ptr) && pctload < 95); 774. likegems = (likes_gems(ptr) && pctload < 85); 775. uses_items = (!mindless(ptr) && !is_animal(ptr) 776. && pctload < 75); 777. likeobjs = (likes_objs(ptr) && pctload < 75); 778. likemagic = (likes_magic(ptr) && pctload < 85); 779. likerock = (throws_rocks(ptr) && pctload < 50 && !In_sokoban(&u.uz)); 780. conceals = hides_under(ptr); 781. setlikes = TRUE; 782. } 783. } 784. 785. #define SQSRCHRADIUS 5 786. 787. { register int minr = SQSRCHRADIUS; /* not too far away */ 788. register struct obj *otmp; 789. register int xx, yy; 790. int oomx, oomy, lmx, lmy; 791. 792. /* cut down the search radius if it thinks character is closer. */ 793. if(distmin(mtmp->mux, mtmp->muy, omx, omy) < SQSRCHRADIUS && 794. !mtmp->mpeaceful) minr--; 795. /* guards shouldn't get too distracted */ 796. if(!mtmp->mpeaceful && is_mercenary(ptr)) minr = 1; 797. 798. if((likegold || likegems || likeobjs || likemagic || likerock || conceals) 799. && (!*in_rooms(omx, omy, SHOPBASE) || (!rn2(25) && !mtmp->isshk))) { 800. look_for_obj: 801. oomx = min(COLNO-1, omx+minr); 802. oomy = min(ROWNO-1, omy+minr); 803. lmx = max(1, omx-minr); 804. lmy = max(0, omy-minr); 805. for(otmp = fobj; otmp; otmp = otmp->nobj) { 806. /* monsters may pick rocks up, but won't go out of their way 807. to grab them; this might hamper sling wielders, but it cuts 808. down on move overhead by filtering out most common item */ 809. if (otmp->otyp == ROCK) continue; 810. xx = otmp->ox; 811. yy = otmp->oy; 812. /* Nymphs take everything. Most other creatures should not 813. * pick up corpses except as a special case like in 814. * searches_for_item(). We need to do this check in 815. * mpickstuff() as well. 816. */ 817. if(xx >= lmx && xx <= oomx && yy >= lmy && yy <= oomy) { 818. /* don't get stuck circling around an object that's underneath 819. an immobile or hidden monster; paralysis victims excluded */ 820. if ((mtoo = m_at(xx,yy)) != 0 && 821. (mtoo->msleeping || mtoo->mundetected || 822. (mtoo->mappearance && !mtoo->iswiz) || 823. !mtoo->data->mmove)) continue; 824. 825. if(((likegold && otmp->oclass == GOLD_CLASS) || 826. (likeobjs && index(practical, otmp->oclass) && 827. (otmp->otyp != CORPSE || (ptr->mlet == S_NYMPH 828. && !is_rider(&mons[otmp->corpsenm])))) || 829. (likemagic && index(magical, otmp->oclass)) || 830. (uses_items && searches_for_item(mtmp, otmp)) || 831. (likerock && otmp->otyp == BOULDER) || 832. (likegems && otmp->oclass == GEM_CLASS && 833. objects[otmp->otyp].oc_material != MINERAL) || 834. (conceals && !cansee(otmp->ox,otmp->oy)) || 835. (ptr == &mons[PM_GELATINOUS_CUBE] && 836. !index(indigestion, otmp->oclass) && 837. !(otmp->otyp == CORPSE && 838. touch_petrifies(&mons[otmp->corpsenm]))) 839. ) && touch_artifact(otmp,mtmp)) { 840. if(can_carry(mtmp,otmp) && 841. (throws_rocks(ptr) || 842. !sobj_at(BOULDER,xx,yy)) && 843. (!is_unicorn(ptr) || 844. objects[otmp->otyp].oc_material == GEMSTONE) && 845. /* Don't get stuck circling an Elbereth */ 846. !(onscary(xx, yy, mtmp))) { 847. minr = distmin(omx,omy,xx,yy); 848. oomx = min(COLNO-1, omx+minr); 849. oomy = min(ROWNO-1, omy+minr); 850. lmx = max(1, omx-minr); 851. lmy = max(0, omy-minr); 852. gx = otmp->ox; 853. gy = otmp->oy; 854. if (gx == omx && gy == omy) { 855. mmoved = 3; /* actually unnecessary */ 856. goto postmov; 857. } 858. } 859. } 860. } 861. } 862. } else if(likegold) { 863. /* don't try to pick up anything else, but use the same loop */ 864. uses_items = 0; 865. likegems = likeobjs = likemagic = likerock = conceals = 0; 866. goto look_for_obj; 867. } 868. 869. if(minr < SQSRCHRADIUS && appr == -1) { 870. if(distmin(omx,omy,mtmp->mux,mtmp->muy) <= 3) { 871. gx = mtmp->mux; 872. gy = mtmp->muy; 873. } else 874. appr = 1; 875. } 876. } 877. 878. if (can_tunnel && needspick(ptr) && 879. (mw_tmp = MON_WEP(mtmp)) != 0 && !is_pick(mw_tmp) && 880. mw_tmp->cursed && mtmp->weapon_check == NO_WEAPON_WANTED) 881. can_tunnel = FALSE; 882. 883. nix = omx; 884. niy = omy; 885. flag = 0L; 886. if (mtmp->mpeaceful && (!Conflict || resist(mtmp, RING_CLASS, 0, 0))) 887. flag |= (ALLOW_SANCT | ALLOW_SSM); 888. else flag |= ALLOW_U; 889. if (is_minion(ptr) || is_rider(ptr)) flag |= ALLOW_SANCT; 890. /* unicorn may not be able to avoid hero on a noteleport level */ 891. if (is_unicorn(ptr) && !level.flags.noteleport) flag |= NOTONL; 892. if (passes_walls(ptr)) flag |= (ALLOW_WALL | ALLOW_ROCK); 893. if (can_tunnel) flag |= ALLOW_DIG; 894. if (is_human(ptr) || ptr == &mons[PM_MINOTAUR]) flag |= ALLOW_SSM; 895. if (is_undead(ptr) && ptr->mlet != S_GHOST) flag |= NOGARLIC; 896. if (throws_rocks(ptr)) flag |= ALLOW_ROCK; 897. if (can_open) flag |= OPENDOOR; 898. if (can_unlock) flag |= UNLOCKDOOR; 899. if (doorbuster) flag |= BUSTDOOR; 900. { 901. register int i, j, nx, ny, nearer; 902. int jcnt, cnt; 903. int ndist, nidist; 904. register coord *mtrk; 905. coord poss[9]; 906. 907. cnt = mfndpos(mtmp, poss, info, flag); 908. chcnt = 0; 909. jcnt = min(MTSZ, cnt-1); 910. chi = -1; 911. nidist = dist2(nix,niy,gx,gy); 912. /* allow monsters be shortsighted on some levels for balance */ 913. if(!mtmp->mpeaceful && level.flags.shortsighted && 914. nidist > (couldsee(nix,niy) ? 144 : 36) && appr == 1) appr = 0; 915. if (is_unicorn(ptr) && level.flags.noteleport) { 916. /* on noteleport levels, perhaps we cannot avoid hero */ 917. for(i = 0; i < cnt; i++) 918. if(!(info[i] & NOTONL)) avoid=TRUE; 919. } 920. 921. for(i=0; i < cnt; i++) { 922. if (avoid && (info[i] & NOTONL)) continue; 923. nx = poss[i].x; 924. ny = poss[i].y; 925. 926. if (appr != 0) { 927. mtrk = &mtmp->mtrack[0]; 928. for(j=0; j < jcnt; mtrk++, j++) 929. if(nx == mtrk->x && ny == mtrk->y) 930. if(rn2(4*(cnt-j))) 931. goto nxti; 932. } 933. 934. nearer = ((ndist = dist2(nx,ny,gx,gy)) < nidist); 935. 936. if((appr == 1 && nearer) || (appr == -1 && !nearer) || 937. (!appr && !rn2(++chcnt)) || !mmoved) { 938. nix = nx; 939. niy = ny; 940. nidist = ndist; 941. chi = i; 942. mmoved = 1; 943. } 944. nxti: ; 945. } 946. } 947. 948. if(mmoved) { 949. register int j; 950. 951. if (mmoved==1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp)) 952. return(3); 953. 954. if(IS_ROCK(levl[nix][niy].typ) && may_dig(nix,niy) && 955. mmoved==1 && can_tunnel && needspick(ptr) && 956. (!(mw_tmp = MON_WEP(mtmp)) || !is_pick(mw_tmp))) { 957. mtmp->weapon_check = NEED_PICK_AXE; 958. if (mon_wield_item(mtmp)) 959. return(3); 960. } 961. /* If ALLOW_U is set, either it's trying to attack you, or it 962. * thinks it is. In either case, attack this spot in preference to 963. * all others. 964. */ 965. /* Actually, this whole section of code doesn't work as you'd expect. 966. * Most attacks are handled in dochug(). It calls distfleeck(), which 967. * among other things sets nearby if the monster is near you--and if 968. * nearby is set, we never call m_move unless it is a special case 969. * (confused, stun, etc.) The effect is that this ALLOW_U (and 970. * mfndpos) has no effect for normal attacks, though it lets a confused 971. * monster attack you by accident. 972. */ 973. if(info[chi] & ALLOW_U) { 974. nix = mtmp->mux; 975. niy = mtmp->muy; 976. } 977. if (nix == u.ux && niy == u.uy) { 978. mtmp->mux = u.ux; 979. mtmp->muy = u.uy; 980. return(0); 981. } 982. /* The monster may attack another based on 1 of 2 conditions: 983. * 1 - It may be confused. 984. * 2 - It may mistake the monster for your (displaced) image. 985. * Pets get taken care of above and shouldn't reach this code. 986. * Conflict gets handled even farther away (movemon()). 987. */ 988. if((info[chi] & ALLOW_M) || 989. (nix == mtmp->mux && niy == mtmp->muy)) { 990. struct monst *mtmp2; 991. int mstatus; 992. mtmp2 = m_at(nix,niy); 993. 994. notonhead = mtmp2 && (nix != mtmp2->mx || niy != mtmp2->my); 995. /* note: mstatus returns 0 if mtmp2 is nonexistent */ 996. mstatus = mattackm(mtmp, mtmp2); 997. 998. if (mstatus & MM_AGR_DIED) /* aggressor died */ 999. return 2; 1000. 1001. if ((mstatus & MM_HIT) && !(mstatus & MM_DEF_DIED) && 1002. rn2(4) && mtmp2->movement >= NORMAL_SPEED) { 1003. mtmp2->movement -= NORMAL_SPEED; 1004. notonhead = 0; 1005. mstatus = mattackm(mtmp2, mtmp); /* return attack */ 1006. if (mstatus & MM_DEF_DIED) 1007. return 2; 1008. } 1009. return 3; 1010. } 1011. 1012. if (!m_in_out_region(mtmp,nix,niy)) 1013. return 3; 1014. remove_monster(omx, omy); 1015. place_monster(mtmp, nix, niy); 1016. for(j = MTSZ-1; j > 0; j--) 1017. mtmp->mtrack[j] = mtmp->mtrack[j-1]; 1018. mtmp->mtrack[0].x = omx; 1019. mtmp->mtrack[0].y = omy; 1020. /* Place a segment at the old position. */ 1021. if (mtmp->wormno) worm_move(mtmp); 1022. } else { 1023. if(is_unicorn(ptr) && rn2(2) && !tele_restrict(mtmp)) { 1024. rloc(mtmp); 1025. return(1); 1026. } 1027. if(mtmp->wormno) worm_nomove(mtmp); 1028. } 1029. postmov: 1030. if(mmoved == 1 || mmoved == 3) { 1031. boolean canseeit = cansee(mtmp->mx, mtmp->my); 1032. 1033. if(mmoved == 1) { 1034. newsym(omx,omy); /* update the old position */ 1035. if (mintrap(mtmp) >= 2) { 1036. if(mtmp->mx) newsym(mtmp->mx,mtmp->my); 1037. return(2); /* it died */ 1038. } 1039. ptr = mtmp->data; 1040. 1041. /* open a door, or crash through it, if you can */ 1042. if(IS_DOOR(levl[mtmp->mx][mtmp->my].typ) 1043. && !passes_walls(ptr) /* doesn't need to open doors */ 1044. && !can_tunnel /* taken care of below */ 1045. ) { 1046. struct rm *here = &levl[mtmp->mx][mtmp->my]; 1047. boolean btrapped = (here->doormask & D_TRAPPED); 1048. 1049. if(here->doormask & (D_LOCKED|D_CLOSED) && amorphous(ptr)) { 1050. if (flags.verbose && canseemon(mtmp)) 1051. pline("%s %ss under the door.", Monnam(mtmp), 1052. (ptr == &mons[PM_FOG_CLOUD] || 1053. ptr == &mons[PM_YELLOW_LIGHT]) 1054. ? "flow" : "ooze"); 1055. } else if(here->doormask & D_LOCKED && can_unlock) { 1056. if(btrapped) { 1057. here->doormask = D_NODOOR; 1058. newsym(mtmp->mx, mtmp->my); 1059. unblock_point(mtmp->mx,mtmp->my); /* vision */ 1060. if(mb_trapped(mtmp)) return(2); 1061. } else { 1062. if (flags.verbose) { 1063. if (canseeit) 1064. You("see a door unlock and open."); 1065. else if (flags.soundok) 1066. You_hear("a door unlock and open."); 1067. } 1068. here->doormask = D_ISOPEN; 1069. /* newsym(mtmp->mx, mtmp->my); */ 1070. unblock_point(mtmp->mx,mtmp->my); /* vision */ 1071. } 1072. } else if (here->doormask == D_CLOSED && can_open) { 1073. if(btrapped) { 1074. here->doormask = D_NODOOR; 1075. newsym(mtmp->mx, mtmp->my); 1076. unblock_point(mtmp->mx,mtmp->my); /* vision */ 1077. if(mb_trapped(mtmp)) return(2); 1078. } else { 1079. if (flags.verbose) { 1080. if (canseeit) 1081. You("see a door open."); 1082. else if (flags.soundok) 1083. You_hear("a door open."); 1084. } 1085. here->doormask = D_ISOPEN; 1086. /* newsym(mtmp->mx, mtmp->my); */ /* done below */ 1087. unblock_point(mtmp->mx,mtmp->my); /* vision */ 1088. } 1089. } else if (here->doormask & (D_LOCKED|D_CLOSED)) { 1090. /* mfndpos guarantees this must be a doorbuster */ 1091. if(btrapped) { 1092. here->doormask = D_NODOOR; 1093. newsym(mtmp->mx, mtmp->my); 1094. unblock_point(mtmp->mx,mtmp->my); /* vision */ 1095. if(mb_trapped(mtmp)) return(2); 1096. } else { 1097. if (flags.verbose) { 1098. if (canseeit) 1099. You("see a door crash open."); 1100. else if (flags.soundok) 1101. You_hear("a door crash open."); 1102. } 1103. if (here->doormask & D_LOCKED && !rn2(2)) 1104. here->doormask = D_NODOOR; 1105. else here->doormask = D_BROKEN; 1106. /* newsym(mtmp->mx, mtmp->my); */ /* done below */ 1107. unblock_point(mtmp->mx,mtmp->my); /* vision */ 1108. } 1109. /* if it's a shop door, schedule repair */ 1110. if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE)) 1111. add_damage(mtmp->mx, mtmp->my, 0L); 1112. } 1113. } 1114. 1115. /* possibly dig */ 1116. if (can_tunnel && mdig_tunnel(mtmp)) 1117. return(2); /* mon died (position already updated) */ 1118. 1119. /* set also in domove(), hack.c */ 1120. if (u.uswallow && mtmp == u.ustuck && 1121. (mtmp->mx != omx || mtmp->my != omy)) { 1122. /* If the monster moved, then update */ 1123. u.ux0 = u.ux; 1124. u.uy0 = u.uy; 1125. u.ux = mtmp->mx; 1126. u.uy = mtmp->my; 1127. swallowed(0); 1128. } else 1129. newsym(mtmp->mx,mtmp->my); 1130. } 1131. if(OBJ_AT(mtmp->mx, mtmp->my) && mtmp->mcanmove) { 1132. /* recompute the likes tests, in case we polymorphed 1133. * or if the "likegold" case got taken above */ 1134. if (setlikes) { 1135. register int pctload = (curr_mon_load(mtmp) * 100) / 1136. max_mon_load(mtmp); 1137. 1138. /* look for gold or jewels nearby */ 1139. likegold = (likes_gold(ptr) && pctload < 95); 1140. likegems = (likes_gems(ptr) && pctload < 85); 1141. uses_items = (!mindless(ptr) && !is_animal(ptr) 1142. && pctload < 75); 1143. likeobjs = (likes_objs(ptr) && pctload < 75); 1144. likemagic = (likes_magic(ptr) && pctload < 85); 1145. likerock = (throws_rocks(ptr) && pctload < 50 && 1146. !In_sokoban(&u.uz)); 1147. conceals = hides_under(ptr); 1148. } 1149. 1150. /* Maybe a rock mole just ate some metal object */ 1151. if (metallivorous(ptr)) { 1152. if (meatmetal(mtmp) == 2) return 2; /* it died */ 1153. } 1154. 1155. if(g_at(mtmp->mx,mtmp->my) && likegold) mpickgold(mtmp); 1156. 1157. /* Maybe a cube ate just about anything */ 1158. if (ptr == &mons[PM_GELATINOUS_CUBE]) { 1159. if (meatobj(mtmp) == 2) return 2; /* it died */ 1160. } 1161. 1162. if(!*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || !rn2(25)) { 1163. boolean picked = FALSE; 1164. 1165. if(likeobjs) picked |= mpickstuff(mtmp, practical); 1166. if(likemagic) picked |= mpickstuff(mtmp, magical); 1167. if(likerock) picked |= mpickstuff(mtmp, boulder_class); 1168. if(likegems) picked |= mpickstuff(mtmp, gem_class); 1169. if(uses_items) picked |= mpickstuff(mtmp, (char *)0); 1170. if(picked) mmoved = 3; 1171. } 1172. 1173. if(mtmp->minvis) { 1174. newsym(mtmp->mx, mtmp->my); 1175. if (mtmp->wormno) see_wsegs(mtmp); 1176. } 1177. } 1178. 1179. if(hides_under(ptr) || ptr->mlet == S_EEL) { 1180. /* Always set--or reset--mundetected if it's already hidden 1181. (just in case the object it was hiding under went away); 1182. usually set mundetected unless monster can't move. */ 1183. if (mtmp->mundetected || 1184. (mtmp->mcanmove && !mtmp->msleeping && rn2(5))) 1185. mtmp->mundetected = (ptr->mlet != S_EEL) ? 1186. OBJ_AT(mtmp->mx, mtmp->my) : 1187. (is_pool(mtmp->mx, mtmp->my) && !Is_waterlevel(&u.uz)); 1188. newsym(mtmp->mx, mtmp->my); 1189. } 1190. } 1191. return(mmoved); 1192. } 1193. 1194. #endif /* OVL0 */ 1195. #ifdef OVL2 1196. 1197. boolean 1198. closed_door(x, y) 1199. register int x, y; 1200. { 1201. return((boolean)(IS_DOOR(levl[x][y].typ) && 1202. (levl[x][y].doormask & (D_LOCKED | D_CLOSED)))); 1203. } 1204. 1205. boolean 1206. accessible(x, y) 1207. register int x, y; 1208. { 1209. return((boolean)(ACCESSIBLE(levl[x][y].typ) && !closed_door(x, y))); 1210. } 1211. 1212. #endif /* OVL2 */ 1213. #ifdef OVL0 1214. 1215. /* decide where the monster thinks you are standing */ 1216. void 1217. set_apparxy(mtmp) 1218. register struct monst *mtmp; 1219. { 1220. boolean notseen, gotu; 1221. register int disp, mx = mtmp->mux, my = mtmp->muy; 1222. #ifdef GOLDOBJ 1223. long umoney = money_cnt(invent); 1224. #endif 1225. 1226. /* 1227. * do cheapest and/or most likely tests first 1228. */ 1229. 1230. /* pet knows your smell; grabber still has hold of you */ 1231. if (mtmp->mtame || mtmp == u.ustuck) goto found_you; 1232. 1233. /* monsters which know where you are don't suddenly forget, 1234. if you haven't moved away */ 1235. if (mx == u.ux && my == u.uy) goto found_you; 1236. 1237. notseen = (!mtmp->mcansee || (Invis && !perceives(mtmp->data))); 1238. /* add cases as required. eg. Displacement ... */ 1239. if (notseen || Underwater) { 1240. /* Xorns can smell valuable metal like gold, treat as seen */ 1241. if ((mtmp->data == &mons[PM_XORN]) && 1242. #ifndef GOLDOBJ 1243. u.ugold 1244. #else 1245. umoney 1246. #endif 1247. && !Underwater) 1248. disp = 0; 1249. else 1250. disp = 1; 1251. } else if (Displaced) { 1252. disp = couldsee(mx, my) ? 2 : 1; 1253. } else disp = 0; 1254. if (!disp) goto found_you; 1255. 1256. /* without something like the following, invis. and displ. 1257. are too powerful */ 1258. gotu = notseen ? !rn2(3) : Displaced ? !rn2(4) : FALSE; 1259. 1260. #if 0 /* this never worked as intended & isn't needed anyway */ 1261. /* If invis but not displaced, staying around gets you 'discovered' */ 1262. gotu |= (!Displaced && u.dx == 0 && u.dy == 0); 1263. #endif 1264. 1265. if (!gotu) { 1266. register int try_cnt = 0; 1267. do { 1268. if (++try_cnt > 200) goto found_you; /* punt */ 1269. mx = u.ux - disp + rn2(2*disp+1); 1270. my = u.uy - disp + rn2(2*disp+1); 1271. } while (!isok(mx,my) 1272. || (disp != 2 && mx == mtmp->mx && my == mtmp->my) 1273. || ((mx != u.ux || my != u.uy) && 1274. !passes_walls(mtmp->data) && 1275. (!ACCESSIBLE(levl[mx][my].typ) || 1276. (closed_door(mx, my) && !can_ooze(mtmp)))) 1277. || !couldsee(mx, my)); 1278. } else { 1279. found_you: 1280. mx = u.ux; 1281. my = u.uy; 1282. } 1283. 1284. mtmp->mux = mx; 1285. mtmp->muy = my; 1286. } 1287. 1288. boolean 1289. can_ooze(mtmp) 1290. struct monst *mtmp; 1291. { 1292. struct obj *chain, *obj; 1293. 1294. if (!amorphous(mtmp->data)) return FALSE; 1295. if (mtmp == &youmonst) { 1296. #ifndef GOLDOBJ 1297. if (u.ugold > 100L) return FALSE; 1298. #endif 1299. chain = invent; 1300. } else { 1301. #ifndef GOLDOBJ 1302. if (mtmp->mgold > 100L) return FALSE; 1303. #endif 1304. chain = mtmp->minvent; 1305. } 1306. for (obj = chain; obj; obj = obj->nobj) { 1307. int typ = obj->otyp; 1308. 1309. #ifdef GOLDOBJ 1310. if (typ == GOLD_CLASS && obj->quan > 100L) return FALSE; 1311. #endif 1312. if (obj->oclass != GEM_CLASS && 1313. !(typ >= ARROW && typ <= BOOMERANG) && 1314. !(typ >= DAGGER && typ <= CRYSKNIFE) && 1315. typ != SLING && 1316. !is_cloak(obj) && typ != FEDORA && 1317. !is_gloves(obj) && typ != LEATHER_JACKET && 1318. #ifdef TOURIST 1319. typ != CREDIT_CARD && !is_shirt(obj) && 1320. #endif 1321. !(typ == CORPSE && verysmall(&mons[obj->corpsenm])) && 1322. typ != FORTUNE_COOKIE && typ != CANDY_BAR && 1323. typ != PANCAKE && typ != LEMBAS_WAFER && 1324. typ != LUMP_OF_ROYAL_JELLY && 1325. obj->oclass != AMULET_CLASS && 1326. obj->oclass != RING_CLASS && 1327. #ifdef WIZARD 1328. obj->oclass != VENOM_CLASS && 1329. #endif 1330. typ != SACK && typ != BAG_OF_HOLDING && 1331. typ != BAG_OF_TRICKS && !Is_candle(obj) && 1332. typ != OILSKIN_SACK && typ != LEASH && 1333. typ != STETHOSCOPE && typ != BLINDFOLD && typ != TOWEL && 1334. typ != TIN_WHISTLE && typ != MAGIC_WHISTLE && 1335. typ != MAGIC_MARKER && typ != TIN_OPENER && 1336. typ != SKELETON_KEY && typ != LOCK_PICK 1337. ) return FALSE; 1338. if (Is_container(obj) && obj->cobj) return FALSE; 1339. 1340. } 1341. return TRUE; 1342. } 1343. 1344. #endif /* OVL0 */ 1345. 1346. /*monmove.c*/
Alternative Linked Data Views: ODE     Raw Data in: CXML | CSV | RDF ( N-Triples N3/Turtle JSON XML ) | OData ( Atom JSON ) | Microdata ( JSON HTML) | JSON-LD    About   
This material is Open Knowledge   W3C Semantic Web Technology [RDF Data] Valid XHTML + RDFa
OpenLink Virtuoso version 07.20.3217, on Linux (x86_64-pc-linux-gnu), Standard Edition
Data on this page belongs to its respective rights holders.
Virtuoso Faceted Browser Copyright © 2009-2012 OpenLink Software