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