Below is the full text to src/uhitm.c from NetHack 3.4.3. To link to a particular line, write [[uhitm.c#line123]], for example.
Top of file[]
1. /* SCCS Id: @(#)uhitm.c 3.4 2003/02/18 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 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. #include "hack.h" 6. 7. STATIC_DCL boolean FDECL(known_hitum, (struct monst *,int *,struct attack *)); 8. STATIC_DCL void FDECL(steal_it, (struct monst *, struct attack *)); 9. STATIC_DCL boolean FDECL(hitum, (struct monst *,int,struct attack *)); 10. STATIC_DCL boolean FDECL(hmon_hitmon, (struct monst *,struct obj *,int)); 11. #ifdef STEED 12. STATIC_DCL int FDECL(joust, (struct monst *,struct obj *)); 13. #endif 14. STATIC_DCL void NDECL(demonpet); 15. STATIC_DCL boolean FDECL(m_slips_free, (struct monst *mtmp,struct attack *mattk)); 16. STATIC_DCL int FDECL(explum, (struct monst *,struct attack *)); 17. STATIC_DCL void FDECL(start_engulf, (struct monst *)); 18. STATIC_DCL void NDECL(end_engulf); 19. STATIC_DCL int FDECL(gulpum, (struct monst *,struct attack *)); 20. STATIC_DCL boolean FDECL(hmonas, (struct monst *,int)); 21. STATIC_DCL void FDECL(nohandglow, (struct monst *)); 22. STATIC_DCL boolean FDECL(shade_aware, (struct obj *)); 23. 24. extern boolean notonhead; /* for long worms */ 25. /* The below might become a parameter instead if we use it a lot */ 26. static int dieroll; 27. /* Used to flag attacks caused by Stormbringer's maliciousness. */ 28. static boolean override_confirmation = FALSE; 29. 30. #define PROJECTILE(obj) ((obj) && is_ammo(obj)) 31.
hurtmarmor[]
32. /* modified from hurtarmor() in mhitu.c */ 33. /* This is not static because it is also used for monsters rusting monsters */ 34. void 35. hurtmarmor(mdef, attk) 36. struct monst *mdef; 37. int attk; 38. { 39. int hurt; 40. struct obj *target; 41. 42. switch(attk) { 43. /* 0 is burning, which we should never be called with */ 44. case AD_RUST: hurt = 1; break; 45. case AD_CORR: hurt = 3; break; 46. default: hurt = 2; break; 47. } 48. /* What the following code does: it keeps looping until it 49. * finds a target for the rust monster. 50. * Head, feet, etc... not covered by metal, or covered by 51. * rusty metal, are not targets. However, your body always 52. * is, no matter what covers it. 53. */ 54. while (1) { 55. switch(rn2(5)) { 56. case 0: 57. target = which_armor(mdef, W_ARMH); 58. if (!target || !rust_dmg(target, xname(target), hurt, FALSE, mdef)) 59. continue; 60. break; 61. case 1: 62. target = which_armor(mdef, W_ARMC); 63. if (target) { 64. (void)rust_dmg(target, xname(target), hurt, TRUE, mdef); 65. break; 66. } 67. if ((target = which_armor(mdef, W_ARM)) != (struct obj *)0) { 68. (void)rust_dmg(target, xname(target), hurt, TRUE, mdef); 69. #ifdef TOURIST 70. } else if ((target = which_armor(mdef, W_ARMU)) != (struct obj *)0) { 71. (void)rust_dmg(target, xname(target), hurt, TRUE, mdef); 72. #endif 73. } 74. break; 75. case 2: 76. target = which_armor(mdef, W_ARMS); 77. if (!target || !rust_dmg(target, xname(target), hurt, FALSE, mdef)) 78. continue; 79. break; 80. case 3: 81. target = which_armor(mdef, W_ARMG); 82. if (!target || !rust_dmg(target, xname(target), hurt, FALSE, mdef)) 83. continue; 84. break; 85. case 4: 86. target = which_armor(mdef, W_ARMF); 87. if (!target || !rust_dmg(target, xname(target), hurt, FALSE, mdef)) 88. continue; 89. break; 90. } 91. break; /* Out of while loop */ 92. } 93. } 94.
attack_checks[]
95. /* FALSE means it's OK to attack */ 96. boolean 97. attack_checks(mtmp, wep) 98. register struct monst *mtmp; 99. struct obj *wep; /* uwep for attack(), null for kick_monster() */ 100. { 101. char qbuf[QBUFSZ]; 102. 103. /* if you're close enough to attack, alert any waiting monster */ 104. mtmp->mstrategy &= ~STRAT_WAITMASK; 105. 106. if (u.uswallow && mtmp == u.ustuck) return FALSE; 107. 108. if (flags.forcefight) { 109. /* Do this in the caller, after we checked that the monster 110. * didn't die from the blow. Reason: putting the 'I' there 111. * causes the hero to forget the square's contents since 112. * both 'I' and remembered contents are stored in .glyph. 113. * If the monster dies immediately from the blow, the 'I' will 114. * not stay there, so the player will have suddenly forgotten 115. * the square's contents for no apparent reason. 116. if (!canspotmon(mtmp) && 117. !glyph_is_invisible(levl[u.ux+u.dx][u.uy+u.dy].glyph)) 118. map_invisible(u.ux+u.dx, u.uy+u.dy); 119. */ 120. return FALSE; 121. } 122. 123. /* Put up an invisible monster marker, but with exceptions for 124. * monsters that hide and monsters you've been warned about. 125. * The former already prints a warning message and 126. * prevents you from hitting the monster just via the hidden monster 127. * code below; if we also did that here, similar behavior would be 128. * happening two turns in a row. The latter shows a glyph on 129. * the screen, so you know something is there. 130. */ 131. if (!canspotmon(mtmp) && 132. !glyph_is_warning(glyph_at(u.ux+u.dx,u.uy+u.dy)) && 133. !glyph_is_invisible(levl[u.ux+u.dx][u.uy+u.dy].glyph) && 134. !(!Blind && mtmp->mundetected && hides_under(mtmp->data))) { 135. pline("Wait! There's %s there you can't see!", 136. something); 137. map_invisible(u.ux+u.dx, u.uy+u.dy); 138. /* if it was an invisible mimic, treat it as if we stumbled 139. * onto a visible mimic 140. */ 141. if(mtmp->m_ap_type && !Protection_from_shape_changers) { 142. if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK)) 143. u.ustuck = mtmp; 144. } 145. wakeup(mtmp); /* always necessary; also un-mimics mimics */ 146. return TRUE; 147. } 148. 149. if (mtmp->m_ap_type && !Protection_from_shape_changers && 150. !sensemon(mtmp) && 151. !glyph_is_warning(glyph_at(u.ux+u.dx,u.uy+u.dy))) { 152. /* If a hidden mimic was in a square where a player remembers 153. * some (probably different) unseen monster, the player is in 154. * luck--he attacks it even though it's hidden. 155. */ 156. if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph)) { 157. seemimic(mtmp); 158. return(FALSE); 159. } 160. stumble_onto_mimic(mtmp); 161. return TRUE; 162. } 163. 164. if (mtmp->mundetected && !canseemon(mtmp) && 165. !glyph_is_warning(glyph_at(u.ux+u.dx,u.uy+u.dy)) && 166. (hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)) { 167. mtmp->mundetected = mtmp->msleeping = 0; 168. newsym(mtmp->mx, mtmp->my); 169. if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph)) { 170. seemimic(mtmp); 171. return(FALSE); 172. } 173. if (!(Blind ? Blind_telepat : Unblind_telepat)) { 174. struct obj *obj; 175. 176. if (Blind || (is_pool(mtmp->mx,mtmp->my) && !Underwater)) 177. pline("Wait! There's a hidden monster there!"); 178. else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0) 179. pline("Wait! There's %s hiding under %s!", 180. an(l_monnam(mtmp)), doname(obj)); 181. return TRUE; 182. } 183. } 184. 185. /* 186. * make sure to wake up a monster from the above cases if the 187. * hero can sense that the monster is there. 188. */ 189. if ((mtmp->mundetected || mtmp->m_ap_type) && sensemon(mtmp)) { 190. mtmp->mundetected = 0; 191. wakeup(mtmp); 192. } 193. 194. if (flags.confirm && mtmp->mpeaceful 195. && !Confusion && !Hallucination && !Stunned) { 196. /* Intelligent chaotic weapons (Stormbringer) want blood */ 197. if (wep && wep->oartifact == ART_STORMBRINGER) { 198. override_confirmation = TRUE; 199. return(FALSE); 200. } 201. if (canspotmon(mtmp)) { 202. Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp)); 203. if (yn(qbuf) != 'y') { 204. flags.move = 0; 205. return(TRUE); 206. } 207. } 208. } 209. 210. return(FALSE); 211. } 212.
check_caitiff[]
213. /* 214. * It is unchivalrous for a knight to attack the defenseless or from behind. 215. */ 216. void 217. check_caitiff(mtmp) 218. struct monst *mtmp; 219. { 220. if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL && 221. (!mtmp->mcanmove || mtmp->msleeping || 222. (mtmp->mflee && !mtmp->mavenge)) && 223. u.ualign.record > -10) { 224. You("caitiff!"); 225. adjalign(-1); 226. } 227. } 228.
find_roll_to_hit[]
229. schar 230. find_roll_to_hit(mtmp) 231. register struct monst *mtmp; 232. { 233. schar tmp; 234. int tmp2; 235. 236. tmp = 1 + Luck + abon() + find_mac(mtmp) + u.uhitinc + 237. maybe_polyd(youmonst.data->mlevel, u.ulevel); 238. 239. check_caitiff(mtmp); 240. 241. /* attacking peaceful creatures is bad for the samurai's giri */ 242. if (Role_if(PM_SAMURAI) && mtmp->mpeaceful && 243. u.ualign.record > -10) { 244. You("dishonorably attack the innocent!"); 245. adjalign(-1); 246. } 247. 248. /* Adjust vs. (and possibly modify) monster state. */ 249. 250. if(mtmp->mstun) tmp += 2; 251. if(mtmp->mflee) tmp += 2; 252. 253. if (mtmp->msleeping) { 254. mtmp->msleeping = 0; 255. tmp += 2; 256. } 257. if(!mtmp->mcanmove) { 258. tmp += 4; 259. if(!rn2(10)) { 260. mtmp->mcanmove = 1; 261. mtmp->mfrozen = 0; 262. } 263. } 264. if (is_orc(mtmp->data) && maybe_polyd(is_elf(youmonst.data), 265. Race_if(PM_ELF))) 266. tmp++; 267. if(Role_if(PM_MONK) && !Upolyd) { 268. if (uarm) { 269. Your("armor is rather cumbersome..."); 270. tmp -= urole.spelarmr; 271. } else if (!uwep && !uarms) { 272. tmp += (u.ulevel / 3) + 2; 273. } 274. } 275. 276. /* with a lot of luggage, your agility diminishes */ 277. if ((tmp2 = near_capacity()) != 0) tmp -= (tmp2*2) - 1; 278. if (u.utrap) tmp -= 3; 279. /* Some monsters have a combination of weapon attacks and non-weapon 280. * attacks. It is therefore wrong to add hitval to tmp; we must add 281. * it only for the specific attack (in hmonas()). 282. */ 283. if (uwep && !Upolyd) { 284. tmp += hitval(uwep, mtmp); 285. tmp += weapon_hit_bonus(uwep); 286. } 287. return tmp; 288. } 289.
attack[]
290. /* try to attack; return FALSE if monster evaded */ 291. /* u.dx and u.dy must be set */ 292. boolean 293. attack(mtmp) 294. register struct monst *mtmp; 295. { 296. schar tmp; 297. register struct permonst *mdat = mtmp->data; 298. 299. /* This section of code provides protection against accidentally 300. * hitting peaceful (like '@') and tame (like 'd') monsters. 301. * Protection is provided as long as player is not: blind, confused, 302. * hallucinating or stunned. 303. * changes by wwp 5/16/85 304. * More changes 12/90, -dkh-. if its tame and safepet, (and protected 305. * 07/92) then we assume that you're not trying to attack. Instead, 306. * you'll usually just swap places if this is a movement command 307. */ 308. /* Intelligent chaotic weapons (Stormbringer) want blood */ 309. if (is_safepet(mtmp) && !flags.forcefight) { 310. if (!uwep || uwep->oartifact != ART_STORMBRINGER) { 311. /* there are some additional considerations: this won't work 312. * if in a shop or Punished or you miss a random roll or 313. * if you can walk thru walls and your pet cannot (KAA) or 314. * if your pet is a long worm (unless someone does better). 315. * there's also a chance of displacing a "frozen" monster. 316. * sleeping monsters might magically walk in their sleep. 317. */ 318. boolean foo = (Punished || !rn2(7) || is_longworm(mtmp->data)), 319. inshop = FALSE; 320. char *p; 321. 322. for (p = in_rooms(mtmp->mx, mtmp->my, SHOPBASE); *p; p++) 323. if (tended_shop(&rooms[*p - ROOMOFFSET])) { 324. inshop = TRUE; 325. break; 326. } 327. 328. if (inshop || foo || 329. (IS_ROCK(levl[u.ux][u.uy].typ) && 330. !passes_walls(mtmp->data))) { 331. char buf[BUFSZ]; 332. 333. monflee(mtmp, rnd(6), FALSE, FALSE); 334. Strcpy(buf, y_monnam(mtmp)); 335. buf[0] = highc(buf[0]); 336. You("stop. %s is in the way!", buf); 337. return(TRUE); 338. } else if ((mtmp->mfrozen || (! mtmp->mcanmove) 339. || (mtmp->data->mmove == 0)) && rn2(6)) { 340. pline("%s doesn't seem to move!", Monnam(mtmp)); 341. return(TRUE); 342. } else return(FALSE); 343. } 344. } 345. 346. /* possibly set in attack_checks; 347. examined in known_hitum, called via hitum or hmonas below */ 348. override_confirmation = FALSE; 349. if (attack_checks(mtmp, uwep)) return(TRUE); 350. 351. if (Upolyd) { 352. /* certain "pacifist" monsters don't attack */ 353. if(noattacks(youmonst.data)) { 354. You("have no way to attack monsters physically."); 355. mtmp->mstrategy &= ~STRAT_WAITMASK; 356. goto atk_done; 357. } 358. } 359. 360. if(check_capacity("You cannot fight while so heavily loaded.")) 361. goto atk_done; 362. 363. if (u.twoweap && !can_twoweapon()) 364. untwoweapon(); 365. 366. if(unweapon) { 367. unweapon = FALSE; 368. if(flags.verbose) { 369. if(uwep) 370. You("begin bashing monsters with your %s.", 371. aobjnam(uwep, (char *)0)); 372. else if (!cantwield(youmonst.data)) 373. You("begin %sing monsters with your %s %s.", 374. Role_if(PM_MONK) ? "strik" : "bash", 375. uarmg ? "gloved" : "bare", /* Del Lamb */ 376. makeplural(body_part(HAND))); 377. } 378. } 379. exercise(A_STR, TRUE); /* you're exercising muscles */ 380. /* andrew@orca: prevent unlimited pick-axe attacks */ 381. u_wipe_engr(3); 382. 383. /* Is the "it died" check actually correct? */ 384. if(mdat->mlet == S_LEPRECHAUN && !mtmp->mfrozen && !mtmp->msleeping && 385. !mtmp->mconf && mtmp->mcansee && !rn2(7) && 386. (m_move(mtmp, 0) == 2 || /* it died */ 387. mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) /* it moved */ 388. return(FALSE); 389. 390. tmp = find_roll_to_hit(mtmp); 391. if (Upolyd) 392. (void) hmonas(mtmp, tmp); 393. else 394. (void) hitum(mtmp, tmp, youmonst.data->mattk); 395. mtmp->mstrategy &= ~STRAT_WAITMASK; 396. 397. atk_done: 398. /* see comment in attack_checks() */ 399. /* we only need to check for this if we did an attack_checks() 400. * and it returned 0 (it's okay to attack), and the monster didn't 401. * evade. 402. */ 403. if (flags.forcefight && mtmp->mhp > 0 && !canspotmon(mtmp) && 404. !glyph_is_invisible(levl[u.ux+u.dx][u.uy+u.dy].glyph) && 405. !(u.uswallow && mtmp == u.ustuck)) 406. map_invisible(u.ux+u.dx, u.uy+u.dy); 407. 408. return(TRUE); 409. } 410.
known_hitum[]
411. STATIC_OVL boolean 412. known_hitum(mon, mhit, uattk) /* returns TRUE if monster still lives */ 413. register struct monst *mon; 414. register int *mhit; 415. struct attack *uattk; 416. { 417. register boolean malive = TRUE; 418. 419. if (override_confirmation) { 420. /* this may need to be generalized if weapons other than 421. Stormbringer acquire similar anti-social behavior... */ 422. if (flags.verbose) Your("bloodthirsty blade attacks!"); 423. } 424. 425. if(!*mhit) { 426. missum(mon, uattk); 427. } else { 428. int oldhp = mon->mhp, 429. x = u.ux + u.dx, y = u.uy + u.dy; 430. 431. /* KMH, conduct */ 432. if (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))) 433. u.uconduct.weaphit++; 434. 435. /* we hit the monster; be careful: it might die or 436. be knocked into a different location */ 437. notonhead = (mon->mx != x || mon->my != y); 438. malive = hmon(mon, uwep, 0); 439. /* this assumes that Stormbringer was uwep not uswapwep */ 440. if (malive && u.twoweap && !override_confirmation && 441. m_at(x, y) == mon) 442. malive = hmon(mon, uswapwep, 0); 443. if (malive) { 444. /* monster still alive */ 445. if(!rn2(25) && mon->mhp < mon->mhpmax/2 446. && !(u.uswallow && mon == u.ustuck)) { 447. /* maybe should regurgitate if swallowed? */ 448. if(!rn2(3)) { 449. monflee(mon, rnd(100), FALSE, TRUE); 450. } else monflee(mon, 0, FALSE, TRUE); 451. 452. if(u.ustuck == mon && !u.uswallow && !sticks(youmonst.data)) 453. u.ustuck = 0; 454. } 455. /* Vorpal Blade hit converted to miss */ 456. /* could be headless monster or worm tail */ 457. if (mon->mhp == oldhp) { 458. *mhit = 0; 459. /* a miss does not break conduct */ 460. if (uwep && 461. (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))) 462. --u.uconduct.weaphit; 463. } 464. if (mon->wormno && *mhit) 465. cutworm(mon, x, y, uwep); 466. } 467. } 468. return(malive); 469. } 470.
hitum[]
471. STATIC_OVL boolean 472. hitum(mon, tmp, uattk) /* returns TRUE if monster still lives */ 473. struct monst *mon; 474. int tmp; 475. struct attack *uattk; 476. { 477. boolean malive; 478. int mhit = (tmp > (dieroll = rnd(20)) || u.uswallow); 479. 480. if(tmp > dieroll) exercise(A_DEX, TRUE); 481. malive = known_hitum(mon, &mhit, uattk); 482. (void) passive(mon, mhit, malive, AT_WEAP); 483. return(malive); 484. } 485.
hmon[]
486. boolean /* general "damage monster" routine */ 487. hmon(mon, obj, thrown) /* return TRUE if mon still alive */ 488. struct monst *mon; 489. struct obj *obj; 490. int thrown; 491. { 492. boolean result, anger_guards; 493. 494. anger_guards = (mon->mpeaceful && 495. (mon->ispriest || mon->isshk || 496. mon->data == &mons[PM_WATCHMAN] || 497. mon->data == &mons[PM_WATCH_CAPTAIN])); 498. result = hmon_hitmon(mon, obj, thrown); 499. if (mon->ispriest && !rn2(2)) ghod_hitsu(mon); 500. if (anger_guards) (void)angry_guards(!flags.soundok); 501. return result; 502. } 503.
hmon_hitmon[]
504. /* guts of hmon() */ 505. STATIC_OVL boolean 506. hmon_hitmon(mon, obj, thrown) 507. struct monst *mon; 508. struct obj *obj; 509. int thrown; 510. { 511. int tmp; 512. struct permonst *mdat = mon->data; 513. int barehand_silver_rings = 0; 514. /* The basic reason we need all these booleans is that we don't want 515. * a "hit" message when a monster dies, so we have to know how much 516. * damage it did _before_ outputting a hit message, but any messages 517. * associated with the damage don't come out until _after_ outputting 518. * a hit message. 519. */ 520. boolean hittxt = FALSE, destroyed = FALSE, already_killed = FALSE; 521. boolean get_dmg_bonus = TRUE; 522. boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE; 523. boolean silvermsg = FALSE, silverobj = FALSE; 524. boolean valid_weapon_attack = FALSE; 525. boolean unarmed = !uwep && !uarm && !uarms; 526. #ifdef STEED 527. int jousting = 0; 528. #endif 529. int wtype; 530. struct obj *monwep; 531. char yourbuf[BUFSZ]; 532. char unconventional[BUFSZ]; /* substituted for word "attack" in msg */ 533. char saved_oname[BUFSZ]; 534. 535. unconventional[0] = '\0'; 536. saved_oname[0] = '\0'; 537. 538. wakeup(mon); 539. if(!obj) { /* attack with bare hands */ 540. if (mdat == &mons[PM_SHADE]) 541. tmp = 0; 542. else if (martial_bonus()) 543. tmp = rnd(4); /* bonus for martial arts */ 544. else 545. tmp = rnd(2); 546. valid_weapon_attack = (tmp > 1); 547. /* blessed gloves give bonuses when fighting 'bare-handed' */ 548. if (uarmg && uarmg->blessed && (is_undead(mdat) || is_demon(mdat))) 549. tmp += rnd(4); 550. /* So do silver rings. Note: rings are worn under gloves, so you 551. * don't get both bonuses. 552. */ 553. if (!uarmg) { 554. if (uleft && objects[uleft->otyp].oc_material == SILVER) 555. barehand_silver_rings++; 556. if (uright && objects[uright->otyp].oc_material == SILVER) 557. barehand_silver_rings++; 558. if (barehand_silver_rings && hates_silver(mdat)) { 559. tmp += rnd(20); 560. silvermsg = TRUE; 561. } 562. } 563. } else { 564. Strcpy(saved_oname, cxname(obj)); 565. if(obj->oclass == WEAPON_CLASS || is_weptool(obj) || 566. obj->oclass == GEM_CLASS) { 567. 568. /* is it not a melee weapon? */ 569. if (/* if you strike with a bow... */ 570. is_launcher(obj) || 571. /* or strike with a missile in your hand... */ 572. (!thrown && (is_missile(obj) || is_ammo(obj))) || 573. /* or use a pole at short range and not mounted... */ 574. (!thrown && 575. #ifdef STEED 576. !u.usteed && 577. #endif 578. is_pole(obj)) || 579. /* or throw a missile without the proper bow... */ 580. (is_ammo(obj) && !ammo_and_launcher(obj, uwep))) { 581. /* then do only 1-2 points of damage */ 582. if (mdat == &mons[PM_SHADE] && obj->otyp != SILVER_ARROW) 583. tmp = 0; 584. else 585. tmp = rnd(2); 586. if (!thrown && obj == uwep && obj->otyp == BOOMERANG && 587. rnl(4) == 4-1) { 588. boolean more_than_1 = (obj->quan > 1L); 589. 590. pline("As you hit %s, %s%s %s breaks into splinters.", 591. mon_nam(mon), more_than_1 ? "one of " : "", 592. shk_your(yourbuf, obj), xname(obj)); 593. if (!more_than_1) uwepgone(); /* set unweapon */ 594. useup(obj); 595. if (!more_than_1) obj = (struct obj *) 0; 596. hittxt = TRUE; 597. if (mdat != &mons[PM_SHADE]) 598. tmp++; 599. } 600. } else { 601. tmp = dmgval(obj, mon); 602. /* a minimal hit doesn't exercise proficiency */ 603. valid_weapon_attack = (tmp > 1); 604. if (!valid_weapon_attack || mon == u.ustuck || u.twoweap) { 605. ; /* no special bonuses */ 606. } else if (mon->mflee && Role_if(PM_ROGUE) && !Upolyd) { 607. You("strike %s from behind!", mon_nam(mon)); 608. tmp += rnd(u.ulevel); 609. hittxt = TRUE; 610. } else if (dieroll == 2 && obj == uwep && 611. obj->oclass == WEAPON_CLASS && 612. (bimanual(obj) || 613. (Role_if(PM_SAMURAI) && obj->otyp == KATANA && !uarms)) && 614. ((wtype = uwep_skill_type()) != P_NONE && 615. P_SKILL(wtype) >= P_SKILLED) && 616. ((monwep = MON_WEP(mon)) != 0 && 617. !is_flimsy(monwep) && 618. !obj_resists(monwep, 619. 50 + 15 * greatest_erosion(obj), 100))) { 620. /* 621. * 2.5% chance of shattering defender's weapon when 622. * using a two-handed weapon; less if uwep is rusted. 623. * [dieroll == 2 is most successful non-beheading or 624. * -bisecting hit, in case of special artifact damage; 625. * the percentage chance is (1/20)*(50/100).] 626. */ 627. setmnotwielded(mon,monwep); 628. MON_NOWEP(mon); 629. mon->weapon_check = NEED_WEAPON; 630. pline("%s %s %s from the force of your blow!", 631. s_suffix(Monnam(mon)), xname(monwep), 632. otense(monwep, "shatter")); 633. m_useup(mon, monwep); 634. /* If someone just shattered MY weapon, I'd flee! */ 635. if (rn2(4)) { 636. monflee(mon, d(2,3), TRUE, TRUE); 637. } 638. hittxt = TRUE; 639. } 640. 641. if (obj->oartifact && 642. artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) { 643. if(mon->mhp <= 0) /* artifact killed monster */ 644. return FALSE; 645. if (tmp == 0) return TRUE; 646. hittxt = TRUE; 647. } 648. if (objects[obj->otyp].oc_material == SILVER 649. && hates_silver(mdat)) { 650. silvermsg = TRUE; silverobj = TRUE; 651. } 652. #ifdef STEED 653. if (u.usteed && !thrown && tmp > 0 && 654. weapon_type(obj) == P_LANCE && mon != u.ustuck) { 655. jousting = joust(mon, obj); 656. /* exercise skill even for minimal damage hits */ 657. if (jousting) valid_weapon_attack = TRUE; 658. } 659. #endif 660. if (thrown && (is_ammo(obj) || is_missile(obj))) { 661. if (ammo_and_launcher(obj, uwep)) { 662. /* Elves and Samurai do extra damage using 663. * their bows&arrows; they're highly trained. 664. */ 665. if (Role_if(PM_SAMURAI) && 666. obj->otyp == YA && uwep->otyp == YUMI) 667. tmp++; 668. else if (Race_if(PM_ELF) && 669. obj->otyp == ELVEN_ARROW && 670. uwep->otyp == ELVEN_BOW) 671. tmp++; 672. } 673. if(obj->opoisoned && is_poisonable(obj)) 674. ispoisoned = TRUE; 675. } 676. } 677. } else if(obj->oclass == POTION_CLASS) { 678. if (obj->quan > 1L) 679. obj = splitobj(obj, 1L); 680. else 681. setuwep((struct obj *)0); 682. freeinv(obj); 683. potionhit(mon, obj, TRUE); 684. if (mon->mhp <= 0) return FALSE; /* killed */ 685. hittxt = TRUE; 686. /* in case potion effect causes transformation */ 687. mdat = mon->data; 688. tmp = (mdat == &mons[PM_SHADE]) ? 0 : 1; 689. } else { 690. if (mdat == &mons[PM_SHADE] && !shade_aware(obj)) { 691. tmp = 0; 692. Strcpy(unconventional, cxname(obj)); 693. } else { 694. switch(obj->otyp) { 695. case BOULDER: /* 1d20 */ 696. case HEAVY_IRON_BALL: /* 1d25 */ 697. case IRON_CHAIN: /* 1d4+1 */ 698. tmp = dmgval(obj, mon); 699. break; 700. case MIRROR: 701. if (breaktest(obj)) { 702. You("break %s mirror. That's bad luck!", 703. shk_your(yourbuf, obj)); 704. change_luck(-2); 705. useup(obj); 706. obj = (struct obj *) 0; 707. unarmed = FALSE; /* avoid obj==0 confusion */ 708. get_dmg_bonus = FALSE; 709. hittxt = TRUE; 710. } 711. tmp = 1; 712. break; 713. #ifdef TOURIST 714. case EXPENSIVE_CAMERA: 715. You("succeed in destroying %s camera. Congratulations!", 716. shk_your(yourbuf, obj)); 717. useup(obj); 718. return(TRUE); 719. /*NOTREACHED*/ 720. break; 721. #endif 722. case CORPSE: /* fixed by polder@cs.vu.nl */ 723. if (touch_petrifies(&mons[obj->corpsenm])) { 724. static const char withwhat[] = "corpse"; 725. tmp = 1; 726. hittxt = TRUE; 727. You("hit %s with %s %s.", mon_nam(mon), 728. obj->dknown ? the(mons[obj->corpsenm].mname) : 729. an(mons[obj->corpsenm].mname), 730. (obj->quan > 1) ? makeplural(withwhat) : withwhat); 731. if (!munstone(mon, TRUE)) 732. minstapetrify(mon, TRUE); 733. if (resists_ston(mon)) break; 734. /* note: hp may be <= 0 even if munstoned==TRUE */ 735. return (boolean) (mon->mhp > 0); 736. #if 0 737. } else if (touch_petrifies(mdat)) { 738. /* maybe turn the corpse into a statue? */ 739. #endif 740. } 741. tmp = (obj->corpsenm >= LOW_PM ? 742. mons[obj->corpsenm].msize : 0) + 1; 743. break; 744. case EGG: 745. { 746. #define useup_eggs(o) { if (thrown) obfree(o,(struct obj *)0); \ 747. else useupall(o); \ 748. o = (struct obj *)0; } /* now gone */ 749. long cnt = obj->quan; 750. 751. tmp = 1; /* nominal physical damage */ 752. get_dmg_bonus = FALSE; 753. hittxt = TRUE; /* message always given */ 754. /* egg is always either used up or transformed, so next 755. hand-to-hand attack should yield a "bashing" mesg */ 756. if (obj == uwep) unweapon = TRUE; 757. if (obj->spe && obj->corpsenm >= LOW_PM) { 758. if (obj->quan < 5) 759. change_luck((schar) -(obj->quan)); 760. else 761. change_luck(-5); 762. } 763. 764. if (touch_petrifies(&mons[obj->corpsenm])) { 765. /*learn_egg_type(obj->corpsenm);*/ 766. pline("Splat! You hit %s with %s %s egg%s!", 767. mon_nam(mon), 768. obj->known ? "the" : cnt > 1L ? "some" : "a", 769. obj->known ? mons[obj->corpsenm].mname : "petrifying", 770. plur(cnt)); 771. obj->known = 1; /* (not much point...) */ 772. useup_eggs(obj); 773. if (!munstone(mon, TRUE)) 774. minstapetrify(mon, TRUE); 775. if (resists_ston(mon)) break; 776. return (boolean) (mon->mhp > 0); 777. } else { /* ordinary egg(s) */ 778. const char *eggp = 779. (obj->corpsenm != NON_PM && obj->known) ? 780. the(mons[obj->corpsenm].mname) : 781. (cnt > 1L) ? "some" : "an"; 782. You("hit %s with %s egg%s.", 783. mon_nam(mon), eggp, plur(cnt)); 784. if (touch_petrifies(mdat) && !stale_egg(obj)) { 785. pline_The("egg%s %s alive any more...", 786. plur(cnt), 787. (cnt == 1L) ? "isn't" : "aren't"); 788. if (obj->timed) obj_stop_timers(obj); 789. obj->otyp = ROCK; 790. obj->oclass = GEM_CLASS; 791. obj->oartifact = 0; 792. obj->spe = 0; 793. obj->known = obj->dknown = obj->bknown = 0; 794. obj->owt = weight(obj); 795. if (thrown) place_object(obj, mon->mx, mon->my); 796. } else { 797. pline("Splat!"); 798. useup_eggs(obj); 799. exercise(A_WIS, FALSE); 800. } 801. } 802. break; 803. #undef useup_eggs 804. } 805. case CLOVE_OF_GARLIC: /* no effect against demons */ 806. if (is_undead(mdat)) { 807. monflee(mon, d(2, 4), FALSE, TRUE); 808. } 809. tmp = 1; 810. break; 811. case CREAM_PIE: 812. case BLINDING_VENOM: 813. mon->msleeping = 0; 814. if (can_blnd(&youmonst, mon, (uchar) 815. (obj->otyp == BLINDING_VENOM 816. ? AT_SPIT : AT_WEAP), obj)) { 817. if (Blind) { 818. pline(obj->otyp == CREAM_PIE ? 819. "Splat!" : "Splash!"); 820. } else if (obj->otyp == BLINDING_VENOM) { 821. pline_The("venom blinds %s%s!", mon_nam(mon), 822. mon->mcansee ? "" : " further"); 823. } else { 824. char *whom = mon_nam(mon); 825. char *what = The(xname(obj)); 826. if (!thrown && obj->quan > 1) 827. what = An(singular(obj, xname)); 828. /* note: s_suffix returns a modifiable buffer */ 829. if (haseyes(mdat) 830. && mdat != &mons[PM_FLOATING_EYE]) 831. whom = strcat(strcat(s_suffix(whom), " "), 832. mbodypart(mon, FACE)); 833. pline("%s %s over %s!", 834. what, vtense(what, "splash"), whom); 835. } 836. setmangry(mon); 837. mon->mcansee = 0; 838. tmp = rn1(25, 21); 839. if(((int) mon->mblinded + tmp) > 127) 840. mon->mblinded = 127; 841. else mon->mblinded += tmp; 842. } else { 843. pline(obj->otyp==CREAM_PIE ? "Splat!" : "Splash!"); 844. setmangry(mon); 845. } 846. if (thrown) obfree(obj, (struct obj *)0); 847. else useup(obj); 848. hittxt = TRUE; 849. get_dmg_bonus = FALSE; 850. tmp = 0; 851. break; 852. case ACID_VENOM: /* thrown (or spit) */ 853. if (resists_acid(mon)) { 854. Your("venom hits %s harmlessly.", 855. mon_nam(mon)); 856. tmp = 0; 857. } else { 858. Your("venom burns %s!", mon_nam(mon)); 859. tmp = dmgval(obj, mon); 860. } 861. if (thrown) obfree(obj, (struct obj *)0); 862. else useup(obj); 863. hittxt = TRUE; 864. get_dmg_bonus = FALSE; 865. break; 866. default: 867. /* non-weapons can damage because of their weight */ 868. /* (but not too much) */ 869. tmp = obj->owt/100; 870. if(tmp < 1) tmp = 1; 871. else tmp = rnd(tmp); 872. if(tmp > 6) tmp = 6; 873. /* 874. * Things like silver wands can arrive here so 875. * so we need another silver check. 876. */ 877. if (objects[obj->otyp].oc_material == SILVER 878. && hates_silver(mdat)) { 879. tmp += rnd(20); 880. silvermsg = TRUE; silverobj = TRUE; 881. } 882. } 883. } 884. } 885. } 886. 887. /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) 888. * *OR* if attacking bare-handed!! */ 889. 890. if (get_dmg_bonus && tmp > 0) { 891. tmp += u.udaminc; 892. /* If you throw using a propellor, you don't get a strength 893. * bonus but you do get an increase-damage bonus. 894. */ 895. if(!thrown || !obj || !uwep || !ammo_and_launcher(obj, uwep)) 896. tmp += dbon(); 897. } 898. 899. if (valid_weapon_attack) { 900. struct obj *wep; 901. 902. /* to be valid a projectile must have had the correct projector */ 903. wep = PROJECTILE(obj) ? uwep : obj; 904. tmp += weapon_dam_bonus(wep); 905. /* [this assumes that `!thrown' implies wielded...] */ 906. wtype = thrown ? weapon_type(wep) : uwep_skill_type(); 907. use_skill(wtype, 1); 908. } 909. 910. if (ispoisoned) { 911. int nopoison = (10 - (obj->owt/10)); 912. if(nopoison < 2) nopoison = 2; 913. if Role_if(PM_SAMURAI) { 914. You("dishonorably use a poisoned weapon!"); 915. adjalign(-sgn(u.ualign.type)); 916. } else if ((u.ualign.type == A_LAWFUL) && (u.ualign.record > -10)) { 917. You_feel("like an evil coward for using a poisoned weapon."); 918. adjalign(-1); 919. } 920. if (obj && !rn2(nopoison)) { 921. obj->opoisoned = FALSE; 922. Your("%s %s no longer poisoned.", xname(obj), 923. otense(obj, "are")); 924. } 925. if (resists_poison(mon)) 926. needpoismsg = TRUE; 927. else if (rn2(10)) 928. tmp += rnd(6); 929. else poiskilled = TRUE; 930. } 931. if (tmp < 1) { 932. /* make sure that negative damage adjustment can't result 933. in inadvertently boosting the victim's hit points */ 934. tmp = 0; 935. if (mdat == &mons[PM_SHADE]) { 936. if (!hittxt) { 937. const char *what = unconventional[0] ? unconventional : "attack"; 938. Your("%s %s harmlessly through %s.", 939. what, vtense(what, "pass"), 940. mon_nam(mon)); 941. hittxt = TRUE; 942. } 943. } else { 944. if (get_dmg_bonus) tmp = 1; 945. } 946. } 947. 948. #ifdef STEED 949. if (jousting) { 950. tmp += d(2, (obj == uwep) ? 10 : 2); /* [was in dmgval()] */ 951. You("joust %s%s", 952. mon_nam(mon), canseemon(mon) ? exclam(tmp) : "."); 953. if (jousting < 0) { 954. Your("%s shatters on impact!", xname(obj)); 955. /* (must be either primary or secondary weapon to get here) */ 956. u.twoweap = FALSE; /* untwoweapon() is too verbose here */ 957. if (obj == uwep) uwepgone(); /* set unweapon */ 958. /* minor side-effect: broken lance won't split puddings */ 959. useup(obj); 960. obj = 0; 961. } 962. /* avoid migrating a dead monster */ 963. if (mon->mhp > tmp) { 964. mhurtle(mon, u.dx, u.dy, 1); 965. mdat = mon->data; /* in case of a polymorph trap */ 966. if (DEADMONSTER(mon)) already_killed = TRUE; 967. } 968. hittxt = TRUE; 969. } else 970. #endif 971. 972. /* VERY small chance of stunning opponent if unarmed. */ 973. if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd) { 974. if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) && 975. !bigmonst(mdat) && !thick_skinned(mdat)) { 976. if (canspotmon(mon)) 977. pline("%s %s from your powerful strike!", Monnam(mon), 978. makeplural(stagger(mon->data, "stagger"))); 979. /* avoid migrating a dead monster */ 980. if (mon->mhp > tmp) { 981. mhurtle(mon, u.dx, u.dy, 1); 982. mdat = mon->data; /* in case of a polymorph trap */ 983. if (DEADMONSTER(mon)) already_killed = TRUE; 984. } 985. hittxt = TRUE; 986. } 987. } 988. 989. if (!already_killed) mon->mhp -= tmp; 990. /* adjustments might have made tmp become less than what 991. a level draining artifact has already done to max HP */ 992. if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; 993. if (mon->mhp < 1) 994. destroyed = TRUE; 995. if (mon->mtame && (!mon->mflee || mon->mfleetim) && tmp > 0) { 996. abuse_dog(mon); 997. monflee(mon, 10 * rnd(tmp), FALSE, FALSE); 998. } 999. if((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING]) 1000. && obj && obj == uwep 1001. && objects[obj->otyp].oc_material == IRON 1002. && mon->mhp > 1 && !thrown && !mon->mcan 1003. /* && !destroyed -- guaranteed by mhp > 1 */ ) { 1004. if (clone_mon(mon, 0, 0)) { 1005. pline("%s divides as you hit it!", Monnam(mon)); 1006. hittxt = TRUE; 1007. } 1008. } 1009. 1010. if (!hittxt && /*( thrown => obj exists )*/ 1011. (!destroyed || (thrown && m_shot.n > 1 && m_shot.o == obj->otyp))) { 1012. if (thrown) hit(mshot_xname(obj), mon, exclam(tmp)); 1013. else if (!flags.verbose) You("hit it."); 1014. else You("%s %s%s", Role_if(PM_BARBARIAN) ? "smite" : "hit", 1015. mon_nam(mon), canseemon(mon) ? exclam(tmp) : "."); 1016. } 1017. 1018. if (silvermsg) { 1019. const char *fmt; 1020. char *whom = mon_nam(mon); 1021. char silverobjbuf[BUFSZ]; 1022. 1023. if (canspotmon(mon)) { 1024. if (barehand_silver_rings == 1) 1025. fmt = "Your silver ring sears %s!"; 1026. else if (barehand_silver_rings == 2) 1027. fmt = "Your silver rings sear %s!"; 1028. else if (silverobj && saved_oname[0]) { 1029. Sprintf(silverobjbuf, "Your %s%s %s %%s!", 1030. strstri(saved_oname, "silver") ? 1031. "" : "silver ", 1032. saved_oname, vtense(saved_oname, "sear")); 1033. fmt = silverobjbuf; 1034. } else 1035. fmt = "The silver sears %s!"; 1036. } else { 1037. *whom = highc(*whom); /* "it" -> "It" */ 1038. fmt = "%s is seared!"; 1039. } 1040. /* note: s_suffix returns a modifiable buffer */ 1041. if (!noncorporeal(mdat)) 1042. whom = strcat(s_suffix(whom), " flesh"); 1043. pline(fmt, whom); 1044. } 1045. 1046. if (needpoismsg) 1047. pline_The("poison doesn't seem to affect %s.", mon_nam(mon)); 1048. if (poiskilled) { 1049. pline_The("poison was deadly..."); 1050. if (!already_killed) xkilled(mon, 0); 1051. return FALSE; 1052. } else if (destroyed) { 1053. if (!already_killed) 1054. killed(mon); /* takes care of most messages */ 1055. } else if(u.umconf && !thrown) { 1056. nohandglow(mon); 1057. if (!mon->mconf && !resist(mon, SPBOOK_CLASS, 0, NOTELL)) { 1058. mon->mconf = 1; 1059. if (!mon->mstun && mon->mcanmove && !mon->msleeping && 1060. canseemon(mon)) 1061. pline("%s appears confused.", Monnam(mon)); 1062. } 1063. } 1064. 1065. return((boolean)(destroyed ? FALSE : TRUE)); 1066. } 1067.
shade_aware[]
1068. STATIC_OVL boolean 1069. shade_aware(obj) 1070. struct obj *obj; 1071. { 1072. if (!obj) return FALSE; 1073. /* 1074. * The things in this list either 1075. * 1) affect shades. 1076. * OR 1077. * 2) are dealt with properly by other routines 1078. * when it comes to shades. 1079. */ 1080. if (obj->otyp == BOULDER || obj->otyp == HEAVY_IRON_BALL 1081. || obj->otyp == IRON_CHAIN /* dmgval handles those first three */ 1082. || obj->otyp == MIRROR /* silver in the reflective surface */ 1083. || obj->otyp == CLOVE_OF_GARLIC /* causes shades to flee */ 1084. || objects[obj->otyp].oc_material == SILVER) 1085. return TRUE; 1086. return FALSE; 1087. } 1088.
m_slips_free[]
1089. /* check whether slippery clothing protects from hug or wrap attack */ 1090. /* [currently assumes that you are the attacker] */ 1091. STATIC_OVL boolean 1092. m_slips_free(mdef, mattk) 1093. struct monst *mdef; 1094. struct attack *mattk; 1095. { 1096. struct obj *obj; 1097. 1098. if (mattk->adtyp == AD_DRIN) { 1099. /* intelligence drain attacks the head */ 1100. obj = which_armor(mdef, W_ARMH); 1101. } else { 1102. /* grabbing attacks the body */ 1103. obj = which_armor(mdef, W_ARMC); /* cloak */ 1104. if (!obj) obj = which_armor(mdef, W_ARM); /* suit */ 1105. #ifdef TOURIST 1106. if (!obj) obj = which_armor(mdef, W_ARMU); /* shirt */ 1107. #endif 1108. } 1109. 1110. /* if your cloak/armor is greased, monster slips off; this 1111. protection might fail (33% chance) when the armor is cursed */ 1112. if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK) && 1113. (!obj->cursed || rn2(3))) { 1114. You("%s %s %s %s!", 1115. mattk->adtyp == AD_WRAP ? 1116. "slip off of" : "grab, but cannot hold onto", 1117. s_suffix(mon_nam(mdef)), 1118. obj->greased ? "greased" : "slippery", 1119. /* avoid "slippery slippery cloak" 1120. for undiscovered oilskin cloak */ 1121. (obj->greased || objects[obj->otyp].oc_name_known) ? 1122. xname(obj) : cloak_simple_name(obj)); 1123. 1124. if (obj->greased && !rn2(2)) { 1125. pline_The("grease wears off."); 1126. obj->greased = 0; 1127. } 1128. return TRUE; 1129. } 1130. return FALSE; 1131. } 1132.
joust[]
1133. /* used when hitting a monster with a lance while mounted */ 1134. STATIC_OVL int /* 1: joust hit; 0: ordinary hit; -1: joust but break lance */ 1135. joust(mon, obj) 1136. struct monst *mon; /* target */ 1137. struct obj *obj; /* weapon */ 1138. { 1139. int skill_rating, joust_dieroll; 1140. 1141. if (Fumbling || Stunned) return 0; 1142. /* sanity check; lance must be wielded in order to joust */ 1143. if (obj != uwep && (obj != uswapwep || !u.twoweap)) return 0; 1144. 1145. /* if using two weapons, use worse of lance and two-weapon skills */ 1146. skill_rating = P_SKILL(weapon_type(obj)); /* lance skill */ 1147. if (u.twoweap && P_SKILL(P_TWO_WEAPON_COMBAT) < skill_rating) 1148. skill_rating = P_SKILL(P_TWO_WEAPON_COMBAT); 1149. if (skill_rating == P_ISRESTRICTED) skill_rating = P_UNSKILLED; /* 0=>1 */ 1150. 1151. /* odds to joust are expert:80%, skilled:60%, basic:40%, unskilled:20% */ 1152. if ((joust_dieroll = rn2(5)) < skill_rating) { 1153. if (joust_dieroll == 0 && rnl(50) == (50-1) && 1154. !unsolid(mon->data) && !obj_resists(obj, 0, 100)) 1155. return -1; /* hit that breaks lance */ 1156. return 1; /* successful joust */ 1157. } 1158. return 0; /* no joust bonus; revert to ordinary attack */ 1159. } 1160.
demonpet[]
1161. /* 1162. * Send in a demon pet for the hero. Exercise wisdom. 1163. * 1164. * This function used to be inline to damageum(), but the Metrowerks compiler 1165. * (DR4 and DR4.5) screws up with an internal error 5 "Expression Too Complex." 1166. * Pulling it out makes it work. 1167. */ 1168. STATIC_OVL void 1169. demonpet() 1170. { 1171. int i; 1172. struct permonst *pm; 1173. struct monst *dtmp; 1174. 1175. pline("Some hell-p has arrived!"); 1176. i = !rn2(6) ? ndemon(u.ualign.type) : NON_PM; 1177. pm = i != NON_PM ? &mons[i] : youmonst.data; 1178. if ((dtmp = makemon(pm, u.ux, u.uy, NO_MM_FLAGS)) != 0) 1179. (void)tamedog(dtmp, (struct obj *)0); 1180. exercise(A_WIS, TRUE); 1181. } 1182.
steal_it[]
1183. /* 1184. * Player uses theft attack against monster. 1185. * 1186. * If the target is wearing body armor, take all of its possesions; 1187. * otherwise, take one object. [Is this really the behavior we want?] 1188. * 1189. * This routine implicitly assumes that there is no way to be able to 1190. * resist petfication (ie, be polymorphed into a xorn or golem) at the 1191. * same time as being able to steal (poly'd into nymph or succubus). 1192. * If that ever changes, the check for touching a cockatrice corpse 1193. * will need to be smarter about whether to break out of the theft loop. 1194. */ 1195. STATIC_OVL void 1196. steal_it(mdef, mattk) 1197. struct monst *mdef; 1198. struct attack *mattk; 1199. { 1200. struct obj *otmp, *stealoid, **minvent_ptr; 1201. long unwornmask; 1202. 1203. if (!mdef->minvent) return; /* nothing to take */ 1204. 1205. /* look for worn body armor */ 1206. stealoid = (struct obj *)0; 1207. if (could_seduce(&youmonst, mdef, mattk)) { 1208. /* find armor, and move it to end of inventory in the process */ 1209. minvent_ptr = &mdef->minvent; 1210. while ((otmp = *minvent_ptr) != 0) 1211. if (otmp->owornmask & W_ARM) { 1212. if (stealoid) panic("steal_it: multiple worn suits"); 1213. *minvent_ptr = otmp->nobj; /* take armor out of minvent */ 1214. stealoid = otmp; 1215. stealoid->nobj = (struct obj *)0; 1216. } else { 1217. minvent_ptr = &otmp->nobj; 1218. } 1219. *minvent_ptr = stealoid; /* put armor back into minvent */ 1220. } 1221. 1222. if (stealoid) { /* we will be taking everything */ 1223. if (gender(mdef) == (int) u.mfemale && 1224. youmonst.data->mlet == S_NYMPH) 1225. You("charm %s. She gladly hands over her possessions.", 1226. mon_nam(mdef)); 1227. else 1228. You("seduce %s and %s starts to take off %s clothes.", 1229. mon_nam(mdef), mhe(mdef), mhis(mdef)); 1230. } 1231. 1232. while ((otmp = mdef->minvent) != 0) { 1233. if (!Upolyd) break; /* no longer have ability to steal */ 1234. /* take the object away from the monster */ 1235. obj_extract_self(otmp); 1236. if ((unwornmask = otmp->owornmask) != 0L) { 1237. mdef->misc_worn_check &= ~unwornmask; 1238. if (otmp->owornmask & W_WEP) { 1239. setmnotwielded(mdef,otmp); 1240. MON_NOWEP(mdef); 1241. } 1242. otmp->owornmask = 0L; 1243. update_mon_intrinsics(mdef, otmp, FALSE, FALSE); 1244. 1245. if (otmp == stealoid) /* special message for final item */ 1246. pline("%s finishes taking off %s suit.", 1247. Monnam(mdef), mhis(mdef)); 1248. } 1249. /* give the object to the character */ 1250. otmp = hold_another_object(otmp, "You snatched but dropped %s.", 1251. doname(otmp), "You steal: "); 1252. if (otmp->where != OBJ_INVENT) continue; 1253. if (otmp->otyp == CORPSE && 1254. touch_petrifies(&mons[otmp->corpsenm]) && !uarmg) { 1255. char kbuf[BUFSZ]; 1256. 1257. Sprintf(kbuf, "stolen %s corpse", mons[otmp->corpsenm].mname); 1258. instapetrify(kbuf); 1259. break; /* stop the theft even if hero survives */ 1260. } 1261. /* more take-away handling, after theft message */ 1262. if (unwornmask & W_WEP) { /* stole wielded weapon */ 1263. possibly_unwield(mdef, FALSE); 1264. } else if (unwornmask & W_ARMG) { /* stole worn gloves */ 1265. mselftouch(mdef, (const char *)0, TRUE); 1266. if (mdef->mhp <= 0) /* it's now a statue */ 1267. return; /* can't continue stealing */ 1268. } 1269. 1270. if (!stealoid) break; /* only taking one item */ 1271. } 1272. } 1273.
damageum[]
1274. int 1275. damageum(mdef, mattk) 1276. register struct monst *mdef; 1277. register struct attack *mattk; 1278. { 1279. register struct permonst *pd = mdef->data; 1280. register int tmp = d((int)mattk->damn, (int)mattk->damd); 1281. int armpro; 1282. boolean negated; 1283. 1284. armpro = magic_negation(mdef); 1285. /* since hero can't be cancelled, only defender's armor applies */ 1286. negated = !((rn2(3) >= armpro) || !rn2(50)); 1287. 1288. if (is_demon(youmonst.data) && !rn2(13) && !uwep 1289. && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS 1290. && u.umonnum != PM_BALROG) { 1291. demonpet(); 1292. return(0); 1293. } 1294. switch(mattk->adtyp) { 1295. case AD_STUN: 1296. if(!Blind) 1297. pline("%s %s for a moment.", Monnam(mdef), 1298. makeplural(stagger(mdef->data, "stagger"))); 1299. mdef->mstun = 1; 1300. goto physical; 1301. case AD_LEGS: 1302. /* if (u.ucancelled) { */ 1303. /* tmp = 0; */ 1304. /* break; */ 1305. /* } */ 1306. goto physical; 1307. case AD_WERE: /* no special effect on monsters */ 1308. case AD_HEAL: /* likewise */ 1309. case AD_PHYS: 1310. physical: 1311. if(mattk->aatyp == AT_WEAP) { 1312. if(uwep) tmp = 0; 1313. } else if(mattk->aatyp == AT_KICK) { 1314. if(thick_skinned(mdef->data)) tmp = 0; 1315. if(mdef->data == &mons[PM_SHADE]) { 1316. if (!(uarmf && uarmf->blessed)) { 1317. impossible("bad shade attack function flow?"); 1318. tmp = 0; 1319. } else 1320. tmp = rnd(4); /* bless damage */ 1321. } 1322. } 1323. break; 1324. case AD_FIRE: 1325. if (negated) { 1326. tmp = 0; 1327. break; 1328. } 1329. if (!Blind) 1330. pline("%s is %s!", Monnam(mdef), 1331. on_fire(mdef->data, mattk)); 1332. if (pd == &mons[PM_STRAW_GOLEM] || 1333. pd == &mons[PM_PAPER_GOLEM]) { 1334. if (!Blind) 1335. pline("%s burns completely!", Monnam(mdef)); 1336. xkilled(mdef,2); 1337. tmp = 0; 1338. break; 1339. /* Don't return yet; keep hp<1 and tmp=0 for pet msg */ 1340. } 1341. tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); 1342. tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); 1343. if (resists_fire(mdef)) { 1344. if (!Blind) 1345. pline_The("fire doesn't heat %s!", mon_nam(mdef)); 1346. golemeffects(mdef, AD_FIRE, tmp); 1347. shieldeff(mdef->mx, mdef->my); 1348. tmp = 0; 1349. } 1350. /* only potions damage resistant players in destroy_item */ 1351. tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); 1352. break; 1353. case AD_COLD: 1354. if (negated) { 1355. tmp = 0; 1356. break; 1357. } 1358. if (!Blind) pline("%s is covered in frost!", Monnam(mdef)); 1359. if (resists_cold(mdef)) { 1360. shieldeff(mdef->mx, mdef->my); 1361. if (!Blind) 1362. pline_The("frost doesn't chill %s!", mon_nam(mdef)); 1363. golemeffects(mdef, AD_COLD, tmp); 1364. tmp = 0; 1365. } 1366. tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD); 1367. break; 1368. case AD_ELEC: 1369. if (negated) { 1370. tmp = 0; 1371. break; 1372. } 1373. if (!Blind) pline("%s is zapped!", Monnam(mdef)); 1374. tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); 1375. if (resists_elec(mdef)) { 1376. if (!Blind) 1377. pline_The("zap doesn't shock %s!", mon_nam(mdef)); 1378. golemeffects(mdef, AD_ELEC, tmp); 1379. shieldeff(mdef->mx, mdef->my); 1380. tmp = 0; 1381. } 1382. /* only rings damage resistant players in destroy_item */ 1383. tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC); 1384. break; 1385. case AD_ACID: 1386. if (resists_acid(mdef)) tmp = 0; 1387. break; 1388. case AD_STON: 1389. if (!munstone(mdef, TRUE)) 1390. minstapetrify(mdef, TRUE); 1391. tmp = 0; 1392. break; 1393. #ifdef SEDUCE 1394. case AD_SSEX: 1395. #endif 1396. case AD_SEDU: 1397. case AD_SITM: 1398. steal_it(mdef, mattk); 1399. tmp = 0; 1400. break; 1401. case AD_SGLD: 1402. #ifndef GOLDOBJ 1403. if (mdef->mgold) { 1404. u.ugold += mdef->mgold; 1405. mdef->mgold = 0; 1406. Your("purse feels heavier."); 1407. } 1408. #else 1409. /* This you as a leprechaun, so steal 1410. real gold only, no lesser coins */ 1411. { 1412. struct obj *mongold = findgold(mdef->minvent); 1413. if (mongold) { 1414. obj_extract_self(mongold); 1415. if (merge_choice(invent, mongold) || inv_cnt() < 52) { 1416. addinv(mongold); 1417. Your("purse feels heavier."); 1418. } else { 1419. You("grab %s's gold, but find no room in your knapsack.", mon_nam(mdef)); 1420. dropy(mongold); 1421. } 1422. } 1423. } 1424. #endif 1425. exercise(A_DEX, TRUE); 1426. tmp = 0; 1427. break; 1428. case AD_TLPT: 1429. if (tmp <= 0) tmp = 1; 1430. if (!negated && tmp < mdef->mhp) { 1431. char nambuf[BUFSZ]; 1432. boolean u_saw_mon = canseemon(mdef) || 1433. (u.uswallow && u.ustuck == mdef); 1434. /* record the name before losing sight of monster */ 1435. Strcpy(nambuf, Monnam(mdef)); 1436. if (u_teleport_mon(mdef, FALSE) && 1437. u_saw_mon && !canseemon(mdef)) 1438. pline("%s suddenly disappears!", nambuf); 1439. } 1440. break; 1441. case AD_BLND: 1442. if (can_blnd(&youmonst, mdef, mattk->aatyp, (struct obj*)0)) { 1443. if(!Blind && mdef->mcansee) 1444. pline("%s is blinded.", Monnam(mdef)); 1445. mdef->mcansee = 0; 1446. tmp += mdef->mblinded; 1447. if (tmp > 127) tmp = 127; 1448. mdef->mblinded = tmp; 1449. } 1450. tmp = 0; 1451. break; 1452. case AD_CURS: 1453. if (night() && !rn2(10) && !mdef->mcan) { 1454. if (mdef->data == &mons[PM_CLAY_GOLEM]) { 1455. if (!Blind) 1456. pline("Some writing vanishes from %s head!", 1457. s_suffix(mon_nam(mdef))); 1458. xkilled(mdef, 0); 1459. /* Don't return yet; keep hp<1 and tmp=0 for pet msg */ 1460. } else { 1461. mdef->mcan = 1; 1462. You("chuckle."); 1463. } 1464. } 1465. tmp = 0; 1466. break; 1467. case AD_DRLI: 1468. if (!negated && !rn2(3) && !resists_drli(mdef)) { 1469. int xtmp = d(2,6); 1470. pline("%s suddenly seems weaker!", Monnam(mdef)); 1471. mdef->mhpmax -= xtmp; 1472. if ((mdef->mhp -= xtmp) <= 0 || !mdef->m_lev) { 1473. pline("%s dies!", Monnam(mdef)); 1474. xkilled(mdef,0); 1475. } else 1476. mdef->m_lev--; 1477. tmp = 0; 1478. } 1479. break; 1480. case AD_RUST: 1481. if (pd == &mons[PM_IRON_GOLEM]) { 1482. pline("%s falls to pieces!", Monnam(mdef)); 1483. xkilled(mdef,0); 1484. } 1485. hurtmarmor(mdef, AD_RUST); 1486. tmp = 0; 1487. break; 1488. case AD_CORR: 1489. hurtmarmor(mdef, AD_CORR); 1490. tmp = 0; 1491. break; 1492. case AD_DCAY: 1493. if (pd == &mons[PM_WOOD_GOLEM] || 1494. pd == &mons[PM_LEATHER_GOLEM]) { 1495. pline("%s falls to pieces!", Monnam(mdef)); 1496. xkilled(mdef,0); 1497. } 1498. hurtmarmor(mdef, AD_DCAY); 1499. tmp = 0; 1500. break; 1501. case AD_DRST: 1502. case AD_DRDX: 1503. case AD_DRCO: 1504. if (!negated && !rn2(8)) { 1505. Your("%s was poisoned!", mpoisons_subj(&youmonst, mattk)); 1506. if (resists_poison(mdef)) 1507. pline_The("poison doesn't seem to affect %s.", 1508. mon_nam(mdef)); 1509. else { 1510. if (!rn2(10)) { 1511. Your("poison was deadly..."); 1512. tmp = mdef->mhp; 1513. } else tmp += rn1(10,6); 1514. } 1515. } 1516. break; 1517. case AD_DRIN: 1518. if (notonhead || !has_head(mdef->data)) { 1519. pline("%s doesn't seem harmed.", Monnam(mdef)); 1520. tmp = 0; 1521. if (!Unchanging && mdef->data == &mons[PM_GREEN_SLIME]) { 1522. if (!Slimed) { 1523. You("suck in some slime and don't feel very well."); 1524. Slimed = 10L; 1525. } 1526. } 1527. break; 1528. } 1529. if (m_slips_free(mdef, mattk)) break; 1530. 1531. if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) { 1532. pline("%s helmet blocks your attack to %s head.", 1533. s_suffix(Monnam(mdef)), mhis(mdef)); 1534. break; 1535. } 1536. 1537. You("eat %s brain!", s_suffix(mon_nam(mdef))); 1538. u.uconduct.food++; 1539. if (touch_petrifies(mdef->data) && !Stone_resistance && !Stoned) { 1540. Stoned = 5; 1541. killer_format = KILLED_BY_AN; 1542. delayed_killer = mdef->data->mname; 1543. } 1544. if (!vegan(mdef->data)) 1545. u.uconduct.unvegan++; 1546. if (!vegetarian(mdef->data)) 1547. violated_vegetarian(); 1548. if (mindless(mdef->data)) { 1549. pline("%s doesn't notice.", Monnam(mdef)); 1550. break; 1551. } 1552. tmp += rnd(10); 1553. morehungry(-rnd(30)); /* cannot choke */ 1554. if (ABASE(A_INT) < AMAX(A_INT)) { 1555. ABASE(A_INT) += rnd(4); 1556. if (ABASE(A_INT) > AMAX(A_INT)) 1557. ABASE(A_INT) = AMAX(A_INT); 1558. flags.botl = 1; 1559. } 1560. exercise(A_WIS, TRUE); 1561. break; 1562. case AD_STCK: 1563. if (!negated && !sticks(mdef->data)) 1564. u.ustuck = mdef; /* it's now stuck to you */ 1565. break; 1566. case AD_WRAP: 1567. if (!sticks(mdef->data)) { 1568. if (!u.ustuck && !rn2(10)) { 1569. if (m_slips_free(mdef, mattk)) { 1570. tmp = 0; 1571. } else { 1572. You("swing yourself around %s!", 1573. mon_nam(mdef)); 1574. u.ustuck = mdef; 1575. } 1576. } else if(u.ustuck == mdef) { 1577. /* Monsters don't wear amulets of magical breathing */ 1578. if (is_pool(u.ux,u.uy) && !is_swimmer(mdef->data) && 1579. !amphibious(mdef->data)) { 1580. You("drown %s...", mon_nam(mdef)); 1581. tmp = mdef->mhp; 1582. } else if(mattk->aatyp == AT_HUGS) 1583. pline("%s is being crushed.", Monnam(mdef)); 1584. } else { 1585. tmp = 0; 1586. if (flags.verbose) 1587. You("brush against %s %s.", 1588. s_suffix(mon_nam(mdef)), 1589. mbodypart(mdef, LEG)); 1590. } 1591. } else tmp = 0; 1592. break; 1593. case AD_PLYS: 1594. if (!negated && mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) { 1595. if (!Blind) pline("%s is frozen by you!", Monnam(mdef)); 1596. mdef->mcanmove = 0; 1597. mdef->mfrozen = rnd(10); 1598. } 1599. break; 1600. case AD_SLEE: 1601. if (!negated && !mdef->msleeping && 1602. sleep_monst(mdef, rnd(10), -1)) { 1603. if (!Blind) 1604. pline("%s is put to sleep by you!", Monnam(mdef)); 1605. slept_monst(mdef); 1606. } 1607. break; 1608. case AD_SLIM: 1609. if (negated) break; /* physical damage only */ 1610. if (!rn2(4) && !flaming(mdef->data) && 1611. mdef->data != &mons[PM_GREEN_SLIME]) { 1612. You("turn %s into slime.", mon_nam(mdef)); 1613. (void) newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, FALSE); 1614. tmp = 0; 1615. } 1616. break; 1617. case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ 1618. /* there's no msomearmor() function, so just do damage */ 1619. /* if (negated) break; */ 1620. break; 1621. case AD_SLOW: 1622. if (!negated && mdef->mspeed != MSLOW) { 1623. unsigned int oldspeed = mdef->mspeed; 1624. 1625. mon_adjust_speed(mdef, -1, (struct obj *)0); 1626. if (mdef->mspeed != oldspeed && canseemon(mdef)) 1627. pline("%s slows down.", Monnam(mdef)); 1628. } 1629. break; 1630. case AD_CONF: 1631. if (!mdef->mconf) { 1632. if (canseemon(mdef)) 1633. pline("%s looks confused.", Monnam(mdef)); 1634. mdef->mconf = 1; 1635. } 1636. break; 1637. default: tmp = 0; 1638. break; 1639. } 1640. 1641. mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */ 1642. if((mdef->mhp -= tmp) < 1) { 1643. if (mdef->mtame && !cansee(mdef->mx,mdef->my)) { 1644. You_feel("embarrassed for a moment."); 1645. if (tmp) xkilled(mdef, 0); /* !tmp but hp<1: already killed */ 1646. } else if (!flags.verbose) { 1647. You("destroy it!"); 1648. if (tmp) xkilled(mdef, 0); 1649. } else 1650. if (tmp) killed(mdef); 1651. return(2); 1652. } 1653. return(1); 1654. } 1655.
explum[]
1656. STATIC_OVL int 1657. explum(mdef, mattk) 1658. register struct monst *mdef; 1659. register struct attack *mattk; 1660. { 1661. register int tmp = d((int)mattk->damn, (int)mattk->damd); 1662. 1663. You("explode!"); 1664. switch(mattk->adtyp) { 1665. boolean resistance; /* only for cold/fire/elec */ 1666. 1667. case AD_BLND: 1668. if (!resists_blnd(mdef)) { 1669. pline("%s is blinded by your flash of light!", Monnam(mdef)); 1670. mdef->mblinded = min((int)mdef->mblinded + tmp, 127); 1671. mdef->mcansee = 0; 1672. } 1673. break; 1674. case AD_HALU: 1675. if (haseyes(mdef->data) && mdef->mcansee) { 1676. pline("%s is affected by your flash of light!", 1677. Monnam(mdef)); 1678. mdef->mconf = 1; 1679. } 1680. break; 1681. case AD_COLD: 1682. resistance = resists_cold(mdef); 1683. goto common; 1684. case AD_FIRE: 1685. resistance = resists_fire(mdef); 1686. goto common; 1687. case AD_ELEC: 1688. resistance = resists_elec(mdef); 1689. common: 1690. if (!resistance) { 1691. pline("%s gets blasted!", Monnam(mdef)); 1692. mdef->mhp -= tmp; 1693. if (mdef->mhp <= 0) { 1694. killed(mdef); 1695. return(2); 1696. } 1697. } else { 1698. shieldeff(mdef->mx, mdef->my); 1699. if (is_golem(mdef->data)) 1700. golemeffects(mdef, (int)mattk->adtyp, tmp); 1701. else 1702. pline_The("blast doesn't seem to affect %s.", 1703. mon_nam(mdef)); 1704. } 1705. break; 1706. default: 1707. break; 1708. } 1709. return(1); 1710. } 1711.
start_engulf[]
1712. STATIC_OVL void 1713. start_engulf(mdef) 1714. struct monst *mdef; 1715. { 1716. if (!Invisible) { 1717. map_location(u.ux, u.uy, TRUE); 1718. tmp_at(DISP_ALWAYS, mon_to_glyph(&youmonst)); 1719. tmp_at(mdef->mx, mdef->my); 1720. } 1721. You("engulf %s!", mon_nam(mdef)); 1722. delay_output(); 1723. delay_output(); 1724. } 1725.
end_engulf[]
1726. STATIC_OVL void 1727. end_engulf() 1728. { 1729. if (!Invisible) { 1730. tmp_at(DISP_END, 0); 1731. newsym(u.ux, u.uy); 1732. } 1733. } 1734.
gulpum[]
1735. STATIC_OVL int 1736. gulpum(mdef,mattk) 1737. register struct monst *mdef; 1738. register struct attack *mattk; 1739. { 1740. register int tmp; 1741. register int dam = d((int)mattk->damn, (int)mattk->damd); 1742. struct obj *otmp; 1743. /* Not totally the same as for real monsters. Specifically, these 1744. * don't take multiple moves. (It's just too hard, for too little 1745. * result, to program monsters which attack from inside you, which 1746. * would be necessary if done accurately.) Instead, we arbitrarily 1747. * kill the monster immediately for AD_DGST and we regurgitate them 1748. * after exactly 1 round of attack otherwise. -KAA 1749. */ 1750. 1751. if(mdef->data->msize >= MZ_HUGE) return 0; 1752. 1753. if(u.uhunger < 1500 && !u.uswallow) { 1754. for (otmp = mdef->minvent; otmp; otmp = otmp->nobj) 1755. (void) snuff_lit(otmp); 1756. 1757. if(!touch_petrifies(mdef->data) || Stone_resistance) { 1758. #ifdef LINT /* static char msgbuf[BUFSZ]; */ 1759. char msgbuf[BUFSZ]; 1760. #else 1761. static char msgbuf[BUFSZ]; 1762. #endif 1763. start_engulf(mdef); 1764. switch(mattk->adtyp) { 1765. case AD_DGST: 1766. /* eating a Rider or its corpse is fatal */ 1767. if (is_rider(mdef->data)) { 1768. pline("Unfortunately, digesting any of it is fatal."); 1769. end_engulf(); 1770. Sprintf(msgbuf, "unwisely tried to eat %s", 1771. mdef->data->mname); 1772. killer = msgbuf; 1773. killer_format = NO_KILLER_PREFIX; 1774. done(DIED); 1775. return 0; /* lifesaved */ 1776. } 1777. 1778. if (Slow_digestion) { 1779. dam = 0; 1780. break; 1781. } 1782. 1783. /* KMH, conduct */ 1784. u.uconduct.food++; 1785. if (!vegan(mdef->data)) 1786. u.uconduct.unvegan++; 1787. if (!vegetarian(mdef->data)) 1788. violated_vegetarian(); 1789. 1790. /* Use up amulet of life saving */ 1791. if (!!(otmp = mlifesaver(mdef))) m_useup(mdef, otmp); 1792. 1793. newuhs(FALSE); 1794. xkilled(mdef,2); 1795. if (mdef->mhp > 0) { /* monster lifesaved */ 1796. You("hurriedly regurgitate the sizzling in your %s.", 1797. body_part(STOMACH)); 1798. } else { 1799. tmp = 1 + (mdef->data->cwt >> 8); 1800. if (corpse_chance(mdef, &youmonst, TRUE) && 1801. !(mvitals[monsndx(mdef->data)].mvflags & 1802. G_NOCORPSE)) { 1803. /* nutrition only if there can be a corpse */ 1804. u.uhunger += (mdef->data->cnutrit+1) / 2; 1805. } else tmp = 0; 1806. Sprintf(msgbuf, "You totally digest %s.", 1807. mon_nam(mdef)); 1808. if (tmp != 0) { 1809. /* setting afternmv = end_engulf is tempting, 1810. * but will cause problems if the player is 1811. * attacked (which uses his real location) or 1812. * if his See_invisible wears off 1813. */ 1814. You("digest %s.", mon_nam(mdef)); 1815. if (Slow_digestion) tmp *= 2; 1816. nomul(-tmp); 1817. nomovemsg = msgbuf; 1818. } else pline("%s", msgbuf); 1819. if (mdef->data == &mons[PM_GREEN_SLIME]) { 1820. Sprintf(msgbuf, "%s isn't sitting well with you.", 1821. The(mdef->data->mname)); 1822. if (!Unchanging) { 1823. Slimed = 5L; 1824. flags.botl = 1; 1825. } 1826. } else 1827. exercise(A_CON, TRUE); 1828. } 1829. end_engulf(); 1830. return(2); 1831. case AD_PHYS: 1832. if (youmonst.data == &mons[PM_FOG_CLOUD]) { 1833. pline("%s is laden with your moisture.", 1834. Monnam(mdef)); 1835. if (amphibious(mdef->data) && 1836. !flaming(mdef->data)) { 1837. dam = 0; 1838. pline("%s seems unharmed.", Monnam(mdef)); 1839. } 1840. } else 1841. pline("%s is pummeled with your debris!", 1842. Monnam(mdef)); 1843. break; 1844. case AD_ACID: 1845. pline("%s is covered with your goo!", Monnam(mdef)); 1846. if (resists_acid(mdef)) { 1847. pline("It seems harmless to %s.", mon_nam(mdef)); 1848. dam = 0; 1849. } 1850. break; 1851. case AD_BLND: 1852. if (can_blnd(&youmonst, mdef, mattk->aatyp, (struct obj *)0)) { 1853. if (mdef->mcansee) 1854. pline("%s can't see in there!", Monnam(mdef)); 1855. mdef->mcansee = 0; 1856. dam += mdef->mblinded; 1857. if (dam > 127) dam = 127; 1858. mdef->mblinded = dam; 1859. } 1860. dam = 0; 1861. break; 1862. case AD_ELEC: 1863. if (rn2(2)) { 1864. pline_The("air around %s crackles with electricity.", mon_nam(mdef)); 1865. if (resists_elec(mdef)) { 1866. pline("%s seems unhurt.", Monnam(mdef)); 1867. dam = 0; 1868. } 1869. golemeffects(mdef,(int)mattk->adtyp,dam); 1870. } else dam = 0; 1871. break; 1872. case AD_COLD: 1873. if (rn2(2)) { 1874. if (resists_cold(mdef)) { 1875. pline("%s seems mildly chilly.", Monnam(mdef)); 1876. dam = 0; 1877. } else 1878. pline("%s is freezing to death!",Monnam(mdef)); 1879. golemeffects(mdef,(int)mattk->adtyp,dam); 1880. } else dam = 0; 1881. break; 1882. case AD_FIRE: 1883. if (rn2(2)) { 1884. if (resists_fire(mdef)) { 1885. pline("%s seems mildly hot.", Monnam(mdef)); 1886. dam = 0; 1887. } else 1888. pline("%s is burning to a crisp!",Monnam(mdef)); 1889. golemeffects(mdef,(int)mattk->adtyp,dam); 1890. } else dam = 0; 1891. break; 1892. } 1893. end_engulf(); 1894. if ((mdef->mhp -= dam) <= 0) { 1895. killed(mdef); 1896. if (mdef->mhp <= 0) /* not lifesaved */ 1897. return(2); 1898. } 1899. You("%s %s!", is_animal(youmonst.data) ? "regurgitate" 1900. : "expel", mon_nam(mdef)); 1901. if (Slow_digestion || is_animal(youmonst.data)) { 1902. pline("Obviously, you didn't like %s taste.", 1903. s_suffix(mon_nam(mdef))); 1904. } 1905. } else { 1906. char kbuf[BUFSZ]; 1907. 1908. You("bite into %s.", mon_nam(mdef)); 1909. Sprintf(kbuf, "swallowing %s whole", an(mdef->data->mname)); 1910. instapetrify(kbuf); 1911. } 1912. } 1913. return(0); 1914. } 1915.
missum[]
1916. void 1917. missum(mdef,mattk) 1918. register struct monst *mdef; 1919. register struct attack *mattk; 1920. { 1921. if (could_seduce(&youmonst, mdef, mattk)) 1922. You("pretend to be friendly to %s.", mon_nam(mdef)); 1923. else if(canspotmon(mdef) && flags.verbose) 1924. You("miss %s.", mon_nam(mdef)); 1925. else 1926. You("miss it."); 1927. if (!mdef->msleeping && mdef->mcanmove) 1928. wakeup(mdef); 1929. } 1930.
hmonas[]
1931. STATIC_OVL boolean 1932. hmonas(mon, tmp) /* attack monster as a monster. */ 1933. register struct monst *mon; 1934. register int tmp; 1935. { 1936. struct attack *mattk, alt_attk; 1937. int i, sum[NATTK], hittmp = 0; 1938. int nsum = 0; 1939. int dhit = 0; 1940. 1941. for(i = 0; i < NATTK; i++) { 1942. 1943. sum[i] = 0; 1944. mattk = getmattk(youmonst.data, i, sum, &alt_attk); 1945. switch(mattk->aatyp) { 1946. case AT_WEAP: 1947. use_weapon: 1948. /* Certain monsters don't use weapons when encountered as enemies, 1949. * but players who polymorph into them have hands or claws and thus 1950. * should be able to use weapons. This shouldn't prohibit the use 1951. * of most special abilities, either. 1952. */ 1953. /* Potential problem: if the monster gets multiple weapon attacks, 1954. * we currently allow the player to get each of these as a weapon 1955. * attack. Is this really desirable? 1956. */ 1957. if (uwep) { 1958. hittmp = hitval(uwep, mon); 1959. hittmp += weapon_hit_bonus(uwep); 1960. tmp += hittmp; 1961. } 1962. dhit = (tmp > (dieroll = rnd(20)) || u.uswallow); 1963. /* KMH -- Don't accumulate to-hit bonuses */ 1964. if (uwep) tmp -= hittmp; 1965. /* Enemy dead, before any special abilities used */ 1966. if (!known_hitum(mon,&dhit,mattk)) { 1967. sum[i] = 2; 1968. break; 1969. } else sum[i] = dhit; 1970. /* might be a worm that gets cut in half */ 1971. if (m_at(u.ux+u.dx, u.uy+u.dy) != mon) return((boolean)(nsum != 0)); 1972. /* Do not print "You hit" message, since known_hitum 1973. * already did it. 1974. */ 1975. if (dhit && mattk->adtyp != AD_SPEL 1976. && mattk->adtyp != AD_PHYS) 1977. sum[i] = damageum(mon,mattk); 1978. break; 1979. case AT_CLAW: 1980. if (i==0 && uwep && !cantwield(youmonst.data)) goto use_weapon; 1981. #ifdef SEDUCE 1982. /* succubi/incubi are humanoid, but their _second_ 1983. * attack is AT_CLAW, not their first... 1984. */ 1985. if (i==1 && uwep && (u.umonnum == PM_SUCCUBUS || 1986. u.umonnum == PM_INCUBUS)) goto use_weapon; 1987. #endif 1988. case AT_KICK: 1989. case AT_BITE: 1990. case AT_STNG: 1991. case AT_TUCH: 1992. case AT_BUTT: 1993. case AT_TENT: 1994. if (i==0 && uwep && (youmonst.data->mlet==S_LICH)) goto use_weapon; 1995. if ((dhit = (tmp > rnd(20) || u.uswallow)) != 0) { 1996. int compat; 1997. 1998. if (!u.uswallow && 1999. (compat=could_seduce(&youmonst, mon, mattk))) { 2000. You("%s %s %s.", 2001. mon->mcansee && haseyes(mon->data) 2002. ? "smile at" : "talk to", 2003. mon_nam(mon), 2004. compat == 2 ? "engagingly":"seductively"); 2005. /* doesn't anger it; no wakeup() */ 2006. sum[i] = damageum(mon, mattk); 2007. break; 2008. } 2009. wakeup(mon); 2010. /* maybe this check should be in damageum()? */ 2011. if (mon->data == &mons[PM_SHADE] && 2012. !(mattk->aatyp == AT_KICK && 2013. uarmf && uarmf->blessed)) { 2014. Your("attack passes harmlessly through %s.", 2015. mon_nam(mon)); 2016. break; 2017. } 2018. if (mattk->aatyp == AT_KICK) 2019. You("kick %s.", mon_nam(mon)); 2020. else if (mattk->aatyp == AT_BITE) 2021. You("bite %s.", mon_nam(mon)); 2022. else if (mattk->aatyp == AT_STNG) 2023. You("sting %s.", mon_nam(mon)); 2024. else if (mattk->aatyp == AT_BUTT) 2025. You("butt %s.", mon_nam(mon)); 2026. else if (mattk->aatyp == AT_TUCH) 2027. You("touch %s.", mon_nam(mon)); 2028. else if (mattk->aatyp == AT_TENT) 2029. Your("tentacles suck %s.", mon_nam(mon)); 2030. else You("hit %s.", mon_nam(mon)); 2031. sum[i] = damageum(mon, mattk); 2032. } else 2033. missum(mon, mattk); 2034. break; 2035. 2036. case AT_HUGS: 2037. /* automatic if prev two attacks succeed, or if 2038. * already grabbed in a previous attack 2039. */ 2040. dhit = 1; 2041. wakeup(mon); 2042. if (mon->data == &mons[PM_SHADE]) 2043. Your("hug passes harmlessly through %s.", 2044. mon_nam(mon)); 2045. else if (!sticks(mon->data) && !u.uswallow) { 2046. if (mon==u.ustuck) { 2047. pline("%s is being %s.", Monnam(mon), 2048. u.umonnum==PM_ROPE_GOLEM ? "choked": 2049. "crushed"); 2050. sum[i] = damageum(mon, mattk); 2051. } else if(i >= 2 && sum[i-1] && sum[i-2]) { 2052. You("grab %s!", mon_nam(mon)); 2053. u.ustuck = mon; 2054. sum[i] = damageum(mon, mattk); 2055. } 2056. } 2057. break; 2058. 2059. case AT_EXPL: /* automatic hit if next to */ 2060. dhit = -1; 2061. wakeup(mon); 2062. sum[i] = explum(mon, mattk); 2063. break; 2064. 2065. case AT_ENGL: 2066. if((dhit = (tmp > rnd(20+i)))) { 2067. wakeup(mon); 2068. if (mon->data == &mons[PM_SHADE]) 2069. Your("attempt to surround %s is harmless.", 2070. mon_nam(mon)); 2071. else { 2072. sum[i]= gulpum(mon,mattk); 2073. if (sum[i] == 2 && 2074. (mon->data->mlet == S_ZOMBIE || 2075. mon->data->mlet == S_MUMMY) && 2076. rn2(5) && 2077. !Sick_resistance) { 2078. You_feel("%ssick.", 2079. (Sick) ? "very " : ""); 2080. mdamageu(mon, rnd(8)); 2081. } 2082. } 2083. } else 2084. missum(mon, mattk); 2085. break; 2086. 2087. case AT_MAGC: 2088. /* No check for uwep; if wielding nothing we want to 2089. * do the normal 1-2 points bare hand damage... 2090. */ 2091. if (i==0 && (youmonst.data->mlet==S_KOBOLD 2092. || youmonst.data->mlet==S_ORC 2093. || youmonst.data->mlet==S_GNOME 2094. )) goto use_weapon; 2095. 2096. case AT_NONE: 2097. case AT_BOOM: 2098. continue; 2099. /* Not break--avoid passive attacks from enemy */ 2100. 2101. case AT_BREA: 2102. case AT_SPIT: 2103. case AT_GAZE: /* all done using #monster command */ 2104. dhit = 0; 2105. break; 2106. 2107. default: /* Strange... */ 2108. impossible("strange attack of yours (%d)", 2109. mattk->aatyp); 2110. } 2111. if (dhit == -1) { 2112. u.mh = -1; /* dead in the current form */ 2113. rehumanize(); 2114. } 2115. if (sum[i] == 2) 2116. return((boolean)passive(mon, 1, 0, mattk->aatyp)); 2117. /* defender dead */ 2118. else { 2119. (void) passive(mon, sum[i], 1, mattk->aatyp); 2120. nsum |= sum[i]; 2121. } 2122. if (!Upolyd) 2123. break; /* No extra attacks if no longer a monster */ 2124. if (multi < 0) 2125. break; /* If paralyzed while attacking, i.e. floating eye */ 2126. } 2127. return((boolean)(nsum != 0)); 2128. } 2129.
passive[]
2130. /* Special (passive) attacks on you by monsters done here. */ 2131. 2132. int 2133. passive(mon, mhit, malive, aatyp) 2134. register struct monst *mon; 2135. register boolean mhit; 2136. register int malive; 2137. uchar aatyp; 2138. { 2139. register struct permonst *ptr = mon->data; 2140. register int i, tmp; 2141. 2142. for(i = 0; ; i++) { 2143. if(i >= NATTK) return(malive | mhit); /* no passive attacks */ 2144. if(ptr->mattk[i].aatyp == AT_NONE) break; /* try this one */ 2145. } 2146. /* Note: tmp not always used */ 2147. if (ptr->mattk[i].damn) 2148. tmp = d((int)ptr->mattk[i].damn, (int)ptr->mattk[i].damd); 2149. else if(ptr->mattk[i].damd) 2150. tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd); 2151. else 2152. tmp = 0; 2153. 2154. /* These affect you even if they just died */ 2155. 2156. switch(ptr->mattk[i].adtyp) { 2157. 2158. case AD_ACID: 2159. if(mhit && rn2(2)) { 2160. if (Blind || !flags.verbose) You("are splashed!"); 2161. else You("are splashed by %s acid!", 2162. s_suffix(mon_nam(mon))); 2163. 2164. if (!Acid_resistance) 2165. mdamageu(mon, tmp); 2166. if(!rn2(30)) erode_armor(&youmonst, TRUE); 2167. } 2168. if (mhit) { 2169. if (aatyp == AT_KICK) { 2170. if (uarmf && !rn2(6)) 2171. (void)rust_dmg(uarmf, xname(uarmf), 3, TRUE, &youmonst); 2172. } else if (aatyp == AT_WEAP || aatyp == AT_CLAW || 2173. aatyp == AT_MAGC || aatyp == AT_TUCH) 2174. passive_obj(mon, (struct obj*)0, &(ptr->mattk[i])); 2175. } 2176. exercise(A_STR, FALSE); 2177. break; 2178. case AD_STON: 2179. if (mhit) { /* successful attack */ 2180. long protector = attk_protection((int)aatyp); 2181. 2182. /* hero using monsters' AT_MAGC attack is hitting hand to 2183. hand rather than casting a spell */ 2184. if (aatyp == AT_MAGC) protector = W_ARMG; 2185. 2186. if (protector == 0L || /* no protection */ 2187. (protector == W_ARMG && !uarmg && !uwep) || 2188. (protector == W_ARMF && !uarmf) || 2189. (protector == W_ARMH && !uarmh) || 2190. (protector == (W_ARMC|W_ARMG) && (!uarmc || !uarmg))) { 2191. if (!Stone_resistance && 2192. !(poly_when_stoned(youmonst.data) && 2193. polymon(PM_STONE_GOLEM))) { 2194. You("turn to stone..."); 2195. done_in_by(mon); 2196. return 2; 2197. } 2198. } 2199. } 2200. break; 2201. case AD_RUST: 2202. if(mhit && !mon->mcan) { 2203. if (aatyp == AT_KICK) { 2204. if (uarmf) 2205. (void)rust_dmg(uarmf, xname(uarmf), 1, TRUE, &youmonst); 2206. } else if (aatyp == AT_WEAP || aatyp == AT_CLAW || 2207. aatyp == AT_MAGC || aatyp == AT_TUCH) 2208. passive_obj(mon, (struct obj*)0, &(ptr->mattk[i])); 2209. } 2210. break; 2211. case AD_CORR: 2212. if(mhit && !mon->mcan) { 2213. if (aatyp == AT_KICK) { 2214. if (uarmf) 2215. (void)rust_dmg(uarmf, xname(uarmf), 3, TRUE, &youmonst); 2216. } else if (aatyp == AT_WEAP || aatyp == AT_CLAW || 2217. aatyp == AT_MAGC || aatyp == AT_TUCH) 2218. passive_obj(mon, (struct obj*)0, &(ptr->mattk[i])); 2219. } 2220. break; 2221. case AD_MAGM: 2222. /* wrath of gods for attacking Oracle */ 2223. if(Antimagic) { 2224. shieldeff(u.ux, u.uy); 2225. pline("A hail of magic missiles narrowly misses you!"); 2226. } else { 2227. You("are hit by magic missiles appearing from thin air!"); 2228. mdamageu(mon, tmp); 2229. } 2230. break; 2231. case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ 2232. if (mhit) { 2233. struct obj *obj = (struct obj *)0; 2234. 2235. if (aatyp == AT_KICK) { 2236. obj = uarmf; 2237. if (!obj) break; 2238. } else if (aatyp == AT_BITE || aatyp == AT_BUTT || 2239. (aatyp >= AT_STNG && aatyp < AT_WEAP)) { 2240. break; /* no object involved */ 2241. } 2242. passive_obj(mon, obj, &(ptr->mattk[i])); 2243. } 2244. break; 2245. default: 2246. break; 2247. } 2248. 2249. /* These only affect you if they still live */ 2250. 2251. if(malive && !mon->mcan && rn2(3)) { 2252. 2253. switch(ptr->mattk[i].adtyp) { 2254. 2255. case AD_PLYS: 2256. if(ptr == &mons[PM_FLOATING_EYE]) { 2257. if (!canseemon(mon)) { 2258. break; 2259. } 2260. if(mon->mcansee) { 2261. if (ureflects("%s gaze is reflected by your %s.", 2262. s_suffix(Monnam(mon)))) 2263. ; 2264. else if (Free_action) 2265. You("momentarily stiffen under %s gaze!", 2266. s_suffix(mon_nam(mon))); 2267. else { 2268. You("are frozen by %s gaze!", 2269. s_suffix(mon_nam(mon))); 2270. nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -127); 2271. } 2272. } else { 2273. pline("%s cannot defend itself.", 2274. Adjmonnam(mon,"blind")); 2275. if(!rn2(500)) change_luck(-1); 2276. } 2277. } else if (Free_action) { 2278. You("momentarily stiffen."); 2279. } else { /* gelatinous cube */ 2280. You("are frozen by %s!", mon_nam(mon)); 2281. nomovemsg = 0; /* default: "you can move again" */ 2282. nomul(-tmp); 2283. exercise(A_DEX, FALSE); 2284. } 2285. break; 2286. case AD_COLD: /* brown mold or blue jelly */ 2287. if(monnear(mon, u.ux, u.uy)) { 2288. if(Cold_resistance) { 2289. shieldeff(u.ux, u.uy); 2290. You_feel("a mild chill."); 2291. ugolemeffects(AD_COLD, tmp); 2292. break; 2293. } 2294. You("are suddenly very cold!"); 2295. mdamageu(mon, tmp); 2296. /* monster gets stronger with your heat! */ 2297. mon->mhp += tmp / 2; 2298. if (mon->mhpmax < mon->mhp) mon->mhpmax = mon->mhp; 2299. /* at a certain point, the monster will reproduce! */ 2300. if(mon->mhpmax > ((int) (mon->m_lev+1) * 8)) 2301. (void)split_mon(mon, &youmonst); 2302. } 2303. break; 2304. case AD_STUN: /* specifically yellow mold */ 2305. if(!Stunned) 2306. make_stunned((long)tmp, TRUE); 2307. break; 2308. case AD_FIRE: 2309. if(monnear(mon, u.ux, u.uy)) { 2310. if(Fire_resistance) { 2311. shieldeff(u.ux, u.uy); 2312. You_feel("mildly warm."); 2313. ugolemeffects(AD_FIRE, tmp); 2314. break; 2315. } 2316. You("are suddenly very hot!"); 2317. mdamageu(mon, tmp); 2318. } 2319. break; 2320. case AD_ELEC: 2321. if(Shock_resistance) { 2322. shieldeff(u.ux, u.uy); 2323. You_feel("a mild tingle."); 2324. ugolemeffects(AD_ELEC, tmp); 2325. break; 2326. } 2327. You("are jolted with electricity!"); 2328. mdamageu(mon, tmp); 2329. break; 2330. default: 2331. break; 2332. } 2333. } 2334. return(malive | mhit); 2335. } 2336.
passive_obj[]
2337. /* 2338. * Special (passive) attacks on an attacking object by monsters done here. 2339. * Assumes the attack was successful. 2340. */ 2341. void 2342. passive_obj(mon, obj, mattk) 2343. register struct monst *mon; 2344. register struct obj *obj; /* null means pick uwep, uswapwep or uarmg */ 2345. struct attack *mattk; /* null means we find one internally */ 2346. { 2347. register struct permonst *ptr = mon->data; 2348. register int i; 2349. 2350. /* if caller hasn't specified an object, use uwep, uswapwep or uarmg */ 2351. if (!obj) { 2352. obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep; 2353. if (!obj && mattk->adtyp == AD_ENCH) 2354. obj = uarmg; /* no weapon? then must be gloves */ 2355. if (!obj) return; /* no object to affect */ 2356. } 2357. 2358. /* if caller hasn't specified an attack, find one */ 2359. if (!mattk) { 2360. for(i = 0; ; i++) { 2361. if(i >= NATTK) return; /* no passive attacks */ 2362. if(ptr->mattk[i].aatyp == AT_NONE) break; /* try this one */ 2363. } 2364. mattk = &(ptr->mattk[i]); 2365. } 2366. 2367. switch(mattk->adtyp) { 2368. 2369. case AD_ACID: 2370. if(!rn2(6)) { 2371. erode_obj(obj, TRUE, FALSE); 2372. } 2373. break; 2374. case AD_RUST: 2375. if(!mon->mcan) { 2376. erode_obj(obj, FALSE, FALSE); 2377. } 2378. break; 2379. case AD_CORR: 2380. if(!mon->mcan) { 2381. erode_obj(obj, TRUE, FALSE); 2382. } 2383. break; 2384. case AD_ENCH: 2385. if (!mon->mcan) { 2386. if (drain_item(obj) && carried(obj) && 2387. (obj->known || obj->oclass == ARMOR_CLASS)) { 2388. Your("%s less effective.", aobjnam(obj, "seem")); 2389. } 2390. break; 2391. } 2392. default: 2393. break; 2394. } 2395. 2396. if (carried(obj)) update_inventory(); 2397. } 2398.
stumble_onto_mimic[]
2399. /* Note: caller must ascertain mtmp is mimicking... */ 2400. void 2401. stumble_onto_mimic(mtmp) 2402. struct monst *mtmp; 2403. { 2404. const char *fmt = "Wait! That's %s!", 2405. *generic = "a monster", 2406. *what = 0; 2407. 2408. if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK)) 2409. u.ustuck = mtmp; 2410. 2411. if (Blind) { 2412. if (!Blind_telepat) 2413. what = generic; /* with default fmt */ 2414. else if (mtmp->m_ap_type == M_AP_MONSTER) 2415. what = a_monnam(mtmp); /* differs from what was sensed */ 2416. } else { 2417. int glyph = levl[u.ux+u.dx][u.uy+u.dy].glyph; 2418. 2419. if (glyph_is_cmap(glyph) && 2420. (glyph_to_cmap(glyph) == S_hcdoor || 2421. glyph_to_cmap(glyph) == S_vcdoor)) 2422. fmt = "The door actually was %s!"; 2423. else if (glyph_is_object(glyph) && 2424. glyph_to_obj(glyph) == GOLD_PIECE) 2425. fmt = "That gold was %s!"; 2426. 2427. /* cloned Wiz starts out mimicking some other monster and 2428. might make himself invisible before being revealed */ 2429. if (mtmp->minvis && !See_invisible) 2430. what = generic; 2431. else 2432. what = a_monnam(mtmp); 2433. } 2434. if (what) pline(fmt, what); 2435. 2436. wakeup(mtmp); /* clears mimicking */ 2437. } 2438.
nohandglow[]
2439. STATIC_OVL void 2440. nohandglow(mon) 2441. struct monst *mon; 2442. { 2443. char *hands=makeplural(body_part(HAND)); 2444. 2445. if (!u.umconf || mon->mconf) return; 2446. if (u.umconf == 1) { 2447. if (Blind) 2448. Your("%s stop tingling.", hands); 2449. else 2450. Your("%s stop glowing %s.", hands, hcolor(NH_RED)); 2451. } else { 2452. if (Blind) 2453. pline_The("tingling in your %s lessens.", hands); 2454. else 2455. Your("%s no longer glow so brightly %s.", hands, 2456. hcolor(NH_RED)); 2457. } 2458. u.umconf--; 2459. } 2460.
flash_hits_mon[]
2461. int 2462. flash_hits_mon(mtmp, otmp) 2463. struct monst *mtmp; 2464. struct obj *otmp; /* source of flash */ 2465. { 2466. int tmp, amt, res = 0, useeit = canseemon(mtmp); 2467. 2468. if (mtmp->msleeping) { 2469. mtmp->msleeping = 0; 2470. if (useeit) { 2471. pline_The("flash awakens %s.", mon_nam(mtmp)); 2472. res = 1; 2473. } 2474. } else if (mtmp->data->mlet != S_LIGHT) { 2475. if (!resists_blnd(mtmp)) { 2476. tmp = dist2(otmp->ox, otmp->oy, mtmp->mx, mtmp->my); 2477. if (useeit) { 2478. pline("%s is blinded by the flash!", Monnam(mtmp)); 2479. res = 1; 2480. } 2481. if (mtmp->data == &mons[PM_GREMLIN]) { 2482. /* Rule #1: Keep them out of the light. */ 2483. amt = otmp->otyp == WAN_LIGHT ? d(1 + otmp->spe, 4) : 2484. rn2(min(mtmp->mhp,4)); 2485. pline("%s %s!", Monnam(mtmp), amt > mtmp->mhp / 2 ? 2486. "wails in agony" : "cries out in pain"); 2487. if ((mtmp->mhp -= amt) <= 0) { 2488. if (flags.mon_moving) 2489. monkilled(mtmp, (char *)0, AD_BLND); 2490. else 2491. killed(mtmp); 2492. } else if (cansee(mtmp->mx,mtmp->my) && !canspotmon(mtmp)){ 2493. map_invisible(mtmp->mx, mtmp->my); 2494. } 2495. } 2496. if (mtmp->mhp > 0) { 2497. if (!flags.mon_moving) setmangry(mtmp); 2498. if (tmp < 9 && !mtmp->isshk && rn2(4)) { 2499. if (rn2(4)) 2500. monflee(mtmp, rnd(100), FALSE, TRUE); 2501. else 2502. monflee(mtmp, 0, FALSE, TRUE); 2503. } 2504. mtmp->mcansee = 0; 2505. mtmp->mblinded = (tmp < 3) ? 0 : rnd(1 + 50/tmp); 2506. } 2507. } 2508. } 2509. return res; 2510. } 2511. 2512. /*uhitm.c*/