Below is the full text to muse.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/muse.c#line123]], for example.
The latest source code for vanilla NetHack is at Source code.
The NetHack General Public License applies to screenshots, source code and other content from NetHack. |
1. /* SCCS Id: @(#)muse.c 3.4 2002/12/23 */ 2. /* Copyright (C) 1990 by Ken Arromdee */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* 6. * Monster item usage routines. 7. */ 8. 9. #include "hack.h" 10. #include "edog.h" 11. 12. extern const int monstr[]; 13. 14. boolean m_using = FALSE; 15. 16. /* Let monsters use magic items. Arbitrary assumptions: Monsters only use 17. * scrolls when they can see, monsters know when wands have 0 charges, monsters 18. * cannot recognize if items are cursed are not, monsters which are confused 19. * don't know not to read scrolls, etc.... 20. */ 21. 22. #if 0 23. STATIC_DCL struct permonst *FDECL(muse_newcham_mon, (struct monst *)); 24. #endif 25. STATIC_DCL int FDECL(precheck, (struct monst *,struct obj *)); 26. STATIC_DCL void FDECL(mzapmsg, (struct monst *,struct obj *,BOOLEAN_P)); 27. STATIC_DCL void FDECL(mreadmsg, (struct monst *,struct obj *)); 28. STATIC_DCL void FDECL(mquaffmsg, (struct monst *,struct obj *)); 29. STATIC_PTR int FDECL(mbhitm, (struct monst *,struct obj *)); 30. STATIC_DCL void FDECL(mbhit, 31. (struct monst *,int,int FDECL((*),(MONST_P,OBJ_P)), 32. int FDECL((*),(OBJ_P,OBJ_P)),struct obj *)); 33. STATIC_DCL void FDECL(you_aggravate, (struct monst *)); 34. STATIC_DCL void FDECL(mon_consume_unstone, (struct monst *,struct obj *, 35. BOOLEAN_P,BOOLEAN_P)); 36. 37. static struct musable { 38. struct obj *offensive; 39. struct obj *defensive; 40. struct obj *misc; 41. int has_offense, has_defense, has_misc; 42. /* =0, no capability; otherwise, different numbers. 43. * If it's an object, the object is also set (it's 0 otherwise). 44. */ 45. } m; 46. static int trapx, trapy; 47. static boolean zap_oseen; 48. /* for wands which use mbhitm and are zapped at players. We usually 49. * want an oseen local to the function, but this is impossible since the 50. * function mbhitm has to be compatible with the normal zap routines, 51. * and those routines don't remember who zapped the wand. 52. */ 53. 54. /* Any preliminary checks which may result in the monster being unable to use 55. * the item. Returns 0 if nothing happened, 2 if the monster can't do anything 56. * (i.e. it teleported) and 1 if it's dead. 57. */ 58. STATIC_OVL int 59. precheck(mon, obj) 60. struct monst *mon; 61. struct obj *obj; 62. { 63. boolean vis; 64. 65. if (!obj) return 0; 66. vis = cansee(mon->mx, mon->my); 67. 68. if (obj->oclass == POTION_CLASS) { 69. coord cc; 70. static const char *empty = "The potion turns out to be empty."; 71. const char *potion_descr; 72. struct monst *mtmp; 73. #define POTION_OCCUPANT_CHANCE(n) (13 + 2*(n)) /* also in potion.c */ 74. 75. potion_descr = OBJ_DESCR(objects[obj->otyp]); 76. if (potion_descr && !strcmp(potion_descr, "milky")) { 77. if ( flags.ghost_count < MAXMONNO && 78. !rn2(POTION_OCCUPANT_CHANCE(flags.ghost_count))) { 79. if (!enexto(&cc, mon->mx, mon->my, &mons[PM_GHOST])) return 0; 80. mquaffmsg(mon, obj); 81. m_useup(mon, obj); 82. mtmp = makemon(&mons[PM_GHOST], cc.x, cc.y, NO_MM_FLAGS); 83. if (!mtmp) { 84. if (vis) pline(empty); 85. } else { 86. if (vis) { 87. pline("As %s opens the bottle, an enormous %s emerges!", 88. mon_nam(mon), 89. Hallucination ? rndmonnam() : (const char *)"ghost"); 90. pline("%s is frightened to death, and unable to move.", 91. Monnam(mon)); 92. } 93. mon->mcanmove = 0; 94. mon->mfrozen = 3; 95. } 96. return 2; 97. } 98. } 99. if (potion_descr && !strcmp(potion_descr, "smoky") && 100. flags.djinni_count < MAXMONNO && 101. !rn2(POTION_OCCUPANT_CHANCE(flags.djinni_count))) { 102. if (!enexto(&cc, mon->mx, mon->my, &mons[PM_DJINNI])) return 0; 103. mquaffmsg(mon, obj); 104. m_useup(mon, obj); 105. mtmp = makemon(&mons[PM_DJINNI], cc.x, cc.y, NO_MM_FLAGS); 106. if (!mtmp) { 107. if (vis) pline(empty); 108. } else { 109. if (vis) 110. pline("In a cloud of smoke, %s emerges!", 111. a_monnam(mtmp)); 112. pline("%s speaks.", vis ? Monnam(mtmp) : Something); 113. /* I suspect few players will be upset that monsters */ 114. /* can't wish for wands of death here.... */ 115. if (rn2(2)) { 116. verbalize("You freed me!"); 117. mtmp->mpeaceful = 1; 118. set_malign(mtmp); 119. } else { 120. verbalize("It is about time."); 121. if (vis) pline("%s vanishes.", Monnam(mtmp)); 122. mongone(mtmp); 123. } 124. } 125. return 2; 126. } 127. } 128. if (obj->oclass == WAND_CLASS && obj->cursed && !rn2(100)) { 129. int dam = d(obj->spe+2, 6); 130. 131. if (flags.soundok) { 132. if (vis) pline("%s zaps %s, which suddenly explodes!", 133. Monnam(mon), an(xname(obj))); 134. else You_hear("a zap and an explosion in the distance."); 135. } 136. m_useup(mon, obj); 137. if (mon->mhp <= dam) { 138. monkilled(mon, "", AD_RBRE); 139. return 1; 140. } 141. else mon->mhp -= dam; 142. m.has_defense = m.has_offense = m.has_misc = 0; 143. /* Only one needed to be set to 0 but the others are harmless */ 144. } 145. return 0; 146. } 147. 148. STATIC_OVL void 149. mzapmsg(mtmp, otmp, self) 150. struct monst *mtmp; 151. struct obj *otmp; 152. boolean self; 153. { 154. if (!canseemon(mtmp)) { 155. if (flags.soundok) 156. You_hear("a %s zap.", 157. (distu(mtmp->mx,mtmp->my) <= (BOLT_LIM+1)*(BOLT_LIM+1)) ? 158. "nearby" : "distant"); 159. } else if (self) 160. pline("%s zaps %sself with %s!", 161. Monnam(mtmp), mhim(mtmp), doname(otmp)); 162. else { 163. pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp))); 164. stop_occupation(); 165. } 166. } 167. 168. STATIC_OVL void 169. mreadmsg(mtmp, otmp) 170. struct monst *mtmp; 171. struct obj *otmp; 172. { 173. boolean vismon = canseemon(mtmp); 174. char onambuf[BUFSZ]; 175. short saverole; 176. unsigned savebknown; 177. 178. if (!vismon && !flags.soundok) 179. return; /* no feedback */ 180. 181. otmp->dknown = 1; /* seeing or hearing it read reveals its label */ 182. /* shouldn't be able to hear curse/bless status of unseen scrolls; 183. for priest characters, bknown will always be set during naming */ 184. savebknown = otmp->bknown; 185. saverole = Role_switch; 186. if (!vismon) { 187. otmp->bknown = 0; 188. if (Role_if(PM_PRIEST)) Role_switch = 0; 189. } 190. Strcpy(onambuf, singular(otmp, doname)); 191. Role_switch = saverole; 192. otmp->bknown = savebknown; 193. 194. if (vismon) 195. pline("%s reads %s!", Monnam(mtmp), onambuf); 196. else 197. You_hear("%s reading %s.", 198. x_monnam(mtmp, ARTICLE_A, (char *)0, 199. (SUPPRESS_IT|SUPPRESS_INVISIBLE|SUPPRESS_SADDLE), FALSE), 200. onambuf); 201. 202. if (mtmp->mconf) 203. pline("Being confused, %s mispronounces the magic words...", 204. vismon ? mon_nam(mtmp) : mhe(mtmp)); 205. } 206. 207. STATIC_OVL void 208. mquaffmsg(mtmp, otmp) 209. struct monst *mtmp; 210. struct obj *otmp; 211. { 212. if (canseemon(mtmp)) { 213. otmp->dknown = 1; 214. pline("%s drinks %s!", Monnam(mtmp), singular(otmp, doname)); 215. } else 216. if (flags.soundok) 217. You_hear("a chugging sound."); 218. } 219. 220. /* Defines for various types of stuff. The order in which monsters prefer 221. * to use them is determined by the order of the code logic, not the 222. * numerical order in which they are defined. 223. */ 224. #define MUSE_SCR_TELEPORTATION 1 225. #define MUSE_WAN_TELEPORTATION_SELF 2 226. #define MUSE_POT_HEALING 3 227. #define MUSE_POT_EXTRA_HEALING 4 228. #define MUSE_WAN_DIGGING 5 229. #define MUSE_TRAPDOOR 6 230. #define MUSE_TELEPORT_TRAP 7 231. #define MUSE_UPSTAIRS 8 232. #define MUSE_DOWNSTAIRS 9 233. #define MUSE_WAN_CREATE_MONSTER 10 234. #define MUSE_SCR_CREATE_MONSTER 11 235. #define MUSE_UP_LADDER 12 236. #define MUSE_DN_LADDER 13 237. #define MUSE_SSTAIRS 14 238. #define MUSE_WAN_TELEPORTATION 15 239. #define MUSE_BUGLE 16 240. #define MUSE_UNICORN_HORN 17 241. #define MUSE_POT_FULL_HEALING 18 242. #define MUSE_LIZARD_CORPSE 19 243. /* [Tom] my new items... */ 244. #define MUSE_WAN_HEALING 20 245. #define MUSE_WAN_EXTRA_HEALING 21 246. #define MUSE_WAN_CREATE_HORDE 22 247. #define MUSE_POT_VAMPIRE_BLOOD 23 248. /* 249. #define MUSE_INNATE_TPT 9999 250. * We cannot use this. Since monsters get unlimited teleportation, if they 251. * were allowed to teleport at will you could never catch them. Instead, 252. * assume they only teleport at random times, despite the inconsistency that if 253. * you polymorph into one you teleport at will. 254. */ 255. 256. /* Select a defensive item/action for a monster. Returns TRUE iff one is 257. * found. 258. */ 259. boolean 260. find_defensive(mtmp) 261. struct monst *mtmp; 262. { 263. register struct obj *obj = 0; 264. struct trap *t; 265. int x=mtmp->mx, y=mtmp->my; 266. boolean stuck = (mtmp == u.ustuck); 267. boolean immobile = (mtmp->data->mmove == 0); 268. int fraction; 269. 270. if (is_animal(mtmp->data) || mindless(mtmp->data)) 271. return FALSE; 272. if(dist2(x, y, mtmp->mux, mtmp->muy) > 25) 273. return FALSE; 274. if (u.uswallow && stuck) return FALSE; 275. 276. m.defensive = (struct obj *)0; 277. m.has_defense = 0; 278. 279. /* since unicorn horns don't get used up, the monster would look 280. * silly trying to use the same cursed horn round after round 281. */ 282. if (mtmp->mconf || mtmp->mstun || !mtmp->mcansee) { 283. if (!is_unicorn(mtmp->data) && !nohands(mtmp->data)) { 284. for(obj = mtmp->minvent; obj; obj = obj->nobj) 285. if (obj->otyp == UNICORN_HORN && !obj->cursed) 286. break; 287. } 288. if (obj || is_unicorn(mtmp->data)) { 289. m.defensive = obj; 290. m.has_defense = MUSE_UNICORN_HORN; 291. return TRUE; 292. } 293. } 294. 295. if (mtmp->mconf) { 296. for(obj = mtmp->minvent; obj; obj = obj->nobj) { 297. if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD) { 298. m.defensive = obj; 299. m.has_defense = MUSE_LIZARD_CORPSE; 300. return TRUE; 301. } 302. } 303. } 304. 305. /* It so happens there are two unrelated cases when we might want to 306. * check specifically for healing alone. The first is when the monster 307. * is blind (healing cures blindness). The second is when the monster 308. * is peaceful; then we don't want to flee the player, and by 309. * coincidence healing is all there is that doesn't involve fleeing. 310. * These would be hard to combine because of the control flow. 311. * Pestilence won't use healing even when blind. 312. */ 313. if (!mtmp->mcansee && !nohands(mtmp->data) && 314. mtmp->data != &mons[PM_PESTILENCE]) { 315. if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) { 316. m.defensive = obj; 317. m.has_defense = MUSE_POT_FULL_HEALING; 318. return TRUE; 319. } 320. if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) { 321. m.defensive = obj; 322. m.has_defense = MUSE_POT_EXTRA_HEALING; 323. return TRUE; 324. } 325. if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) { 326. m.defensive = obj; 327. m.has_defense = MUSE_POT_HEALING; 328. return TRUE; 329. } 330. if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) !=0) { 331. m.defensive = obj; 332. m.has_defense = MUSE_POT_FULL_HEALING; 333. return TRUE; 334. } 335. } 336. 337. fraction = u.ulevel < 10 ? 5 : u.ulevel < 14 ? 4 : 3; 338. if(mtmp->mhp >= mtmp->mhpmax || 339. (mtmp->mhp >= 10 && mtmp->mhp*fraction >= mtmp->mhpmax)) 340. return FALSE; 341. 342. if (mtmp->mpeaceful) { 343. if (!nohands(mtmp->data)) { 344. if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) { 345. m.defensive = obj; 346. m.has_defense = MUSE_POT_FULL_HEALING; 347. return TRUE; 348. } 349. if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) { 350. m.defensive = obj; 351. m.has_defense = MUSE_POT_EXTRA_HEALING; 352. return TRUE; 353. } 354. if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) { 355. m.defensive = obj; 356. m.has_defense = MUSE_POT_HEALING; 357. return TRUE; 358. } 359. if (is_vampire(mtmp->data) && 360. (obj = m_carrying(mtmp, POT_VAMPIRE_BLOOD)) !=0) { 361. m.defensive = obj; 362. m.has_defense = MUSE_POT_VAMPIRE_BLOOD; 363. return TRUE; 364. } 365. } 366. return FALSE; 367. } 368. 369. if (levl[x][y].typ == STAIRS && !stuck && !immobile) { 370. if (x == xdnstair && y == ydnstair && !is_floater(mtmp->data)) 371. m.has_defense = MUSE_DOWNSTAIRS; 372. if (x == xupstair && y == yupstair && ledger_no(&u.uz) != 1) 373. /* Unfair to let the monsters leave the dungeon with the Amulet */ 374. /* (or go to the endlevel since you also need it, to get there) */ 375. m.has_defense = MUSE_UPSTAIRS; 376. } else if (levl[x][y].typ == LADDER && !stuck && !immobile) { 377. if (x == xupladder && y == yupladder) 378. m.has_defense = MUSE_UP_LADDER; 379. if (x == xdnladder && y == ydnladder && !is_floater(mtmp->data)) 380. m.has_defense = MUSE_DN_LADDER; 381. } else if (sstairs.sx && sstairs.sx == x && sstairs.sy == y) { 382. m.has_defense = MUSE_SSTAIRS; 383. } else if (!stuck && !immobile) { 384. /* Note: trap doors take precedence over teleport traps. */ 385. int xx, yy; 386. 387. for(xx = x-1; xx <= x+1; xx++) for(yy = y-1; yy <= y+1; yy++) 388. if (isok(xx,yy)) 389. if (xx != u.ux && yy != u.uy) 390. if (mtmp->data != &mons[PM_GRID_BUG] || xx == x || yy == y) 391. if ((xx==x && yy==y) || !level.monsters[xx][yy]) 392. if ((t = t_at(xx,yy)) != 0) 393. if ((verysmall(mtmp->data) || throws_rocks(mtmp->data) || 394. passes_walls(mtmp->data)) || !sobj_at(BOULDER, xx, yy)) 395. if (!onscary(xx,yy,mtmp)) { 396. if ((t->ttyp == TRAPDOOR || t->ttyp == HOLE) 397. && !is_floater(mtmp->data) 398. && !mtmp->isshk && !mtmp->isgd 399. && !mtmp->ispriest 400. && Can_fall_thru(&u.uz) 401. ) { 402. trapx = xx; 403. trapy = yy; 404. m.has_defense = MUSE_TRAPDOOR; 405. } else if (t->ttyp == TELEP_TRAP && m.has_defense != MUSE_TRAPDOOR) { 406. trapx = xx; 407. trapy = yy; 408. m.has_defense = MUSE_TELEPORT_TRAP; 409. } 410. } 411. } 412. 413. if (nohands(mtmp->data)) /* can't use objects */ 414. goto botm; 415. 416. if (is_mercenary(mtmp->data) && (obj = m_carrying(mtmp, BUGLE))) { 417. int xx, yy; 418. struct monst *mon; 419. 420. /* Distance is arbitrary. What we really want to do is 421. * have the soldier play the bugle when it sees or 422. * remembers soldiers nearby... 423. */ 424. for(xx = x-3; xx <= x+3; xx++) for(yy = y-3; yy <= y+3; yy++) 425. if (isok(xx,yy)) 426. if ((mon = m_at(xx,yy)) && is_mercenary(mon->data) && 427. mon->data != &mons[PM_GUARD] && 428. (mon->msleeping || (!mon->mcanmove))) { 429. m.defensive = obj; 430. m.has_defense = MUSE_BUGLE; 431. } 432. } 433. 434. /* use immediate physical escape prior to attempting magic */ 435. if (m.has_defense) /* stairs, trap door or tele-trap, bugle alert */ 436. goto botm; 437. 438. /* kludge to cut down on trap destruction (particularly portals) */ 439. t = t_at(x,y); 440. if (t && (t->ttyp == PIT || t->ttyp == SPIKED_PIT || 441. t->ttyp == WEB || t->ttyp == BEAR_TRAP)) 442. t = 0; /* ok for monster to dig here */ 443. 444. #define nomore(x) if(m.has_defense==x) continue; 445. for (obj = mtmp->minvent; obj; obj = obj->nobj) { 446. /* don't always use the same selection pattern */ 447. if (m.has_defense && !rn2(3)) break; 448. 449. /* nomore(MUSE_WAN_DIGGING); */ 450. if (m.has_defense == MUSE_WAN_DIGGING) break; 451. if (obj->otyp == WAN_DIGGING && obj->spe > 0 && !stuck && !t 452. && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest 453. && !is_floater(mtmp->data) 454. /* monsters digging in Sokoban can ruin things */ 455. && !In_sokoban(&u.uz) 456. /* digging wouldn't be effective; assume they know that */ 457. && !(levl[x][y].wall_info & W_NONDIGGABLE) 458. && !(Is_botlevel(&u.uz) || In_endgame(&u.uz)) 459. && !(is_ice(x,y) || is_pool(x,y) || is_lava(x,y)) 460. && !(mtmp->data == &mons[PM_VLAD_THE_IMPALER] 461. && In_V_tower(&u.uz))) { 462. m.defensive = obj; 463. m.has_defense = MUSE_WAN_DIGGING; 464. } 465. nomore(MUSE_WAN_TELEPORTATION_SELF); 466. nomore(MUSE_WAN_TELEPORTATION); 467. if(obj->otyp == WAN_TELEPORTATION && obj->spe > 0) { 468. /* use the TELEP_TRAP bit to determine if they know 469. * about noteleport on this level or not. Avoids 470. * ineffective re-use of teleportation. This does 471. * mean if the monster leaves the level, they'll know 472. * about teleport traps. 473. */ 474. if (!level.flags.noteleport || 475. !(mtmp->mtrapseen & (1 << (TELEP_TRAP-1)))) { 476. m.defensive = obj; 477. m.has_defense = (mon_has_amulet(mtmp)) 478. ? MUSE_WAN_TELEPORTATION 479. : MUSE_WAN_TELEPORTATION_SELF; 480. } 481. } 482. nomore(MUSE_SCR_TELEPORTATION); 483. if(obj->otyp == SCR_TELEPORTATION && mtmp->mcansee 484. && haseyes(mtmp->data) 485. && (!obj->cursed || 486. (!(mtmp->isshk && inhishop(mtmp)) 487. && !mtmp->isgd && !mtmp->ispriest))) { 488. /* see WAN_TELEPORTATION case above */ 489. if (!level.flags.noteleport || 490. !(mtmp->mtrapseen & (1 << (TELEP_TRAP-1)))) { 491. m.defensive = obj; 492. m.has_defense = MUSE_SCR_TELEPORTATION; 493. } 494. } 495. 496. if (mtmp->data != &mons[PM_PESTILENCE]) { 497. nomore(MUSE_POT_FULL_HEALING); 498. if(obj->otyp == POT_FULL_HEALING) { 499. m.defensive = obj; 500. m.has_defense = MUSE_POT_FULL_HEALING; 501. } 502. nomore(MUSE_POT_EXTRA_HEALING); 503. if(obj->otyp == POT_EXTRA_HEALING) { 504. m.defensive = obj; 505. m.has_defense = MUSE_POT_EXTRA_HEALING; 506. } 507. nomore(MUSE_WAN_CREATE_MONSTER); 508. if(obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) { 509. m.defensive = obj; 510. m.has_defense = MUSE_WAN_CREATE_MONSTER; 511. } 512. nomore(MUSE_WAN_CREATE_HORDE); 513. if(obj->otyp == WAN_CREATE_HORDE && obj->spe > 0) { 514. m.defensive = obj; 515. m.has_defense = MUSE_WAN_CREATE_HORDE; 516. } 517. nomore(MUSE_POT_HEALING); 518. if(obj->otyp == POT_HEALING) { 519. m.defensive = obj; 520. m.has_defense = MUSE_POT_HEALING; 521. } 522. nomore(MUSE_WAN_HEALING); 523. if(obj->otyp == WAN_HEALING && obj->spe > 0) { 524. m.defensive = obj; 525. m.has_defense = MUSE_WAN_HEALING; 526. } 527. nomore(MUSE_WAN_EXTRA_HEALING); 528. if(obj->otyp == WAN_EXTRA_HEALING && obj->spe > 0) { 529. m.defensive = obj; 530. m.has_defense = MUSE_WAN_EXTRA_HEALING; 531. } 532. nomore(MUSE_POT_VAMPIRE_BLOOD); 533. if(is_vampire(mtmp->data) && obj->otyp == POT_VAMPIRE_BLOOD) { 534. m.defensive = obj; 535. m.has_defense = MUSE_POT_VAMPIRE_BLOOD; 536. } 537. } else { /* Pestilence */ 538. nomore(MUSE_POT_FULL_HEALING); 539. if (obj->otyp == POT_SICKNESS) { 540. m.defensive = obj; 541. m.has_defense = MUSE_POT_FULL_HEALING; 542. } 543. nomore(MUSE_WAN_CREATE_MONSTER); 544. if (obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) { 545. m.defensive = obj; 546. m.has_defense = MUSE_WAN_CREATE_MONSTER; 547. } 548. } 549. nomore(MUSE_SCR_CREATE_MONSTER); 550. if(obj->otyp == SCR_CREATE_MONSTER) { 551. m.defensive = obj; 552. m.has_defense = MUSE_SCR_CREATE_MONSTER; 553. } 554. } 555. botm: return((boolean)(!!m.has_defense)); 556. #undef nomore 557. } 558. 559. /* Perform a defensive action for a monster. Must be called immediately 560. * after find_defensive(). Return values are 0: did something, 1: died, 561. * 2: did something and can't attack again (i.e. teleported). 562. */ 563. int 564. use_defensive(mtmp) 565. struct monst *mtmp; 566. { 567. int i, fleetim, how = 0; 568. struct obj *otmp = m.defensive; 569. boolean vis, vismon, oseen; 570. const char *mcsa = "%s can see again."; 571. 572. if ((i = precheck(mtmp, otmp)) != 0) return i; 573. vis = cansee(mtmp->mx, mtmp->my); 574. vismon = canseemon(mtmp); 575. oseen = otmp && vismon; 576. 577. /* when using defensive choice to run away, we want monster to avoid 578. rushing right straight back; don't override if already scared */ 579. fleetim = !mtmp->mflee ? (33 - (30 * mtmp->mhp / mtmp->mhpmax)) : 0; 580. #define m_flee(m) if (fleetim && !m->iswiz) \ 581. { monflee(m, fleetim, FALSE, FALSE); } 582. 583. switch(m.has_defense) { 584. case MUSE_UNICORN_HORN: 585. if (vismon) { 586. if (otmp) 587. pline("%s uses a unicorn horn!", Monnam(mtmp)); 588. else 589. pline_The("tip of %s's horn glows!", mon_nam(mtmp)); 590. } 591. if (!mtmp->mcansee) { 592. mtmp->mcansee = 1; 593. mtmp->mblinded = 0; 594. if (vismon) pline(mcsa, Monnam(mtmp)); 595. } else if (mtmp->mconf || mtmp->mstun) { 596. mtmp->mconf = mtmp->mstun = 0; 597. if (vismon) 598. pline("%s seems steadier now.", Monnam(mtmp)); 599. } else impossible("No need for unicorn horn?"); 600. return 2; 601. case MUSE_BUGLE: 602. if (vismon) 603. pline("%s plays %s!", Monnam(mtmp), doname(otmp)); 604. else if (flags.soundok) 605. You_hear("a bugle playing reveille!"); 606. awaken_soldiers(); 607. return 2; 608. case MUSE_WAN_TELEPORTATION_SELF: 609. if ((mtmp->isshk && inhishop(mtmp)) 610. || mtmp->isgd || mtmp->ispriest) return 2; 611. m_flee(mtmp); 612. mzapmsg(mtmp, otmp, TRUE); 613. otmp->spe--; 614. how = WAN_TELEPORTATION; 615. mon_tele: 616. if (tele_restrict(mtmp)) { /* mysterious force... */ 617. if (vismon && how) /* mentions 'teleport' */ 618. makeknown(how); 619. /* monster learns that teleportation isn't useful here */ 620. if (level.flags.noteleport) 621. mtmp->mtrapseen |= (1 << (TELEP_TRAP-1)); 622. return 2; 623. } 624. if (( 625. #if 0 626. mon_has_amulet(mtmp) || 627. #endif 628. On_W_tower_level(&u.uz)) && !rn2(3)) { 629. if (vismon) 630. pline("%s seems disoriented for a moment.", 631. Monnam(mtmp)); 632. return 2; 633. } 634. if (oseen && how) makeknown(how); 635. (void) rloc(mtmp, FALSE); 636. return 2; 637. case MUSE_WAN_TELEPORTATION: 638. zap_oseen = oseen; 639. mzapmsg(mtmp, otmp, FALSE); 640. otmp->spe--; 641. m_using = TRUE; 642. mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp); 643. /* monster learns that teleportation isn't useful here */ 644. if (level.flags.noteleport) 645. mtmp->mtrapseen |= (1 << (TELEP_TRAP-1)); 646. m_using = FALSE; 647. return 2; 648. case MUSE_SCR_TELEPORTATION: 649. { 650. int obj_is_cursed = otmp->cursed; 651. 652. if (mtmp->isshk || mtmp->isgd || mtmp->ispriest) return 2; 653. m_flee(mtmp); 654. mreadmsg(mtmp, otmp); 655. m_useup(mtmp, otmp); /* otmp might be free'ed */ 656. how = SCR_TELEPORTATION; 657. if (obj_is_cursed || mtmp->mconf) { 658. int nlev; 659. d_level flev; 660. 661. if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) { 662. if (vismon) 663. pline("%s seems very disoriented for a moment.", 664. Monnam(mtmp)); 665. return 2; 666. } 667. nlev = random_teleport_level(); 668. if (nlev == depth(&u.uz)) { 669. if (vismon) 670. pline("%s shudders for a moment.", 671. Monnam(mtmp)); 672. return 2; 673. } 674. get_level(&flev, nlev); 675. migrate_to_level(mtmp, ledger_no(&flev), MIGR_RANDOM, 676. (coord *)0); 677. if (oseen) makeknown(SCR_TELEPORTATION); 678. } else goto mon_tele; 679. return 2; 680. } 681. case MUSE_WAN_DIGGING: 682. { struct trap *ttmp; 683. 684. m_flee(mtmp); 685. mzapmsg(mtmp, otmp, FALSE); 686. otmp->spe--; 687. if (oseen) makeknown(WAN_DIGGING); 688. if (IS_FURNITURE(levl[mtmp->mx][mtmp->my].typ) || 689. IS_DRAWBRIDGE(levl[mtmp->mx][mtmp->my].typ) || 690. (is_drawbridge_wall(mtmp->mx, mtmp->my) >= 0) || 691. (sstairs.sx && sstairs.sx == mtmp->mx && 692. sstairs.sy == mtmp->my)) { 693. pline_The("digging ray is ineffective."); 694. return 2; 695. } 696. if (!Can_dig_down(&u.uz)) { 697. if(canseemon(mtmp)) 698. pline_The("%s here is too hard to dig in.", 699. surface(mtmp->mx, mtmp->my)); 700. return 2; 701. } 702. ttmp = maketrap(mtmp->mx, mtmp->my, HOLE); 703. if (!ttmp) return 2; 704. seetrap(ttmp); 705. if (vis) { 706. pline("%s has made a hole in the %s.", Monnam(mtmp), 707. surface(mtmp->mx, mtmp->my)); 708. pline("%s %s through...", Monnam(mtmp), 709. is_flyer(mtmp->data) ? "dives" : "falls"); 710. } else if (flags.soundok) 711. You_hear("%s crash through the %s.", something, 712. surface(mtmp->mx, mtmp->my)); 713. /* we made sure that there is a level for mtmp to go to */ 714. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 715. MIGR_RANDOM, (coord *)0); 716. return 2; 717. } 718. case MUSE_WAN_CREATE_HORDE: 719. { coord cc; 720. struct permonst *pm=rndmonst(); 721. int cnt = 1; 722. if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) return 0; 723. mzapmsg(mtmp, otmp, FALSE); 724. otmp->spe--; 725. if (oseen) makeknown(WAN_CREATE_HORDE); 726. cnt = rnd(4) + 10; 727. while(cnt--) { 728. struct monst *mon; 729. if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) continue; 730. mon = makemon(rndmonst(), cc.x, cc.y, NO_MM_FLAGS); 731. if (mon) newsym(mon->mx,mon->my); 732. } 733. return 2; 734. } 735. case MUSE_WAN_CREATE_MONSTER: 736. { coord cc; 737. /* pm: 0 => random, eel => aquatic, croc => amphibious */ 738. struct permonst *pm = !is_pool(mtmp->mx, mtmp->my) ? 0 : 739. &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE]; 740. struct monst *mon; 741. 742. if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) return 0; 743. mzapmsg(mtmp, otmp, FALSE); 744. otmp->spe--; 745. mon = makemon((struct permonst *)0, cc.x, cc.y, NO_MM_FLAGS); 746. if (mon && canspotmon(mon) && oseen) 747. makeknown(WAN_CREATE_MONSTER); 748. return 2; 749. } 750. case MUSE_SCR_CREATE_MONSTER: 751. { coord cc; 752. struct permonst *pm = 0, *fish = 0; 753. int cnt = 1; 754. struct monst *mon; 755. boolean known = FALSE; 756. 757. if (!rn2(73)) cnt += rnd(4); 758. if (mtmp->mconf || otmp->cursed) cnt += 12; 759. if (mtmp->mconf) pm = fish = &mons[PM_ACID_BLOB]; 760. else if (is_pool(mtmp->mx, mtmp->my)) 761. fish = &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE]; 762. mreadmsg(mtmp, otmp); 763. while(cnt--) { 764. /* `fish' potentially gives bias towards water locations; 765. `pm' is what to actually create (0 => random) */ 766. if (!enexto(&cc, mtmp->mx, mtmp->my, fish)) break; 767. mon = makemon(pm, cc.x, cc.y, NO_MM_FLAGS); 768. if (mon && canspotmon(mon)) known = TRUE; 769. } 770. /* The only case where we don't use oseen. For wands, you 771. * have to be able to see the monster zap the wand to know 772. * what type it is. For teleport scrolls, you have to see 773. * the monster to know it teleported. 774. */ 775. if (known) 776. makeknown(SCR_CREATE_MONSTER); 777. else if (!objects[SCR_CREATE_MONSTER].oc_name_known 778. && !objects[SCR_CREATE_MONSTER].oc_uname) 779. docall(otmp); 780. m_useup(mtmp, otmp); 781. return 2; 782. } 783. case MUSE_TRAPDOOR: 784. /* trap doors on "bottom" levels of dungeons are rock-drop 785. * trap doors, not holes in the floor. We check here for 786. * safety. 787. */ 788. if (Is_botlevel(&u.uz)) return 0; 789. m_flee(mtmp); 790. if (vis) { 791. struct trap *t; 792. t = t_at(trapx,trapy); 793. pline("%s %s into a %s!", Monnam(mtmp), 794. makeplural(locomotion(mtmp->data, "jump")), 795. t->ttyp == TRAPDOOR ? "trap door" : "hole"); 796. if (levl[trapx][trapy].typ == SCORR) { 797. levl[trapx][trapy].typ = CORR; 798. unblock_point(trapx, trapy); 799. } 800. seetrap(t_at(trapx,trapy)); 801. } 802. 803. /* don't use rloc_to() because worm tails must "move" */ 804. remove_monster(mtmp->mx, mtmp->my); 805. newsym(mtmp->mx, mtmp->my); /* update old location */ 806. place_monster(mtmp, trapx, trapy); 807. if (mtmp->wormno) worm_move(mtmp); 808. newsym(trapx, trapy); 809. 810. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 811. MIGR_RANDOM, (coord *)0); 812. return 2; 813. case MUSE_UPSTAIRS: 814. /* Monsters without amulets escape the dungeon and are 815. * gone for good when they leave up the up stairs. 816. * Monsters with amulets would reach the endlevel, 817. * which we cannot allow since that would leave the 818. * player stranded. 819. */ 820. if (ledger_no(&u.uz) == 1) { 821. if (mon_has_special(mtmp)) 822. return 0; 823. if (vismon) 824. pline("%s escapes the dungeon!", Monnam(mtmp)); 825. mongone(mtmp); 826. return 2; 827. } 828. m_flee(mtmp); 829. if (Inhell && mon_has_amulet(mtmp) && !rn2(4) && 830. (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) { 831. if (vismon) pline( 832. "As %s climbs the stairs, a mysterious force momentarily surrounds %s...", 833. mon_nam(mtmp), mhim(mtmp)); 834. /* simpler than for the player; this will usually be 835. the Wizard and he'll immediately go right to the 836. upstairs, so there's not much point in having any 837. chance for a random position on the current level */ 838. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 839. MIGR_RANDOM, (coord *)0); 840. } else { 841. if (vismon) pline("%s escapes upstairs!", Monnam(mtmp)); 842. migrate_to_level(mtmp, ledger_no(&u.uz) - 1, 843. MIGR_STAIRS_DOWN, (coord *)0); 844. } 845. return 2; 846. case MUSE_DOWNSTAIRS: 847. m_flee(mtmp); 848. if (vismon) pline("%s escapes downstairs!", Monnam(mtmp)); 849. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 850. MIGR_STAIRS_UP, (coord *)0); 851. return 2; 852. case MUSE_UP_LADDER: 853. m_flee(mtmp); 854. if (vismon) pline("%s escapes up the ladder!", Monnam(mtmp)); 855. migrate_to_level(mtmp, ledger_no(&u.uz) - 1, 856. MIGR_LADDER_DOWN, (coord *)0); 857. return 2; 858. case MUSE_DN_LADDER: 859. m_flee(mtmp); 860. if (vismon) pline("%s escapes down the ladder!", Monnam(mtmp)); 861. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 862. MIGR_LADDER_UP, (coord *)0); 863. return 2; 864. case MUSE_SSTAIRS: 865. m_flee(mtmp); 866. /* the stairs leading up from the 1st level are */ 867. /* regular stairs, not sstairs. */ 868. if (sstairs.up) { 869. if (vismon) 870. pline("%s escapes upstairs!", Monnam(mtmp)); 871. if(Inhell) { 872. migrate_to_level(mtmp, ledger_no(&sstairs.tolev), 873. MIGR_RANDOM, (coord *)0); 874. return 2; 875. } 876. } else if (vismon) 877. pline("%s escapes downstairs!", Monnam(mtmp)); 878. migrate_to_level(mtmp, ledger_no(&sstairs.tolev), 879. MIGR_SSTAIRS, (coord *)0); 880. return 2; 881. case MUSE_TELEPORT_TRAP: 882. m_flee(mtmp); 883. if (vis) { 884. pline("%s %s onto a teleport trap!", Monnam(mtmp), 885. makeplural(locomotion(mtmp->data, "jump"))); 886. if (levl[trapx][trapy].typ == SCORR) { 887. levl[trapx][trapy].typ = CORR; 888. unblock_point(trapx, trapy); 889. } 890. seetrap(t_at(trapx,trapy)); 891. } 892. /* don't use rloc_to() because worm tails must "move" */ 893. remove_monster(mtmp->mx, mtmp->my); 894. newsym(mtmp->mx, mtmp->my); /* update old location */ 895. place_monster(mtmp, trapx, trapy); 896. if (mtmp->wormno) worm_move(mtmp); 897. newsym(trapx, trapy); 898. 899. goto mon_tele; 900. /* [Tom] */ 901. case MUSE_WAN_HEALING: 902. mzapmsg(mtmp, otmp, TRUE); 903. otmp->spe--; 904. i = d(5,2) + 5 * !!bcsign(otmp); 905. mtmp->mhp += i; 906. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = ++mtmp->mhpmax; 907. if (!otmp->cursed) mtmp->mcansee = 1; 908. if (vismon) pline("%s begins to look better.", Monnam(mtmp)); 909. if (oseen) makeknown(WAN_HEALING); 910. return 2; 911. case MUSE_WAN_EXTRA_HEALING: 912. mzapmsg(mtmp, otmp, TRUE); 913. otmp->spe--; 914. i = d(5,4) + 10 * !!bcsign(otmp); 915. mtmp->mhp += i; 916. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = ++mtmp->mhpmax; 917. if (!otmp->cursed) mtmp->mcansee = 1; 918. if (vismon) pline("%s begins to look better.", Monnam(mtmp)); 919. if (oseen) makeknown(WAN_EXTRA_HEALING); 920. return 2; 921. case MUSE_POT_HEALING: 922. mquaffmsg(mtmp, otmp); 923. i = d(6 + 2 * bcsign(otmp), 4); 924. mtmp->mhp += i; 925. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = ++mtmp->mhpmax; 926. if (!otmp->cursed && !mtmp->mcansee) { 927. mtmp->mcansee = 1; 928. mtmp->mblinded = 0; 929. if (vismon) pline(mcsa, Monnam(mtmp)); 930. } 931. if (vismon) pline("%s looks better.", Monnam(mtmp)); 932. if (oseen) makeknown(POT_HEALING); 933. m_useup(mtmp, otmp); 934. return 2; 935. case MUSE_POT_EXTRA_HEALING: 936. mquaffmsg(mtmp, otmp); 937. i = d(6 + 2 * bcsign(otmp), 8); 938. mtmp->mhp += i; 939. if (mtmp->mhp > mtmp->mhpmax) 940. mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2)); 941. if (!mtmp->mcansee) { 942. mtmp->mcansee = 1; 943. mtmp->mblinded = 0; 944. if (vismon) pline(mcsa, Monnam(mtmp)); 945. } 946. if (vismon) pline("%s looks much better.", Monnam(mtmp)); 947. if (oseen) makeknown(POT_EXTRA_HEALING); 948. m_useup(mtmp, otmp); 949. return 2; 950. case MUSE_POT_FULL_HEALING: 951. mquaffmsg(mtmp, otmp); 952. if (otmp->otyp == POT_SICKNESS) unbless(otmp); /* Pestilence */ 953. mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 8 : 4)); 954. if (!mtmp->mcansee && otmp->otyp != POT_SICKNESS) { 955. mtmp->mcansee = 1; 956. mtmp->mblinded = 0; 957. if (vismon) pline(mcsa, Monnam(mtmp)); 958. } 959. if (vismon) pline("%s looks completely healed.", Monnam(mtmp)); 960. if (oseen) makeknown(otmp->otyp); 961. m_useup(mtmp, otmp); 962. return 2; 963. case MUSE_POT_VAMPIRE_BLOOD: 964. mquaffmsg(mtmp, otmp); 965. if (!otmp->cursed) { 966. i = rnd(8) + rnd(2); 967. mtmp->mhp += i; 968. mtmp->mhpmax += i; 969. if (vismon) pline("%s looks full of life.", Monnam(mtmp)); 970. } 971. else if (vismon) 972. pline("%s discards the congealed blood in disgust.", Monnam(mtmp)); 973. if (oseen) makeknown(POT_VAMPIRE_BLOOD); 974. m_useup(mtmp, otmp); 975. return 2; 976. case MUSE_LIZARD_CORPSE: 977. /* not actually called for its unstoning effect */ 978. mon_consume_unstone(mtmp, otmp, FALSE, FALSE); 979. return 2; 980. case 0: return 0; /* i.e. an exploded wand */ 981. default: impossible("%s wanted to perform action %d?", Monnam(mtmp), 982. m.has_defense); 983. break; 984. } 985. return 0; 986. #undef m_flee 987. } 988. 989. int 990. rnd_defensive_item(mtmp) 991. struct monst *mtmp; 992. { 993. struct permonst *pm = mtmp->data; 994. int difficulty = monstr[(monsndx(pm))]; 995. int trycnt = 0; 996. 997. if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data) 998. || pm->mlet == S_GHOST 999. # ifdef KOPS 1000. || pm->mlet == S_KOP 1001. # endif 1002. ) return 0; 1003. try_again: 1004. switch (rn2(8 + (difficulty > 3) + (difficulty > 6) + 1005. (difficulty > 8))) { 1006. case 6: case 9: 1007. if (level.flags.noteleport && ++trycnt < 2) 1008. goto try_again; 1009. if (!rn2(3)) return WAN_TELEPORTATION; 1010. /* else FALLTHRU */ 1011. case 0: case 1: 1012. return SCR_TELEPORTATION; 1013. case 8: case 10: 1014. if (!rn2(3)) return WAN_CREATE_MONSTER; 1015. /* else FALLTHRU */ 1016. case 2: return SCR_CREATE_MONSTER; 1017. case 3: return POT_HEALING; 1018. case 4: return POT_EXTRA_HEALING; 1019. case 5: return (mtmp->data != &mons[PM_PESTILENCE]) ? 1020. POT_FULL_HEALING : POT_SICKNESS; 1021. case 7: if (is_floater(pm) || mtmp->isshk || mtmp->isgd 1022. || mtmp->ispriest 1023. ) 1024. return 0; 1025. else 1026. return WAN_DIGGING; 1027. } 1028. /*NOTREACHED*/ 1029. return 0; 1030. } 1031. 1032. #define MUSE_WAN_DEATH 1 1033. #define MUSE_WAN_SLEEP 2 1034. #define MUSE_WAN_FIREBALL 3 1035. #define MUSE_WAN_FIRE 4 1036. #define MUSE_WAN_COLD 5 1037. #define MUSE_WAN_LIGHTNING 6 1038. #define MUSE_WAN_MAGIC_MISSILE 7 1039. #define MUSE_WAN_STRIKING 8 1040. #define MUSE_SCR_FIRE 9 1041. #define MUSE_POT_PARALYSIS 10 1042. #define MUSE_POT_BLINDNESS 11 1043. #define MUSE_POT_CONFUSION 12 1044. #define MUSE_POT_SLEEPING 13 1045. #define MUSE_POT_ACID 14 1046. #define MUSE_FROST_HORN 15 1047. #define MUSE_FIRE_HORN 16 1048. #define MUSE_WAN_DRAINING 17 /* KMH */ 1049. /*#define MUSE_WAN_TELEPORTATION 18*/ 1050. #define MUSE_SCR_EARTH 19 1051. #define MUSE_POT_AMNESIA 20 1052. #define MUSE_WAN_CANCELLATION 21 /* Lethe */ 1053. 1054. /* Select an offensive item/action for a monster. Returns TRUE iff one is 1055. * found. 1056. */ 1057. boolean 1058. find_offensive(mtmp) 1059. struct monst *mtmp; 1060. { 1061. register struct obj *obj; 1062. boolean ranged_stuff = lined_up(mtmp); 1063. boolean reflection_skip = (Reflecting && rn2(2)); 1064. struct obj *helmet = which_armor(mtmp, W_ARMH); 1065. 1066. m.offensive = (struct obj *)0; 1067. m.has_offense = 0; 1068. if (mtmp->mpeaceful || is_animal(mtmp->data) || 1069. mindless(mtmp->data) || nohands(mtmp->data)) 1070. return FALSE; 1071. if (u.uswallow) return FALSE; 1072. if (in_your_sanctuary(mtmp, 0, 0)) return FALSE; 1073. if (dmgtype(mtmp->data, AD_HEAL) && !uwep 1074. #ifdef TOURIST 1075. && !uarmu 1076. #endif 1077. && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) 1078. return FALSE; 1079. 1080. if (!ranged_stuff) return FALSE; 1081. #define nomore(x) if(m.has_offense==x) continue; 1082. for(obj=mtmp->minvent; obj; obj=obj->nobj) { 1083. /* nomore(MUSE_WAN_DEATH); */ 1084. if (!reflection_skip) { 1085. if(obj->otyp == WAN_DEATH && obj->spe > 0) { 1086. m.offensive = obj; 1087. m.has_offense = MUSE_WAN_DEATH; 1088. } 1089. nomore(MUSE_WAN_SLEEP); 1090. if(obj->otyp == WAN_SLEEP && obj->spe > 0 && multi >= 0) { 1091. m.offensive = obj; 1092. m.has_offense = MUSE_WAN_SLEEP; 1093. } 1094. /*WAC fixed*/ 1095. /* [Tom] doesn't work...*/ 1096. 1097. nomore(MUSE_WAN_FIREBALL); 1098. if(obj->otyp == WAN_FIREBALL && obj->spe > 0) { 1099. m.offensive = obj; 1100. m.has_offense = MUSE_WAN_FIREBALL; 1101. } 1102. nomore(MUSE_WAN_FIRE); 1103. if(obj->otyp == WAN_FIRE && obj->spe > 0) { 1104. m.offensive = obj; 1105. m.has_offense = MUSE_WAN_FIRE; 1106. } 1107. nomore(MUSE_FIRE_HORN); 1108. if(obj->otyp == FIRE_HORN && obj->spe > 0) { 1109. m.offensive = obj; 1110. m.has_offense = MUSE_FIRE_HORN; 1111. } 1112. nomore(MUSE_WAN_COLD); 1113. if(obj->otyp == WAN_COLD && obj->spe > 0) { 1114. m.offensive = obj; 1115. m.has_offense = MUSE_WAN_COLD; 1116. } 1117. nomore(MUSE_FROST_HORN); 1118. if(obj->otyp == FROST_HORN && obj->spe > 0) { 1119. m.offensive = obj; 1120. m.has_offense = MUSE_FROST_HORN; 1121. } 1122. nomore(MUSE_WAN_LIGHTNING); 1123. if(obj->otyp == WAN_LIGHTNING && obj->spe > 0) { 1124. m.offensive = obj; 1125. m.has_offense = MUSE_WAN_LIGHTNING; 1126. } 1127. nomore(MUSE_WAN_MAGIC_MISSILE); 1128. if(obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) { 1129. m.offensive = obj; 1130. m.has_offense = MUSE_WAN_MAGIC_MISSILE; 1131. } 1132. } 1133. nomore(MUSE_WAN_DRAINING); 1134. if(obj->otyp == WAN_DRAINING && obj->spe > 0) { 1135. m.offensive = obj; 1136. m.has_offense = MUSE_WAN_DRAINING; 1137. } 1138. nomore(MUSE_WAN_STRIKING); 1139. if(obj->otyp == WAN_STRIKING && obj->spe > 0) { 1140. m.offensive = obj; 1141. m.has_offense = MUSE_WAN_STRIKING; 1142. } 1143. nomore(MUSE_POT_PARALYSIS); 1144. if(obj->otyp == POT_PARALYSIS && multi >= 0) { 1145. m.offensive = obj; 1146. m.has_offense = MUSE_POT_PARALYSIS; 1147. } 1148. nomore(MUSE_POT_BLINDNESS); 1149. if(obj->otyp == POT_BLINDNESS && !attacktype(mtmp->data, AT_GAZE)) { 1150. m.offensive = obj; 1151. m.has_offense = MUSE_POT_BLINDNESS; 1152. } 1153. nomore(MUSE_POT_CONFUSION); 1154. if(obj->otyp == POT_CONFUSION) { 1155. m.offensive = obj; 1156. m.has_offense = MUSE_POT_CONFUSION; 1157. } 1158. nomore(MUSE_POT_SLEEPING); 1159. if(obj->otyp == POT_SLEEPING) { 1160. m.offensive = obj; 1161. m.has_offense = MUSE_POT_SLEEPING; 1162. } 1163. /* Mik's Lethe patch - monsters use !oAmnesia */ 1164. nomore(MUSE_POT_AMNESIA); 1165. if (obj->otyp == POT_AMNESIA) { 1166. m.offensive = obj; 1167. m.has_offense = MUSE_POT_AMNESIA; 1168. } 1169. nomore(MUSE_POT_SLEEPING); 1170. if(obj->otyp == POT_SLEEPING) { 1171. m.offensive = obj; 1172. m.has_offense = MUSE_POT_SLEEPING; 1173. } 1174. /* KMH, balance patch -- monsters use potion of acid */ 1175. nomore(MUSE_POT_ACID); 1176. if(obj->otyp == POT_ACID) { 1177. m.offensive = obj; 1178. m.has_offense = MUSE_POT_ACID; 1179. } 1180. /* we can safely put this scroll here since the locations that 1181. * are in a 1 square radius are a subset of the locations that 1182. * are in wand range 1183. */ 1184. nomore(MUSE_SCR_EARTH); 1185. if (obj->otyp == SCR_EARTH 1186. && ((helmet && is_metallic(helmet)) || 1187. mtmp->mconf || amorphous(mtmp->data) || 1188. passes_walls(mtmp->data) || 1189. noncorporeal(mtmp->data) || 1190. unsolid(mtmp->data) || !rn2(10)) 1191. && dist2(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy) <= 2 1192. && mtmp->mcansee && haseyes(mtmp->data) 1193. #ifdef REINCARNATION 1194. && !Is_rogue_level(&u.uz) 1195. #endif 1196. && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) { 1197. m.offensive = obj; 1198. m.has_offense = MUSE_SCR_EARTH; 1199. } 1200. nomore(MUSE_WAN_CANCELLATION); 1201. if (obj->otyp == WAN_CANCELLATION && obj->spe > 0) { 1202. m.offensive = obj; 1203. m.has_offense = MUSE_WAN_CANCELLATION; 1204. } 1205. #if 0 1206. nomore(MUSE_SCR_FIRE); 1207. if (obj->otyp == SCR_FIRE && resists_fire(mtmp) 1208. && dist2(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy) <= 2 1209. && mtmp->mcansee && haseyes(mtmp->data)) { 1210. m.offensive = obj; 1211. m.has_offense = MUSE_SCR_FIRE; 1212. } 1213. #endif 1214. } 1215. return((boolean)(!!m.has_offense)); 1216. #undef nomore 1217. } 1218. 1219. STATIC_PTR 1220. int 1221. mbhitm(mtmp, otmp) 1222. register struct monst *mtmp; 1223. register struct obj *otmp; 1224. { 1225. int tmp; 1226. 1227. boolean reveal_invis = FALSE; 1228. if (mtmp != &youmonst) { 1229. mtmp->msleeping = 0; 1230. if (mtmp->m_ap_type) seemimic(mtmp); 1231. } 1232. switch(otmp->otyp) { 1233. case WAN_STRIKING: 1234. reveal_invis = TRUE; 1235. if (mtmp == &youmonst) { 1236. if (zap_oseen) makeknown(WAN_STRIKING); 1237. if (Antimagic) { 1238. shieldeff(u.ux, u.uy); 1239. pline("Boing!"); 1240. } else if (rnd(20) < 10 + u.uac) { 1241. pline_The("wand hits you!"); 1242. tmp = d(2,12); 1243. if(Half_spell_damage) tmp = (tmp+1) / 2; 1244. losehp(tmp, "wand", KILLED_BY_AN); 1245. } else pline_The("wand misses you."); 1246. stop_occupation(); 1247. nomul(0); 1248. } else if (resists_magm(mtmp)) { 1249. shieldeff(mtmp->mx, mtmp->my); 1250. pline("Boing!"); 1251. } else if (rnd(20) < 10+find_mac(mtmp)) { 1252. tmp = d(2,12); 1253. hit("wand", mtmp, exclam(tmp)); 1254. (void) resist(mtmp, otmp->oclass, tmp, TELL); 1255. if (cansee(mtmp->mx, mtmp->my) && zap_oseen) 1256. makeknown(WAN_STRIKING); 1257. } else { 1258. miss("wand", mtmp); 1259. if (cansee(mtmp->mx, mtmp->my) && zap_oseen) 1260. makeknown(WAN_STRIKING); 1261. } 1262. break; 1263. case WAN_TELEPORTATION: 1264. if (mtmp == &youmonst) { 1265. if (zap_oseen) makeknown(WAN_TELEPORTATION); 1266. tele(); 1267. } else { 1268. /* for consistency with zap.c, don't identify */ 1269. if (mtmp->ispriest && 1270. *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) { 1271. if (cansee(mtmp->mx, mtmp->my)) 1272. pline("%s resists the magic!", Monnam(mtmp)); 1273. mtmp->msleeping = 0; 1274. if(mtmp->m_ap_type) seemimic(mtmp); 1275. } else if (!tele_restrict(mtmp)) 1276. (void) rloc(mtmp, FALSE); 1277. } 1278. break; 1279. case WAN_CANCELLATION: 1280. case SPE_CANCELLATION: 1281. (void) cancel_monst(mtmp, otmp, FALSE, TRUE, FALSE); 1282. break; 1283. case WAN_DRAINING: /* KMH */ 1284. tmp = d(2,6); 1285. if (mtmp == &youmonst) { 1286. if (Drain_resistance) { 1287. shieldeff(u.ux, u.uy); 1288. pline("Boing!"); 1289. } else 1290. losexp("life drainage", FALSE); 1291. if (zap_oseen) 1292. makeknown(WAN_DRAINING); 1293. stop_occupation(); 1294. nomul(0); 1295. break; 1296. } else if (resists_drli(mtmp)) { 1297. shieldeff(mtmp->mx, mtmp->my); 1298. break; /* skip makeknown */ 1299. } else if (!resist(mtmp, otmp->oclass, tmp, NOTELL) && 1300. mtmp->mhp > 0) { 1301. mtmp->mhpmax -= tmp; 1302. if (mtmp->mhpmax <= 0 || mtmp->m_lev <= 0) 1303. monkilled(mtmp, "", AD_DRLI); 1304. else { 1305. mtmp->m_lev--; 1306. if (canseemon(mtmp)) { 1307. pline("%s suddenly seems weaker!", Monnam(mtmp)); 1308. } 1309. } 1310. } 1311. if (cansee(mtmp->mx, mtmp->my) && zap_oseen) 1312. makeknown(WAN_DRAINING); 1313. break; 1314. } 1315. if (reveal_invis) { 1316. if (mtmp->mhp > 0 && cansee(bhitpos.x,bhitpos.y) 1317. && !canspotmon(mtmp)) 1318. map_invisible(bhitpos.x, bhitpos.y); 1319. } 1320. return 0; 1321. } 1322. 1323. /* A modified bhit() for monsters. Based on bhit() in zap.c. Unlike 1324. * buzz(), bhit() doesn't take into account the possibility of a monster 1325. * zapping you, so we need a special function for it. (Unless someone wants 1326. * to merge the two functions...) 1327. */ 1328. STATIC_OVL void 1329. mbhit(mon,range,fhitm,fhito,obj) 1330. struct monst *mon; /* monster shooting the wand */ 1331. register int range; /* direction and range */ 1332. int FDECL((*fhitm),(MONST_P,OBJ_P)); 1333. int FDECL((*fhito),(OBJ_P,OBJ_P)); /* fns called when mon/obj hit */ 1334. struct obj *obj; /* 2nd arg to fhitm/fhito */ 1335. { 1336. register struct monst *mtmp; 1337. register struct obj *otmp; 1338. register uchar typ; 1339. int ddx, ddy; 1340. 1341. bhitpos.x = mon->mx; 1342. bhitpos.y = mon->my; 1343. u.dx = ddx = sgn(mon->mux - mon->mx); 1344. u.dy = ddy = sgn(mon->muy - mon->my); 1345. 1346. while(range-- > 0) { 1347. int x,y; 1348. 1349. bhitpos.x += ddx; 1350. bhitpos.y += ddy; 1351. x = bhitpos.x; y = bhitpos.y; 1352. 1353. if (!isok(x,y)) { 1354. bhitpos.x -= ddx; 1355. bhitpos.y -= ddy; 1356. break; 1357. } 1358. if (find_drawbridge(&x,&y)) 1359. switch (obj->otyp) { 1360. case WAN_STRIKING: 1361. destroy_drawbridge(x,y); 1362. } 1363. if(bhitpos.x==u.ux && bhitpos.y==u.uy) { 1364. (*fhitm)(&youmonst, obj); 1365. range -= 3; 1366. } else if(MON_AT(bhitpos.x, bhitpos.y)){ 1367. mtmp = m_at(bhitpos.x,bhitpos.y); 1368. if (cansee(bhitpos.x,bhitpos.y) && !canspotmon(mtmp)) 1369. map_invisible(bhitpos.x, bhitpos.y); 1370. (*fhitm)(mtmp, obj); 1371. range -= 3; 1372. } 1373. /* modified by GAN to hit all objects */ 1374. if(fhito){ 1375. int hitanything = 0; 1376. register struct obj *next_obj; 1377. 1378. for(otmp = level.objects[bhitpos.x][bhitpos.y]; 1379. otmp; otmp = next_obj) { 1380. /* Fix for polymorph bug, Tim Wright */ 1381. next_obj = otmp->nexthere; 1382. hitanything += (*fhito)(otmp, obj); 1383. } 1384. if(hitanything) range--; 1385. } 1386. typ = levl[bhitpos.x][bhitpos.y].typ; 1387. if(IS_DOOR(typ) || typ == SDOOR) { 1388. switch (obj->otyp) { 1389. /* note: monsters don't use opening or locking magic 1390. at present, but keep these as placeholders */ 1391. case WAN_OPENING: 1392. case WAN_LOCKING: 1393. case WAN_STRIKING: 1394. if (doorlock(obj, bhitpos.x, bhitpos.y)) { 1395. makeknown(obj->otyp); 1396. /* if a shop door gets broken, add it to 1397. the shk's fix list (no cost to player) */ 1398. if (levl[bhitpos.x][bhitpos.y].doormask == 1399. D_BROKEN && 1400. *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE)) 1401. add_damage(bhitpos.x, bhitpos.y, 0L); 1402. } 1403. break; 1404. } 1405. } 1406. if(!ZAP_POS(typ) || (IS_DOOR(typ) && 1407. (levl[bhitpos.x][bhitpos.y].doormask & (D_LOCKED | D_CLOSED))) 1408. ) { 1409. bhitpos.x -= ddx; 1410. bhitpos.y -= ddy; 1411. break; 1412. } 1413. } 1414. } 1415. 1416. /* Perform an offensive action for a monster. Must be called immediately 1417. * after find_offensive(). Return values are same as use_defensive(). 1418. */ 1419. int 1420. use_offensive(mtmp) 1421. struct monst *mtmp; 1422. { 1423. int i; 1424. struct obj *otmp = m.offensive; 1425. boolean oseen; 1426. 1427. /* offensive potions are not drunk, they're thrown */ 1428. if (otmp->oclass != POTION_CLASS && (i = precheck(mtmp, otmp)) != 0) 1429. return i; 1430. oseen = otmp && canseemon(mtmp); 1431. 1432. switch(m.has_offense) { 1433. case MUSE_WAN_DEATH: 1434. case MUSE_WAN_SLEEP: 1435. /*WAC reactivate*/ 1436. case MUSE_WAN_FIREBALL: 1437. case MUSE_WAN_FIRE: 1438. case MUSE_WAN_COLD: 1439. case MUSE_WAN_LIGHTNING: 1440. case MUSE_WAN_MAGIC_MISSILE: 1441. mzapmsg(mtmp, otmp, FALSE); 1442. otmp->spe--; 1443. if (oseen) makeknown(otmp->otyp); 1444. m_using = TRUE; 1445. /*WAC Handled later 1446. if (otmp->otyp == WAN_FIREBALL) { 1447. buzz((int) -10 - SPE_FIREBALL - SPE_MAGIC_MISSILE, rn2(2)+3, 1448. mtmp->mx, mtmp->my, 1449. sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my)); 1450. } 1451. else { 1452. */ 1453. buzz((int)(-30 - (otmp->otyp - WAN_MAGIC_MISSILE)), 1454. (otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6, 1455. mtmp->mx, mtmp->my, 1456. sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my)); 1457. m_using = FALSE; 1458. /* }*/ 1459. return (mtmp->mhp <= 0) ? 1 : 2; 1460. case MUSE_FIRE_HORN: 1461. case MUSE_FROST_HORN: 1462. if (oseen) { 1463. makeknown(otmp->otyp); 1464. pline("%s plays a %s!", Monnam(mtmp), xname(otmp)); 1465. } else 1466. You_hear("a horn being played."); 1467. otmp->spe--; 1468. m_using = TRUE; 1469. buzz(-30 - ((otmp->otyp==FROST_HORN) ? AD_COLD-1 : AD_FIRE-1), 1470. rn1(6,6), mtmp->mx, mtmp->my, 1471. sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my)); 1472. m_using = FALSE; 1473. return (mtmp->mhp <= 0) ? 1 : 2; 1474. /* case MUSE_WAN_TELEPORTATION:*/ 1475. case MUSE_WAN_STRIKING: 1476. case MUSE_WAN_DRAINING: /* KMH */ 1477. case MUSE_WAN_CANCELLATION: /* Lethe */ 1478. zap_oseen = oseen; 1479. mzapmsg(mtmp, otmp, FALSE); 1480. otmp->spe--; 1481. m_using = TRUE; 1482. mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp); 1483. m_using = FALSE; 1484. return 2; 1485. case MUSE_SCR_EARTH: 1486. { 1487. /* TODO: handle steeds */ 1488. register int x, y; 1489. /* don't use monster fields after killing it */ 1490. boolean confused = (mtmp->mconf ? TRUE : FALSE); 1491. int mmx = mtmp->mx, mmy = mtmp->my; 1492. 1493. mreadmsg(mtmp, otmp); 1494. /* Identify the scroll */ 1495. if (canspotmon(mtmp)) { 1496. pline_The("%s rumbles %s %s!", ceiling(mtmp->mx, mtmp->my), 1497. otmp->blessed ? "around" : "above", 1498. mon_nam(mtmp)); 1499. if (oseen) makeknown(otmp->otyp); 1500. } else if (cansee(mtmp->mx, mtmp->my)) { 1501. pline_The("%s rumbles in the middle of nowhere!", 1502. ceiling(mtmp->mx, mtmp->my)); 1503. if (mtmp->minvis) 1504. map_invisible(mtmp->mx, mtmp->my); 1505. if (oseen) makeknown(otmp->otyp); 1506. } 1507. 1508. /* Loop through the surrounding squares */ 1509. for (x = mmx-1; x <= mmx+1; x++) { 1510. for (y = mmy-1; y <= mmy+1; y++) { 1511. /* Is this a suitable spot? */ 1512. if (isok(x, y) && !closed_door(x, y) && 1513. !IS_ROCK(levl[x][y].typ) && 1514. !IS_AIR(levl[x][y].typ) && 1515. (((x == mmx) && (y == mmy)) ? 1516. !otmp->blessed : !otmp->cursed) && 1517. (x != u.ux || y != u.uy)) { 1518. register struct obj *otmp2; 1519. register struct monst *mtmp2; 1520. 1521. /* Make the object(s) */ 1522. otmp2 = mksobj(confused ? ROCK : BOULDER, 1523. FALSE, FALSE); 1524. if (!otmp2) continue; /* Shouldn't happen */ 1525. otmp2->quan = confused ? rn1(5,2) : 1; 1526. otmp2->owt = weight(otmp2); 1527. 1528. /* Find the monster here (might be same as mtmp) */ 1529. mtmp2 = m_at(x, y); 1530. if (mtmp2 && !amorphous(mtmp2->data) && 1531. !passes_walls(mtmp2->data) && 1532. !noncorporeal(mtmp2->data) && 1533. !unsolid(mtmp2->data)) { 1534. struct obj *helmet = which_armor(mtmp2, W_ARMH); 1535. int mdmg; 1536. 1537. if (cansee(mtmp2->mx, mtmp2->my)) { 1538. pline("%s is hit by %s!", Monnam(mtmp2), 1539. doname(otmp2)); 1540. if (mtmp2->minvis && !canspotmon(mtmp2)) 1541. map_invisible(mtmp2->mx, mtmp2->my); 1542. } 1543. mdmg = dmgval(otmp2, mtmp2) * otmp2->quan; 1544. if (helmet) { 1545. if(is_metallic(helmet)) { 1546. if (canspotmon(mtmp2)) 1547. pline("Fortunately, %s is wearing a hard helmet.", mon_nam(mtmp2)); 1548. else if (flags.soundok) 1549. You_hear("a clanging sound."); 1550. if (mdmg > 2) mdmg = 2; 1551. } else { 1552. if (canspotmon(mtmp2)) 1553. pline("%s's %s does not protect %s.", 1554. Monnam(mtmp2), xname(helmet), 1555. mhim(mtmp2)); 1556. } 1557. } 1558. mtmp2->mhp -= mdmg; 1559. if (mtmp2->mhp <= 0) { 1560. pline("%s is killed.", Monnam(mtmp2)); 1561. mondied(mtmp2); 1562. } 1563. } 1564. /* Drop the rock/boulder to the floor */ 1565. if (!flooreffects(otmp2, x, y, "fall")) { 1566. place_object(otmp2, x, y); 1567. stackobj(otmp2); 1568. newsym(x, y); /* map the rock */ 1569. } 1570. } 1571. } 1572. } 1573. m_useup(mtmp, otmp); 1574. /* Attack the player */ 1575. if (distmin(mmx, mmy, u.ux, u.uy) == 1 && !otmp->cursed) { 1576. int dmg; 1577. struct obj *otmp2; 1578. 1579. /* Okay, _you_ write this without repeating the code */ 1580. otmp2 = mksobj(confused ? ROCK : BOULDER, 1581. FALSE, FALSE); 1582. if (!otmp2) goto xxx_noobj; /* Shouldn't happen */ 1583. otmp2->quan = confused ? rn1(5,2) : 1; 1584. otmp2->owt = weight(otmp2); 1585. if (!amorphous(youmonst.data) && 1586. !Passes_walls && 1587. !noncorporeal(youmonst.data) && 1588. !unsolid(youmonst.data)) { 1589. You("are hit by %s!", doname(otmp2)); 1590. dmg = dmgval(otmp2, &youmonst) * otmp2->quan; 1591. if (uarmh) { 1592. if(is_metallic(uarmh)) { 1593. pline("Fortunately, you are wearing a hard helmet."); 1594. if (dmg > 2) dmg = 2; 1595. } else if (flags.verbose) { 1596. Your("%s does not protect you.", 1597. xname(uarmh)); 1598. } 1599. } 1600. } else 1601. dmg = 0; 1602. if (!flooreffects(otmp2, u.ux, u.uy, "fall")) { 1603. place_object(otmp2, u.ux, u.uy); 1604. stackobj(otmp2); 1605. newsym(u.ux, u.uy); 1606. } 1607. if (dmg) losehp(dmg, "scroll of earth", KILLED_BY_AN); 1608. } 1609. xxx_noobj: 1610. 1611. return (mtmp->mhp <= 0) ? 1 : 2; 1612. } 1613. #if 0 1614. case MUSE_SCR_FIRE: 1615. { 1616. boolean vis = cansee(mtmp->mx, mtmp->my); 1617. 1618. mreadmsg(mtmp, otmp); 1619. if (mtmp->mconf) { 1620. if (vis) 1621. pline("Oh, what a pretty fire!"); 1622. } else { 1623. struct monst *mtmp2; 1624. int num; 1625. 1626. if (vis) 1627. pline_The("scroll erupts in a tower of flame!"); 1628. shieldeff(mtmp->mx, mtmp->my); 1629. pline("%s is uninjured.", Monnam(mtmp)); 1630. (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); 1631. (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); 1632. (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); 1633. num = (2*(rn1(3, 3) + 2 * bcsign(otmp)) + 1)/3; 1634. if (Slimed) { 1635. Your("slimy parts are burned away!"); 1636. Slimed = 0; 1637. } 1638. if (Fire_resistance) 1639. You("are not harmed."); 1640. burn_away_slime(); 1641. if (Half_spell_damage) num = (num+1) / 2; 1642. else losehp(num, "scroll of fire", KILLED_BY_AN); 1643. for(mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) { 1644. if(DEADMONSTER(mtmp2)) continue; 1645. if(mtmp == mtmp2) continue; 1646. if(dist2(mtmp2->mx,mtmp2->my,mtmp->mx,mtmp->my) < 3){ 1647. if (resists_fire(mtmp2)) continue; 1648. mtmp2->mhp -= num; 1649. if (resists_cold(mtmp2)) 1650. mtmp2->mhp -= 3*num; 1651. if(mtmp2->mhp < 1) { 1652. mondied(mtmp2); 1653. break; 1654. } 1655. } 1656. } 1657. } 1658. return 2; 1659. } 1660. #endif /* 0 */ 1661. case MUSE_POT_PARALYSIS: 1662. case MUSE_POT_BLINDNESS: 1663. case MUSE_POT_CONFUSION: 1664. case MUSE_POT_SLEEPING: 1665. case MUSE_POT_ACID: 1666. case MUSE_POT_AMNESIA: 1667. /* Note: this setting of dknown doesn't suffice. A monster 1668. * which is out of sight might throw and it hits something _in_ 1669. * sight, a problem not existing with wands because wand rays 1670. * are not objects. Also set dknown in mthrowu.c. 1671. */ 1672. if (cansee(mtmp->mx, mtmp->my)) { 1673. otmp->dknown = 1; 1674. pline("%s hurls %s!", Monnam(mtmp), 1675. singular(otmp, doname)); 1676. } 1677. m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux-mtmp->mx), 1678. sgn(mtmp->muy-mtmp->my), 1679. distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy), otmp); 1680. return 2; 1681. case 0: return 0; /* i.e. an exploded wand */ 1682. default: impossible("%s wanted to perform action %d?", Monnam(mtmp), 1683. m.has_offense); 1684. break; 1685. } 1686. return 0; 1687. } 1688. 1689. int 1690. rnd_offensive_item(mtmp) 1691. struct monst *mtmp; 1692. { 1693. struct permonst *pm = mtmp->data; 1694. int difficulty = monstr[(monsndx(pm))]; 1695. 1696. if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data) 1697. || pm->mlet == S_GHOST 1698. # ifdef KOPS 1699. || pm->mlet == S_KOP 1700. # endif 1701. ) return 0; 1702. if (difficulty > 7 && !rn2(35)) return WAN_DEATH; 1703. if (difficulty > 6 && !rn2(25)) return WAN_FIREBALL; 1704. switch (rn2(9 - (difficulty < 4) + 4 * (difficulty > 6))) { 1705. 1706. case 0: { 1707. struct obj *helmet = which_armor(mtmp, W_ARMH); 1708. 1709. if ((helmet && is_metallic(helmet)) || amorphous(pm) || passes_walls(pm) || noncorporeal(pm) || unsolid(pm)) 1710. return SCR_EARTH; 1711. } /* fall through */ 1712. case 1: return WAN_STRIKING; 1713. case 2: return POT_ACID; 1714. case 3: return POT_CONFUSION; 1715. case 4: return POT_BLINDNESS; 1716. case 5: return POT_SLEEPING; 1717. case 6: return POT_PARALYSIS; 1718. case 7: return WAN_MAGIC_MISSILE; 1719. case 8: return WAN_SLEEP; 1720. case 9: return WAN_FIRE; 1721. case 10: return WAN_COLD; 1722. case 11: return WAN_LIGHTNING; 1723. case 12: return WAN_DRAINING; 1724. } 1725. /*NOTREACHED*/ 1726. return 0; 1727. } 1728. 1729. #define MUSE_POT_GAIN_LEVEL 1 1730. #define MUSE_WAN_MAKE_INVISIBLE 2 1731. #define MUSE_POT_INVISIBILITY 3 1732. #define MUSE_POLY_TRAP 4 1733. #define MUSE_WAN_POLYMORPH 5 1734. #define MUSE_POT_SPEED 6 1735. #define MUSE_WAN_SPEED_MONSTER 7 1736. #define MUSE_BULLWHIP 8 1737. #define MUSE_POT_POLYMORPH 9 1738. 1739. boolean 1740. find_misc(mtmp) 1741. struct monst *mtmp; 1742. { 1743. register struct obj *obj; 1744. struct permonst *mdat = mtmp->data; 1745. int x = mtmp->mx, y = mtmp->my; 1746. struct trap *t; 1747. int xx, yy; 1748. #ifdef STEED 1749. boolean immobile = (mdat->mmove == 0 || mtmp == u.usteed); 1750. #else 1751. boolean immobile = (mdat->mmove == 0); 1752. #endif 1753. boolean stuck = (mtmp == u.ustuck); 1754. 1755. m.misc = (struct obj *)0; 1756. m.has_misc = 0; 1757. if (is_animal(mdat) || mindless(mdat)) 1758. return 0; 1759. if (u.uswallow && stuck) return FALSE; 1760. 1761. /* We arbitrarily limit to times when a player is nearby for the 1762. * same reason as Junior Pac-Man doesn't have energizers eaten until 1763. * you can see them... 1764. */ 1765. if(dist2(x, y, mtmp->mux, mtmp->muy) > 36) 1766. return FALSE; 1767. 1768. if (!stuck && !immobile && !mtmp->cham && monstr[monsndx(mdat)] < 6) { 1769. boolean ignore_boulders = (verysmall(mdat) || 1770. throws_rocks(mdat) || 1771. passes_walls(mdat)); 1772. for(xx = x-1; xx <= x+1; xx++) 1773. for(yy = y-1; yy <= y+1; yy++) 1774. if (isok(xx,yy) && (xx != u.ux || yy != u.uy)) 1775. if (mdat != &mons[PM_GRID_BUG] || xx == x || yy == y) 1776. if (/* (xx==x && yy==y) || */ !level.monsters[xx][yy]) 1777. if ((t = t_at(xx, yy)) != 0 && 1778. (ignore_boulders || !sobj_at(BOULDER, xx, yy)) 1779. && !onscary(xx, yy, mtmp)) { 1780. if (t->ttyp == POLY_TRAP) { 1781. trapx = xx; 1782. trapy = yy; 1783. m.has_misc = MUSE_POLY_TRAP; 1784. return TRUE; 1785. } 1786. } 1787. } 1788. if (nohands(mdat)) 1789. return 0; 1790. 1791. #define nomore(x) if(m.has_misc==x) continue; 1792. for(obj=mtmp->minvent; obj; obj=obj->nobj) { 1793. /* Monsters shouldn't recognize cursed items; this kludge is */ 1794. /* necessary to prevent serious problems though... */ 1795. if(obj->otyp == POT_GAIN_LEVEL && (!obj->cursed || 1796. (!mtmp->isgd && !mtmp->isshk && !mtmp->ispriest))) { 1797. m.misc = obj; 1798. m.has_misc = MUSE_POT_GAIN_LEVEL; 1799. } 1800. nomore(MUSE_BULLWHIP); 1801. /* WAC kludge here so monsters don't attempt to grab cursed weapon */ 1802. if(obj->otyp == BULLWHIP && (MON_WEP(mtmp) == obj) && 1803. distu(mtmp->mx,mtmp->my)==1 && uwep && !uwep->cursed && 1804. !mtmp->mpeaceful) { 1805. m.misc = obj; 1806. m.has_misc = MUSE_BULLWHIP; 1807. } 1808. /* Note: peaceful/tame monsters won't make themselves 1809. * invisible unless you can see them. Not really right, but... 1810. */ 1811. nomore(MUSE_WAN_MAKE_INVISIBLE); 1812. if(obj->otyp == WAN_MAKE_INVISIBLE && obj->spe > 0 && 1813. !mtmp->minvis && !mtmp->invis_blkd && 1814. (!mtmp->mpeaceful || See_invisible) && 1815. (!attacktype(mtmp->data, AT_GAZE) || mtmp->mcan)) { 1816. m.misc = obj; 1817. m.has_misc = MUSE_WAN_MAKE_INVISIBLE; 1818. } 1819. nomore(MUSE_POT_INVISIBILITY); 1820. if(obj->otyp == POT_INVISIBILITY && 1821. !mtmp->minvis && !mtmp->invis_blkd && 1822. (!mtmp->mpeaceful || See_invisible) && 1823. (!attacktype(mtmp->data, AT_GAZE) || mtmp->mcan)) { 1824. m.misc = obj; 1825. m.has_misc = MUSE_POT_INVISIBILITY; 1826. } 1827. nomore(MUSE_WAN_SPEED_MONSTER); 1828. if(obj->otyp == WAN_SPEED_MONSTER && obj->spe > 0 1829. && mtmp->mspeed != MFAST && !mtmp->isgd) { 1830. m.misc = obj; 1831. m.has_misc = MUSE_WAN_SPEED_MONSTER; 1832. } 1833. nomore(MUSE_POT_SPEED); 1834. if(obj->otyp == POT_SPEED && mtmp->mspeed != MFAST 1835. && !mtmp->isgd) { 1836. m.misc = obj; 1837. m.has_misc = MUSE_POT_SPEED; 1838. } 1839. nomore(MUSE_WAN_POLYMORPH); 1840. if(obj->otyp == WAN_POLYMORPH && obj->spe > 0 && !mtmp->cham 1841. && monstr[monsndx(mdat)] < 6) { 1842. m.misc = obj; 1843. m.has_misc = MUSE_WAN_POLYMORPH; 1844. } 1845. nomore(MUSE_POT_POLYMORPH); 1846. if(obj->otyp == POT_POLYMORPH && !mtmp->cham 1847. && monstr[monsndx(mdat)] < 6) { 1848. m.misc = obj; 1849. m.has_misc = MUSE_POT_POLYMORPH; 1850. } 1851. } 1852. return((boolean)(!!m.has_misc)); 1853. #undef nomore 1854. } 1855. 1856. #if 0 1857. /* type of monster to polymorph into; defaults to one suitable for the 1858. current level rather than the totally arbitrary choice of newcham() */ 1859. static struct permonst * 1860. muse_newcham_mon(mon) 1861. struct monst *mon; 1862. { 1863. struct obj *m_armr; 1864. 1865. if ((m_armr = which_armor(mon, W_ARM)) != 0) { 1866. if (Is_dragon_scales(m_armr)) 1867. return Dragon_scales_to_pm(m_armr); 1868. else if (Is_dragon_mail(m_armr)) 1869. return Dragon_mail_to_pm(m_armr); 1870. } 1871. return rndmonst(); 1872. } 1873. #endif 1874. 1875. int 1876. use_misc(mtmp) 1877. struct monst *mtmp; 1878. { 1879. int i; 1880. struct obj *otmp = m.misc; 1881. boolean vis, vismon, oseen; 1882. char nambuf[BUFSZ]; 1883. 1884. if ((i = precheck(mtmp, otmp)) != 0) return i; 1885. vis = cansee(mtmp->mx, mtmp->my); 1886. vismon = canseemon(mtmp); 1887. oseen = otmp && vismon; 1888. 1889. switch(m.has_misc) { 1890. case MUSE_POT_GAIN_LEVEL: 1891. mquaffmsg(mtmp, otmp); 1892. if (otmp->cursed) { 1893. if (Can_rise_up(mtmp->mx, mtmp->my, &u.uz)) { 1894. register int tolev = depth(&u.uz)-1; 1895. d_level tolevel; 1896. 1897. get_level(&tolevel, tolev); 1898. /* insurance against future changes... */ 1899. if(on_level(&tolevel, &u.uz)) goto skipmsg; 1900. if (vismon) { 1901. pline("%s rises up, through the %s!", 1902. Monnam(mtmp), ceiling(mtmp->mx, mtmp->my)); 1903. if(!objects[POT_GAIN_LEVEL].oc_name_known 1904. && !objects[POT_GAIN_LEVEL].oc_uname) 1905. docall(otmp); 1906. } 1907. m_useup(mtmp, otmp); 1908. migrate_to_level(mtmp, ledger_no(&tolevel), 1909. MIGR_RANDOM, (coord *)0); 1910. return 2; 1911. } else { 1912. skipmsg: 1913. if (vismon) { 1914. pline("%s looks uneasy.", Monnam(mtmp)); 1915. if(!objects[POT_GAIN_LEVEL].oc_name_known 1916. && !objects[POT_GAIN_LEVEL].oc_uname) 1917. docall(otmp); 1918. } 1919. m_useup(mtmp, otmp); 1920. return 2; 1921. } 1922. } 1923. if (vismon) pline("%s seems more experienced.", Monnam(mtmp)); 1924. if (oseen) makeknown(POT_GAIN_LEVEL); 1925. m_useup(mtmp, otmp); 1926. if (!grow_up(mtmp,(struct monst *)0)) return 1; 1927. /* grew into genocided monster */ 1928. return 2; 1929. case MUSE_WAN_MAKE_INVISIBLE: 1930. case MUSE_POT_INVISIBILITY: 1931. if (otmp->otyp == WAN_MAKE_INVISIBLE) { 1932. mzapmsg(mtmp, otmp, TRUE); 1933. otmp->spe--; 1934. } else 1935. mquaffmsg(mtmp, otmp); 1936. /* format monster's name before altering its visibility */ 1937. Strcpy(nambuf, See_invisible ? Monnam(mtmp) : mon_nam(mtmp)); 1938. mon_set_minvis(mtmp); 1939. if (vismon && mtmp->minvis) { /* was seen, now invisible */ 1940. if (See_invisible) 1941. pline("%s body takes on a %s transparency.", 1942. s_suffix(nambuf), 1943. Hallucination ? "normal" : "strange"); 1944. else 1945. pline("Suddenly you cannot see %s.", nambuf); 1946. if (oseen) makeknown(otmp->otyp); 1947. } 1948. if (otmp->otyp == POT_INVISIBILITY) { 1949. if (otmp->cursed) you_aggravate(mtmp); 1950. m_useup(mtmp, otmp); 1951. } 1952. return 2; 1953. case MUSE_WAN_SPEED_MONSTER: 1954. mzapmsg(mtmp, otmp, TRUE); 1955. otmp->spe--; 1956. mon_adjust_speed(mtmp, 1, otmp); 1957. return 2; 1958. case MUSE_POT_SPEED: 1959. mquaffmsg(mtmp, otmp); 1960. /* note difference in potion effect due to substantially 1961. different methods of maintaining speed ratings: 1962. player's character becomes "very fast" temporarily; 1963. monster becomes "one stage faster" permanently */ 1964. mon_adjust_speed(mtmp, 1, otmp); 1965. m_useup(mtmp, otmp); 1966. return 2; 1967. case MUSE_WAN_POLYMORPH: 1968. mzapmsg(mtmp, otmp, TRUE); 1969. otmp->spe--; 1970. #if 0 1971. (void) newcham(mtmp, muse_newcham_mon(), TRUE, vismon); 1972. #else 1973. (void) mon_poly(mtmp, FALSE, "%s changes!"); 1974. #endif 1975. if (oseen) makeknown(WAN_POLYMORPH); 1976. return 2; 1977. case MUSE_POT_POLYMORPH: 1978. mquaffmsg(mtmp, otmp); 1979. #if 0 1980. if (vismon) pline("%s suddenly mutates!", Monnam(mtmp)); 1981. (void) newcham(mtmp, muse_newcham_mon(mtmp), FALSE, vismon); 1982. #else 1983. (void) mon_poly(mtmp, FALSE, "%s suddenly mutates!"); 1984. #endif 1985. if (oseen) makeknown(POT_POLYMORPH); 1986. m_useup(mtmp, otmp); 1987. return 2; 1988. case MUSE_POLY_TRAP: 1989. if (vismon) 1990. pline("%s deliberately %s onto a polymorph trap!", 1991. Monnam(mtmp), 1992. makeplural(locomotion(mtmp->data, "jump"))); 1993. if (vis) seetrap(t_at(trapx,trapy)); 1994. 1995. /* don't use rloc() due to worms */ 1996. remove_monster(mtmp->mx, mtmp->my); 1997. newsym(mtmp->mx, mtmp->my); 1998. place_monster(mtmp, trapx, trapy); 1999. if (mtmp->wormno) worm_move(mtmp); 2000. newsym(trapx, trapy); 2001. 2002. #if 0 2003. (void) newcham(mtmp, (struct permonst *)0, FALSE, vismon); 2004. #else 2005. (void) mon_poly(mtmp, FALSE, "%s changes!"); 2006. #endif 2007. return 2; 2008. case MUSE_BULLWHIP: 2009. /* attempt to disarm hero */ 2010. if (uwep && !rn2(5)) { 2011. const char *The_whip = vismon ? "The bullwhip" : "A whip"; 2012. int where_to = rn2(4); 2013. struct obj *obj = uwep; 2014. const char *hand; 2015. char the_weapon[BUFSZ]; 2016. 2017. Strcpy(the_weapon, the(xname(obj))); 2018. hand = body_part(HAND); 2019. if (bimanual(obj)) hand = makeplural(hand); 2020. 2021. if (vismon) 2022. pline("%s flicks a bullwhip towards your %s!", 2023. Monnam(mtmp), hand); 2024. if (obj->otyp == HEAVY_IRON_BALL) { 2025. pline("%s fails to wrap around %s.", 2026. The_whip, the_weapon); 2027. return 1; 2028. } 2029. pline("%s wraps around %s you're wielding!", 2030. The_whip, the_weapon); 2031. if (welded(obj)) { 2032. pline("%s welded to your %s%c", 2033. !is_plural(obj) ? "It is" : "They are", 2034. hand, !obj->bknown ? '!' : '.'); 2035. /* obj->bknown = 1; */ /* welded() takes care of this */ 2036. where_to = 0; 2037. } 2038. if (!where_to) { 2039. pline_The("whip slips free."); /* not `The_whip' */ 2040. return 1; 2041. } else if (where_to == 3 && hates_silver(mtmp->data) && 2042. objects[obj->otyp].oc_material == SILVER) { 2043. /* this monster won't want to catch a silver 2044. weapon; drop it at hero's feet instead */ 2045. where_to = 2; 2046. } 2047. freeinv(obj); 2048. uwepgone(); 2049. switch (where_to) { 2050. case 1: /* onto floor beneath mon */ 2051. pline("%s yanks %s from your %s!", Monnam(mtmp), 2052. the_weapon, hand); 2053. place_object(obj, mtmp->mx, mtmp->my); 2054. break; 2055. case 2: /* onto floor beneath you */ 2056. pline("%s yanks %s to the %s!", Monnam(mtmp), 2057. the_weapon, surface(u.ux, u.uy)); 2058. dropy(obj); 2059. break; 2060. case 3: /* into mon's inventory */ 2061. pline("%s snatches %s!", Monnam(mtmp), 2062. the_weapon); 2063. (void) mpickobj(mtmp,obj); 2064. break; 2065. } 2066. return 1; 2067. } 2068. return 0; 2069. case 0: return 0; /* i.e. an exploded wand */ 2070. default: impossible("%s wanted to perform action %d?", Monnam(mtmp), 2071. m.has_misc); 2072. break; 2073. } 2074. return 0; 2075. } 2076. 2077. STATIC_OVL void 2078. you_aggravate(mtmp) 2079. struct monst *mtmp; 2080. { 2081. pline("For some reason, %s presence is known to you.", 2082. s_suffix(noit_mon_nam(mtmp))); 2083. cls(); 2084. #ifdef CLIPPING 2085. cliparound(mtmp->mx, mtmp->my); 2086. #endif 2087. show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp)); 2088. display_self(); 2089. You_feel("aggravated at %s.", noit_mon_nam(mtmp)); 2090. display_nhwindow(WIN_MAP, TRUE); 2091. docrt(); 2092. if (unconscious()) { 2093. multi = -1; 2094. nomovemsg = 2095. "Aggravated, you are jolted into full consciousness."; 2096. } 2097. newsym(mtmp->mx,mtmp->my); 2098. if (!canspotmon(mtmp)) 2099. map_invisible(mtmp->mx, mtmp->my); 2100. } 2101. 2102. int 2103. rnd_misc_item(mtmp) 2104. struct monst *mtmp; 2105. { 2106. struct permonst *pm = mtmp->data; 2107. int difficulty = monstr[(monsndx(pm))]; 2108. 2109. if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data) 2110. || pm->mlet == S_GHOST 2111. # ifdef KOPS 2112. || pm->mlet == S_KOP 2113. # endif 2114. ) return 0; 2115. /* Unlike other rnd_item functions, we only allow _weak_ monsters 2116. * to have this item; after all, the item will be used to strengthen 2117. * the monster and strong monsters won't use it at all... 2118. */ 2119. if (difficulty < 6 && !rn2(30)) 2120. return rn2(6) ? POT_POLYMORPH : WAN_POLYMORPH; 2121. 2122. if (!rn2(40) && !nonliving(pm)) return AMULET_OF_LIFE_SAVING; 2123. 2124. switch (rn2(3)) { 2125. case 0: 2126. if (mtmp->isgd) return 0; 2127. return rn2(6) ? POT_SPEED : WAN_SPEED_MONSTER; 2128. case 1: 2129. if (mtmp->mpeaceful && !See_invisible) return 0; 2130. return rn2(6) ? POT_INVISIBILITY : WAN_MAKE_INVISIBLE; 2131. case 2: 2132. return POT_GAIN_LEVEL; 2133. } 2134. /*NOTREACHED*/ 2135. return 0; 2136. } 2137. 2138. boolean 2139. searches_for_item(mon, obj) 2140. struct monst *mon; 2141. struct obj *obj; 2142. { 2143. int typ = obj->otyp; 2144. 2145. if (is_animal(mon->data) || 2146. mindless(mon->data) || 2147. mon->data == &mons[PM_GHOST]) /* don't loot bones piles */ 2148. return FALSE; 2149. 2150. if (typ == WAN_MAKE_INVISIBLE || typ == POT_INVISIBILITY) 2151. return (boolean)(!mon->minvis && !mon->invis_blkd && !attacktype(mon->data, AT_GAZE)); 2152. if (typ == WAN_SPEED_MONSTER || typ == POT_SPEED) 2153. return (boolean)(mon->mspeed != MFAST); 2154. 2155. switch (obj->oclass) { 2156. case WAND_CLASS: 2157. if (obj->spe <= 0) 2158. return FALSE; 2159. if (typ == WAN_DIGGING) 2160. return (boolean)(!is_floater(mon->data)); 2161. if (typ == WAN_POLYMORPH) 2162. return (boolean)(monstr[monsndx(mon->data)] < 6); 2163. if (objects[typ].oc_dir == RAY || 2164. typ == WAN_STRIKING || 2165. typ == WAN_TELEPORTATION || 2166. typ == WAN_CREATE_MONSTER || 2167. typ == WAN_CREATE_HORDE || 2168. typ == WAN_DRAINING || 2169. typ == WAN_HEALING || 2170. typ == WAN_EXTRA_HEALING || 2171. typ == WAN_CANCELLATION) 2172. return TRUE; 2173. break; 2174. case POTION_CLASS: 2175. if (typ == POT_VAMPIRE_BLOOD) 2176. return is_vampire(mon->data); 2177. if (typ == POT_HEALING || 2178. typ == POT_EXTRA_HEALING || 2179. typ == POT_FULL_HEALING || 2180. typ == POT_POLYMORPH || 2181. typ == POT_GAIN_LEVEL || 2182. typ == POT_PARALYSIS || 2183. typ == POT_SLEEPING || 2184. typ == POT_ACID || 2185. typ == POT_CONFUSION || 2186. typ == POT_AMNESIA) 2187. return TRUE; 2188. if (typ == POT_BLINDNESS && !attacktype(mon->data, AT_GAZE)) 2189. return TRUE; 2190. break; 2191. case SCROLL_CLASS: 2192. if (typ == SCR_TELEPORTATION || typ == SCR_CREATE_MONSTER 2193. || typ == SCR_EARTH) 2194. return TRUE; 2195. break; 2196. case AMULET_CLASS: 2197. if (typ == AMULET_OF_LIFE_SAVING) 2198. return (boolean)(!nonliving(mon->data)); 2199. if (typ == AMULET_OF_REFLECTION) 2200. return TRUE; 2201. break; 2202. case TOOL_CLASS: 2203. if (typ == PICK_AXE) 2204. return (boolean)needspick(mon->data); 2205. if (typ == UNICORN_HORN) 2206. return (boolean)(!obj->cursed && !is_unicorn(mon->data)); 2207. if (typ == FROST_HORN || typ == FIRE_HORN) 2208. return (obj->spe > 0); 2209. if (is_weptool(obj)) 2210. return (boolean)likes_objs(mon->data); 2211. break; 2212. case FOOD_CLASS: 2213. if (typ == CORPSE) 2214. return (boolean)(((mon->misc_worn_check & W_ARMG) && 2215. touch_petrifies(&mons[obj->corpsenm])) || 2216. (!resists_ston(mon) && 2217. (obj->corpsenm == PM_LIZARD || 2218. (acidic(&mons[obj->corpsenm]) && 2219. obj->corpsenm != PM_GREEN_SLIME)))); 2220. if (typ == EGG) 2221. return (boolean)(touch_petrifies(&mons[obj->corpsenm])); 2222. break; 2223. default: 2224. break; 2225. } 2226. 2227. return FALSE; 2228. } 2229. 2230. boolean 2231. mon_reflects(mon,str) 2232. struct monst *mon; 2233. const char *str; 2234. { 2235. struct obj *orefl = which_armor(mon, W_ARMS); 2236. 2237. if (orefl && orefl->otyp == SHIELD_OF_REFLECTION) { 2238. if (str) { 2239. pline(str, s_suffix(mon_nam(mon)), "shield"); 2240. makeknown(SHIELD_OF_REFLECTION); 2241. } 2242. return TRUE; 2243. } else if (arti_reflects(MON_WEP(mon))) { 2244. /* due to wielded artifact weapon */ 2245. if (str) 2246. pline(str, s_suffix(mon_nam(mon)), "weapon"); 2247. return TRUE; 2248. } else if ((orefl = which_armor(mon, W_AMUL)) && 2249. orefl->otyp == AMULET_OF_REFLECTION) { 2250. if (str) { 2251. pline(str, s_suffix(mon_nam(mon)), "amulet"); 2252. makeknown(AMULET_OF_REFLECTION); 2253. } 2254. return TRUE; 2255. } else if (mon->data == &mons[PM_NIGHTMARE]) { 2256. pline(str,s_suffix(mon_nam(mon)),"horn"); 2257. return TRUE; 2258. } else if ((orefl = which_armor(mon, W_ARM)) && 2259. (orefl->otyp == SILVER_DRAGON_SCALES || orefl->otyp == SILVER_DRAGON_SCALE_MAIL)) { 2260. if (str) 2261. pline(str, s_suffix(mon_nam(mon)), "armor"); 2262. return TRUE; 2263. } else if (mon->data == &mons[PM_SILVER_DRAGON] || 2264. mon->data == &mons[PM_CHROMATIC_DRAGON]) { 2265. /* Silver dragons only reflect when mature; babies do not */ 2266. if (str) 2267. pline(str, s_suffix(mon_nam(mon)), "scales"); 2268. return TRUE; 2269. } else if (mon->data == &mons[PM_DIAMOND_GOLEM] 2270. || mon->data == &mons[PM_SAPPHIRE_GOLEM] 2271. || mon->data == &mons[PM_CRYSTAL_GOLEM]) { 2272. /* Some of the higher golems have intrinsic reflection */ 2273. if (str) 2274. pline(str, s_suffix(mon_nam(mon)), "body"); 2275. return TRUE; 2276. } 2277. return FALSE; 2278. } 2279. 2280. boolean 2281. ureflects (fmt, str) 2282. const char *fmt, *str; 2283. { 2284. /* Check from outermost to innermost objects */ 2285. if (EReflecting & W_ARMS) { 2286. if (fmt && str) { 2287. pline(fmt, str, "shield"); 2288. makeknown(SHIELD_OF_REFLECTION); 2289. } 2290. return TRUE; 2291. } else if (EReflecting & W_WEP) { 2292. /* Due to wielded artifact weapon */ 2293. if (fmt && str) 2294. pline(fmt, str, "weapon"); 2295. return TRUE; 2296. } else if (EReflecting & W_AMUL) { 2297. if (fmt && str) { 2298. pline(fmt, str, "medallion"); 2299. makeknown(AMULET_OF_REFLECTION); 2300. } 2301. return TRUE; 2302. } else if (EReflecting & W_ARM) { 2303. if (fmt && str) 2304. pline(fmt, str, "armor"); 2305. return TRUE; 2306. } else if (youmonst.data == &mons[PM_SILVER_DRAGON]) { 2307. if (fmt && str) 2308. pline(fmt, str, "scales"); 2309. return TRUE; 2310. } else if (youmonst.data == &mons[PM_DIAMOND_GOLEM] 2311. || youmonst.data == &mons[PM_SAPPHIRE_GOLEM] 2312. || youmonst.data == &mons[PM_CRYSTAL_GOLEM]) { 2313. if (fmt && str) 2314. pline(fmt, str, "body"); 2315. return TRUE; 2316. } 2317. return FALSE; 2318. } 2319. 2320. 2321. /* TRUE if the monster ate something */ 2322. boolean 2323. munstone(mon, by_you) 2324. struct monst *mon; 2325. boolean by_you; 2326. { 2327. struct obj *obj; 2328. 2329. if (resists_ston(mon)) return FALSE; 2330. if (mon->meating || !mon->mcanmove || mon->msleeping) return FALSE; 2331. 2332. for(obj = mon->minvent; obj; obj = obj->nobj) { 2333. /* Monsters can also use potions of acid */ 2334. if ((obj->otyp == POT_ACID) || (obj->otyp == CORPSE && 2335. (obj->corpsenm == PM_LIZARD || (acidic(&mons[obj->corpsenm]) && obj->corpsenm != PM_GREEN_SLIME)))) { 2336. mon_consume_unstone(mon, obj, by_you, TRUE); 2337. return TRUE; 2338. } 2339. } 2340. return FALSE; 2341. } 2342. 2343. STATIC_OVL void 2344. mon_consume_unstone(mon, obj, by_you, stoning) 2345. struct monst *mon; 2346. struct obj *obj; 2347. boolean by_you; 2348. boolean stoning; 2349. { 2350. int nutrit = (obj->otyp == CORPSE) ? dog_nutrition(mon, obj) : 0; 2351. /* also sets meating */ 2352. 2353. /* give a "<mon> is slowing down" message and also remove 2354. intrinsic speed (comparable to similar effect on the hero) */ 2355. mon_adjust_speed(mon, -3, (struct obj *)0); 2356. 2357. if (canseemon(mon)) { 2358. long save_quan = obj->quan; 2359. 2360. obj->quan = 1L; 2361. pline("%s %ss %s.", Monnam(mon), 2362. (obj->otyp == POT_ACID) ? "quaff" : "eat", 2363. distant_name(obj,doname)); 2364. obj->quan = save_quan; 2365. } else if (flags.soundok) 2366. You_hear("%s.", (obj->otyp == POT_ACID) ? "drinking" : "chewing"); 2367. m_useup(mon, obj); 2368. if (((obj->otyp == POT_ACID) || acidic(&mons[obj->corpsenm])) && 2369. !resists_acid(mon)) { 2370. mon->mhp -= rnd(15); 2371. pline("%s has a very bad case of stomach acid.", 2372. Monnam(mon)); 2373. } 2374. if (mon->mhp <= 0) { 2375. pline("%s dies!", Monnam(mon)); 2376. if (by_you) xkilled(mon, 0); 2377. else mondead(mon); 2378. return; 2379. } 2380. if (stoning && canseemon(mon)) { 2381. if (Hallucination) 2382. pline("What a pity - %s just ruined a future piece of art!", 2383. mon_nam(mon)); 2384. else 2385. pline("%s seems limber!", Monnam(mon)); 2386. } 2387. if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD && mon->mconf) { 2388. mon->mconf = 0; 2389. if (canseemon(mon)) 2390. pline("%s seems steadier now.", Monnam(mon)); 2391. } 2392. if (mon->mtame && !mon->isminion && nutrit > 0) { 2393. struct edog *edog = EDOG(mon); 2394. 2395. if (edog->hungrytime < monstermoves) edog->hungrytime = monstermoves; 2396. edog->hungrytime += nutrit; 2397. mon->mconf = 0; 2398. } 2399. mon->mlstmv = monstermoves; /* it takes a turn */ 2400. } 2401. 2402. /*muse.c*/