About: Source:NetHack 3.3.0/muse.c   Sponge Permalink

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

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

AttributesValues
rdfs:label
  • Source:NetHack 3.3.0/muse.c
rdfs:comment
  • Below is the full text to muse.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/muse.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code
dcterms:subject
dbkwik:nethack/pro...iPageUsesTemplate
abstract
  • Below is the full text to muse.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/muse.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)muse.c 3.3 1999/12/03 */ 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. STATIC_DCL int FDECL(precheck, (struct monst *,struct obj *)); 23. STATIC_DCL void FDECL(mzapmsg, (struct monst *,struct obj *,BOOLEAN_P)); 24. STATIC_DCL void FDECL(mreadmsg, (struct monst *,struct obj *)); 25. STATIC_DCL void FDECL(mquaffmsg, (struct monst *,struct obj *)); 26. STATIC_PTR int FDECL(mbhitm, (struct monst *,struct obj *)); 27. STATIC_DCL void FDECL(mbhit, 28. (struct monst *,int,int FDECL((*),(MONST_P,OBJ_P)), 29. int FDECL((*),(OBJ_P,OBJ_P)),struct obj *)); 30. STATIC_DCL 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_OVL 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, NO_MM_FLAGS); 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, NO_MM_FLAGS); 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_OVL 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 %s zap.", 151. (distu(mtmp->mx,mtmp->my) <= (BOLT_LIM+1)*(BOLT_LIM+1)) ? 152. "nearby" : "distant"); 153. } else if (self) 154. pline("%s zaps %sself with %s!", 155. Monnam(mtmp), him[pronoun_gender(mtmp)], doname(otmp)); 156. else { 157. pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp))); 158. stop_occupation(); 159. } 160. } 161. 162. STATIC_OVL void 163. mreadmsg(mtmp, otmp) 164. struct monst *mtmp; 165. struct obj *otmp; 166. { 167. boolean vismon = canseemon(mtmp); 168. char onambuf[BUFSZ]; 169. short saverole; 170. unsigned savebknown; 171. 172. if (!vismon && !flags.soundok) 173. return; /* no feedback */ 174. 175. otmp->dknown = 1; /* seeing or hearing it read reveals its label */ 176. /* shouldn't be able to hear curse/bless status of unseen scrolls; 177. for priest characters, bknown will always be set during naming */ 178. savebknown = otmp->bknown; 179. saverole = Role_switch; 180. if (!vismon) { 181. otmp->bknown = 0; 182. if (Role_if(PM_PRIEST)) Role_switch = 0; 183. } 184. Strcpy(onambuf, singular(otmp, doname)); 185. Role_switch = saverole; 186. otmp->bknown = savebknown; 187. 188. if (vismon) 189. pline("%s reads %s!", Monnam(mtmp), onambuf); 190. else 191. You_hear("%s reading %s.", 192. an(Hallucination ? rndmonnam() : mtmp->data->mname), 193. onambuf); 194. 195. if (mtmp->mconf) 196. pline("Being confused, %s mispronounces the magic words...", 197. vismon ? mon_nam(mtmp) : he[pronoun_gender(mtmp)]); 198. } 199. 200. STATIC_OVL void 201. mquaffmsg(mtmp, otmp) 202. struct monst *mtmp; 203. struct obj *otmp; 204. { 205. if (canseemon(mtmp)) { 206. otmp->dknown = 1; 207. pline("%s drinks %s!", Monnam(mtmp), singular(otmp, doname)); 208. } else 209. if (flags.soundok) 210. You_hear("a chugging sound."); 211. } 212. 213. /* Defines for various types of stuff. The order in which monsters prefer 214. * to use them is determined by the order of the code logic, not the 215. * numerical order in which they are defined. 216. */ 217. #define MUSE_SCR_TELEPORTATION 1 218. #define MUSE_WAN_TELEPORTATION_SELF 2 219. #define MUSE_POT_HEALING 3 220. #define MUSE_POT_EXTRA_HEALING 4 221. #define MUSE_WAN_DIGGING 5 222. #define MUSE_TRAPDOOR 6 223. #define MUSE_TELEPORT_TRAP 7 224. #define MUSE_UPSTAIRS 8 225. #define MUSE_DOWNSTAIRS 9 226. #define MUSE_WAN_CREATE_MONSTER 10 227. #define MUSE_SCR_CREATE_MONSTER 11 228. #define MUSE_UP_LADDER 12 229. #define MUSE_DN_LADDER 13 230. #define MUSE_SSTAIRS 14 231. #define MUSE_WAN_TELEPORTATION 15 232. #define MUSE_BUGLE 16 233. #define MUSE_UNICORN_HORN 17 234. #define MUSE_POT_FULL_HEALING 18 235. /* 236. #define MUSE_INNATE_TPT 9999 237. * We cannot use this. Since monsters get unlimited teleportation, if they 238. * were allowed to teleport at will you could never catch them. Instead, 239. * assume they only teleport at random times, despite the inconsistency that if 240. * you polymorph into one you teleport at will. 241. */ 242. 243. /* Select a defensive item/action for a monster. Returns TRUE iff one is 244. * found. 245. */ 246. boolean 247. find_defensive(mtmp) 248. struct monst *mtmp; 249. { 250. register struct obj *obj = 0; 251. struct trap *t; 252. int x=mtmp->mx, y=mtmp->my; 253. boolean stuck = (mtmp == u.ustuck); 254. boolean immobile = (mtmp->data->mmove == 0); 255. int fraction; 256. 257. if (is_animal(mtmp->data) || mindless(mtmp->data)) 258. return FALSE; 259. if(dist2(x, y, mtmp->mux, mtmp->muy) > 25) 260. return FALSE; 261. if (u.uswallow && stuck) return FALSE; 262. 263. m.defensive = (struct obj *)0; 264. m.has_defense = 0; 265. 266. /* since unicorn horns don't get used up, the monster would look 267. * silly trying to use the same cursed horn round after round 268. */ 269. if (mtmp->mconf || mtmp->mstun || !mtmp->mcansee) { 270. if (!is_unicorn(mtmp->data) && !nohands(mtmp->data)) { 271. for(obj = mtmp->minvent; obj; obj = obj->nobj) 272. if (obj->otyp == UNICORN_HORN && !obj->cursed) 273. break; 274. } 275. if (obj || is_unicorn(mtmp->data)) { 276. m.defensive = obj; 277. m.has_defense = MUSE_UNICORN_HORN; 278. return TRUE; 279. } 280. } 281. 282. /* It so happens there are two unrelated cases when we might want to 283. * check specifically for healing alone. The first is when the monster 284. * is blind (healing cures blindness). The second is when the monster 285. * is peaceful; then we don't want to flee the player, and by 286. * coincidence healing is all there is that doesn't involve fleeing. 287. * These would be hard to combine because of the control flow. 288. */ 289. if (!mtmp->mcansee && !nohands(mtmp->data)) { 290. if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) { 291. m.defensive = obj; 292. m.has_defense = MUSE_POT_FULL_HEALING; 293. return TRUE; 294. } 295. if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) { 296. m.defensive = obj; 297. m.has_defense = MUSE_POT_EXTRA_HEALING; 298. return TRUE; 299. } 300. if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) { 301. m.defensive = obj; 302. m.has_defense = MUSE_POT_HEALING; 303. return TRUE; 304. } 305. } 306. 307. fraction = u.ulevel < 10 ? 5 : u.ulevel < 14 ? 4 : 3; 308. if(mtmp->mhp >= mtmp->mhpmax || 309. (mtmp->mhp >= 10 && mtmp->mhp*fraction >= mtmp->mhpmax)) 310. return FALSE; 311. 312. if (mtmp->mpeaceful) { 313. if (!nohands(mtmp->data)) { 314. if ((obj = m_carrying(mtmp, POT_FULL_HEALING)) != 0) { 315. m.defensive = obj; 316. m.has_defense = MUSE_POT_FULL_HEALING; 317. return TRUE; 318. } 319. if ((obj = m_carrying(mtmp, POT_EXTRA_HEALING)) != 0) { 320. m.defensive = obj; 321. m.has_defense = MUSE_POT_EXTRA_HEALING; 322. return TRUE; 323. } 324. if ((obj = m_carrying(mtmp, POT_HEALING)) != 0) { 325. m.defensive = obj; 326. m.has_defense = MUSE_POT_HEALING; 327. return TRUE; 328. } 329. } 330. return FALSE; 331. } 332. 333. if (levl[x][y].typ == STAIRS && !stuck && !immobile) { 334. if (x == xdnstair && y == ydnstair && !is_floater(mtmp->data)) 335. m.has_defense = MUSE_DOWNSTAIRS; 336. if (x == xupstair && y == yupstair && ledger_no(&u.uz) != 1) 337. /* Unfair to let the monsters leave the dungeon with the Amulet */ 338. /* (or go to the endlevel since you also need it, to get there) */ 339. m.has_defense = MUSE_UPSTAIRS; 340. } else if (levl[x][y].typ == LADDER && !stuck && !immobile) { 341. if (x == xupladder && y == yupladder) 342. m.has_defense = MUSE_UP_LADDER; 343. if (x == xdnladder && y == ydnladder && !is_floater(mtmp->data)) 344. m.has_defense = MUSE_DN_LADDER; 345. } else if (sstairs.sx && sstairs.sx == x && sstairs.sy == y) { 346. m.has_defense = MUSE_SSTAIRS; 347. } else if (!stuck && !immobile) { 348. /* Note: trapdoors take precedence over teleport traps. */ 349. int xx, yy; 350. 351. for(xx = x-1; xx <= x+1; xx++) for(yy = y-1; yy <= y+1; yy++) 352. if (isok(xx,yy)) 353. if (xx != u.ux && yy != u.uy) 354. if (mtmp->data != &mons[PM_GRID_BUG] || xx == x || yy == y) 355. if ((xx==x && yy==y) || !level.monsters[xx][yy]) 356. if ((t = t_at(xx,yy)) != 0) 357. if ((verysmall(mtmp->data) || throws_rocks(mtmp->data) || 358. passes_walls(mtmp->data)) || !sobj_at(BOULDER, xx, yy)) 359. if (!onscary(xx,yy,mtmp)) { 360. if ((t->ttyp == TRAPDOOR || t->ttyp == HOLE) 361. && !is_floater(mtmp->data) 362. && !mtmp->isshk && !mtmp->isgd 363. && !mtmp->ispriest 364. && Can_fall_thru(&u.uz) 365. ) { 366. trapx = xx; 367. trapy = yy; 368. m.has_defense = MUSE_TRAPDOOR; 369. } else if (t->ttyp == TELEP_TRAP && m.has_defense != MUSE_TRAPDOOR) { 370. trapx = xx; 371. trapy = yy; 372. m.has_defense = MUSE_TELEPORT_TRAP; 373. } 374. } 375. } 376. 377. if (nohands(mtmp->data)) /* can't use objects */ 378. goto botm; 379. 380. if (is_mercenary(mtmp->data) && (obj = m_carrying(mtmp, BUGLE))) { 381. int xx, yy; 382. struct monst *mon; 383. 384. /* Distance is arbitrary. What we really want to do is 385. * have the soldier play the bugle when it sees or 386. * remembers soldiers nearby... 387. */ 388. for(xx = x-3; xx <= x+3; xx++) for(yy = y-3; yy <= y+3; yy++) 389. if (isok(xx,yy)) 390. if ((mon = m_at(xx,yy)) && is_mercenary(mon->data) && 391. mon->data != &mons[PM_GUARD] && 392. (mon->msleeping || (!mon->mcanmove))) { 393. m.defensive = obj; 394. m.has_defense = MUSE_BUGLE; 395. } 396. } 397. 398. /* use immediate physical escape prior to attempting magic */ 399. if (m.has_defense) /* stairs, trapdoor or tele-trap, bugle alert */ 400. goto botm; 401. 402. /* kludge to cut down on trap destruction (particularly portals) */ 403. t = t_at(x,y); 404. if (t && (t->ttyp == PIT || t->ttyp == SPIKED_PIT || 405. t->ttyp == WEB || t->ttyp == BEAR_TRAP)) 406. t = 0; /* ok for monster to dig here */ 407. 408. #define nomore(x) if(m.has_defense==x) continue; 409. for (obj = mtmp->minvent; obj; obj = obj->nobj) { 410. /* don't always use the same selection pattern */ 411. if (m.has_defense && !rn2(3)) break; 412. 413. /* nomore(MUSE_WAN_DIGGING); */ 414. if (m.has_defense == MUSE_WAN_DIGGING) break; 415. if (obj->otyp == WAN_DIGGING && obj->spe > 0 && !stuck && !t 416. && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest 417. && !is_floater(mtmp->data) 418. /* digging wouldn't be effective; assume they know that */ 419. && !(levl[x][y].wall_info & W_NONDIGGABLE) 420. && !(Is_botlevel(&u.uz) || In_endgame(&u.uz)) 421. && !(is_ice(x,y) || is_pool(x,y) || is_lava(x,y))) { 422. m.defensive = obj; 423. m.has_defense = MUSE_WAN_DIGGING; 424. } 425. nomore(MUSE_WAN_TELEPORTATION_SELF); 426. nomore(MUSE_WAN_TELEPORTATION); 427. if(obj->otyp == WAN_TELEPORTATION && obj->spe > 0) { 428. m.defensive = obj; 429. m.has_defense = (mon_has_amulet(mtmp)) 430. ? MUSE_WAN_TELEPORTATION 431. : MUSE_WAN_TELEPORTATION_SELF; 432. } 433. nomore(MUSE_SCR_TELEPORTATION); 434. if(obj->otyp == SCR_TELEPORTATION && mtmp->mcansee 435. && haseyes(mtmp->data) 436. && (!obj->cursed || 437. (!(mtmp->isshk && inhishop(mtmp)) 438. && !mtmp->isgd && !mtmp->ispriest))) { 439. m.defensive = obj; 440. m.has_defense = MUSE_SCR_TELEPORTATION; 441. } 442. nomore(MUSE_POT_FULL_HEALING); 443. if(obj->otyp == POT_FULL_HEALING) { 444. m.defensive = obj; 445. m.has_defense = MUSE_POT_FULL_HEALING; 446. } 447. nomore(MUSE_POT_EXTRA_HEALING); 448. if(obj->otyp == POT_EXTRA_HEALING) { 449. m.defensive = obj; 450. m.has_defense = MUSE_POT_EXTRA_HEALING; 451. } 452. nomore(MUSE_WAN_CREATE_MONSTER); 453. if(obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) { 454. m.defensive = obj; 455. m.has_defense = MUSE_WAN_CREATE_MONSTER; 456. } 457. nomore(MUSE_POT_HEALING); 458. if(obj->otyp == POT_HEALING) { 459. m.defensive = obj; 460. m.has_defense = MUSE_POT_HEALING; 461. } 462. nomore(MUSE_SCR_CREATE_MONSTER); 463. if(obj->otyp == SCR_CREATE_MONSTER) { 464. m.defensive = obj; 465. m.has_defense = MUSE_SCR_CREATE_MONSTER; 466. } 467. } 468. botm: return((boolean)(!!m.has_defense)); 469. #undef nomore 470. } 471. 472. /* Perform a defensive action for a monster. Must be called immediately 473. * after find_defensive(). Return values are 0: did something, 1: died, 474. * 2: did something and can't attack again (i.e. teleported). 475. */ 476. int 477. use_defensive(mtmp) 478. struct monst *mtmp; 479. { 480. int i, fleetim, how = 0; 481. struct obj *otmp = m.defensive; 482. boolean vis, vismon, oseen; 483. const char *mcsa = "%s can see again."; 484. 485. if ((i = precheck(mtmp, otmp)) != 0) return i; 486. vis = cansee(mtmp->mx, mtmp->my); 487. vismon = canseemon(mtmp); 488. oseen = otmp && vismon; 489. 490. /* when using defensive choice to run away, we want monster to avoid 491. rushing right straight back; don't override if already scared */ 492. fleetim = !mtmp->mflee ? (33 - (30 * mtmp->mhp / mtmp->mhpmax)) : 0; 493. #define m_flee(m) if (fleetim && !m->iswiz) \ 494. { m->mflee = 1; m->mfleetim = fleetim; } 495. 496. switch(m.has_defense) { 497. case MUSE_UNICORN_HORN: 498. if (vismon) { 499. if (otmp) 500. pline("%s uses a unicorn horn!", Monnam(mtmp)); 501. else 502. pline("The tip of %s's horn glows!", mon_nam(mtmp)); 503. } 504. if (!mtmp->mcansee) { 505. mtmp->mcansee = 1; 506. mtmp->mblinded = 0; 507. if (vismon) pline(mcsa, Monnam(mtmp)); 508. } else if (mtmp->mconf || mtmp->mstun) { 509. mtmp->mconf = mtmp->mstun = 0; 510. if (vismon) 511. pline("%s seems steadier now.", Monnam(mtmp)); 512. } else impossible("No need for unicorn horn?"); 513. return 2; 514. case MUSE_BUGLE: 515. if (vismon) 516. pline("%s plays %s!", Monnam(mtmp), doname(otmp)); 517. else if (flags.soundok) 518. You_hear("a bugle playing reveille!"); 519. awaken_soldiers(); 520. return 2; 521. case MUSE_WAN_TELEPORTATION_SELF: 522. if ((mtmp->isshk && inhishop(mtmp)) 523. || mtmp->isgd || mtmp->ispriest) return 2; 524. m_flee(mtmp); 525. mzapmsg(mtmp, otmp, TRUE); 526. otmp->spe--; 527. how = WAN_TELEPORTATION; 528. mon_tele: 529. if (tele_restrict(mtmp)) { /* mysterious force... */ 530. if (vismon && how) /* mentions 'teleport' */ 531. makeknown(how); 532. return 2; 533. } 534. if (( 535. #if 0 536. mon_has_amulet(mtmp) || 537. #endif 538. On_W_tower_level(&u.uz)) && !rn2(3)) { 539. if (vismon) 540. pline("%s seems disoriented for a moment.", 541. Monnam(mtmp)); 542. return 2; 543. } 544. if (oseen && how) makeknown(how); 545. rloc(mtmp); 546. return 2; 547. case MUSE_WAN_TELEPORTATION: 548. zap_oseen = oseen; 549. mzapmsg(mtmp, otmp, FALSE); 550. otmp->spe--; 551. m_using = TRUE; 552. mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp); 553. m_using = FALSE; 554. return 2; 555. case MUSE_SCR_TELEPORTATION: 556. { 557. int obj_is_cursed = otmp->cursed; 558. 559. if (mtmp->isshk || mtmp->isgd || mtmp->ispriest) return 2; 560. m_flee(mtmp); 561. mreadmsg(mtmp, otmp); 562. m_useup(mtmp, otmp); /* otmp might be free'ed */ 563. how = SCR_TELEPORTATION; 564. if (obj_is_cursed || mtmp->mconf) { 565. int nlev; 566. d_level flev; 567. 568. if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) { 569. if (vismon) 570. pline("%s seems very disoriented for a moment.", 571. Monnam(mtmp)); 572. return 2; 573. } 574. nlev = random_teleport_level(); 575. if (nlev == depth(&u.uz)) { 576. if (vismon) 577. pline("%s shudders for a moment.", 578. Monnam(mtmp)); 579. return 2; 580. } 581. get_level(&flev, nlev); 582. migrate_to_level(mtmp, ledger_no(&flev), MIGR_RANDOM, 583. (coord *)0); 584. if (oseen) makeknown(SCR_TELEPORTATION); 585. } else goto mon_tele; 586. return 2; 587. } 588. case MUSE_WAN_DIGGING: 589. { struct trap *ttmp; 590. 591. m_flee(mtmp); 592. mzapmsg(mtmp, otmp, FALSE); 593. otmp->spe--; 594. if (oseen) makeknown(WAN_DIGGING); 595. if (IS_FURNITURE(levl[mtmp->mx][mtmp->my].typ) || 596. IS_DRAWBRIDGE(levl[mtmp->mx][mtmp->my].typ) || 597. (is_drawbridge_wall(mtmp->mx, mtmp->my) >= 0) || 598. (sstairs.sx && sstairs.sx == mtmp->mx && 599. sstairs.sy == mtmp->my)) { 600. pline_The("digging ray is ineffective."); 601. return 2; 602. } 603. if (!Can_dig_down(&u.uz)) { 604. if(canseemon(mtmp)) 605. pline_The("floor here is too hard to dig in."); 606. return 2; 607. } 608. ttmp = maketrap(mtmp->mx, mtmp->my, HOLE); 609. if (!ttmp) return 2; 610. seetrap(ttmp); 611. if (vis) { 612. pline("%s has made a hole in the floor.", Monnam(mtmp)); 613. pline("%s %s through...", Monnam(mtmp), 614. is_flyer(mtmp->data) ? "dives" : "falls"); 615. } else if (flags.soundok) 616. You_hear("%s crash through the floor.", something); 617. /* we made sure that there is a level for mtmp to go to */ 618. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 619. MIGR_RANDOM, (coord *)0); 620. return 2; 621. } 622. case MUSE_WAN_CREATE_MONSTER: 623. { coord cc; 624. /* pm: 0 => random, eel => aquatic, croc => amphibious */ 625. struct permonst *pm = !is_pool(mtmp->mx, mtmp->my) ? 0 : 626. &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE]; 627. struct monst *mon; 628. 629. if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) return 0; 630. mzapmsg(mtmp, otmp, FALSE); 631. otmp->spe--; 632. mon = makemon((struct permonst *)0, cc.x, cc.y, NO_MM_FLAGS); 633. if (mon && canspotmon(mon) && oseen) 634. makeknown(WAN_CREATE_MONSTER); 635. return 2; 636. } 637. case MUSE_SCR_CREATE_MONSTER: 638. { coord cc; 639. struct permonst *pm = 0, *fish = 0; 640. int cnt = 1; 641. struct monst *mon; 642. boolean known = FALSE; 643. 644. if (!rn2(73)) cnt += rnd(4); 645. if (mtmp->mconf || otmp->cursed) cnt += 12; 646. if (mtmp->mconf) pm = fish = &mons[PM_ACID_BLOB]; 647. else if (is_pool(mtmp->mx, mtmp->my)) 648. fish = &mons[u.uinwater ? PM_GIANT_EEL : PM_CROCODILE]; 649. mreadmsg(mtmp, otmp); 650. while(cnt--) { 651. /* `fish' potentially gives bias towards water locations; 652. `pm' is what to actually create (0 => random) */ 653. if (!enexto(&cc, mtmp->mx, mtmp->my, fish)) break; 654. mon = makemon(pm, cc.x, cc.y, NO_MM_FLAGS); 655. if (mon && canspotmon(mon)) known = TRUE; 656. } 657. /* The only case where we don't use oseen. For wands, you 658. * have to be able to see the monster zap the wand to know 659. * what type it is. For teleport scrolls, you have to see 660. * the monster to know it teleported. 661. */ 662. if (known) 663. makeknown(SCR_CREATE_MONSTER); 664. else if (!objects[SCR_CREATE_MONSTER].oc_name_known 665. && !objects[SCR_CREATE_MONSTER].oc_uname) 666. docall(otmp); 667. m_useup(mtmp, otmp); 668. return 2; 669. } 670. case MUSE_TRAPDOOR: 671. /* trapdoors on "bottom" levels of dungeons are rock-drop 672. * trapdoors, not holes in the floor. We check here for 673. * safety. 674. */ 675. if (Is_botlevel(&u.uz)) return 0; 676. m_flee(mtmp); 677. if (vis) { 678. struct trap *t; 679. t = t_at(trapx,trapy); 680. pline("%s %s into a %s!", Monnam(mtmp), 681. makeplural(locomotion(mtmp->data, "jump")), 682. t->ttyp == TRAPDOOR ? "trapdoor" : "hole"); 683. seetrap(t_at(trapx,trapy)); 684. } 685. 686. /* don't use rloc_to() because worm tails must "move" */ 687. remove_monster(mtmp->mx, mtmp->my); 688. newsym(mtmp->mx, mtmp->my); /* update old location */ 689. place_monster(mtmp, trapx, trapy); 690. if (mtmp->wormno) worm_move(mtmp); 691. newsym(trapx, trapy); 692. 693. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 694. MIGR_RANDOM, (coord *)0); 695. return 2; 696. case MUSE_UPSTAIRS: 697. /* Monsters without amulets escape the dungeon and are 698. * gone for good when they leave up the up stairs. 699. * Monsters with amulets would reach the endlevel, 700. * which we cannot allow since that would leave the 701. * player stranded. 702. */ 703. if (ledger_no(&u.uz) == 1) { 704. if (mon_has_special(mtmp)) 705. return 0; 706. if (vismon) 707. pline("%s escapes the dungeon!", Monnam(mtmp)); 708. mongone(mtmp); 709. return 2; 710. } 711. m_flee(mtmp); 712. if (Inhell && mon_has_amulet(mtmp) && !rn2(4) && 713. (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) { 714. if (vismon) pline( 715. "As %s climbs the stairs, a mysterious force momentarily surrounds %s...", 716. mon_nam(mtmp), him[pronoun_gender(mtmp)]); 717. /* simpler than for the player; this will usually be 718. the Wizard and he'll immediately go right to the 719. upstairs, so there's not much point in having any 720. chance for a random position on the current level */ 721. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 722. MIGR_RANDOM, (coord *)0); 723. } else { 724. if (vismon) pline("%s escapes upstairs!", Monnam(mtmp)); 725. migrate_to_level(mtmp, ledger_no(&u.uz) - 1, 726. MIGR_STAIRS_DOWN, (coord *)0); 727. } 728. return 2; 729. case MUSE_DOWNSTAIRS: 730. m_flee(mtmp); 731. if (vismon) pline("%s escapes downstairs!", Monnam(mtmp)); 732. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 733. MIGR_STAIRS_UP, (coord *)0); 734. return 2; 735. case MUSE_UP_LADDER: 736. m_flee(mtmp); 737. if (vismon) pline("%s escapes up the ladder!", Monnam(mtmp)); 738. migrate_to_level(mtmp, ledger_no(&u.uz) - 1, 739. MIGR_LADDER_DOWN, (coord *)0); 740. return 2; 741. case MUSE_DN_LADDER: 742. m_flee(mtmp); 743. if (vismon) pline("%s escapes down the ladder!", Monnam(mtmp)); 744. migrate_to_level(mtmp, ledger_no(&u.uz) + 1, 745. MIGR_LADDER_UP, (coord *)0); 746. return 2; 747. case MUSE_SSTAIRS: 748. m_flee(mtmp); 749. /* the stairs leading up from the 1st level are */ 750. /* regular stairs, not sstairs. */ 751. if (sstairs.up) { 752. if (vismon) 753. pline("%s escapes upstairs!", Monnam(mtmp)); 754. if(Inhell) { 755. migrate_to_level(mtmp, ledger_no(&sstairs.tolev), 756. MIGR_RANDOM, (coord *)0); 757. return 2; 758. } 759. } else if (vismon) 760. pline("%s escapes downstairs!", Monnam(mtmp)); 761. migrate_to_level(mtmp, ledger_no(&sstairs.tolev), 762. MIGR_SSTAIRS, (coord *)0); 763. return 2; 764. case MUSE_TELEPORT_TRAP: 765. m_flee(mtmp); 766. if (vis) { 767. pline("%s %s onto a teleport trap!", Monnam(mtmp), 768. makeplural(locomotion(mtmp->data, "jump"))); 769. seetrap(t_at(trapx,trapy)); 770. } 771. /* don't use rloc_to() because worm tails must "move" */ 772. remove_monster(mtmp->mx, mtmp->my); 773. newsym(mtmp->mx, mtmp->my); /* update old location */ 774. place_monster(mtmp, trapx, trapy); 775. if (mtmp->wormno) worm_move(mtmp); 776. newsym(trapx, trapy); 777. 778. goto mon_tele; 779. case MUSE_POT_HEALING: 780. mquaffmsg(mtmp, otmp); 781. i = d(6 + 2 * bcsign(otmp), 4); 782. mtmp->mhp += i; 783. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = ++mtmp->mhpmax; 784. if (!otmp->cursed && !mtmp->mcansee) { 785. mtmp->mcansee = 1; 786. mtmp->mblinded = 0; 787. if (vismon) pline(mcsa, Monnam(mtmp)); 788. } 789. if (vismon) pline("%s looks better.", Monnam(mtmp)); 790. if (oseen) makeknown(POT_HEALING); 791. m_useup(mtmp, otmp); 792. return 2; 793. case MUSE_POT_EXTRA_HEALING: 794. mquaffmsg(mtmp, otmp); 795. i = d(6 + 2 * bcsign(otmp), 8); 796. mtmp->mhp += i; 797. if (mtmp->mhp > mtmp->mhpmax) 798. mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2)); 799. if (!mtmp->mcansee) { 800. mtmp->mcansee = 1; 801. mtmp->mblinded = 0; 802. if (vismon) pline(mcsa, Monnam(mtmp)); 803. } 804. if (vismon) pline("%s looks much better.", Monnam(mtmp)); 805. if (oseen) makeknown(POT_EXTRA_HEALING); 806. m_useup(mtmp, otmp); 807. return 2; 808. case MUSE_POT_FULL_HEALING: 809. mquaffmsg(mtmp, otmp); 810. mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 8 : 4)); 811. if (!mtmp->mcansee) { 812. mtmp->mcansee = 1; 813. mtmp->mblinded = 0; 814. if (vismon) pline(mcsa, Monnam(mtmp)); 815. } 816. if (vismon) pline("%s looks completely healed.", Monnam(mtmp)); 817. if (oseen) makeknown(POT_FULL_HEALING); 818. m_useup(mtmp, otmp); 819. return 2; 820. case 0: return 0; /* i.e. an exploded wand */ 821. default: impossible("%s wanted to perform action %d?", Monnam(mtmp), 822. m.has_defense); 823. break; 824. } 825. return 0; 826. #undef m_flee 827. } 828. 829. int 830. rnd_defensive_item(mtmp) 831. struct monst *mtmp; 832. { 833. struct permonst *pm = mtmp->data; 834. int difficulty = monstr[(monsndx(pm))]; 835. 836. if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data) 837. || pm->mlet == S_GHOST 838. # ifdef KOPS 839. || pm->mlet == S_KOP 840. # endif 841. ) return 0; 842. switch (rn2(8 + (difficulty > 3) + (difficulty > 6) + 843. (difficulty > 8))) { 844. case 6: case 9: 845. if (!rn2(3)) return WAN_TELEPORTATION; 846. /* else FALLTHRU */ 847. case 0: case 1: 848. return SCR_TELEPORTATION; 849. case 8: case 10: 850. if (!rn2(3)) return WAN_CREATE_MONSTER; 851. /* else FALLTHRU */ 852. case 2: return SCR_CREATE_MONSTER; 853. case 3: return POT_HEALING; 854. case 4: return POT_EXTRA_HEALING; 855. case 5: return POT_FULL_HEALING; 856. case 7: if (is_floater(pm) || mtmp->isshk || mtmp->isgd 857. || mtmp->ispriest 858. ) 859. return 0; 860. else 861. return WAN_DIGGING; 862. } 863. /*NOTREACHED*/ 864. return 0; 865. } 866. 867. #define MUSE_WAN_DEATH 1 868. #define MUSE_WAN_SLEEP 2 869. #define MUSE_WAN_FIRE 3 870. #define MUSE_WAN_COLD 4 871. #define MUSE_WAN_LIGHTNING 5 872. #define MUSE_WAN_MAGIC_MISSILE 6 873. #define MUSE_WAN_STRIKING 7 874. #define MUSE_SCR_FIRE 8 875. #define MUSE_POT_PARALYSIS 9 876. #define MUSE_POT_BLINDNESS 10 877. #define MUSE_POT_CONFUSION 11 878. #define MUSE_FROST_HORN 12 879. #define MUSE_FIRE_HORN 13 880. #define MUSE_POT_ACID 14 881. /*#define MUSE_WAN_TELEPORTATION 15*/ 882. #define MUSE_POT_SLEEPING 16 883. #define MUSE_SCR_EARTH 17 884. 885. /* Select an offensive item/action for a monster. Returns TRUE iff one is 886. * found. 887. */ 888. boolean 889. find_offensive(mtmp) 890. struct monst *mtmp; 891. { 892. register struct obj *obj; 893. boolean ranged_stuff = lined_up(mtmp); 894. boolean reflection_skip = (Reflecting && rn2(2)); 895. 896. m.offensive = (struct obj *)0; 897. m.has_offense = 0; 898. if (mtmp->mpeaceful || is_animal(mtmp->data) || 899. mindless(mtmp->data) || nohands(mtmp->data)) 900. return FALSE; 901. if (u.uswallow) return FALSE; 902. if (in_your_sanctuary(mtmp, 0, 0)) return FALSE; 903. if (dmgtype(mtmp->data, AD_HEAL) && !uwep 904. #ifdef TOURIST 905. && !uarmu 906. #endif 907. && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) 908. return FALSE; 909. 910. if (!ranged_stuff) return FALSE; 911. #define nomore(x) if(m.has_offense==x) continue; 912. for(obj=mtmp->minvent; obj; obj=obj->nobj) { 913. /* nomore(MUSE_WAN_DEATH); */ 914. if (!reflection_skip) { 915. if(obj->otyp == WAN_DEATH && obj->spe > 0) { 916. m.offensive = obj; 917. m.has_offense = MUSE_WAN_DEATH; 918. } 919. nomore(MUSE_WAN_SLEEP); 920. if(obj->otyp == WAN_SLEEP && obj->spe > 0 && multi >= 0) { 921. m.offensive = obj; 922. m.has_offense = MUSE_WAN_SLEEP; 923. } 924. nomore(MUSE_WAN_FIRE); 925. if(obj->otyp == WAN_FIRE && obj->spe > 0) { 926. m.offensive = obj; 927. m.has_offense = MUSE_WAN_FIRE; 928. } 929. nomore(MUSE_FIRE_HORN); 930. if(obj->otyp == FIRE_HORN && obj->spe > 0) { 931. m.offensive = obj; 932. m.has_offense = MUSE_FIRE_HORN; 933. } 934. nomore(MUSE_WAN_COLD); 935. if(obj->otyp == WAN_COLD && obj->spe > 0) { 936. m.offensive = obj; 937. m.has_offense = MUSE_WAN_COLD; 938. } 939. nomore(MUSE_FROST_HORN); 940. if(obj->otyp == FROST_HORN && obj->spe > 0) { 941. m.offensive = obj; 942. m.has_offense = MUSE_FROST_HORN; 943. } 944. nomore(MUSE_WAN_LIGHTNING); 945. if(obj->otyp == WAN_LIGHTNING && obj->spe > 0) { 946. m.offensive = obj; 947. m.has_offense = MUSE_WAN_LIGHTNING; 948. } 949. nomore(MUSE_WAN_MAGIC_MISSILE); 950. if(obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) { 951. m.offensive = obj; 952. m.has_offense = MUSE_WAN_MAGIC_MISSILE; 953. } 954. } 955. nomore(MUSE_WAN_STRIKING); 956. if(obj->otyp == WAN_STRIKING && obj->spe > 0) { 957. m.offensive = obj; 958. m.has_offense = MUSE_WAN_STRIKING; 959. } 960. nomore(MUSE_POT_PARALYSIS); 961. if(obj->otyp == POT_PARALYSIS && multi >= 0) { 962. m.offensive = obj; 963. m.has_offense = MUSE_POT_PARALYSIS; 964. } 965. nomore(MUSE_POT_BLINDNESS); 966. if(obj->otyp == POT_BLINDNESS) { 967. m.offensive = obj; 968. m.has_offense = MUSE_POT_BLINDNESS; 969. } 970. nomore(MUSE_POT_CONFUSION); 971. if(obj->otyp == POT_CONFUSION) { 972. m.offensive = obj; 973. m.has_offense = MUSE_POT_CONFUSION; 974. } 975. nomore(MUSE_POT_SLEEPING); 976. if(obj->otyp == POT_SLEEPING) { 977. m.offensive = obj; 978. m.has_offense = MUSE_POT_SLEEPING; 979. } 980. nomore(MUSE_POT_ACID); 981. if(obj->otyp == POT_ACID) { 982. m.offensive = obj; 983. m.has_offense = MUSE_POT_ACID; 984. } 985. /* we can safely put this scroll here since the locations that 986. * are in a 1 square radius are a subset of the locations that 987. * are in wand range 988. */ 989. { 990. struct obj *helmet = which_armor(mtmp, W_ARMH); 991. 992. nomore(MUSE_SCR_EARTH); 993. if (obj->otyp == SCR_EARTH 994. && ((helmet && is_metallic(helmet)) || mtmp->mconf || amorphous(mtmp->data) || passes_walls(mtmp->data) || noncorporeal(mtmp->data) || unsolid(mtmp->data) || !rn2(10)) 995. && dist2(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy) <= 2 996. && mtmp->mcansee && haseyes(mtmp->data) 997. #ifdef REINCARNATION 998. && !Is_rogue_level(&u.uz) 999. #endif 1000. && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) { 1001. m.offensive = obj; 1002. m.has_offense = MUSE_SCR_EARTH; 1003. } 1004. } 1005. #if 0 1006. nomore(MUSE_SCR_FIRE); 1007. if (obj->otyp == SCR_FIRE && resists_fire(mtmp) 1008. && dist2(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy) <= 2 1009. && mtmp->mcansee && haseyes(mtmp->data)) { 1010. m.offensive = obj; 1011. m.has_offense = MUSE_SCR_FIRE; 1012. } 1013. #endif 1014. } 1015. return((boolean)(!!m.has_offense)); 1016. #undef nomore 1017. } 1018. 1019. STATIC_PTR 1020. int 1021. mbhitm(mtmp, otmp) 1022. register struct monst *mtmp; 1023. register struct obj *otmp; 1024. { 1025. int tmp; 1026. 1027. boolean reveal_invis = FALSE; 1028. if (mtmp != &youmonst) { 1029. mtmp->msleeping = 0; 1030. if (mtmp->m_ap_type) seemimic(mtmp); 1031. } 1032. switch(otmp->otyp) { 1033. case WAN_STRIKING: 1034. reveal_invis = TRUE; 1035. if (mtmp == &youmonst) { 1036. if (zap_oseen) makeknown(WAN_STRIKING); 1037. if (rnd(20) < 10 + u.uac) { 1038. pline_The("wand hits you!"); 1039. tmp = d(2,12); 1040. if(Half_spell_damage) tmp = (tmp+1) / 2; 1041. losehp(tmp, "wand", KILLED_BY_AN); 1042. } else pline_The("wand misses you."); 1043. stop_occupation(); 1044. nomul(0); 1045. } else if (rnd(20) < 10+find_mac(mtmp)) { 1046. tmp = d(2,12); 1047. if(Half_spell_damage) tmp = (tmp+1) / 2; 1048. hit("wand", mtmp, exclam(tmp)); 1049. (void) resist(mtmp, otmp->oclass, tmp, TELL); 1050. if (cansee(mtmp->mx, mtmp->my) && zap_oseen) 1051. makeknown(WAN_STRIKING); 1052. } else { 1053. miss("wand", mtmp); 1054. if (cansee(mtmp->mx, mtmp->my) && zap_oseen) 1055. makeknown(WAN_STRIKING); 1056. } 1057. break; 1058. case WAN_TELEPORTATION: 1059. if (mtmp == &youmonst) { 1060. if (zap_oseen) makeknown(WAN_TELEPORTATION); 1061. tele(); 1062. } else { 1063. /* for consistency with zap.c, don't identify */ 1064. if (mtmp->ispriest && 1065. *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) { 1066. if (cansee(mtmp->mx, mtmp->my)) 1067. pline("%s resists the magic!", Monnam(mtmp)); 1068. mtmp->msleeping = 0; 1069. if(mtmp->m_ap_type) seemimic(mtmp); 1070. } else 1071. rloc(mtmp); 1072. } 1073. break; 1074. case WAN_CANCELLATION: 1075. case SPE_CANCELLATION: 1076. cancel_monst(mtmp, otmp, FALSE, TRUE, FALSE); 1077. break; 1078. } 1079. if (reveal_invis) { 1080. if (mtmp->mhp > 0 && cansee(bhitpos.x,bhitpos.y) 1081. && !canspotmon(mtmp)) 1082. map_invisible(bhitpos.x, bhitpos.y); 1083. } 1084. return 0; 1085. } 1086. 1087. /* A modified bhit() for monsters. Based on bhit() in zap.c. Unlike 1088. * buzz(), bhit() doesn't take into account the possibility of a monster 1089. * zapping you, so we need a special function for it. (Unless someone wants 1090. * to merge the two functions...) 1091. */ 1092. STATIC_OVL void 1093. mbhit(mon,range,fhitm,fhito,obj) 1094. struct monst *mon; /* monster shooting the wand */ 1095. register int range; /* direction and range */ 1096. int FDECL((*fhitm),(MONST_P,OBJ_P)); 1097. int FDECL((*fhito),(OBJ_P,OBJ_P)); /* fns called when mon/obj hit */ 1098. struct obj *obj; /* 2nd arg to fhitm/fhito */ 1099. { 1100. register struct monst *mtmp; 1101. register struct obj *otmp; 1102. register uchar typ; 1103. int ddx, ddy; 1104. 1105. bhitpos.x = mon->mx; 1106. bhitpos.y = mon->my; 1107. ddx = sgn(mon->mux - mon->mx); 1108. ddy = sgn(mon->muy - mon->my); 1109. 1110. while(range-- > 0) { 1111. int x,y; 1112. 1113. bhitpos.x += ddx; 1114. bhitpos.y += ddy; 1115. x = bhitpos.x; y = bhitpos.y; 1116. 1117. if (!isok(x,y)) { 1118. bhitpos.x -= ddx; 1119. bhitpos.y -= ddy; 1120. break; 1121. } 1122. if (find_drawbridge(&x,&y)) 1123. switch (obj->otyp) { 1124. case WAN_STRIKING: 1125. destroy_drawbridge(x,y); 1126. } 1127. if(bhitpos.x==u.ux && bhitpos.y==u.uy) { 1128. (*fhitm)(&youmonst, obj); 1129. range -= 3; 1130. } else if(MON_AT(bhitpos.x, bhitpos.y)){ 1131. mtmp = m_at(bhitpos.x,bhitpos.y); 1132. if (cansee(bhitpos.x,bhitpos.y) && !canspotmon(mtmp)) 1133. map_invisible(bhitpos.x, bhitpos.y); 1134. (*fhitm)(mtmp, obj); 1135. range -= 3; 1136. } 1137. /* modified by GAN to hit all objects */ 1138. if(fhito){ 1139. int hitanything = 0; 1140. register struct obj *next_obj; 1141. 1142. for(otmp = level.objects[bhitpos.x][bhitpos.y]; 1143. otmp; otmp = next_obj) { 1144. /* Fix for polymorph bug, Tim Wright */ 1145. next_obj = otmp->nexthere; 1146. hitanything += (*fhito)(otmp, obj); 1147. } 1148. if(hitanything) range--; 1149. } 1150. typ = levl[bhitpos.x][bhitpos.y].typ; 1151. if(IS_DOOR(typ) || typ == SDOOR) { 1152. switch (obj->otyp) { 1153. /* note: monsters don't use opening or locking magic 1154. at present, but keep these as placeholders */ 1155. case WAN_OPENING: 1156. case WAN_LOCKING: 1157. case WAN_STRIKING: 1158. if (doorlock(obj, bhitpos.x, bhitpos.y)) { 1159. makeknown(obj->otyp); 1160. /* if a shop door gets broken, add it to 1161. the shk's fix list (no cost to player) */ 1162. if (levl[bhitpos.x][bhitpos.y].doormask == 1163. D_BROKEN && 1164. *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE)) 1165. add_damage(bhitpos.x, bhitpos.y, 0L); 1166. } 1167. break; 1168. } 1169. } 1170. if(!ZAP_POS(typ) || (IS_DOOR(typ) && 1171. (levl[bhitpos.x][bhitpos.y].doormask & (D_LOCKED | D_CLOSED))) 1172. ) { 1173. bhitpos.x -= ddx; 1174. bhitpos.y -= ddy; 1175. break; 1176. } 1177. } 1178. } 1179. 1180. /* Perform an offensive action for a monster. Must be called immediately 1181. * after find_offensive(). Return values are same as use_defensive(). 1182. */ 1183. int 1184. use_offensive(mtmp) 1185. struct monst *mtmp; 1186. { 1187. int i; 1188. struct obj *otmp = m.offensive; 1189. boolean oseen; 1190. 1191. /* offensive potions are not drunk, they're thrown */ 1192. if (otmp->oclass != POTION_CLASS && (i = precheck(mtmp, otmp)) != 0) 1193. return i; 1194. oseen = otmp && canseemon(mtmp); 1195. 1196. switch(m.has_offense) { 1197. case MUSE_WAN_DEATH: 1198. case MUSE_WAN_SLEEP: 1199. case MUSE_WAN_FIRE: 1200. case MUSE_WAN_COLD: 1201. case MUSE_WAN_LIGHTNING: 1202. case MUSE_WAN_MAGIC_MISSILE: 1203. mzapmsg(mtmp, otmp, FALSE); 1204. otmp->spe--; 1205. if (oseen) makeknown(otmp->otyp); 1206. m_using = TRUE; 1207. buzz((int)(-30 - (otmp->otyp - WAN_MAGIC_MISSILE)), 1208. (otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6, 1209. mtmp->mx, mtmp->my, 1210. sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my)); 1211. m_using = FALSE; 1212. return (mtmp->mhp <= 0) ? 1 : 2; 1213. case MUSE_FIRE_HORN: 1214. case MUSE_FROST_HORN: 1215. if (oseen) { 1216. makeknown(otmp->otyp); 1217. pline("%s plays a %s!", Monnam(mtmp), xname(otmp)); 1218. } else 1219. You_hear("a horn being played."); 1220. otmp->spe--; 1221. m_using = TRUE; 1222. buzz(-30 - ((otmp->otyp==FROST_HORN) ? AD_COLD-1 : AD_FIRE-1), 1223. rn1(6,6), mtmp->mx, mtmp->my, 1224. sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my)); 1225. m_using = FALSE; 1226. return (mtmp->mhp <= 0) ? 1 : 2; 1227. case MUSE_WAN_TELEPORTATION: 1228. case MUSE_WAN_STRIKING: 1229. zap_oseen = oseen; 1230. mzapmsg(mtmp, otmp, FALSE); 1231. otmp->spe--; 1232. m_using = TRUE; 1233. mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp); 1234. m_using = FALSE; 1235. return 2; 1236. case MUSE_SCR_EARTH: 1237. { 1238. /* TODO: handle steeds */ 1239. register int x, y; 1240. /* don't use monster fields after killing it */ 1241. boolean confused = (mtmp->mconf ? TRUE : FALSE); 1242. int mmx = mtmp->mx, mmy = mtmp->my; 1243. 1244. mreadmsg(mtmp, otmp); 1245. /* Identify the scroll */ 1246. if (canspotmon(mtmp)) { 1247. pline_The("%s rumbles %s %s!", ceiling(mtmp->mx, mtmp->my), 1248. otmp->blessed ? "around" : "above", 1249. mon_nam(mtmp)); 1250. if (oseen) makeknown(otmp->otyp); 1251. } else if (cansee(mtmp->mx, mtmp->my)) { 1252. pline_The("%s rumbles in the middle of nowhere!", 1253. ceiling(mtmp->mx, mtmp->my)); 1254. if (mtmp->minvis) 1255. map_invisible(mtmp->mx, mtmp->my); 1256. if (oseen) makeknown(otmp->otyp); 1257. } 1258. 1259. /* Loop through the surrounding squares */ 1260. for (x = mmx-1; x <= mmx+1; x++) { 1261. for (y = mmy-1; y <= mmy+1; y++) { 1262. /* Is this a suitable spot? */ 1263. if (isok(x, y) && !closed_door(x, y) && 1264. !IS_ROCK(levl[x][y].typ) && 1265. !IS_AIR(levl[x][y].typ) && 1266. (((x == mmx) && (y == mmy)) ? 1267. !otmp->blessed : !otmp->cursed) && 1268. (x != u.ux || y != u.uy)) { 1269. register struct obj *otmp2; 1270. register struct monst *mtmp2; 1271. 1272. /* Make the object(s) */ 1273. otmp2 = mksobj(confused ? ROCK : BOULDER, 1274. FALSE, FALSE); 1275. if (!otmp2) continue; /* Shouldn't happen */ 1276. otmp2->quan = confused ? rn1(5,2) : 1; 1277. otmp2->owt = weight(otmp2); 1278. 1279. /* Find the monster here (might be same as mtmp) */ 1280. mtmp2 = m_at(x, y); 1281. if (mtmp2 && !amorphous(mtmp2->data) && 1282. !passes_walls(mtmp2->data) && 1283. !noncorporeal(mtmp2->data) && 1284. !unsolid(mtmp2->data)) { 1285. struct obj *helmet = which_armor(mtmp2, W_ARMH); 1286. int mdmg; 1287. 1288. if (cansee(mtmp2->mx, mtmp2->my)) { 1289. pline("%s is hit by %s!", Monnam(mtmp2), 1290. doname(otmp2)); 1291. if (mtmp2->minvis && !canspotmon(mtmp2)) 1292. map_invisible(mtmp2->mx, mtmp2->my); 1293. } 1294. mdmg = dmgval(otmp2, mtmp2) * otmp2->quan; 1295. if (helmet) { 1296. if(is_metallic(helmet)) { 1297. if (canspotmon(mtmp2)) 1298. pline("Fortunately, %s is wearing a hard helmet.", mon_nam(mtmp2)); 1299. else if (flags.soundok) 1300. You_hear("a clanging sound."); 1301. if (mdmg > 2) mdmg = 2; 1302. } else { 1303. if (canspotmon(mtmp2)) 1304. pline("%s's %s does not protect %s.", 1305. Monnam(mtmp2), xname(helmet), 1306. him[pronoun_gender(mtmp2)]); 1307. } 1308. } 1309. mtmp2->mhp -= mdmg; 1310. if (mtmp2->mhp <= 0) { 1311. pline("%s is killed.", Monnam(mtmp2)); 1312. mondied(mtmp2); 1313. } 1314. } 1315. /* Drop the rock/boulder to the floor */ 1316. if (!flooreffects(otmp2, x, y, "fall")) { 1317. place_object(otmp2, x, y); 1318. stackobj(otmp2); 1319. newsym(x, y); /* map the rock */ 1320. } 1321. } 1322. } 1323. } 1324. m_useup(mtmp, otmp); 1325. /* Attack the player */ 1326. if (dist2(mmx, mmy, u.ux, u.uy) == 1 && !otmp->cursed) { 1327. int dmg; 1328. struct obj *otmp2; 1329. 1330. /* Okay, _you_ write this without repeating the code */ 1331. otmp2 = mksobj(confused ? ROCK : BOULDER, 1332. FALSE, FALSE); 1333. if (!otmp2) break; 1334. otmp2->quan = confused ? rn1(5,2) : 1; 1335. otmp2->owt = weight(otmp2); 1336. if (!amorphous(youmonst.data) && 1337. !Passes_walls && 1338. !noncorporeal(youmonst.data) && 1339. !unsolid(youmonst.data)) { 1340. You("are hit by %s!", doname(otmp2)); 1341. dmg = dmgval(otmp2, &youmonst) * otmp2->quan; 1342. if (uarmh) { 1343. if(is_metallic(uarmh)) { 1344. pline("Fortunately, you are wearing a hard helmet."); 1345. if (dmg > 2) dmg = 2; 1346. } else if (flags.verbose) { 1347. Your("%s does not protect you.", 1348. xname(uarmh)); 1349. } 1350. } 1351. } else 1352. dmg = 0; 1353. if (!flooreffects(otmp2, u.ux, u.uy, "fall")) { 1354. place_object(otmp2, u.ux, u.uy); 1355. stackobj(otmp2); 1356. newsym(u.ux, u.uy); 1357. } 1358. if (dmg) losehp(dmg, "scroll of earth", KILLED_BY_AN); 1359. } 1360. 1361. } 1362. break; 1363. #if 0 1364. case MUSE_SCR_FIRE: 1365. { 1366. boolean vis = cansee(mtmp->mx, mtmp->my); 1367. 1368. mreadmsg(mtmp, otmp); 1369. if (mtmp->mconf) { 1370. if (vis) 1371. pline("Oh, what a pretty fire!"); 1372. } else { 1373. struct monst *mtmp2; 1374. int num; 1375. 1376. if (vis) 1377. pline_The("scroll erupts in a tower of flame!"); 1378. shieldeff(mtmp->mx, mtmp->my); 1379. pline("%s is uninjured.", Monnam(mtmp)); 1380. (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); 1381. (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); 1382. (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); 1383. num = (2*(rn1(3, 3) + 2 * bcsign(otmp)) + 1)/3; 1384. if (Fire_resistance) 1385. You("are not harmed."); 1386. burn_away_slime(); 1387. if (Half_spell_damage) num = (num+1) / 2; 1388. else losehp(num, "scroll of fire", KILLED_BY_AN); 1389. for(mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) { 1390. if(mtmp == mtmp2) continue; 1391. if(dist2(mtmp2->mx,mtmp2->my,mtmp->mx,mtmp->my) < 3){ 1392. if (resists_fire(mtmp2)) continue; 1393. mtmp2->mhp -= num; 1394. if (resists_cold(mtmp2)) 1395. mtmp2->mhp -= 3*num; 1396. if(mtmp2->mhp < 1) { 1397. mondied(mtmp2); 1398. break; 1399. } 1400. } 1401. } 1402. } 1403. return 2; 1404. } 1405. #endif /* 0 */ 1406. case MUSE_POT_PARALYSIS: 1407. case MUSE_POT_BLINDNESS: 1408. case MUSE_POT_CONFUSION: 1409. case MUSE_POT_SLEEPING: 1410. case MUSE_POT_ACID: 1411. /* Note: this setting of dknown doesn't suffice. A monster 1412. * which is out of sight might throw and it hits something _in_ 1413. * sight, a problem not existing with wands because wand rays 1414. * are not objects. Also set dknown in mthrowu.c. 1415. */ 1416. if (cansee(mtmp->mx, mtmp->my)) { 1417. otmp->dknown = 1; 1418. pline("%s hurls %s!", Monnam(mtmp), 1419. singular(otmp, doname)); 1420. } 1421. m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux-mtmp->mx), 1422. sgn(mtmp->muy-mtmp->my), 1423. distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy), otmp); 1424. return 2; 1425. case 0: return 0; /* i.e. an exploded wand */ 1426. default: impossible("%s wanted to perform action %d?", Monnam(mtmp), 1427. m.has_offense); 1428. break; 1429. } 1430. return 0; 1431. } 1432. 1433. int 1434. rnd_offensive_item(mtmp) 1435. struct monst *mtmp; 1436. { 1437. struct permonst *pm = mtmp->data; 1438. int difficulty = monstr[(monsndx(pm))]; 1439. 1440. if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data) 1441. || pm->mlet == S_GHOST 1442. # ifdef KOPS 1443. || pm->mlet == S_KOP 1444. # endif 1445. ) return 0; 1446. if (difficulty > 7 && !rn2(35)) return WAN_DEATH; 1447. switch (rn2(9 - (difficulty < 4) + 4 * (difficulty > 6))) { 1448. case 0: { 1449. struct obj *helmet = which_armor(mtmp, W_ARMH); 1450. 1451. if ((helmet && is_metallic(helmet)) || amorphous(pm) || passes_walls(pm) || noncorporeal(pm) || unsolid(pm)) 1452. return SCR_EARTH; 1453. } /* fall through */ 1454. case 1: return WAN_STRIKING; 1455. case 2: return POT_ACID; 1456. case 3: return POT_CONFUSION; 1457. case 4: return POT_BLINDNESS; 1458. case 5: return POT_SLEEPING; 1459. case 6: return POT_PARALYSIS; 1460. case 7: case 8: 1461. return WAN_MAGIC_MISSILE; 1462. case 9: return WAN_SLEEP; 1463. case 10: return WAN_FIRE; 1464. case 11: return WAN_COLD; 1465. case 12: return WAN_LIGHTNING; 1466. } 1467. /*NOTREACHED*/ 1468. return 0; 1469. } 1470. 1471. #define MUSE_POT_GAIN_LEVEL 1 1472. #define MUSE_WAN_MAKE_INVISIBLE 2 1473. #define MUSE_POT_INVISIBILITY 3 1474. #define MUSE_POLY_TRAP 4 1475. #define MUSE_WAN_POLYMORPH 5 1476. #define MUSE_POT_SPEED 6 1477. #define MUSE_WAN_SPEED_MONSTER 7 1478. #define MUSE_BULLWHIP 8 1479. #define MUSE_POT_POLYMORPH 9 1480. 1481. boolean 1482. find_misc(mtmp) 1483. struct monst *mtmp; 1484. { 1485. register struct obj *obj; 1486. struct permonst *mdat = mtmp->data; 1487. int x = mtmp->mx, y = mtmp->my; 1488. struct trap *t; 1489. int xx, yy; 1490. boolean immobile = (mdat->mmove == 0); 1491. boolean stuck = (mtmp == u.ustuck); 1492. 1493. m.misc = (struct obj *)0; 1494. m.has_misc = 0; 1495. if (is_animal(mdat) || mindless(mdat)) 1496. return 0; 1497. if (u.uswallow && stuck) return FALSE; 1498. 1499. /* We arbitrarily limit to times when a player is nearby for the 1500. * same reason as Junior Pac-Man doesn't have energizers eaten until 1501. * you can see them... 1502. */ 1503. if(dist2(x, y, mtmp->mux, mtmp->muy) > 36) 1504. return FALSE; 1505. 1506. if (!stuck && !immobile && !mtmp->cham && monstr[monsndx(mdat)] < 6) { 1507. boolean ignore_boulders = (verysmall(mdat) || 1508. throws_rocks(mdat) || 1509. passes_walls(mdat)); 1510. for(xx = x-1; xx <= x+1; xx++) 1511. for(yy = y-1; yy <= y+1; yy++) 1512. if (isok(xx,yy) && (xx != u.ux || yy != u.uy)) 1513. if (mdat != &mons[PM_GRID_BUG] || xx == x || yy == y) 1514. if (/* (xx==x && yy==y) || */ !level.monsters[xx][yy]) 1515. if ((t = t_at(xx, yy)) != 0 && 1516. (ignore_boulders || !sobj_at(BOULDER, xx, yy)) 1517. && !onscary(xx, yy, mtmp)) { 1518. if (t->ttyp == POLY_TRAP) { 1519. trapx = xx; 1520. trapy = yy; 1521. m.has_misc = MUSE_POLY_TRAP; 1522. return TRUE; 1523. } 1524. } 1525. } 1526. if (nohands(mdat)) 1527. return 0; 1528. 1529. #define nomore(x) if(m.has_misc==x) continue; 1530. for(obj=mtmp->minvent; obj; obj=obj->nobj) { 1531. /* Monsters shouldn't recognize cursed items; this kludge is */ 1532. /* necessary to prevent serious problems though... */ 1533. if(obj->otyp == POT_GAIN_LEVEL && (!obj->cursed || 1534. (!mtmp->isgd && !mtmp->isshk && !mtmp->ispriest))) { 1535. m.misc = obj; 1536. m.has_misc = MUSE_POT_GAIN_LEVEL; 1537. } 1538. nomore(MUSE_BULLWHIP); 1539. if(obj->otyp == BULLWHIP && (MON_WEP(mtmp) == obj) && 1540. distu(mtmp->mx,mtmp->my)==1 && uwep && !mtmp->mpeaceful) { 1541. m.misc = obj; 1542. m.has_misc = MUSE_BULLWHIP; 1543. } 1544. /* Note: peaceful/tame monsters won't make themselves 1545. * invisible unless you can see them. Not really right, but... 1546. */ 1547. nomore(MUSE_WAN_MAKE_INVISIBLE); 1548. if(obj->otyp == WAN_MAKE_INVISIBLE && obj->spe > 0 && 1549. !mtmp->minvis && !mtmp->invis_blkd && 1550. (!mtmp->mpeaceful || See_invisible) && 1551. (mdat != &mons[PM_MEDUSA] || mtmp->mcan)) { 1552. m.misc = obj; 1553. m.has_misc = MUSE_WAN_MAKE_INVISIBLE; 1554. } 1555. nomore(MUSE_POT_INVISIBILITY); 1556. if(obj->otyp == POT_INVISIBILITY && 1557. !mtmp->minvis && !mtmp->invis_blkd && 1558. (!mtmp->mpeaceful || See_invisible)) { 1559. m.misc = obj; 1560. m.has_misc = MUSE_POT_INVISIBILITY; 1561. } 1562. nomore(MUSE_WAN_SPEED_MONSTER); 1563. if(obj->otyp == WAN_SPEED_MONSTER && obj->spe > 0 1564. && mtmp->mspeed != MFAST && !mtmp->isgd) { 1565. m.misc = obj; 1566. m.has_misc = MUSE_WAN_SPEED_MONSTER; 1567. } 1568. nomore(MUSE_POT_SPEED); 1569. if(obj->otyp == POT_SPEED && mtmp->mspeed != MFAST 1570. && !mtmp->isgd) { 1571. m.misc = obj; 1572. m.has_misc = MUSE_POT_SPEED; 1573. } 1574. nomore(MUSE_WAN_POLYMORPH); 1575. if(obj->otyp == WAN_POLYMORPH && obj->spe > 0 && !mtmp->cham 1576. && monstr[monsndx(mdat)] < 6) { 1577. m.misc = obj; 1578. m.has_misc = MUSE_WAN_POLYMORPH; 1579. } 1580. nomore(MUSE_POT_POLYMORPH); 1581. if(obj->otyp == POT_POLYMORPH && !mtmp->cham 1582. && monstr[monsndx(mdat)] < 6) { 1583. m.misc = obj; 1584. m.has_misc = MUSE_POT_POLYMORPH; 1585. } 1586. } 1587. return((boolean)(!!m.has_misc)); 1588. #undef nomore 1589. } 1590. 1591. int 1592. use_misc(mtmp) 1593. struct monst *mtmp; 1594. { 1595. int i; 1596. struct obj *otmp = m.misc; 1597. boolean vis, vismon, oseen; 1598. char nambuf[BUFSZ]; 1599. 1600. if ((i = precheck(mtmp, otmp)) != 0) return i; 1601. vis = cansee(mtmp->mx, mtmp->my); 1602. vismon = canseemon(mtmp); 1603. oseen = otmp && vismon; 1604. 1605. switch(m.has_misc) { 1606. case MUSE_POT_GAIN_LEVEL: 1607. mquaffmsg(mtmp, otmp); 1608. if (otmp->cursed) { 1609. if (Can_rise_up(mtmp->mx, mtmp->my, &u.uz)) { 1610. register int tolev = depth(&u.uz)-1; 1611. d_level tolevel; 1612. 1613. get_level(&tolevel, tolev); 1614. /* insurance against future changes... */ 1615. if(on_level(&tolevel, &u.uz)) goto skipmsg; 1616. if (vismon) { 1617. pline("%s rises up, through the %s!", 1618. Monnam(mtmp), ceiling(mtmp->mx, mtmp->my)); 1619. if(!objects[POT_GAIN_LEVEL].oc_name_known 1620. && !objects[POT_GAIN_LEVEL].oc_uname) 1621. docall(otmp); 1622. } 1623. m_useup(mtmp, otmp); 1624. migrate_to_level(mtmp, ledger_no(&tolevel), 1625. MIGR_RANDOM, (coord *)0); 1626. return 2; 1627. } else { 1628. skipmsg: 1629. if (vismon) { 1630. pline("%s looks uneasy.", Monnam(mtmp)); 1631. if(!objects[POT_GAIN_LEVEL].oc_name_known 1632. && !objects[POT_GAIN_LEVEL].oc_uname) 1633. docall(otmp); 1634. } 1635. m_useup(mtmp, otmp); 1636. return 2; 1637. } 1638. } 1639. if (vismon) pline("%s seems more experienced.", Monnam(mtmp)); 1640. if (oseen) makeknown(POT_GAIN_LEVEL); 1641. m_useup(mtmp, otmp); 1642. if (!grow_up(mtmp,(struct monst *)0)) return 1; 1643. /* grew into genocided monster */ 1644. return 2; 1645. case MUSE_WAN_MAKE_INVISIBLE: 1646. case MUSE_POT_INVISIBILITY: 1647. if (otmp->otyp == WAN_MAKE_INVISIBLE) { 1648. mzapmsg(mtmp, otmp, TRUE); 1649. otmp->spe--; 1650. } else 1651. mquaffmsg(mtmp, otmp); 1652. /* format monster's name before altering its visibility */ 1653. Strcpy(nambuf, See_invisible ? Monnam(mtmp) : mon_nam(mtmp)); 1654. mon_set_minvis(mtmp); 1655. if (vismon && mtmp->minvis) { /* was seen, now invisible */ 1656. if (See_invisible) 1657. pline("%s body takes on a %s transparency.", 1658. s_suffix(nambuf), 1659. Hallucination ? "normal" : "strange"); 1660. else 1661. pline("Suddenly you cannot see %s.", nambuf); 1662. if (oseen) makeknown(otmp->otyp); 1663. } 1664. if (otmp->otyp == POT_INVISIBILITY) { 1665. if (otmp->cursed) you_aggravate(mtmp); 1666. m_useup(mtmp, otmp); 1667. } 1668. return 2; 1669. case MUSE_WAN_SPEED_MONSTER: 1670. mzapmsg(mtmp, otmp, TRUE); 1671. otmp->spe--; 1672. mon_adjust_speed(mtmp, 1); 1673. return 2; 1674. case MUSE_POT_SPEED: 1675. mquaffmsg(mtmp, otmp); 1676. /* note difference in potion effect due to substantially 1677. different methods of maintaining speed ratings: 1678. player's character becomes "very fast" temporarily; 1679. monster becomes "one stage faster" permanently */ 1680. if (vismon) 1681. pline("%s is suddenly moving faster.", Monnam(mtmp)); 1682. if (oseen) makeknown(POT_SPEED); 1683. mon_adjust_speed(mtmp, 1); 1684. m_useup(mtmp, otmp); 1685. return 2; 1686. case MUSE_WAN_POLYMORPH: 1687. mzapmsg(mtmp, otmp, TRUE); 1688. otmp->spe--; 1689. (void) newcham(mtmp, rndmonst()); 1690. if (oseen) makeknown(WAN_POLYMORPH); 1691. return 2; 1692. case MUSE_POT_POLYMORPH: 1693. mquaffmsg(mtmp, otmp); 1694. if (vismon) pline("%s suddenly mutates!", Monnam(mtmp)); 1695. (void) newcham(mtmp, rndmonst()); 1696. if (oseen) makeknown(POT_POLYMORPH); 1697. m_useup(mtmp, otmp); 1698. return 2; 1699. case MUSE_POLY_TRAP: 1700. if (vismon) 1701. pline("%s deliberately %s onto a polymorph trap!", 1702. Monnam(mtmp), 1703. makeplural(locomotion(mtmp->data, "jump"))); 1704. if (vis) seetrap(t_at(trapx,trapy)); 1705. 1706. /* don't use rloc() due to worms */ 1707. remove_monster(mtmp->mx, mtmp->my); 1708. newsym(mtmp->mx, mtmp->my); 1709. place_monster(mtmp, trapx, trapy); 1710. if (mtmp->wormno) worm_move(mtmp); 1711. newsym(trapx, trapy); 1712. 1713. (void) newcham(mtmp, (struct permonst *)0); 1714. return 2; 1715. case MUSE_BULLWHIP: 1716. /* attempt to disarm hero */ 1717. if (uwep && !rn2(5)) { 1718. const char *The_whip = vismon ? "The bullwhip" : "A whip"; 1719. int where_to = rn2(4); 1720. struct obj *obj = uwep; 1721. const char *hand; 1722. char the_weapon[BUFSZ]; 1723. 1724. Strcpy(the_weapon, the(xname(obj))); 1725. hand = body_part(HAND); 1726. if (bimanual(obj)) hand = makeplural(hand); 1727. 1728. if (vismon) 1729. pline("%s flicks a bullwhip towards your %s!", 1730. Monnam(mtmp), hand); 1731. if (obj->otyp == HEAVY_IRON_BALL) { 1732. pline("%s fails to wrap around %s.", 1733. The_whip, the_weapon); 1734. return 1; 1735. } 1736. pline("%s wraps around %s you're wielding!", 1737. The_whip, the_weapon); 1738. if (obj->cursed) { 1739. pline("%s is welded to your %s%c", 1740. (obj->quan == 1L) ? "It" : "They", 1741. hand, !obj->bknown ? '!' : '.'); 1742. obj->bknown = 1; 1743. where_to = 0; 1744. } 1745. if (!where_to) { 1746. pline("The whip slips free."); /* not `The_whip' */ 1747. return 1; 1748. } 1749. freeinv(obj); 1750. uwepgone(); 1751. switch (where_to) { 1752. case 1: /* onto floor beneath mon */ 1753. pline("%s yanks %s from your %s!", Monnam(mtmp), 1754. the_weapon, hand); 1755. if (obj->otyp == CRYSKNIFE && (!obj->oerodeproof || !rn2(10))) { 1756. obj->otyp = WORM_TOOTH; 1757. obj->oerodeproof = 0; 1758. } 1759. place_object(obj, mtmp->mx, mtmp->my); 1760. break; 1761. case 2: /* onto floor beneath you */ 1762. pline("%s yanks %s to the %s!", Monnam(mtmp), 1763. the_weapon, surface(u.ux, u.uy)); 1764. dropy(obj); 1765. break; 1766. case 3: /* into mon's inventory */ 1767. pline("%s snatches %s!", Monnam(mtmp), 1768. the_weapon); 1769. mpickobj(mtmp,obj); 1770. break; 1771. } 1772. return 1; 1773. } 1774. return 0; 1775. case 0: return 0; /* i.e. an exploded wand */ 1776. default: impossible("%s wanted to perform action %d?", Monnam(mtmp), 1777. m.has_misc); 1778. break; 1779. } 1780. return 0; 1781. } 1782. 1783. STATIC_OVL void 1784. you_aggravate(mtmp) 1785. struct monst *mtmp; 1786. { 1787. killer = ""; /* hack: prevent "it" in names */ 1788. pline("For some reason, %s presence is known to you.", 1789. s_suffix(mon_nam(mtmp))); 1790. cls(); 1791. #ifdef CLIPPING 1792. cliparound(mtmp->mx, mtmp->my); 1793. #endif 1794. show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp)); 1795. display_self(); 1796. You_feel("aggravated at %s.", mon_nam(mtmp)); 1797. display_nhwindow(WIN_MAP, TRUE); 1798. docrt(); 1799. if (unconscious()) { 1800. multi = -1; 1801. nomovemsg = 1802. "Aggravated, you are jolted into full consciousness."; 1803. } 1804. killer = 0; 1805. newsym(mtmp->mx,mtmp->my); 1806. } 1807. 1808. int 1809. rnd_misc_item(mtmp) 1810. struct monst *mtmp; 1811. { 1812. struct permonst *pm = mtmp->data; 1813. int difficulty = monstr[(monsndx(pm))]; 1814. 1815. if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data) 1816. || pm->mlet == S_GHOST 1817. # ifdef KOPS 1818. || pm->mlet == S_KOP 1819. # endif 1820. ) return 0; 1821. /* Unlike other rnd_item functions, we only allow _weak_ monsters 1822. * to have this item; after all, the item will be used to strengthen 1823. * the monster and strong monsters won't use it at all... 1824. */ 1825. if (difficulty < 6 && !rn2(30)) 1826. return rn2(6) ? POT_POLYMORPH : WAN_POLYMORPH; 1827. 1828. if (!rn2(40) && !nonliving(pm)) return AMULET_OF_LIFE_SAVING; 1829. 1830. switch (rn2(3)) { 1831. case 0: 1832. if (mtmp->isgd) return 0; 1833. return rn2(6) ? POT_SPEED : WAN_SPEED_MONSTER; 1834. case 1: 1835. if (mtmp->mpeaceful && !See_invisible) return 0; 1836. return rn2(6) ? POT_INVISIBILITY : WAN_MAKE_INVISIBLE; 1837. case 2: 1838. return POT_GAIN_LEVEL; 1839. } 1840. /*NOTREACHED*/ 1841. return 0; 1842. } 1843. 1844. boolean 1845. searches_for_item(mon, obj) 1846. struct monst *mon; 1847. struct obj *obj; 1848. { 1849. int typ = obj->otyp; 1850. 1851. if (is_animal(mon->data) || 1852. mindless(mon->data) || 1853. mon->data == &mons[PM_GHOST]) /* don't loot bones piles */ 1854. return FALSE; 1855. 1856. if (typ == WAN_MAKE_INVISIBLE || typ == POT_INVISIBILITY) 1857. return (boolean)(!mon->minvis && !mon->invis_blkd); 1858. if (typ == WAN_SPEED_MONSTER || typ == POT_SPEED) 1859. return (boolean)(mon->mspeed != MFAST); 1860. 1861. switch (obj->oclass) { 1862. case WAND_CLASS: 1863. if (typ == WAN_DIGGING) 1864. return (boolean)(!is_floater(mon->data)); 1865. if (typ == WAN_POLYMORPH) 1866. return (boolean)(monstr[monsndx(mon->data)] < 6); 1867. if (objects[typ].oc_dir == RAY || 1868. typ == WAN_STRIKING || 1869. typ == WAN_TELEPORTATION || 1870. typ == WAN_CREATE_MONSTER) 1871. return TRUE; 1872. break; 1873. case POTION_CLASS: 1874. if (typ == POT_HEALING || 1875. typ == POT_EXTRA_HEALING || 1876. typ == POT_FULL_HEALING || 1877. typ == POT_POLYMORPH || 1878. typ == POT_GAIN_LEVEL || 1879. typ == POT_PARALYSIS || 1880. typ == POT_SLEEPING || 1881. typ == POT_ACID || 1882. typ == POT_BLINDNESS || 1883. typ == POT_CONFUSION) 1884. return TRUE; 1885. break; 1886. case SCROLL_CLASS: 1887. if (typ == SCR_TELEPORTATION || typ == SCR_CREATE_MONSTER 1888. || typ == SCR_EARTH) 1889. return TRUE; 1890. break; 1891. case AMULET_CLASS: 1892. if (typ == AMULET_OF_LIFE_SAVING) 1893. return (boolean)(!nonliving(mon->data)); 1894. if (typ == AMULET_OF_REFLECTION) 1895. return TRUE; 1896. break; 1897. case TOOL_CLASS: 1898. if (typ == PICK_AXE) 1899. return (boolean)needspick(mon->data); 1900. if (typ == UNICORN_HORN) 1901. return (boolean)(!obj->cursed && !is_unicorn(mon->data)); 1902. if (typ == FROST_HORN || typ == FIRE_HORN) 1903. return TRUE; 1904. break; 1905. case FOOD_CLASS: 1906. if (typ == CORPSE) 1907. return (boolean)(((mon->misc_worn_check & W_ARMG) && 1908. touch_petrifies(&mons[obj->corpsenm])) || 1909. (!resists_ston(mon) && 1910. (obj->corpsenm == PM_LIZARD || 1911. acidic(&mons[obj->corpsenm])))); 1912. if (typ == EGG) 1913. return (boolean)(touch_petrifies(&mons[obj->corpsenm])); 1914. break; 1915. default: 1916. break; 1917. } 1918. 1919. return FALSE; 1920. } 1921. 1922. boolean 1923. mon_reflects(mon,str) 1924. struct monst *mon; 1925. const char *str; 1926. { 1927. struct obj *orefl = which_armor(mon, W_ARMS); 1928. 1929. if (orefl && orefl->otyp == SHIELD_OF_REFLECTION) { 1930. if (str) { 1931. pline(str, s_suffix(mon_nam(mon)), "shield"); 1932. makeknown(SHIELD_OF_REFLECTION); 1933. } 1934. return TRUE; 1935. } else if ((orefl = which_armor(mon, W_AMUL)) && 1936. orefl->otyp == AMULET_OF_REFLECTION) { 1937. if (str) { 1938. pline(str, s_suffix(mon_nam(mon)), "amulet"); 1939. makeknown(AMULET_OF_REFLECTION); 1940. } 1941. return TRUE; 1942. } else if ((orefl = which_armor(mon, W_ARM)) && 1943. (orefl->otyp == SILVER_DRAGON_SCALES || orefl->otyp == SILVER_DRAGON_SCALE_MAIL)) { 1944. if (str) 1945. pline(str, s_suffix(mon_nam(mon)), "armor"); 1946. return TRUE; 1947. } else if (mon->data == &mons[PM_SILVER_DRAGON]) { 1948. /* Silver dragons only reflect when mature; babies do not */ 1949. if (str) 1950. pline(str, s_suffix(mon_nam(mon)), "scales"); 1951. return TRUE; 1952. } 1953. return FALSE; 1954. } 1955. 1956. boolean 1957. ureflects (fmt, str) 1958. const char *fmt, *str; 1959. { 1960. /* Check from outermost to innermost objects */ 1961. if (EReflecting & W_ARMS) { 1962. if (fmt && str) { 1963. pline(fmt, str, "shield"); 1964. makeknown(SHIELD_OF_REFLECTION); 1965. } 1966. return TRUE; 1967. } else if (EReflecting & W_WEP) { 1968. /* Due to wielded artifact weapon */ 1969. if (fmt && str) 1970. pline(fmt, str, "weapon"); 1971. return TRUE; 1972. } else if (EReflecting & W_AMUL) { 1973. if (fmt && str) { 1974. pline(fmt, str, "medallion"); 1975. makeknown(AMULET_OF_REFLECTION); 1976. } 1977. return TRUE; 1978. } else if (EReflecting & W_ARM) { 1979. if (fmt && str) 1980. pline(fmt, str, "armor"); 1981. return TRUE; 1982. } else if (youmonst.data == &mons[PM_SILVER_DRAGON]) { 1983. if (fmt && str) 1984. pline(fmt, str, "scales"); 1985. return TRUE; 1986. } 1987. return FALSE; 1988. } 1989. 1990. 1991. /* TRUE if the monster ate something */ 1992. boolean 1993. munstone(mon, by_you) 1994. struct monst *mon; 1995. boolean by_you; 1996. { 1997. struct obj *obj; 1998. 1999. if (resists_ston(mon)) return FALSE; 2000. if (mon->meating || !mon->mcanmove || mon->msleeping) return FALSE; 2001. 2002. for(obj = mon->minvent; obj; obj = obj->nobj) { 2003. /* Monsters can also use potions of acid */ 2004. if ((obj->otyp == POT_ACID) || (obj->otyp == CORPSE && 2005. (obj->corpsenm == PM_LIZARD || acidic(&mons[obj->corpsenm])))) { 2006. int nutrit = dog_nutrition(mon, obj); /* also sets meating */ 2007. 2008. if (canseemon(mon)) { 2009. long save_quan = obj->quan; 2010. 2011. obj->quan = 1L; 2012. pline("%s %ss %s.", Monnam(mon), 2013. (obj->otyp == POT_ACID) ? "quaff" : "eat", 2014. distant_name(obj,doname)); 2015. obj->quan = save_quan; 2016. } else if (flags.soundok) 2017. You("hear %s.", (obj->otyp == POT_ACID) ? "drinking" : "chewing"); 2018. m_useup(mon, obj); 2019. if (((obj->otyp == POT_ACID) || acidic(&mons[obj->corpsenm])) && 2020. !resists_acid(mon)) { 2021. mon->mhp -= rnd(15); 2022. pline("%s has a very bad case of stomach acid.", 2023. Monnam(mon)); 2024. } 2025. if (mon->mhp <= 0) { 2026. pline("%s dies!", Monnam(mon)); 2027. if (by_you) xkilled(mon, 0); 2028. else mondead(mon); 2029. return TRUE; 2030. } 2031. if (canseemon(mon)) { 2032. if (Hallucination) 2033. pline("What a pity - %s just ruined a future piece of art!", 2034. mon_nam(mon)); 2035. else 2036. pline("%s seems limber!", Monnam(mon)); 2037. } 2038. if (mon->mtame && !mon->isminion) { 2039. struct edog *edog = EDOG(mon); 2040. 2041. if (edog->hungrytime < moves) edog->hungrytime = moves; 2042. edog->hungrytime += nutrit; 2043. mon->mconf = 0; 2044. } 2045. mon->mlstmv = monstermoves; /* it takes a turn */ 2046. return TRUE; 2047. } 2048. } 2049. return FALSE; 2050. } 2051. 2052. /*muse.c*/
Alternative Linked Data Views: ODE     Raw Data in: CXML | CSV | RDF ( N-Triples N3/Turtle JSON XML ) | OData ( Atom JSON ) | Microdata ( JSON HTML) | JSON-LD    About   
This material is Open Knowledge   W3C Semantic Web Technology [RDF Data] Valid XHTML + RDFa
OpenLink Virtuoso version 07.20.3217, on Linux (x86_64-pc-linux-gnu), Standard Edition
Data on this page belongs to its respective rights holders.
Virtuoso Faceted Browser Copyright © 2009-2012 OpenLink Software