Source:NetHack 3.2.0/muse.c
(Redirected from NetHack 3.2.0/muse.c)
Jump to navigation
Jump to search
Below is the full text to muse.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/muse.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)muse.c 3.2 96/02/14 */ 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 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. static int FDECL(precheck, (struct monst *,struct obj *)); 23. static void FDECL(mzapmsg, (struct monst *,struct obj *,BOOLEAN_P)); 24. static void FDECL(mreadmsg, (struct monst *,struct obj *)); 25. static void FDECL(mquaffmsg, (struct monst *,struct obj *)); 26. STATIC_PTR int FDECL(mbhitm, (struct monst *,struct obj *)); 27. static void FDECL(mbhit, 28. (struct monst *,int,int FDECL((*),(MONST_P,OBJ_P)), 29. int FDECL((*),(OBJ_P,OBJ_P)),struct obj *)); 30. static void FDECL(you_aggravate, (struct monst *)); 31. 32. static struct musable { 33. struct obj *offensive; 34. struct obj *defensive; 35. struct obj *misc; 36. int has_offense, has_defense, has_misc; 37. /* =0, no capability; otherwise, different numbers. 38. * If it's an object, the object is also set (it's 0 otherwise). 39. */ 40. } m; 41. static int trapx, trapy; 42. static boolean zap_oseen; 43. /* for wands which use mbhitm and are zapped at players. We usually 44. * want an oseen local to the function, but this is impossible since the 45. * function mbhitm has to be compatible with the normal zap routines, 46. * and those routines don't remember who zapped the wand. 47. */ 48. 49. /* Any preliminary checks which may result in the monster being unable to use 50. * the item. Returns 0 if nothing happened, 2 if the monster can't do anything 51. * (i.e. it teleported) and 1 if it's dead. 52. */ 53. static int 54. precheck(mon, obj) 55. struct monst *mon; 56. struct obj *obj; 57. { 58. boolean vis; 59. 60. if (!obj) return 0; 61. vis = cansee(mon->mx, mon->my); 62. 63. if (obj->oclass == POTION_CLASS) { 64. coord cc; 65. static const char *empty = "The potion turns out to be empty."; 66. const char *potion_descr; 67. struct monst *mtmp; 68. #define POTION_OCCUPANT_CHANCE(n) (13 + 2*(n)) /* also in potion.c */ 69. 70. potion_descr = OBJ_DESCR(objects[obj->otyp]); 71. if (potion_descr && !strcmp(potion_descr, "milky") && 72. flags.ghost_count < MAXMONNO && 73. !rn2(POTION_OCCUPANT_CHANCE(flags.ghost_count))) { 74. if (!enexto(&cc, mon->mx, mon->my, &mons[PM_GHOST])) return 0; 75. mquaffmsg(mon, obj); 76. m_useup(mon, obj); 77. mtmp = makemon(&mons[PM_GHOST], cc.x, cc.y); 78. if (!mtmp) { 79. if (vis) pline(empty); 80. } else { 81. if (vis) { 82. pline("As %s opens the bottle, an enormous %s emerges!", 83. mon_nam(mon), 84. Hallucination ? rndmonnam() : (const char *)"ghost"); 85. pline("%s is frightened to death, and unable to move.", 86. Monnam(mon)); 87. } 88. mon->mcanmove = 0; 89. mon->mfrozen = 3; 90. } 91. return 2; 92. } 93. if (potion_descr && !strcmp(potion_descr, "smoky") && 94. flags.djinni_count < MAXMONNO && 95. !rn2(POTION_OCCUPANT_CHANCE(flags.djinni_count))) { 96. if (!enexto(&cc, mon->mx, mon->my, &mons[PM_DJINNI])) return 0; 97. mquaffmsg(mon, obj); 98. m_useup(mon, obj); 99. mtmp = makemon(&mons[PM_DJINNI], cc.x, cc.y); 100. if (!mtmp) { 101. if (vis) pline(empty); 102. } else { 103. if (vis) 104. pline("In a cloud of smoke, %s emerges!", 105. a_monnam(mtmp)); 106. pline("%s speaks.", vis ? Monnam(mtmp) : Something); 107. /* I suspect few players will be upset that monsters */ 108. /* can't wish for wands of death here.... */ 109. if (rn2(2)) { 110. verbalize("You freed me!"); 111. mtmp->mpeaceful = 1; 112. set_malign(mtmp); 113. } else { 114. verbalize("It is about time."); 115. if (vis) pline("%s vanishes.", Monnam(mtmp)); 116. mongone(mtmp); 117. } 118. } 119. return 2; 120. } 121. } 122. if (obj->oclass == WAND_CLASS && obj->cursed && !rn2(100)) { 123. int dam = d(obj->spe+2, 6); 124. 125. if (flags.soundok) { 126. if (vis) pline("%s zaps %s, which suddenly explodes!", 127. Monnam(mon), an(xname(obj))); 128. else You_hear("a zap and an explosion in the distance."); 129. } 130. m_useup(mon, obj); 131. if (mon->mhp <= dam) { 132. monkilled(mon, "", AD_RBRE); 133. return 1; 134. } 135. else mon->mhp -= dam; 136. m.has_defense = m.has_offense = m.has_misc = 0; 137. /* Only one needed to be set to 0 but the others are harmless */ 138. } 139. return 0; 140. } 141. 142. static void 143. mzapmsg(mtmp, otmp, self) 144. struct monst *mtmp; 145. struct obj *otmp; 146. boolean self; 147. { 148. if (!canseemon(mtmp)) { 149. if (flags.soundok) 150. You_hear("a distant zap."); 151. } else if (self) 152. pline("%s zaps %sself with %s!", 153. Monnam(mtmp), him[pronoun_gender(mtmp)], doname(otmp)); 154. else { 155. pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp))); 156. stop_occupation(); 157. } 158. } 159. 160. static void 161. mreadmsg(mtmp, otmp) 162. struct monst *mtmp; 163. struct obj *otmp; 164. { 165. boolean vismon = (canseemon(mtmp)); 166. if (flags.soundok) 167. otmp->dknown = 1; 168. if (!vismon) { 169. if (flags.soundok) 170. You_hear("%s reading %s.", 171. an(Hallucination ? rndmonnam() : mtmp->data->mname), 172. singular(otmp, doname)); 173. } else pline("%s reads %s!", Monnam(mtmp), singular(otmp,doname)); 174. if (mtmp->mconf && (vismon || flags.soundok)) 175. pline("Being confused, %s mispronounces the magic words...", 176. vismon ? mon_nam(mtmp) : he[pronoun_gender(mtmp)]); 177. } 178. 179. static void 180. mquaffmsg(mtmp, otmp) 181. struct monst *mtmp; 182. struct obj *otmp; 183. { 184. if (canseemon(mtmp)) { 185. otmp->dknown = 1; 186. pline("%s drinks %s!", Monnam(mtmp), singular(otmp, doname)); 187. } else 188. if (flags.soundok) 189. You_hear("a chugging sound."); 190. } 191. 192. /* Defines for various types of stuff. The order in which monsters prefer 193. * to use them is determined by the order of the code logic, not the 194. * numerical order in which they are defined. 195. */ 196. #define MUSE_SCR_TELEPORTATION 1 197. #define MUSE_WAN_TELEPORTATION_SELF 2 198. #define MUSE_POT_HEALING 3 199. #define MUSE_POT_EXTRA_HEALING 4 200. #define MUSE_WAN_DIGGING 5 201. #define MUSE_TRAPDOOR 6 202. #define MUSE_TELEPORT_TRAP 7 203. #define MUSE_UPSTAIRS 8 204. #define MUSE_DOWNSTAIRS 9 205. #define MUSE_WAN_CREATE_MONSTER 10 206. #define MUSE_SCR_CREATE_MONSTER 11 207. #define MUSE_UP_LADDER 12 208. #define MUSE_DN_LADDER 13 209. #define MUSE_SSTAIRS 14 210. #define MUSE_WAN_TELEPORTATION 15 211. #define MUSE_BUGLE 16 212. #define MUSE_UNICORN_HORN 17 213. /* 214. #define MUSE_INNATE_TPT 9999 215. * We cannot use this. Since monsters get unlimited teleportation, if they 216. * were allowed to teleport at will you could never catch them. Instead, 217. * assume they only teleport at random times, despite the inconsistency that if 218. * you polymorph into one you teleport at will. 219. */ 220. 221. /* Select a defensive item/action for a monster. Returns TRUE iff one is 222. * found. 223. */ 224. boolean 225. find_defensive(mtmp) 226. struct monst *mtmp; 227. { 228. register struct obj *obj = 0; 229. struct trap *t; 230. int x=mtmp->mx, y=mtmp->my; 231. boolean stuck = (mtmp == u.ustuck); 232. boolean immobile = (mtmp->data->mmove == 0); 233. int fraction; 234. 235. if (is_animal(mtmp->data) || mindless(mtmp->data)) 236. return FALSE; 237. if(dist2(x, y, mtmp->mux, mtmp->muy) > 25) 238. return FALSE; 239. if (u.uswallow && stuck) return FALSE; 240. 241. m.defensive = (struct obj *)0; 242. m.has_defense = 0; 243. 244. /* since unicorn horns don't get used up, the monster would look 245. * silly trying to use the same cursed horn round after round 246. */ 247. if (mtmp->mconf || mtmp->mstun || !mtmp->mcansee) { 248. if (mtmp->data->mlet != S_UNICORN && !nohands(mtmp->data)) { 249. for(obj = mtmp->minvent; obj; obj = obj->nobj) 250. if (obj->otyp == UNICORN_HORN && !obj->cursed) 251. break; 252. } 253. if (obj || (mtmp->data->mlet == S_UNICORN)) { 254. m.defensive = obj; 255. m.has_defense = MUSE_UNICORN_HORN; 256. return TRUE; 257. } 258. } 259. 260. /* It so happens there are two unrelated cases when we might want to 261. * check specifically for healing alone. The first is when the monster 262. * is blind (healing cures blindness). The second is when the monster 263. * is peaceful; then we don't want to flee the player, and by 264. * coincidence healing is all there is that doesn't involve fleeing. 265. * These would be hard to combine because of the control flow. 266. */ 267. if (!mtmp->mcansee && !nohands(mtmp->data)) { 268. if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) { 269. m.defensive = obj; 270. m.has_defense = MUSE_POT_EXTRA_HEALING; 271. return TRUE; 272. } 273. if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) { 274. m.defensive = obj; 275. m.has_defense = MUSE_POT_HEALING; 276. return TRUE; 277. } 278. } 279. 280. fraction = u.ulevel < 10 ? 5 : u.ulevel < 14 ? 4 : 3; 281. if(mtmp->mhp >= mtmp->mhpmax || 282. (mtmp->mhp >= 10 && mtmp->mhp*fraction >= mtmp->mhpmax)) 283. return FALSE; 284. 285. if (mtmp->mpeaceful) { 286. if (!nohands(mtmp->data)) { 287. if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) { 288. m.defensive = obj; 289. m.has_defense = MUSE_POT_EXTRA_HEALING; 290. return TRUE; 291. } 292. if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) { 293. m.defensive = obj; 294. m.has_defense = MUSE_POT_HEALING; 295. return TRUE; 296. } 297. } 298. return FALSE; 299. } 300. 301. if (levl[x][y].typ == STAIRS && !stuck && !immobile) { 302. if (x == xdnstair && y == ydnstair) 303. m.has_defense = MUSE_DOWNSTAIRS; 304. if (x == xupstair && y == yupstair && ledger_no(&u.uz) != 1) 305. /* Unfair to let the monsters leave the dungeon with the Amulet */ 306. /* (or go to the endlevel since you also need it, to get there) */ 307. m.has_defense = MUSE_UPSTAIRS; 308. } else if (levl[x][y].typ == LADDER && !stuck && !immobile) { 309. if (x == xupladder && y == yupladder) 310. m.has_defense = MUSE_UP_LADDER; 311. if (x == xdnladder && y == ydnladder) 312. m.has_defense = MUSE_DN_LADDER; 313. } else if (sstairs.sx && sstairs.sx == x && sstairs.sy == y) { 314. m.has_defense = MUSE_SSTAIRS; 315. } else if (!stuck && !immobile) { 316. /* Note: trapdoors take precedence over teleport traps. */ 317. int xx, yy; 318. 319. for(xx = x-1; xx <= x+1; xx++) for(yy = y-1; yy <= y+1; yy++) 320. if (isok(xx,yy)) 321. if (xx != u.ux && yy != u.uy) 322. if (mtmp->data != &mons[PM_GRID_BUG] || xx == x || yy == y) 323. if ((xx==x && yy==y) || !level.monsters[xx][yy]) 324. if ((t = t_at(xx,yy)) != 0) 325. if ((verysmall(mtmp->data) || throws_rocks(mtmp->data) || 326. passes_walls(mtmp->data)) || !sobj_at(BOULDER, xx, yy)) 327. if (!onscary(xx,yy,mtmp)) { 328. if ((t->ttyp == TRAPDOOR || t->ttyp == HOLE) 329. && !is_floater(mtmp->data) 330. && !mtmp->isshk && !mtmp->isgd 331. && !mtmp->ispriest 332. && Can_fall_thru(&u.uz) 333. ) { 334. trapx = xx; 335. trapy = yy; 336. m.has_defense = MUSE_TRAPDOOR; 337. } else if (t->ttyp == TELEP_TRAP && m.has_defense != MUSE_TRAPDOOR) { 338. trapx = xx; 339. trapy = yy; 340. m.has_defense = MUSE_TELEPORT_TRAP; 341. } 342. } 343. } 344. 345. if (nohands(mtmp->data)) /* can't use objects */ 346. goto botm; 347. 348. if (is_mercenary(mtmp->data) && (obj = m_carrying(mtmp, BUGLE))) { 349. int xx, yy; 350. struct monst *mon; 351. 352. /* Distance is arbitrary. What we really want to do is 353. * have the soldier play the bugle when it sees or 354. * remembers soldiers nearby... 355. */ 356. for(xx = x-3; xx <= x+3; xx++) for(yy = y-3; yy <= y+3; yy++) 357. if (isok(xx,yy)) 358. if ((mon = m_at(xx,yy)) && is_mercenary(mon->data) && 359. mon->data != &mons[PM_GUARD] && 360. (mon->msleep || (!mon->mcanmove))) { 361. m.defensive = obj; 362. m.has_defense = MUSE_BUGLE; 363. } 364. } 365. 366. /* use immediate physical escape prior to attempting magic */ 367. if (m.has_defense) /* stairs, trapdoor or tele-trap, bugle alert */ 368. goto botm; 369. 370. /* kludge to cut down on trap destruction (particularly portals) */ 371. t = t_at(x,y); 372. if (t && (t->ttyp == PIT || t->ttyp == SPIKED_PIT || 373. t->ttyp == WEB || t->ttyp == BEAR_TRAP)) 374. t = 0; /* ok for monster to dig here */ 375. 376. #define nomore(x) if(m.has_defense==x) continue; 377. for (obj = mtmp->minvent; obj; obj = obj->nobj) { 378. /* don't always use the same selection pattern */ 379. if (m.has_defense && !rn2(3)) break; 380. 381. /* nomore(MUSE_WAN_DIGGING); */ 382. if (m.has_defense == MUSE_WAN_DIGGING) break; 383. if (obj->otyp == WAN_DIGGING && obj->spe > 0 && !stuck && !t 384. && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest 385. && !is_floater(mtmp->data) 386. /* digging wouldn't be effective; assume they know that */ 387. && !(levl[x][y].wall_info & W_NONDIGGABLE) 388. && !(Is_botlevel(&u.uz) || In_endgame(&u.uz)) 389. && !(is_ice(x,y) || is_pool(x,y) || is_lava(x,y))) { 390. m.defensive = obj; 391. m.has_defense = MUSE_WAN_DIGGING; 392. } 393. nomore(MUSE_WAN_TELEPORTATION_SELF); 394. nomore(MUSE_WAN_TELEPORTATION); 395. if(obj->otyp == WAN_TELEPORTATION && obj->spe > 0) { 396. m.defensive = obj; 397. m.has_defense = (mon_has_amulet(mtmp)) 398. ? MUSE_WAN_TELEPORTATION 399. : MUSE_WAN_TELEPORTATION_SELF; 400. } 401. nomore(MUSE_SCR_TELEPORTATION); 402. if(obj->otyp == SCR_TELEPORTATION && mtmp->mcansee 403. && haseyes(mtmp->data) 404. && (!obj->cursed || 405. (!(mtmp->isshk && inhishop(mtmp)) 406. && !mtmp->isgd && !mtmp->ispriest))) { 407. m.defensive = obj; 408. m.has_defense = MUSE_SCR_TELEPORTATION; 409. } 410. nomore(MUSE_POT_EXTRA_HEALING); 411. if(obj->otyp == POT_EXTRA_HEALING) { 412. m.defensive = obj; 413. m.has_defense = MUSE_POT_EXTRA_HEALING; 414. } 415. nomore(MUSE_WAN_CREATE_MONSTER); 416. if(obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) { 417. m.defensive = obj; 418. m.has_defense = MUSE_WAN_CREATE_MONSTER; 419. } 420. nomore(MUSE_POT_HEALING); 421. if(obj->otyp == POT_HEALING) { 422. m.defensive = obj; 423. m.has_defense = MUSE_POT_HEALING; 424. } 425. nomore(MUSE_SCR_CREATE_MONSTER); 426. if(obj->otyp == SCR_CREATE_MONSTER) { 427. m.defensive = obj; 428. m.has_defense = MUSE_SCR_CREATE_MONSTER; 429. } 430. } 431. botm: return((boolean)(!!m.has_defense)); 432. #undef nomore 433. } 434. 435. /* Perform a defensive action for a monster. Must be called immediately 436. * after find_defensive(). Return values are 0: did something, 1: died, 437. * 2: did something and can't attack again (i.e. teleported). 438. */ 439. int 440. use_defensive(mtmp) 441. struct monst *mtmp; 442. { 443. int i, fleetim, how = 0; 444. struct obj *otmp = m.defensive; 445. boolean vis, vismon, oseen; 446. const char *mcsa = "%s can see again."; 447. 448. if ((i = precheck(mtmp, otmp)) != 0) return i; 449. vis = cansee(mtmp->mx, mtmp->my); 450. vismon = canseemon(mtmp); 451. oseen = otmp && vismon; 452. 453. /* when using defensive choice to run away, we want monster to avoid 454. rushing right straight back; don't override if already scared */ 455. fleetim = !mtmp->mflee ? (33 - (30 * mtmp->mhp / mtmp->mhpmax)) : 0; 456. #define m_flee(m) if (fleetim && !m->iswiz) \ 457. { m->mflee = 1; m->mfleetim = fleetim; } 458. 459. switch(m.has_defense) { 460. case MUSE_UNICORN_HORN: 461. if (vismon) { 462. if (otmp) 463. pline("%s grasps %s!", Monnam(mtmp), doname(otmp)); 464. else 465. pline("The tip of %s's horn glows!", mon_nam(mtmp)); 466. } 467. if (!mtmp->mcansee) { 468. mtmp->mcansee = 1; 469. mtmp->mblinded = 0; 470. if (vismon) pline(mcsa, Monnam(mtmp)); 471. } else if (mtmp->mconf || mtmp->mstun) { 472. mtmp->mconf = mtmp->mstun = 0; 473. if (vismon) 474. pline("%s seems steadier now.", Monnam(mtmp)); 475. } else impossible("No need for unicorn horn?"); 476. return 2; 477. case MUSE_BUGLE: 478. if (vismon) 479. pline("%s plays %s!", Monnam(mtmp), doname(otmp)); 480. else if (flags.soundok) 481. You_hear("a bugle playing reveille!"); 482. awaken_soldiers(); 483. return 2; 484. case MUSE_WAN_TELEPORTATION_SELF: 485. if ((mtmp->isshk && inhishop(mtmp)) 486. || mtmp->isgd || mtmp->ispriest) return 2; 487. m_flee(mtmp); 488. mzapmsg(mtmp, otmp, TRUE); 489. otmp->spe--; 490. how = WAN_TELEPORTATION; 491. mon_tele: 492. if (tele_restrict(mtmp)) { /* mysterious force... */ 493. if (vismon && how) /* mentions 'teleport' */ 494. makeknown(how); 495. return 2; 496. } 497. if (( 498. #if 0 499. mon_has_amulet(mtmp) || 500. #endif 501. On_W_tower_level(&u.uz)) && !rn2(3)) { 502. if (vismon) 503. pline("%s seems disoriented for a moment.", 504. Monnam(mtmp)); 505. return 2; 506. } 507. if (oseen && how) makeknown(how); 508. rloc(mtmp); 509. return 2; 510. case MUSE_WAN_TELEPORTATION: 511. zap_oseen = oseen; 512. mzapmsg(mtmp, otmp, FALSE); 513. otmp->spe--; 514. m_using = TRUE; 515. mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp); 516. m_using = FALSE; 517. return 2; 518. case MUSE_SCR_TELEPORTATION: 519. { 520. int obj_is_cursed = otmp->cursed; 521. 522. if (mtmp->isshk || mtmp->isgd || mtmp->ispriest) return 2; 523. m_flee(mtmp); 524. mreadmsg(mtmp, otmp); 525. m_useup(mtmp, otmp); /* otmp might be free'ed */ 526. how = SCR_TELEPORTATION; 527. if (obj_is_cursed || mtmp->mconf) { 528. int nlev; 529. d_level flev; 530. 531. if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) { 532. if (vismon) 533. pline("%s seems very disoriented for a moment.", 534. Monnam(mtmp)); 535. return 2; 536. } 537. nlev = random_teleport_level(); 538. if (nlev == depth(&u.uz)) { 539. if (vismon) 540. pline("%s shudders for a moment.", 541. Monnam(mtmp)); 542. return 2; 543. } 544. get_level(&flev, nlev); 545. migrate_to_level(mtmp, ledger_no(&flev), MIGR_RANDOM, 546. (coord *)0); 547. if (oseen) makeknown(SCR_TELEPORTATION); 548. } else goto mon_tele; 549. return 2; 550. } 551. case MUSE_WAN_DIGGING: 552. { struct trap *ttmp; 553. 554. m_flee(mtmp); 555. mzapmsg(mtmp, otmp, FALSE); 556. otmp->spe--; 557. if (oseen) makeknown(WAN_DIGGING); 558. if (IS_FURNITURE(levl[mtmp->mx][mtmp->my].typ) || 559. IS_DRAWBRIDGE(levl[mtmp->mx][mtmp->my].typ) || 560. (is_drawbridge_wall(mtmp->mx, mtmp->my) >= 0) || 561. (sstairs.sx && sstairs.sx == mtmp->mx && 562. sstairs.sy == mtmp->my)) { 563. pline_The("digging ray is ineffective."); 564. return 2; 565. } 566. if (!Can_dig_down(&u.uz)) { 567. if(canseemon(mtmp)) 568. pline_The("floor here is too hard to dig in."); 569. return 2; 570. } 571. ttmp = maketrap(mtmp->mx, mtmp->my, HOLE); 572. if (!ttmp) return 2; 573. seetrap(ttmp); 574. if (vis) { 575. pline("%s has made a hole in the floor.", Monnam(mtmp)); 576. pline("%s %s through...", Monnam(mtmp), 577. is_flyer(mtmp->data) ? "dives" : "falls"); 578. } else if (flags.soundok) 579. You_hear("%s crash through the floor.", something); 580. /* we made sure that there is a level for mtmp to go to */ 581. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 582. MIGR_RANDOM, (coord *)0); 583. return 2; 584. } 585. case MUSE_WAN_CREATE_MONSTER: 586. { coord cc; 587. /* pm: 0 => random, eel => aquatic, croc => amphibious */ 588. struct permonst *pm = !is_pool(mtmp->mx, mtmp->my) ? 0 : 589. &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE]; 590. struct monst *mon; 591. 592. if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) return 0; 593. mzapmsg(mtmp, otmp, FALSE); 594. otmp->spe--; 595. mon = makemon((struct permonst *)0, cc.x, cc.y); 596. if (mon && canspotmon(mon) && oseen) 597. makeknown(WAN_CREATE_MONSTER); 598. return 2; 599. } 600. case MUSE_SCR_CREATE_MONSTER: 601. { coord cc; 602. struct permonst *pm = 0, *fish = 0; 603. int cnt = 1; 604. struct monst *mon; 605. boolean known = FALSE; 606. 607. if (!rn2(73)) cnt += rnd(4); 608. if (mtmp->mconf || otmp->cursed) cnt += 12; 609. if (mtmp->mconf) pm = fish = &mons[PM_ACID_BLOB]; 610. else if (is_pool(mtmp->mx, mtmp->my)) 611. fish = &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE]; 612. mreadmsg(mtmp, otmp); 613. while(cnt--) { 614. /* `fish' potentially gives bias towards water locations; 615. `pm' is what to actually create (0 => random) */ 616. if (!enexto(&cc, mtmp->mx, mtmp->my, fish)) break; 617. mon = makemon(pm, cc.x, cc.y); 618. if (mon && canspotmon(mon)) known = TRUE; 619. } 620. /* The only case where we don't use oseen. For wands, you 621. * have to be able to see the monster zap the wand to know 622. * what type it is. For teleport scrolls, you have to see 623. * the monster to know it teleported. 624. */ 625. if (known) 626. makeknown(SCR_CREATE_MONSTER); 627. else if (!objects[SCR_CREATE_MONSTER].oc_name_known 628. && !objects[SCR_CREATE_MONSTER].oc_uname) 629. docall(otmp); 630. m_useup(mtmp, otmp); 631. return 2; 632. } 633. case MUSE_TRAPDOOR: 634. /* trapdoors on "bottom" levels of dungeons are rock-drop 635. * trapdoors, not holes in the floor. We check here for 636. * safety. 637. */ 638. if (Is_botlevel(&u.uz)) return 0; 639. m_flee(mtmp); 640. if (vis) { 641. struct trap *t; 642. t = t_at(trapx,trapy); 643. pline("%s %s into a %s!", Monnam(mtmp), 644. makeplural(locomotion(mtmp->data, "jump")), 645. t->ttyp == TRAPDOOR ? "trapdoor" : "hole"); 646. seetrap(t_at(trapx,trapy)); 647. } 648. 649. /* don't use rloc_to() because worm tails must "move" */ 650. remove_monster(mtmp->mx, mtmp->my); 651. newsym(mtmp->mx, mtmp->my); /* update old location */ 652. place_monster(mtmp, trapx, trapy); 653. if (mtmp->wormno) worm_move(mtmp); 654. newsym(trapx, trapy); 655. 656. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 657. MIGR_RANDOM, (coord *)0); 658. return 2; 659. case MUSE_UPSTAIRS: 660. /* Monsters without amulets escape the dungeon and are 661. * gone for good when they leave up the up stairs. 662. * Monsters with amulets would reach the endlevel, 663. * which we cannot allow since that would leave the 664. * player stranded. 665. */ 666. if (ledger_no(&u.uz) == 1) { 667. if (mon_has_special(mtmp)) 668. return 0; 669. if (vismon) 670. pline("%s escapes the dungeon!", Monnam(mtmp)); 671. mongone(mtmp); 672. return 2; 673. } 674. m_flee(mtmp); 675. if (Inhell && mon_has_amulet(mtmp) && !rn2(4) && 676. (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) { 677. if (vismon) pline( 678. "As %s climbs the stairs, a mysterious force momentarily surrounds %s...", 679. mon_nam(mtmp), him[pronoun_gender(mtmp)]); 680. /* simpler than for the player; this will usually be 681. the Wizard and he'll immediately go right to the 682. upstairs, so there's not much point in having any 683. chance for a random position on the current level */ 684. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 685. MIGR_RANDOM, (coord *)0); 686. } else { 687. if (vismon) pline("%s escapes upstairs!", Monnam(mtmp)); 688. migrate_to_level(mtmp, ledger_no(&u.uz) - 1, 689. MIGR_STAIRS_DOWN, (coord *)0); 690. } 691. return 2; 692. case MUSE_DOWNSTAIRS: 693. m_flee(mtmp); 694. if (vismon) pline("%s escapes downstairs!", Monnam(mtmp)); 695. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 696. MIGR_STAIRS_UP, (coord *)0); 697. return 2; 698. case MUSE_UP_LADDER: 699. m_flee(mtmp); 700. if (vismon) pline("%s escapes up the ladder!", Monnam(mtmp)); 701. migrate_to_level(mtmp, ledger_no(&u.uz) - 1, 702. MIGR_LADDER_DOWN, (coord *)0); 703. return 2; 704. case MUSE_DN_LADDER: 705. m_flee(mtmp); 706. if (vismon) pline("%s escapes down the ladder!", Monnam(mtmp)); 707. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 708. MIGR_LADDER_UP, (coord *)0); 709. return 2; 710. case MUSE_SSTAIRS: 711. m_flee(mtmp); 712. /* the stairs leading up from the 1st level are */ 713. /* regular stairs, not sstairs. */ 714. if (sstairs.up) { 715. if (vismon) 716. pline("%s escapes upstairs!", Monnam(mtmp)); 717. if(Inhell) { 718. migrate_to_level(mtmp, ledger_no(&sstairs.tolev), 719. MIGR_RANDOM, (coord *)0); 720. return 2; 721. } 722. } else if (vismon) 723. pline("%s escapes downstairs!", Monnam(mtmp)); 724. migrate_to_level(mtmp, ledger_no(&sstairs.tolev), 725. MIGR_SSTAIRS, (coord *)0); 726. return 2; 727. case MUSE_TELEPORT_TRAP: 728. m_flee(mtmp); 729. if (vis) { 730. pline("%s %s onto a teleport trap!", Monnam(mtmp), 731. makeplural(locomotion(mtmp->data, "jump"))); 732. seetrap(t_at(trapx,trapy)); 733. } 734. /* don't use rloc_to() because worm tails must "move" */ 735. remove_monster(mtmp->mx, mtmp->my); 736. newsym(mtmp->mx, mtmp->my); /* update old location */ 737. place_monster(mtmp, trapx, trapy); 738. if (mtmp->wormno) worm_move(mtmp); 739. newsym(trapx, trapy); 740. 741. goto mon_tele; 742. case MUSE_POT_HEALING: 743. mquaffmsg(mtmp, otmp); 744. i = d(6 + 2 * bcsign(otmp), 4); 745. mtmp->mhp += i; 746. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = ++mtmp->mhpmax; 747. if (!otmp->cursed && !mtmp->mcansee) { 748. mtmp->mcansee = 1; 749. mtmp->mblinded = 0; 750. if (vismon) pline(mcsa, Monnam(mtmp)); 751. } 752. if (vismon) pline("%s looks better.", Monnam(mtmp)); 753. if (oseen) makeknown(POT_HEALING); 754. m_useup(mtmp, otmp); 755. return 2; 756. case MUSE_POT_EXTRA_HEALING: 757. mquaffmsg(mtmp, otmp); 758. i = d(6 + 2 * bcsign(otmp), 8); 759. mtmp->mhp += i; 760. if (mtmp->mhp > mtmp->mhpmax) 761. mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2)); 762. if (!mtmp->mcansee) { 763. mtmp->mcansee = 1; 764. mtmp->mblinded = 0; 765. if (vismon) pline(mcsa, Monnam(mtmp)); 766. } 767. if (vismon) pline("%s looks much better.", Monnam(mtmp)); 768. if (oseen) makeknown(POT_EXTRA_HEALING); 769. m_useup(mtmp, otmp); 770. return 2; 771. case 0: return 0; /* i.e. an exploded wand */ 772. default: impossible("%s wanted to perform action %d?", Monnam(mtmp), 773. m.has_defense); 774. break; 775. } 776. return 0; 777. #undef m_flee 778. } 779. 780. int 781. rnd_defensive_item(mtmp) 782. struct monst *mtmp; 783. { 784. struct permonst *pm = mtmp->data; 785. int difficulty = monstr[(monsndx(pm))]; 786. 787. if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data) 788. || pm->mlet == S_GHOST 789. # ifdef KOPS 790. || pm->mlet == S_KOP 791. # endif 792. ) return 0; 793. switch (rn2(8 + (difficulty > 3) + (difficulty > 6) + 794. (difficulty > 8))) { 795. case 6: case 9: 796. if (!rn2(3)) return WAN_TELEPORTATION; 797. /* else FALLTHRU */ 798. case 0: case 1: 799. return SCR_TELEPORTATION; 800. case 8: case 10: 801. if (!rn2(3)) return WAN_CREATE_MONSTER; 802. /* else FALLTHRU */ 803. case 2: return SCR_CREATE_MONSTER; 804. case 3: case 4: 805. return POT_HEALING; 806. case 5: return POT_EXTRA_HEALING; 807. case 7: if (is_floater(pm) || mtmp->isshk || mtmp->isgd 808. || mtmp->ispriest 809. ) 810. return 0; 811. else 812. return WAN_DIGGING; 813. } 814. /*NOTREACHED*/ 815. return 0; 816. } 817. 818. #define MUSE_WAN_DEATH 1 819. #define MUSE_WAN_SLEEP 2 820. #define MUSE_WAN_FIRE 3 821. #define MUSE_WAN_COLD 4 822. #define MUSE_WAN_LIGHTNING 5 823. #define MUSE_WAN_MAGIC_MISSILE 6 824. #define MUSE_WAN_STRIKING 7 825. #define MUSE_SCR_FIRE 8 826. #define MUSE_POT_PARALYSIS 9 827. #define MUSE_POT_BLINDNESS 10 828. #define MUSE_POT_CONFUSION 11 829. 830. /* Select an offensive item/action for a monster. Returns TRUE iff one is 831. * found. 832. */ 833. boolean 834. find_offensive(mtmp) 835. struct monst *mtmp; 836. { 837. register struct obj *obj; 838. boolean ranged_stuff = lined_up(mtmp); 839. boolean reflection_skip = (Reflecting && rn2(2)); 840. 841. m.offensive = (struct obj *)0; 842. m.has_offense = 0; 843. if (mtmp->mpeaceful || is_animal(mtmp->data) || 844. mindless(mtmp->data) || nohands(mtmp->data)) 845. return FALSE; 846. if (u.uswallow) return FALSE; 847. if (in_your_sanctuary(mtmp->mx, mtmp->my)) return FALSE; 848. if (dmgtype(mtmp->data, AD_HEAL) && !uwep 849. #ifdef TOURIST 850. && !uarmu 851. #endif 852. && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) 853. return FALSE; 854. 855. if (!ranged_stuff) return FALSE; 856. #define nomore(x) if(m.has_offense==x) continue; 857. for(obj=mtmp->minvent; obj; obj=obj->nobj) { 858. /* nomore(MUSE_WAN_DEATH); */ 859. if (!reflection_skip) { 860. if(obj->otyp == WAN_DEATH && obj->spe > 0) { 861. m.offensive = obj; 862. m.has_offense = MUSE_WAN_DEATH; 863. } 864. nomore(MUSE_WAN_SLEEP); 865. if(obj->otyp == WAN_SLEEP && obj->spe > 0 && multi >= 0) { 866. m.offensive = obj; 867. m.has_offense = MUSE_WAN_SLEEP; 868. } 869. nomore(MUSE_WAN_FIRE); 870. if(obj->otyp == WAN_FIRE && obj->spe > 0) { 871. m.offensive = obj; 872. m.has_offense = MUSE_WAN_FIRE; 873. } 874. nomore(MUSE_WAN_COLD); 875. if(obj->otyp == WAN_COLD && obj->spe > 0) { 876. m.offensive = obj; 877. m.has_offense = MUSE_WAN_COLD; 878. } 879. nomore(MUSE_WAN_LIGHTNING); 880. if(obj->otyp == WAN_LIGHTNING && obj->spe > 0) { 881. m.offensive = obj; 882. m.has_offense = MUSE_WAN_LIGHTNING; 883. } 884. nomore(MUSE_WAN_MAGIC_MISSILE); 885. if(obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) { 886. m.offensive = obj; 887. m.has_offense = MUSE_WAN_MAGIC_MISSILE; 888. } 889. } 890. nomore(MUSE_WAN_STRIKING); 891. if(obj->otyp == WAN_STRIKING && obj->spe > 0) { 892. m.offensive = obj; 893. m.has_offense = MUSE_WAN_STRIKING; 894. } 895. nomore(MUSE_POT_PARALYSIS); 896. if(obj->otyp == POT_PARALYSIS && multi >= 0) { 897. m.offensive = obj; 898. m.has_offense = MUSE_POT_PARALYSIS; 899. } 900. nomore(MUSE_POT_BLINDNESS); 901. if(obj->otyp == POT_BLINDNESS) { 902. m.offensive = obj; 903. m.has_offense = MUSE_POT_BLINDNESS; 904. } 905. nomore(MUSE_POT_CONFUSION); 906. if(obj->otyp == POT_CONFUSION) { 907. m.offensive = obj; 908. m.has_offense = MUSE_POT_CONFUSION; 909. } 910. #if 0 911. nomore(MUSE_SCR_FIRE); 912. /* even more restrictive than ranged_stuff */ 913. if (obj->otyp == SCR_FIRE && resists_fire(mtmp) 914. && distu(mtmp->mx,mtmp->my)==1 915. && mtmp->mcansee && haseyes(mtmp->data)) { 916. m.offensive = obj; 917. m.has_offense = MUSE_SCR_FIRE; 918. } 919. #endif 920. } 921. return((boolean)(!!m.has_offense)); 922. #undef nomore 923. } 924. 925. STATIC_PTR 926. int 927. mbhitm(mtmp, otmp) 928. register struct monst *mtmp; 929. register struct obj *otmp; 930. { 931. int tmp; 932. 933. if (mtmp != &youmonst) { 934. mtmp->msleep = 0; 935. if (mtmp->m_ap_type) seemimic(mtmp); 936. } 937. switch(otmp->otyp) { 938. case WAN_STRIKING: 939. if (mtmp == &youmonst) { 940. if (zap_oseen) makeknown(WAN_STRIKING); 941. if (rnd(20) < 10 + u.uac) { 942. pline_The("wand hits you!"); 943. tmp = d(2,12); 944. if(Half_spell_damage) tmp = (tmp+1) / 2; 945. losehp(tmp, "wand", KILLED_BY_AN); 946. } else pline_The("wand misses you."); 947. stop_occupation(); 948. nomul(0); 949. } else if (rnd(20) < 10+find_mac(mtmp)) { 950. tmp = d(2,12); 951. if(Half_spell_damage) tmp = (tmp+1) / 2; 952. hit("wand", mtmp, exclam(tmp)); 953. (void) resist(mtmp, otmp->oclass, tmp, TELL); 954. if (cansee(mtmp->mx, mtmp->my) && zap_oseen) 955. makeknown(WAN_STRIKING); 956. } else { 957. miss("wand", mtmp); 958. if (cansee(mtmp->mx, mtmp->my) && zap_oseen) 959. makeknown(WAN_STRIKING); 960. } 961. break; 962. case WAN_TELEPORTATION: 963. if (mtmp == &youmonst) { 964. if (zap_oseen) makeknown(WAN_TELEPORTATION); 965. tele(); 966. } else { 967. /* for consistency with zap.c, don't identify */ 968. if (mtmp->ispriest && 969. *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) { 970. if (cansee(mtmp->mx, mtmp->my)) 971. pline("%s resists the magic!", Monnam(mtmp)); 972. mtmp->msleep = 0; 973. if(mtmp->m_ap_type) seemimic(mtmp); 974. } else 975. rloc(mtmp); 976. } 977. break; 978. case WAN_CANCELLATION: 979. case SPE_CANCELLATION: 980. cancel_monst(mtmp, otmp, FALSE, TRUE, FALSE); 981. break; 982. } 983. return 0; 984. } 985. 986. /* A modified bhit() for monsters. Based on bhit() in zap.c. Unlike 987. * buzz(), bhit() doesn't take into account the possibility of a monster 988. * zapping you, so we need a special function for it. (Unless someone wants 989. * to merge the two functions...) 990. */ 991. static void 992. mbhit(mon,range,fhitm,fhito,obj) 993. struct monst *mon; /* monster shooting the wand */ 994. register int range; /* direction and range */ 995. int FDECL((*fhitm),(MONST_P,OBJ_P)); 996. int FDECL((*fhito),(OBJ_P,OBJ_P)); /* fns called when mon/obj hit */ 997. struct obj *obj; /* 2nd arg to fhitm/fhito */ 998. { 999. register struct monst *mtmp; 1000. register struct obj *otmp; 1001. register uchar typ; 1002. int ddx, ddy; 1003. 1004. bhitpos.x = mon->mx; 1005. bhitpos.y = mon->my; 1006. ddx = sgn(mon->mux - mon->mx); 1007. ddy = sgn(mon->muy - mon->my); 1008. 1009. while(range-- > 0) { 1010. int x,y; 1011. 1012. bhitpos.x += ddx; 1013. bhitpos.y += ddy; 1014. x = bhitpos.x; y = bhitpos.y; 1015. 1016. if (!isok(x,y)) { 1017. bhitpos.x -= ddx; 1018. bhitpos.y -= ddy; 1019. break; 1020. } 1021. if (find_drawbridge(&x,&y)) 1022. switch (obj->otyp) { 1023. case WAN_STRIKING: 1024. destroy_drawbridge(x,y); 1025. } 1026. if(bhitpos.x==u.ux && bhitpos.y==u.uy) { 1027. (*fhitm)(&youmonst, obj); 1028. range -= 3; 1029. } else if(MON_AT(bhitpos.x, bhitpos.y)){ 1030. mtmp = m_at(bhitpos.x,bhitpos.y); 1031. (*fhitm)(mtmp, obj); 1032. range -= 3; 1033. } 1034. /* modified by GAN to hit all objects */ 1035. if(fhito){ 1036. int hitanything = 0; 1037. register struct obj *next_obj; 1038. 1039. for(otmp = level.objects[bhitpos.x][bhitpos.y]; 1040. otmp; otmp = next_obj) { 1041. /* Fix for polymorph bug, Tim Wright */ 1042. next_obj = otmp->nexthere; 1043. hitanything += (*fhito)(otmp, obj); 1044. } 1045. if(hitanything) range--; 1046. } 1047. typ = levl[bhitpos.x][bhitpos.y].typ; 1048. if(IS_DOOR(typ) || typ == SDOOR) { 1049. switch (obj->otyp) { 1050. /* note: monsters don't use opening or locking magic 1051. at present, but keep these as placeholders */ 1052. case WAN_OPENING: 1053. case WAN_LOCKING: 1054. case WAN_STRIKING: 1055. if (doorlock(obj, bhitpos.x, bhitpos.y)) { 1056. makeknown(obj->otyp); 1057. /* if a shop door gets broken, add it to 1058. the shk's fix list (no cost to player) */ 1059. if (levl[bhitpos.x][bhitpos.y].doormask == 1060. D_BROKEN && 1061. *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE)) 1062. add_damage(bhitpos.x, bhitpos.y, 0L); 1063. } 1064. break; 1065. } 1066. } 1067. if(!ZAP_POS(typ) || (IS_DOOR(typ) && 1068. (levl[bhitpos.x][bhitpos.y].doormask & (D_LOCKED | D_CLOSED))) 1069. ) { 1070. bhitpos.x -= ddx; 1071. bhitpos.y -= ddy; 1072. break; 1073. } 1074. } 1075. } 1076. 1077. /* Perform an offensive action for a monster. Must be called immediately 1078. * after find_offensive(). Return values are same as use_defensive(). 1079. */ 1080. int 1081. use_offensive(mtmp) 1082. struct monst *mtmp; 1083. { 1084. int i; 1085. struct obj *otmp = m.offensive; 1086. boolean oseen; 1087. 1088. /* offensive potions are not drunk, they're thrown */ 1089. if (otmp->oclass != POTION_CLASS && (i = precheck(mtmp, otmp)) != 0) 1090. return i; 1091. oseen = otmp && canseemon(mtmp); 1092. 1093. switch(m.has_offense) { 1094. case MUSE_WAN_DEATH: 1095. case MUSE_WAN_SLEEP: 1096. case MUSE_WAN_FIRE: 1097. case MUSE_WAN_COLD: 1098. case MUSE_WAN_LIGHTNING: 1099. case MUSE_WAN_MAGIC_MISSILE: 1100. mzapmsg(mtmp, otmp, FALSE); 1101. otmp->spe--; 1102. if (oseen) makeknown(otmp->otyp); 1103. m_using = TRUE; 1104. buzz((int)(-30 - (otmp->otyp - WAN_MAGIC_MISSILE)), 1105. (otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6, 1106. mtmp->mx, mtmp->my, 1107. sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my)); 1108. m_using = FALSE; 1109. return (mtmp->mhp <= 0) ? 1 : 2; 1110. case MUSE_WAN_TELEPORTATION: 1111. case MUSE_WAN_STRIKING: 1112. zap_oseen = oseen; 1113. mzapmsg(mtmp, otmp, FALSE); 1114. otmp->spe--; 1115. m_using = TRUE; 1116. mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp); 1117. m_using = FALSE; 1118. return 2; 1119. #if 0 1120. case MUSE_SCR_FIRE: 1121. { 1122. boolean vis = cansee(mtmp->mx, mtmp->my); 1123. 1124. mreadmsg(mtmp, otmp); 1125. if (mtmp->mconf) { 1126. if (vis) 1127. pline("Oh, what a pretty fire!"); 1128. } else { 1129. struct monst *mtmp2; 1130. int num; 1131. 1132. if (vis) 1133. pline_The("scroll erupts in a tower of flame!"); 1134. shieldeff(mtmp->mx, mtmp->my); 1135. pline("%s is uninjured.", Monnam(mtmp)); 1136. (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); 1137. (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); 1138. (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); 1139. num = (2*(rn1(3, 3) + 2 * bcsign(otmp)) + 1)/3; 1140. if (Fire_resistance) 1141. You("are not affected."); 1142. if (Half_spell_damage) num = (num+1) / 2; 1143. else losehp(num, "scroll of fire", KILLED_BY_AN); 1144. for(mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) { 1145. if(mtmp == mtmp2) continue; 1146. if(dist2(mtmp2->mx,mtmp2->my,mtmp->mx,mtmp->my) < 3){ 1147. if (resists_fire(mtmp2)) continue; 1148. mtmp2->mhp -= num; 1149. if (resists_cold(mtmp2)) 1150. mtmp2->mhp -= 3*num; 1151. if(mtmp2->mhp < 1) { 1152. mondied(mtmp2); 1153. break; 1154. } 1155. } 1156. } 1157. } 1158. return 2; 1159. } 1160. #endif /* 0 */ 1161. case MUSE_POT_PARALYSIS: 1162. case MUSE_POT_BLINDNESS: 1163. case MUSE_POT_CONFUSION: 1164. /* Note: this setting of dknown doesn't suffice. A monster 1165. * which is out of sight might throw and it hits something _in_ 1166. * sight, a problem not existing with wands because wand rays 1167. * are not objects. Also set dknown in mthrowu.c. 1168. */ 1169. if (cansee(mtmp->mx, mtmp->my)) { 1170. otmp->dknown = 1; 1171. pline("%s hurls %s!", Monnam(mtmp), 1172. singular(otmp, doname)); 1173. } 1174. m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux-mtmp->mx), 1175. sgn(mtmp->muy-mtmp->my), 1176. distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy), otmp); 1177. return 2; 1178. case 0: return 0; /* i.e. an exploded wand */ 1179. default: impossible("%s wanted to perform action %d?", Monnam(mtmp), 1180. m.has_offense); 1181. break; 1182. } 1183. return 0; 1184. } 1185. 1186. int 1187. rnd_offensive_item(mtmp) 1188. struct monst *mtmp; 1189. { 1190. struct permonst *pm = mtmp->data; 1191. int difficulty = monstr[(monsndx(pm))]; 1192. 1193. if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data) 1194. || pm->mlet == S_GHOST 1195. # ifdef KOPS 1196. || pm->mlet == S_KOP 1197. # endif 1198. ) return 0; 1199. if (difficulty > 7 && !rn2(35)) return WAN_DEATH; 1200. switch (rn2(7 - (difficulty < 4) + 4 * (difficulty > 6))) { 1201. case 0: case 1: 1202. return WAN_STRIKING; 1203. case 2: return POT_CONFUSION; 1204. case 3: return POT_BLINDNESS; 1205. case 4: return POT_PARALYSIS; 1206. case 5: case 6: 1207. return WAN_MAGIC_MISSILE; 1208. case 7: return WAN_SLEEP; 1209. case 8: return WAN_FIRE; 1210. case 9: return WAN_COLD; 1211. case 10: return WAN_LIGHTNING; 1212. } 1213. /*NOTREACHED*/ 1214. return 0; 1215. } 1216. 1217. #define MUSE_POT_GAIN_LEVEL 1 1218. #define MUSE_WAN_MAKE_INVISIBLE 2 1219. #define MUSE_POT_INVISIBILITY 3 1220. #define MUSE_POLY_TRAP 4 1221. #define MUSE_WAN_POLYMORPH 5 1222. #define MUSE_POT_SPEED 6 1223. #define MUSE_WAN_SPEED_MONSTER 7 1224. #define MUSE_BULLWHIP 8 1225. 1226. boolean 1227. find_misc(mtmp) 1228. struct monst *mtmp; 1229. { 1230. register struct obj *obj; 1231. struct permonst *mdat = mtmp->data; 1232. int x = mtmp->mx, y = mtmp->my; 1233. struct trap *t; 1234. int xx, yy; 1235. boolean immobile = (mdat->mmove == 0); 1236. boolean stuck = (mtmp == u.ustuck); 1237. 1238. m.misc = (struct obj *)0; 1239. m.has_misc = 0; 1240. if (is_animal(mdat) || mindless(mdat)) 1241. return 0; 1242. if (u.uswallow && stuck) return FALSE; 1243. 1244. /* We arbitrarily limit to times when a player is nearby for the 1245. * same reason as Junior Pac-Man doesn't have energizers eaten until 1246. * you can see them... 1247. */ 1248. if(dist2(x, y, mtmp->mux, mtmp->muy) > 36) 1249. return FALSE; 1250. 1251. if (!stuck && !immobile && !mtmp->cham && monstr[monsndx(mdat)] < 6) { 1252. boolean ignore_boulders = (verysmall(mdat) || 1253. throws_rocks(mdat) || 1254. passes_walls(mdat)); 1255. for(xx = x-1; xx <= x+1; xx++) 1256. for(yy = y-1; yy <= y+1; yy++) 1257. if (isok(xx,yy) && (xx != u.ux || yy != u.uy)) 1258. if (mdat != &mons[PM_GRID_BUG] || xx == x || yy == y) 1259. if (/* (xx==x && yy==y) || */ !level.monsters[xx][yy]) 1260. if ((t = t_at(xx, yy)) != 0 && 1261. (ignore_boulders || !sobj_at(BOULDER, xx, yy)) 1262. && !onscary(xx, yy, mtmp)) { 1263. if (t->ttyp == POLY_TRAP) { 1264. trapx = xx; 1265. trapy = yy; 1266. m.has_misc = MUSE_POLY_TRAP; 1267. return TRUE; 1268. } 1269. } 1270. } 1271. if (nohands(mdat)) 1272. return 0; 1273. 1274. #define nomore(x) if(m.has_misc==x) continue; 1275. for(obj=mtmp->minvent; obj; obj=obj->nobj) { 1276. /* Monsters shouldn't recognize cursed items; this kludge is */ 1277. /* necessary to prevent serious problems though... */ 1278. if(obj->otyp == POT_GAIN_LEVEL && (!obj->cursed || 1279. (!mtmp->isgd && !mtmp->isshk && !mtmp->ispriest))) { 1280. m.misc = obj; 1281. m.has_misc = MUSE_POT_GAIN_LEVEL; 1282. } 1283. nomore(MUSE_BULLWHIP); 1284. if(obj->otyp == BULLWHIP && (MON_WEP(mtmp) == obj) && 1285. distu(mtmp->mx,mtmp->my)==1 && uwep) { 1286. m.misc = obj; 1287. m.has_misc = MUSE_BULLWHIP; 1288. } 1289. /* Note: peaceful/tame monsters won't make themselves 1290. * invisible unless you can see them. Not really right, but... 1291. */ 1292. nomore(MUSE_WAN_MAKE_INVISIBLE); 1293. if(obj->otyp == WAN_MAKE_INVISIBLE && obj->spe > 0 && 1294. !mtmp->minvis && !mtmp->invis_blkd && 1295. (!mtmp->mpeaceful || See_invisible) && 1296. (mdat != &mons[PM_MEDUSA] || mtmp->mcan)) { 1297. m.misc = obj; 1298. m.has_misc = MUSE_WAN_MAKE_INVISIBLE; 1299. } 1300. nomore(MUSE_POT_INVISIBILITY); 1301. if(obj->otyp == POT_INVISIBILITY && 1302. !mtmp->minvis && !mtmp->invis_blkd && 1303. (!mtmp->mpeaceful || See_invisible)) { 1304. m.misc = obj; 1305. m.has_misc = MUSE_POT_INVISIBILITY; 1306. } 1307. nomore(MUSE_WAN_SPEED_MONSTER); 1308. if(obj->otyp == WAN_SPEED_MONSTER && obj->spe > 0 1309. && mtmp->mspeed != MFAST && !mtmp->isgd) { 1310. m.misc = obj; 1311. m.has_misc = MUSE_WAN_SPEED_MONSTER; 1312. } 1313. nomore(MUSE_POT_SPEED); 1314. if(obj->otyp == POT_SPEED && mtmp->mspeed != MFAST 1315. && !mtmp->isgd) { 1316. m.misc = obj; 1317. m.has_misc = MUSE_POT_SPEED; 1318. } 1319. nomore(MUSE_WAN_POLYMORPH); 1320. if(obj->otyp == WAN_POLYMORPH && obj->spe > 0 && !mtmp->cham 1321. && monstr[monsndx(mdat)] < 6) { 1322. m.misc = obj; 1323. m.has_misc = MUSE_WAN_POLYMORPH; 1324. } 1325. } 1326. return((boolean)(!!m.has_misc)); 1327. #undef nomore 1328. } 1329. 1330. int 1331. use_misc(mtmp) 1332. struct monst *mtmp; 1333. { 1334. int i; 1335. struct obj *otmp = m.misc; 1336. boolean vis, vismon, oseen; 1337. 1338. if ((i = precheck(mtmp, otmp)) != 0) return i; 1339. vis = cansee(mtmp->mx, mtmp->my); 1340. vismon = canseemon(mtmp); 1341. oseen = otmp && vismon; 1342. 1343. switch(m.has_misc) { 1344. case MUSE_POT_GAIN_LEVEL: 1345. mquaffmsg(mtmp, otmp); 1346. if (otmp->cursed) { 1347. if (Can_rise_up(mtmp->mx, mtmp->my, &u.uz)) { 1348. register int tolev = depth(&u.uz)-1; 1349. d_level tolevel; 1350. 1351. get_level(&tolevel, tolev); 1352. /* insurance against future changes... */ 1353. if(on_level(&tolevel, &u.uz)) goto skipmsg; 1354. if (vismon) { 1355. pline("%s rises up, through the %s!", 1356. Monnam(mtmp), ceiling(mtmp->mx, mtmp->my)); 1357. if(!objects[POT_GAIN_LEVEL].oc_name_known 1358. && !objects[POT_GAIN_LEVEL].oc_uname) 1359. docall(otmp); 1360. } 1361. m_useup(mtmp, otmp); 1362. migrate_to_level(mtmp, ledger_no(&tolevel), 1363. MIGR_RANDOM, (coord *)0); 1364. return 2; 1365. } else { 1366. skipmsg: 1367. if (vismon) { 1368. pline("%s looks uneasy.", Monnam(mtmp)); 1369. if(!objects[POT_GAIN_LEVEL].oc_name_known 1370. && !objects[POT_GAIN_LEVEL].oc_uname) 1371. docall(otmp); 1372. } 1373. m_useup(mtmp, otmp); 1374. return 2; 1375. } 1376. } 1377. if (vismon) pline("%s seems more experienced.", Monnam(mtmp)); 1378. if (oseen) makeknown(POT_GAIN_LEVEL); 1379. m_useup(mtmp, otmp); 1380. if (!grow_up(mtmp,(struct monst *)0)) return 1; 1381. /* grew into genocided monster */ 1382. return 2; 1383. case MUSE_WAN_MAKE_INVISIBLE: 1384. mzapmsg(mtmp, otmp, TRUE); 1385. otmp->spe--; 1386. mon_set_minvis(mtmp); 1387. return 2; 1388. case MUSE_POT_INVISIBILITY: 1389. mquaffmsg(mtmp, otmp); 1390. if (vis) { 1391. if (See_invisible) 1392. pline("%s body takes on a %s transparency.", 1393. s_suffix(Monnam(mtmp)), 1394. Hallucination ? "normal" : "strange"); 1395. else 1396. pline("Suddenly you cannot see %s.", mon_nam(mtmp)); 1397. } 1398. if (oseen) makeknown(POT_INVISIBILITY); 1399. mon_set_minvis(mtmp); 1400. if (otmp->cursed) you_aggravate(mtmp); 1401. m_useup(mtmp, otmp); 1402. return 2; 1403. case MUSE_WAN_SPEED_MONSTER: 1404. mzapmsg(mtmp, otmp, TRUE); 1405. otmp->spe--; 1406. if (mtmp->mspeed == MSLOW) mtmp->mspeed = 0; 1407. else mtmp->mspeed = MFAST; 1408. return 2; 1409. case MUSE_POT_SPEED: 1410. mquaffmsg(mtmp, otmp); 1411. if (vismon) pline("%s is suddenly moving much faster.", 1412. Monnam(mtmp)); 1413. if (oseen) makeknown(POT_SPEED); 1414. if (mtmp->mspeed == MSLOW) mtmp->mspeed = 0; 1415. else mtmp->mspeed = MFAST; 1416. m_useup(mtmp, otmp); 1417. return 2; 1418. case MUSE_WAN_POLYMORPH: 1419. mzapmsg(mtmp, otmp, TRUE); 1420. otmp->spe--; 1421. (void) newcham(mtmp, rndmonst()); 1422. if (oseen) makeknown(WAN_POLYMORPH); 1423. return 2; 1424. case MUSE_POLY_TRAP: 1425. if (vismon) 1426. pline("%s deliberately goes onto a polymorph trap!", 1427. Monnam(mtmp)); 1428. if (vis) seetrap(t_at(trapx,trapy)); 1429. 1430. /* don't use rloc() due to worms */ 1431. remove_monster(mtmp->mx, mtmp->my); 1432. newsym(mtmp->mx, mtmp->my); 1433. place_monster(mtmp, trapx, trapy); 1434. if (mtmp->wormno) worm_move(mtmp); 1435. newsym(trapx, trapy); 1436. 1437. (void) newcham(mtmp, (struct permonst *)0); 1438. return 2; 1439. case MUSE_BULLWHIP: 1440. /* attempt to disarm hero */ 1441. if (uwep) { 1442. if (!rn2(5)) { 1443. int where_to = rn2(4); 1444. struct obj *obj = uwep; 1445. 1446. if (vismon) 1447. pline("%s flicks a bullwhip towards your %s!", 1448. Monnam(mtmp), 1449. body_part(HAND)); 1450. if (obj->otyp == HEAVY_IRON_BALL) { 1451. pline_The("bullwhip does not wrap around %s.", 1452. the(xname(obj))); 1453. return 1; 1454. } 1455. pline_The("bullwhip wraps around %s %s!", 1456. the(xname(obj)), 1457. "you're wielding"); 1458. if (!where_to) { 1459. pline_The("bullwhip slips free."); 1460. return 1; 1461. } 1462. freeinv(obj); 1463. setuwep((struct obj *)0); 1464. switch (where_to) { 1465. case 1: /* onto floor beneath mon */ 1466. pline("%s yanks %s from your %s!", 1467. Monnam(mtmp), 1468. the(xname(obj)), 1469. body_part(HAND)); 1470. if(obj->otyp == CRYSKNIFE) 1471. obj->otyp = WORM_TOOTH; 1472. place_object(obj, mtmp->mx, mtmp->my); 1473. break; 1474. case 2: /* onto floor beneath you */ 1475. pline("%s yanks %s to the %s!", 1476. Monnam(mtmp), 1477. the(xname(obj)), 1478. surface(u.ux, u.uy)); 1479. dropy(obj); 1480. break; 1481. case 3: /* into mon's inventory */ 1482. pline("%s snatches %s!", 1483. Monnam(mtmp), 1484. the(xname(obj))); 1485. mpickobj(mtmp,obj); 1486. break; 1487. default: 1488. /* shouldn't happen */ 1489. pline("Where's your weapon!"); 1490. place_object(obj,u.ux, u.uy); 1491. } 1492. return 1; 1493. } 1494. } 1495. return 0; 1496. case 0: return 0; /* i.e. an exploded wand */ 1497. default: impossible("%s wanted to perform action %d?", Monnam(mtmp), 1498. m.has_misc); 1499. break; 1500. } 1501. return 0; 1502. } 1503. 1504. static void 1505. you_aggravate(mtmp) 1506. struct monst *mtmp; 1507. { 1508. killer = ""; /* hack: prevent "it" in names */ 1509. pline("For some reason, %s presence is known to you.", 1510. s_suffix(mon_nam(mtmp))); 1511. cls(); 1512. #ifdef CLIPPING 1513. cliparound(mtmp->mx, mtmp->my); 1514. #endif 1515. show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp)); 1516. display_self(); 1517. You_feel("aggravated at %s.", mon_nam(mtmp)); 1518. display_nhwindow(WIN_MAP, TRUE); 1519. docrt(); 1520. if (unconscious()) { 1521. multi = -1; 1522. nomovemsg = 1523. "Aggravated, you are jolted into full consciousness."; 1524. } 1525. killer = 0; 1526. newsym(mtmp->mx,mtmp->my); 1527. } 1528. 1529. int 1530. rnd_misc_item(mtmp) 1531. struct monst *mtmp; 1532. { 1533. struct permonst *pm = mtmp->data; 1534. int difficulty = monstr[(monsndx(pm))]; 1535. 1536. if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data) 1537. || pm->mlet == S_GHOST 1538. # ifdef KOPS 1539. || pm->mlet == S_KOP 1540. # endif 1541. ) return 0; 1542. /* Unlike other rnd_item functions, we only allow _weak_ monsters 1543. * to have this item; after all, the item will be used to strengthen 1544. * the monster and strong monsters won't use it at all... 1545. */ 1546. if (difficulty < 6 && !rn2(30)) return WAN_POLYMORPH; 1547. 1548. if (!rn2(40) && !nonliving(pm)) return AMULET_OF_LIFE_SAVING; 1549. 1550. switch (rn2(3)) { 1551. case 0: 1552. if (mtmp->isgd) return 0; 1553. return rn2(6) ? POT_SPEED : WAN_SPEED_MONSTER; 1554. case 1: 1555. if (mtmp->mpeaceful && !See_invisible) return 0; 1556. return rn2(6) ? POT_INVISIBILITY : WAN_MAKE_INVISIBLE; 1557. case 2: 1558. return POT_GAIN_LEVEL; 1559. } 1560. /*NOTREACHED*/ 1561. return 0; 1562. } 1563. 1564. boolean 1565. searches_for_item(mon, obj) 1566. struct monst *mon; 1567. struct obj *obj; 1568. { 1569. int typ = obj->otyp; 1570. 1571. if (is_animal(mon->data) || mindless(mon->data)) return FALSE; 1572. /* No, the ghost doesn't pick up the bones pile */ 1573. if (mon->data == &mons[PM_GHOST]) return FALSE; 1574. return((boolean)((obj->oclass == WAND_CLASS && objects[typ].oc_dir == RAY) 1575. || typ == WAN_STRIKING 1576. || (!mon->minvis && !mon->invis_blkd && 1577. (typ == WAN_MAKE_INVISIBLE || typ == POT_INVISIBILITY)) 1578. || (mon->mspeed != MFAST && 1579. (typ == WAN_SPEED_MONSTER || typ == POT_SPEED)) 1580. || typ == POT_HEALING 1581. || typ == POT_EXTRA_HEALING 1582. || typ == POT_GAIN_LEVEL 1583. || (monstr[monsndx(mon->data)] < 6 && typ == WAN_POLYMORPH) 1584. || (!is_floater(mon->data) && typ == WAN_DIGGING) 1585. || typ == WAN_TELEPORTATION 1586. || typ == SCR_TELEPORTATION 1587. || typ == WAN_CREATE_MONSTER 1588. || typ == SCR_CREATE_MONSTER 1589. || typ == POT_PARALYSIS 1590. || typ == POT_BLINDNESS 1591. || typ == POT_CONFUSION 1592. || (typ == PICK_AXE && needspick(mon->data)) 1593. || typ == AMULET_OF_REFLECTION 1594. || (typ == AMULET_OF_LIFE_SAVING && !nonliving(mon->data)) 1595. || ((mon->misc_worn_check & W_ARMG) && typ == CORPSE 1596. && obj->corpsenm == PM_COCKATRICE) 1597. || (typ == CORPSE && !resists_ston(mon) && 1598. (obj->corpsenm == PM_LIZARD || 1599. acidic(&mons[obj->corpsenm]))) 1600. || (typ == UNICORN_HORN && !obj->cursed && 1601. mon->data->mlet != S_UNICORN) 1602. )); 1603. } 1604. 1605. boolean 1606. mon_reflects(mon,str) 1607. struct monst *mon; 1608. const char *str; 1609. { 1610. struct obj *orefl = which_armor(mon, W_ARMS); 1611. 1612. if (orefl && orefl->otyp == SHIELD_OF_REFLECTION) { 1613. if (str) { 1614. pline(str, s_suffix(mon_nam(mon)), "shield"); 1615. makeknown(SHIELD_OF_REFLECTION); 1616. } 1617. return TRUE; 1618. } else if ((orefl = which_armor(mon, W_AMUL)) && 1619. orefl->otyp == AMULET_OF_REFLECTION) { 1620. if (str) { 1621. pline(str, s_suffix(mon_nam(mon)), "amulet"); 1622. makeknown(AMULET_OF_REFLECTION); 1623. } 1624. return TRUE; 1625. } 1626. return FALSE; 1627. } 1628. 1629. /* TRUE if the monster ate something */ 1630. boolean 1631. munstone(mon, by_you) 1632. struct monst *mon; 1633. boolean by_you; 1634. { 1635. struct obj *obj; 1636. 1637. if (resists_ston(mon)) return FALSE; 1638. if (mon->meating || !mon->mcanmove || mon->msleep) return FALSE; 1639. 1640. for(obj = mon->minvent; obj; obj = obj->nobj) { 1641. if (obj->otyp == CORPSE && (obj->corpsenm == PM_LIZARD || 1642. acidic(&mons[obj->corpsenm]))) { 1643. int nutrit = dog_nutrition(mon, obj); /* also sets meating */ 1644. 1645. if (canseemon(mon)) { 1646. long save_quan = obj->quan; 1647. 1648. obj->quan = 1L; 1649. pline("%s eats %s.", Monnam(mon), distant_name(obj,doname)); 1650. obj->quan = save_quan; 1651. } else if (flags.soundok) You("hear chewing."); 1652. m_useup(mon, obj); 1653. if (acidic(&mons[obj->corpsenm]) && !resists_acid(mon)) { 1654. mon->mhp -= rnd(15); 1655. pline("%s has a very bad case of stomach acid.", 1656. Monnam(mon)); 1657. } 1658. if (mon->mhp <= 0) { 1659. pline("%s dies!", Monnam(mon)); 1660. if (by_you) xkilled(mon, 0); 1661. else mondead(mon); 1662. return TRUE; 1663. } 1664. if (canseemon(mon)) { 1665. if (Hallucination) 1666. pline("What a pity - %s just ruined a future piece of art!", 1667. mon_nam(mon)); 1668. else 1669. pline("%s seems limber!", Monnam(mon)); 1670. } 1671. if (mon->mtame && !mon->isminion) { 1672. struct edog *edog = EDOG(mon); 1673. 1674. if (edog->hungrytime < moves) edog->hungrytime = moves; 1675. edog->hungrytime += nutrit; 1676. mon->mconf = 0; 1677. } 1678. mon->mlstmv = monstermoves; /* it takes a turn */ 1679. return TRUE; 1680. } 1681. } 1682. return FALSE; 1683. } 1684. 1685. /*muse.c*/