Below is the full text to src/mhitu.c from NetHack 3.4.3. To link to a particular line, write [[mhitu.c#line123]], for example.
Top of file
Edit
1. /* SCCS Id: @(#)mhitu.c 3.4 2003/11/26 */
2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3. /* NetHack may be freely redistributed. See license for details. */
4.
5. #include "hack.h"
6. #include "artifact.h"
7.
8. STATIC_VAR NEARDATA struct obj *otmp;
9.
10. STATIC_DCL void FDECL(urustm, (struct monst *, struct obj *));
11. # ifdef OVL1
12. STATIC_DCL boolean FDECL(u_slip_free, (struct monst *,struct attack *));
13. STATIC_DCL int FDECL(passiveum, (struct permonst *,struct monst *,struct attack *));
14. # endif /* OVL1 */
15.
16. #ifdef OVLB
17. # ifdef SEDUCE
18. STATIC_DCL void FDECL(mayberem, (struct obj *, const char *));
19. # endif
20. #endif /* OVLB */
21.
22. STATIC_DCL boolean FDECL(diseasemu, (struct permonst *));
23. STATIC_DCL int FDECL(hitmu, (struct monst *,struct attack *));
24. STATIC_DCL int FDECL(gulpmu, (struct monst *,struct attack *));
25. STATIC_DCL int FDECL(explmu, (struct monst *,struct attack *,BOOLEAN_P));
26. STATIC_DCL void FDECL(missmu,(struct monst *,BOOLEAN_P,struct attack *));
27. STATIC_DCL void FDECL(mswings,(struct monst *,struct obj *));
28. STATIC_DCL void FDECL(wildmiss, (struct monst *,struct attack *));
29.
30. STATIC_DCL void FDECL(hurtarmor,(int));
31. STATIC_DCL void FDECL(hitmsg,(struct monst *,struct attack *));
32.
33. /* See comment in mhitm.c. If we use this a lot it probably should be */
34. /* changed to a parameter to mhitu. */
35. static int dieroll;
36.
37. #ifdef OVL1
38.
39.
40. STATIC_OVL void
41. hitmsg(mtmp, mattk)
42. register struct monst *mtmp;
43. register struct attack *mattk;
44. {
45. int compat;
46.
47. /* Note: if opposite gender, "seductively" */
48. /* If same gender, "engagingly" for nymph, normal msg for others */
49. if((compat = could_seduce(mtmp, &youmonst, mattk))
50. && !mtmp->mcan && !mtmp->mspec_used) {
51. pline("%s %s you %s.", Monnam(mtmp),
52. Blind ? "talks to" : "smiles at",
53. compat == 2 ? "engagingly" : "seductively");
54. } else
55. switch (mattk->aatyp) {
56. case AT_BITE:
57. pline("%s bites!", Monnam(mtmp));
58. break;
59. case AT_KICK:
60. pline("%s kicks%c", Monnam(mtmp),
61. thick_skinned(youmonst.data) ? '.' : '!');
62. break;
63. case AT_STNG:
64. pline("%s stings!", Monnam(mtmp));
65. break;
66. case AT_BUTT:
67. pline("%s butts!", Monnam(mtmp));
68. break;
69. case AT_TUCH:
70. pline("%s touches you!", Monnam(mtmp));
71. break;
72. case AT_TENT:
73. pline("%s tentacles suck you!",
74. s_suffix(Monnam(mtmp)));
75. break;
76. case AT_EXPL:
77. case AT_BOOM:
78. pline("%s explodes!", Monnam(mtmp));
79. break;
80. default:
81. pline("%s hits!", Monnam(mtmp));
82. }
83. }
84.
85. STATIC_OVL void
86. missmu(mtmp, nearmiss, mattk) /* monster missed you */
87. register struct monst *mtmp;
88. register boolean nearmiss;
89. register struct attack *mattk;
90. {
91. if (!canspotmon(mtmp))
92. map_invisible(mtmp->mx, mtmp->my);
93.
94. if(could_seduce(mtmp, &youmonst, mattk) && !mtmp->mcan)
95. pline("%s pretends to be friendly.", Monnam(mtmp));
96. else {
97. if (!flags.verbose || !nearmiss)
98. pline("%s misses.", Monnam(mtmp));
99. else
100. pline("%s just misses!", Monnam(mtmp));
101. }
102. stop_occupation();
103. }
104.
105. STATIC_OVL void
106. mswings(mtmp, otemp) /* monster swings obj */
107. register struct monst *mtmp;
108. register struct obj *otemp;
109. {
110. if (!flags.verbose || Blind || !mon_visible(mtmp))
111. return;
112. pline("%s %s %s %s.", Monnam(mtmp),
113. (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",
114. mhis(mtmp), singular(otemp, xname));
115. }
116.
mpoisons_subj
Edit
117. /* return how a poison attack was delivered */
118. const char *
119. mpoisons_subj(mtmp, mattk)
120. struct monst *mtmp;
121. struct attack *mattk;
122. {
123. if (mattk->aatyp == AT_WEAP) {
124. struct obj *mwep = (mtmp == &youmonst) ? uwep : MON_WEP(mtmp);
125. /* "Foo's attack was poisoned." is pretty lame, but at least
126. it's better than "sting" when not a stinging attack... */
127. return (!mwep || !mwep->opoisoned) ? "attack" : "weapon";
128. } else {
129. return (mattk->aatyp == AT_TUCH) ? "contact" :
130. (mattk->aatyp == AT_GAZE) ? "gaze" :
131. (mattk->aatyp == AT_BITE) ? "bite" : "sting";
132. }
133. }
134.
u_slow_down
Edit
135. /* called when your intrinsic speed is taken away */
136. void
137. u_slow_down()
138. {
139. HFast = 0L;
140. if (!Fast)
141. You("slow down.");
142. else /* speed boots */
143. Your("quickness feels less natural.");
144. exercise(A_DEX, FALSE);
145. }
146.
147. #endif /* OVL1 */
wildmiss
Edit
148. #ifdef OVLB
149.
150. STATIC_OVL void
151. wildmiss(mtmp, mattk) /* monster attacked your displaced image */
152. register struct monst *mtmp;
153. register struct attack *mattk;
154. {
155. int compat;
156.
157. /* no map_invisible() -- no way to tell where _this_ is coming from */
158.
159. if (!flags.verbose) return;
160. if (!cansee(mtmp->mx, mtmp->my)) return;
161. /* maybe it's attacking an image around the corner? */
162.
163. compat = (mattk->adtyp == AD_SEDU || mattk->adtyp == AD_SSEX) &&
164. could_seduce(mtmp, &youmonst, (struct attack *)0);
165.
166. if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) {
167. const char *swings =
168. mattk->aatyp == AT_BITE ? "snaps" :
169. mattk->aatyp == AT_KICK ? "kicks" :
170. (mattk->aatyp == AT_STNG ||
171. mattk->aatyp == AT_BUTT ||
172. nolimbs(mtmp->data)) ? "lunges" : "swings";
173.
174. if (compat)
175. pline("%s tries to touch you and misses!", Monnam(mtmp));
176. else
177. switch(rn2(3)) {
178. case 0: pline("%s %s wildly and misses!", Monnam(mtmp),
179. swings);
180. break;
181. case 1: pline("%s attacks a spot beside you.", Monnam(mtmp));
182. break;
183. case 2: pline("%s strikes at %s!", Monnam(mtmp),
184. levl[mtmp->mux][mtmp->muy].typ == WATER
185. ? "empty water" : "thin air");
186. break;
187. default:pline("%s %s wildly!", Monnam(mtmp), swings);
188. break;
189. }
190.
191. } else if (Displaced) {
192. if (compat)
193. pline("%s smiles %s at your %sdisplaced image...",
194. Monnam(mtmp),
195. compat == 2 ? "engagingly" : "seductively",
196. Invis ? "invisible " : "");
197. else
198. pline("%s strikes at your %sdisplaced image and misses you!",
199. /* Note: if you're both invisible and displaced,
200. * only monsters which see invisible will attack your
201. * displaced image, since the displaced image is also
202. * invisible.
203. */
204. Monnam(mtmp),
205. Invis ? "invisible " : "");
206.
207. } else if (Underwater) {
208. /* monsters may miss especially on water level where
209. bubbles shake the player here and there */
210. if (compat)
211. pline("%s reaches towards your distorted image.",Monnam(mtmp));
212. else
213. pline("%s is fooled by water reflections and misses!",Monnam(mtmp));
214.
215. } else impossible("%s attacks you without knowing your location?",
216. Monnam(mtmp));
217. }
218.
219. void
220. expels(mtmp, mdat, message)
221. register struct monst *mtmp;
222. register struct permonst *mdat; /* if mtmp is polymorphed, mdat != mtmp->data */
223. boolean message;
224. {
225. if (message) {
226. if (is_animal(mdat))
227. You("get regurgitated!");
228. else {
229. char blast[40];
230. register int i;
231.
232. blast[0] = '\0';
233. for(i = 0; i < NATTK; i++)
234. if(mdat->mattk[i].aatyp == AT_ENGL)
235. break;
236. if (mdat->mattk[i].aatyp != AT_ENGL)
237. impossible("Swallower has no engulfing attack?");
238. else {
239. if (is_whirly(mdat)) {
240. switch (mdat->mattk[i].adtyp) {
241. case AD_ELEC:
242. Strcpy(blast,
243. " in a shower of sparks");
244. break;
245. case AD_COLD:
246. Strcpy(blast,
247. " in a blast of frost");
248. break;
249. }
250. } else
251. Strcpy(blast, " with a squelch");
252. You("get expelled from %s%s!",
253. mon_nam(mtmp), blast);
254. }
255. }
256. }
257. unstuck(mtmp); /* ball&chain returned in unstuck() */
258. mnexto(mtmp);
259. newsym(u.ux,u.uy);
260. spoteffects(TRUE);
261. /* to cover for a case where mtmp is not in a next square */
262. if(um_dist(mtmp->mx,mtmp->my,1))
263. pline("Brrooaa... You land hard at some distance.");
264. }
265.
266. #endif /* OVLB */
getmattk
Edit
267. #ifdef OVL0
268.
269. /* select a monster's next attack, possibly substituting for its usual one */
270. struct attack *
271. getmattk(mptr, indx, prev_result, alt_attk_buf)
272. struct permonst *mptr;
273. int indx, prev_result[];
274. struct attack *alt_attk_buf;
275. {
276. struct attack *attk = &mptr->mattk[indx];
277.
278. /* prevent a monster with two consecutive disease or hunger attacks
279. from hitting with both of them on the same turn; if the first has
280. already hit, switch to a stun attack for the second */
281. if (indx > 0 && prev_result[indx - 1] > 0 &&
282. (attk->adtyp == AD_DISE ||
283. attk->adtyp == AD_PEST ||
284. attk->adtyp == AD_FAMN) &&
285. attk->adtyp == mptr->mattk[indx - 1].adtyp) {
286. *alt_attk_buf = *attk;
287. attk = alt_attk_buf;
288. attk->adtyp = AD_STUN;
289. }
290. return attk;
291. }
292.
mattacku
Edit
293. /*
294. * mattacku: monster attacks you
295. * returns 1 if monster dies (e.g. "yellow light"), 0 otherwise
296. * Note: if you're displaced or invisible the monster might attack the
297. * wrong position...
298. * Assumption: it's attacking you or an empty square; if there's another
299. * monster which it attacks by mistake, the caller had better
300. * take care of it...
301. */
302. int
303. mattacku(mtmp)
304. register struct monst *mtmp;
305. {
306. struct attack *mattk, alt_attk;
307. int i, j, tmp, sum[NATTK];
308. struct permonst *mdat = mtmp->data;
309. boolean ranged = (distu(mtmp->mx, mtmp->my) > 3);
310. /* Is it near you? Affects your actions */
311. boolean range2 = !monnear(mtmp, mtmp->mux, mtmp->muy);
312. /* Does it think it's near you? Affects its actions */
313. boolean foundyou = (mtmp->mux==u.ux && mtmp->muy==u.uy);
314. /* Is it attacking you or your image? */
315. boolean youseeit = canseemon(mtmp);
316. /* Might be attacking your image around the corner, or
317. * invisible, or you might be blind....
318. */
319.
320. if(!ranged) nomul(0);
321. if(mtmp->mhp <= 0 || (Underwater && !is_swimmer(mtmp->data)))
322. return(0);
323.
324. /* If swallowed, can only be affected by u.ustuck */
325. if(u.uswallow) {
326. if(mtmp != u.ustuck)
327. return(0);
328. u.ustuck->mux = u.ux;
329. u.ustuck->muy = u.uy;
330. range2 = 0;
331. foundyou = 1;
332. if(u.uinvulnerable) return (0); /* stomachs can't hurt you! */
333. }
334.
335. #ifdef STEED
336. else if (u.usteed) {
337. if (mtmp == u.usteed)
338. /* Your steed won't attack you */
339. return (0);
340. /* Orcs like to steal and eat horses and the like */
341. if (!rn2(is_orc(mtmp->data) ? 2 : 4) &&
342. distu(mtmp->mx, mtmp->my) <= 2) {
343. /* Attack your steed instead */
344. i = mattackm(mtmp, u.usteed);
345. if ((i & MM_AGR_DIED))
346. return (1);
347. if (i & MM_DEF_DIED || u.umoved)
348. return (0);
349. /* Let your steed retaliate */
350. return (!!(mattackm(u.usteed, mtmp) & MM_DEF_DIED));
351. }
352. }
353. #endif
354.
355. if (u.uundetected && !range2 && foundyou && !u.uswallow) {
356. u.uundetected = 0;
357. if (is_hider(youmonst.data)) {
358. coord cc; /* maybe we need a unexto() function? */
359. struct obj *obj;
360.
361. You("fall from the %s!", ceiling(u.ux,u.uy));
362. if (enexto(&cc, u.ux, u.uy, youmonst.data)) {
363. remove_monster(mtmp->mx, mtmp->my);
364. newsym(mtmp->mx,mtmp->my);
365. place_monster(mtmp, u.ux, u.uy);
366. if(mtmp->wormno) worm_move(mtmp);
367. teleds(cc.x, cc.y, TRUE);
368. set_apparxy(mtmp);
369. newsym(u.ux,u.uy);
370. } else {
371. pline("%s is killed by a falling %s (you)!",
372. Monnam(mtmp), youmonst.data->mname);
373. killed(mtmp);
374. newsym(u.ux,u.uy);
375. if (mtmp->mhp > 0) return 0;
376. else return 1;
377. }
378. if (youmonst.data->mlet != S_PIERCER)
379. return(0); /* trappers don't attack */
380.
381. obj = which_armor(mtmp, WORN_HELMET);
382. if (obj && is_metallic(obj)) {
383. Your("blow glances off %s helmet.",
384. s_suffix(mon_nam(mtmp)));
385. } else {
386. if (3 + find_mac(mtmp) <= rnd(20)) {
387. pline("%s is hit by a falling piercer (you)!",
388. Monnam(mtmp));
389. if ((mtmp->mhp -= d(3,6)) < 1)
390. killed(mtmp);
391. } else
392. pline("%s is almost hit by a falling piercer (you)!",
393. Monnam(mtmp));
394. }
395. } else {
396. if (!youseeit)
397. pline("It tries to move where you are hiding.");
398. else {
399. /* Ugly kludge for eggs. The message is phrased so as
400. * to be directed at the monster, not the player,
401. * which makes "laid by you" wrong. For the
402. * parallelism to work, we can't rephrase it, so we
403. * zap the "laid by you" momentarily instead.
404. */
405. struct obj *obj = level.objects[u.ux][u.uy];
406.
407. if (obj ||
408. (youmonst.data->mlet == S_EEL && is_pool(u.ux, u.uy))) {
409. int save_spe = 0; /* suppress warning */
410. if (obj) {
411. save_spe = obj->spe;
412. if (obj->otyp == EGG) obj->spe = 0;
413. }
414. if (youmonst.data->mlet == S_EEL)
415. pline("Wait, %s! There's a hidden %s named %s there!",
416. m_monnam(mtmp), youmonst.data->mname, plname);
417. else
418. pline("Wait, %s! There's a %s named %s hiding under %s!",
419. m_monnam(mtmp), youmonst.data->mname, plname,
420. doname(level.objects[u.ux][u.uy]));
421. if (obj) obj->spe = save_spe;
422. } else
423. impossible("hiding under nothing?");
424. }
425. newsym(u.ux,u.uy);
426. }
427. return(0);
428. }
429. if (youmonst.data->mlet == S_MIMIC && youmonst.m_ap_type &&
430. !range2 && foundyou && !u.uswallow) {
431. if (!youseeit) pline("It gets stuck on you.");
432. else pline("Wait, %s! That's a %s named %s!",
433. m_monnam(mtmp), youmonst.data->mname, plname);
434. u.ustuck = mtmp;
435. youmonst.m_ap_type = M_AP_NOTHING;
436. youmonst.mappearance = 0;
437. newsym(u.ux,u.uy);
438. return(0);
439. }
440.
441. /* player might be mimicking an object */
442. if (youmonst.m_ap_type == M_AP_OBJECT && !range2 && foundyou && !u.uswallow) {
443. if (!youseeit)
444. pline("%s %s!", Something,
445. (likes_gold(mtmp->data) && youmonst.mappearance == GOLD_PIECE) ?
446. "tries to pick you up" : "disturbs you");
447. else pline("Wait, %s! That %s is really %s named %s!",
448. m_monnam(mtmp),
449. mimic_obj_name(&youmonst),
450. an(mons[u.umonnum].mname),
451. plname);
452. if (multi < 0) { /* this should always be the case */
453. char buf[BUFSZ];
454. Sprintf(buf, "You appear to be %s again.",
455. Upolyd ? (const char *) an(youmonst.data->mname) :
456. (const char *) "yourself");
457. unmul(buf); /* immediately stop mimicking */
458. }
459. return 0;
460. }
461.
462. /* Work out the armor class differential */
463. tmp = AC_VALUE(u.uac) + 10; /* tmp ~= 0 - 20 */
464. tmp += mtmp->m_lev;
465. if(multi < 0) tmp += 4;
466. if((Invis && !perceives(mdat)) || !mtmp->mcansee)
467. tmp -= 2;
468. if(mtmp->mtrapped) tmp -= 2;
469. if(tmp <= 0) tmp = 1;
470.
471. /* make eels visible the moment they hit/miss us */
472. if(mdat->mlet == S_EEL && mtmp->minvis && cansee(mtmp->mx,mtmp->my)) {
473. mtmp->minvis = 0;
474. newsym(mtmp->mx,mtmp->my);
475. }
476.
477. /* Special demon handling code */
478. if(!mtmp->cham && is_demon(mdat) && !range2
479. && mtmp->data != &mons[PM_BALROG]
480. && mtmp->data != &mons[PM_SUCCUBUS]
481. && mtmp->data != &mons[PM_INCUBUS])
482. if(!mtmp->mcan && !rn2(13)) msummon(mtmp);
483.
484. /* Special lycanthrope handling code */
485. if(!mtmp->cham && is_were(mdat) && !range2) {
486.
487. if(is_human(mdat)) {
488. if(!rn2(5 - (night() * 2)) && !mtmp->mcan) new_were(mtmp);
489. } else if(!rn2(30) && !mtmp->mcan) new_were(mtmp);
490. mdat = mtmp->data;
491.
492. if(!rn2(10) && !mtmp->mcan) {
493. int numseen, numhelp;
494. char buf[BUFSZ], genericwere[BUFSZ];
495.
496. Strcpy(genericwere, "creature");
497. numhelp = were_summon(mdat, FALSE, &numseen, genericwere);
498. if (youseeit) {
499. pline("%s summons help!", Monnam(mtmp));
500. if (numhelp > 0) {
501. if (numseen == 0)
502. You_feel("hemmed in.");
503. } else pline("But none comes.");
504. } else {
505. const char *from_nowhere;
506.
507. if (flags.soundok) {
508. pline("%s %s!", Something,
509. makeplural(growl_sound(mtmp)));
510. from_nowhere = "";
511. } else from_nowhere = " from nowhere";
512. if (numhelp > 0) {
513. if (numseen < 1) You_feel("hemmed in.");
514. else {
515. if (numseen == 1)
516. Sprintf(buf, "%s appears",
517. an(genericwere));
518. else
519. Sprintf(buf, "%s appear",
520. makeplural(genericwere));
521. pline("%s%s!", upstart(buf), from_nowhere);
522. }
523. } /* else no help came; but you didn't know it tried */
524. }
525. }
526. }
527.
528. if(u.uinvulnerable) {
529. /* monsters won't attack you */
530. if(mtmp == u.ustuck)
531. pline("%s loosens its grip slightly.", Monnam(mtmp));
532. else if(!range2) {
533. if (youseeit || sensemon(mtmp))
534. pline("%s starts to attack you, but pulls back.",
535. Monnam(mtmp));
536. else
537. You_feel("%s move nearby.", something);
538. }
539. return (0);
540. }
541.
542. /* Unlike defensive stuff, don't let them use item _and_ attack. */
543. if(find_offensive(mtmp)) {
544. int foo = use_offensive(mtmp);
545.
546. if (foo != 0) return(foo==1);
547. }
548.
549. for(i = 0; i < NATTK; i++) {
550.
551. sum[i] = 0;
552. mattk = getmattk(mdat, i, sum, &alt_attk);
553. if (u.uswallow && (mattk->aatyp != AT_ENGL))
554. continue;
555. switch(mattk->aatyp) {
556. case AT_CLAW: /* "hand to hand" attacks */
557. case AT_KICK:
558. case AT_BITE:
559. case AT_STNG:
560. case AT_TUCH:
561. case AT_BUTT:
562. case AT_TENT:
563. if(!range2 && (!MON_WEP(mtmp) || mtmp->mconf || Conflict ||
564. !touch_petrifies(youmonst.data))) {
565. if (foundyou) {
566. if(tmp > (j = rnd(20+i))) {
567. if (mattk->aatyp != AT_KICK ||
568. !thick_skinned(youmonst.data))
569. sum[i] = hitmu(mtmp, mattk);
570. } else
571. missmu(mtmp, (tmp == j), mattk);
572. } else
573. wildmiss(mtmp, mattk);
574. }
575. break;
576.
577. case AT_HUGS: /* automatic if prev two attacks succeed */
578. /* Note: if displaced, prev attacks never succeeded */
579. if((!range2 && i>=2 && sum[i-1] && sum[i-2])
580. || mtmp == u.ustuck)
581. sum[i]= hitmu(mtmp, mattk);
582. break;
583.
584. case AT_GAZE: /* can affect you either ranged or not */
585. /* Medusa gaze already operated through m_respond in
586. * dochug(); don't gaze more than once per round.
587. */
588. if (mdat != &mons[PM_MEDUSA])
589. sum[i] = gazemu(mtmp, mattk);
590. break;
591.
592. case AT_EXPL: /* automatic hit if next to, and aimed at you */
593. if(!range2) sum[i] = explmu(mtmp, mattk, foundyou);
594. break;
595.
596. case AT_ENGL:
597. if (!range2) {
598. if(foundyou) {
599. if(u.uswallow || tmp > (j = rnd(20+i))) {
600. /* Force swallowing monster to be
601. * displayed even when player is
602. * moving away */
603. flush_screen(1);
604. sum[i] = gulpmu(mtmp, mattk);
605. } else {
606. missmu(mtmp, (tmp == j), mattk);
607. }
608. } else if (is_animal(mtmp->data)) {
609. pline("%s gulps some air!", Monnam(mtmp));
610. } else {
611. if (youseeit)
612. pline("%s lunges forward and recoils!",
613. Monnam(mtmp));
614. else
615. You_hear("a %s nearby.",
616. is_whirly(mtmp->data) ?
617. "rushing noise" : "splat");
618. }
619. }
620. break;
621. case AT_BREA:
622. if(range2) sum[i] = breamu(mtmp, mattk);
623. /* Note: breamu takes care of displacement */
624. break;
625. case AT_SPIT:
626. if(range2) sum[i] = spitmu(mtmp, mattk);
627. /* Note: spitmu takes care of displacement */
628. break;
629. case AT_WEAP:
630. if(range2) {
631. #ifdef REINCARNATION
632. if (!Is_rogue_level(&u.uz))
633. #endif
634. thrwmu(mtmp);
635. } else {
636. int hittmp = 0;
637.
638. /* Rare but not impossible. Normally the monster
639. * wields when 2 spaces away, but it can be
640. * teleported or whatever....
641. */
642. if (mtmp->weapon_check == NEED_WEAPON ||
643. !MON_WEP(mtmp)) {
644. mtmp->weapon_check = NEED_HTH_WEAPON;
645. /* mon_wield_item resets weapon_check as
646. * appropriate */
647. if (mon_wield_item(mtmp) != 0) break;
648. }
649. if (foundyou) {
650. otmp = MON_WEP(mtmp);
651. if(otmp) {
652. hittmp = hitval(otmp, &youmonst);
653. tmp += hittmp;
654. mswings(mtmp, otmp);
655. }
656. if(tmp > (j = dieroll = rnd(20+i)))
657. sum[i] = hitmu(mtmp, mattk);
658. else
659. missmu(mtmp, (tmp == j), mattk);
660. /* KMH -- Don't accumulate to-hit bonuses */
661. if (otmp)
662. tmp -= hittmp;
663. } else
664. wildmiss(mtmp, mattk);
665. }
666. break;
667. case AT_MAGC:
668. if (range2)
669. sum[i] = buzzmu(mtmp, mattk);
670. else {
671. if (foundyou)
672. sum[i] = castmu(mtmp, mattk, TRUE, TRUE);
673. else
674. sum[i] = castmu(mtmp, mattk, TRUE, FALSE);
675. }
676. break;
677.
678. default: /* no attack */
679. break;
680. }
681. if(flags.botl) bot();
682. /* give player a chance of waking up before dying -kaa */
683. if(sum[i] == 1) { /* successful attack */
684. if (u.usleep && u.usleep < monstermoves && !rn2(10)) {
685. multi = -1;
686. nomovemsg = "The combat suddenly awakens you.";
687. }
688. }
689. if(sum[i] == 2) return 1; /* attacker dead */
690. if(sum[i] == 3) break; /* attacker teleported, no more attacks */
691. /* sum[i] == 0: unsuccessful attack */
692. }
693. return(0);
694. }
695.
696. #endif /* OVL0 */
hurtarmor
Edit
697. #ifdef OVLB
698.
699. /*
700. * helper function for some compilers that have trouble with hitmu
701. */
702.
703. STATIC_OVL void
704. hurtarmor(attk)
705. int attk;
706. {
707. int hurt;
708.
709. switch(attk) {
710. /* 0 is burning, which we should never be called with */
711. case AD_RUST: hurt = 1; break;
712. case AD_CORR: hurt = 3; break;
713. default: hurt = 2; break;
714. }
715.
716. /* What the following code does: it keeps looping until it
717. * finds a target for the rust monster.
718. * Head, feet, etc... not covered by metal, or covered by
719. * rusty metal, are not targets. However, your body always
720. * is, no matter what covers it.
721. */
722. while (1) {
723. switch(rn2(5)) {
724. case 0:
725. if (!uarmh || !rust_dmg(uarmh, xname(uarmh), hurt, FALSE, &youmonst))
726. continue;
727. break;
728. case 1:
729. if (uarmc) {
730. (void)rust_dmg(uarmc, xname(uarmc), hurt, TRUE, &youmonst);
731. break;
732. }
733. /* Note the difference between break and continue;
734. * break means it was hit and didn't rust; continue
735. * means it wasn't a target and though it didn't rust
736. * something else did.
737. */
738. if (uarm)
739. (void)rust_dmg(uarm, xname(uarm), hurt, TRUE, &youmonst);
740. #ifdef TOURIST
741. else if (uarmu)
742. (void)rust_dmg(uarmu, xname(uarmu), hurt, TRUE, &youmonst);
743. #endif
744. break;
745. case 2:
746. if (!uarms || !rust_dmg(uarms, xname(uarms), hurt, FALSE, &youmonst))
747. continue;
748. break;
749. case 3:
750. if (!uarmg || !rust_dmg(uarmg, xname(uarmg), hurt, FALSE, &youmonst))
751. continue;
752. break;
753. case 4:
754. if (!uarmf || !rust_dmg(uarmf, xname(uarmf), hurt, FALSE, &youmonst))
755. continue;
756. break;
757. }
758. break; /* Out of while loop */
759. }
760. }
761.
762. #endif /* OVLB */
diseasemu
Edit
763. #ifdef OVL1
764.
765. STATIC_OVL boolean
766. diseasemu(mdat)
767. struct permonst *mdat;
768. {
769. if (Sick_resistance) {
770. You_feel("a slight illness.");
771. return FALSE;
772. } else {
773. make_sick(Sick ? Sick/3L + 1L : (long)rn1(ACURR(A_CON), 20),
774. mdat->mname, TRUE, SICK_NONVOMITABLE);
775. return TRUE;
776. }
777. }
778.
u_slip_free
Edit
779. /* check whether slippery clothing protects from hug or wrap attack */
780. STATIC_OVL boolean
781. u_slip_free(mtmp, mattk)
782. struct monst *mtmp;
783. struct attack *mattk;
784. {
785. struct obj *obj = (uarmc ? uarmc : uarm);
786.
787. #ifdef TOURIST
788. if (!obj) obj = uarmu;
789. #endif
790. if (mattk->adtyp == AD_DRIN) obj = uarmh;
791.
792. /* if your cloak/armor is greased, monster slips off; this
793. protection might fail (33% chance) when the armor is cursed */
794. if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK) &&
795. (!obj->cursed || rn2(3))) {
796. pline("%s %s your %s %s!",
797. Monnam(mtmp),
798. (mattk->adtyp == AD_WRAP) ?
799. "slips off of" : "grabs you, but cannot hold onto",
800. obj->greased ? "greased" : "slippery",
801. /* avoid "slippery slippery cloak"
802. for undiscovered oilskin cloak */
803. (obj->greased || objects[obj->otyp].oc_name_known) ?
804. xname(obj) : cloak_simple_name(obj));
805.
806. if (obj->greased && !rn2(2)) {
807. pline_The("grease wears off.");
808. obj->greased = 0;
809. update_inventory();
810. }
811. return TRUE;
812. }
813. return FALSE;
814. }
815.
magic_negation
Edit
816. /* armor that sufficiently covers the body might be able to block magic */
817. int
818. magic_negation(mon)
819. struct monst *mon;
820. {
821. struct obj *armor;
822. int armpro = 0;
823.
824. armor = (mon == &youmonst) ? uarm : which_armor(mon, W_ARM);
825. if (armor && armpro < objects[armor->otyp].a_can)
826. armpro = objects[armor->otyp].a_can;
827. armor = (mon == &youmonst) ? uarmc : which_armor(mon, W_ARMC);
828. if (armor && armpro < objects[armor->otyp].a_can)
829. armpro = objects[armor->otyp].a_can;
830. armor = (mon == &youmonst) ? uarmh : which_armor(mon, W_ARMH);
831. if (armor && armpro < objects[armor->otyp].a_can)
832. armpro = objects[armor->otyp].a_can;
833.
834. /* armor types for shirt, gloves, shoes, and shield don't currently
835. provide any magic cancellation but we might as well be complete */
836. #ifdef TOURIST
837. armor = (mon == &youmonst) ? uarmu : which_armor(mon, W_ARMU);
838. if (armor && armpro < objects[armor->otyp].a_can)
839. armpro = objects[armor->otyp].a_can;
840. #endif
841. armor = (mon == &youmonst) ? uarmg : which_armor(mon, W_ARMG);
842. if (armor && armpro < objects[armor->otyp].a_can)
843. armpro = objects[armor->otyp].a_can;
844. armor = (mon == &youmonst) ? uarmf : which_armor(mon, W_ARMF);
845. if (armor && armpro < objects[armor->otyp].a_can)
846. armpro = objects[armor->otyp].a_can;
847. armor = (mon == &youmonst) ? uarms : which_armor(mon, W_ARMS);
848. if (armor && armpro < objects[armor->otyp].a_can)
849. armpro = objects[armor->otyp].a_can;
850.
851. #ifdef STEED
852. /* this one is really a stretch... */
853. armor = (mon == &youmonst) ? 0 : which_armor(mon, W_SADDLE);
854. if (armor && armpro < objects[armor->otyp].a_can)
855. armpro = objects[armor->otyp].a_can;
856. #endif
857.
858. return armpro;
859. }
860.
861. /*
862. * hitmu: monster hits you
863. * returns 2 if monster dies (e.g. "yellow light"), 1 otherwise
864. * 3 if the monster lives but teleported/paralyzed, so it can't keep
865. * attacking you
866. */
867. STATIC_OVL int
868. hitmu(mtmp, mattk)
869. register struct monst *mtmp;
870. register struct attack *mattk;
871. {
872. register struct permonst *mdat = mtmp->data;
873. register int uncancelled, ptmp;
874. int dmg, armpro, permdmg;
875. char buf[BUFSZ];
876. struct permonst *olduasmon = youmonst.data;
877. int res;
878.
879. if (!canspotmon(mtmp))
880. map_invisible(mtmp->mx, mtmp->my);
881.
882. /* If the monster is undetected & hits you, you should know where
883. * the attack came from.
884. */
885. if(mtmp->mundetected && (hides_under(mdat) || mdat->mlet == S_EEL)) {
886. mtmp->mundetected = 0;
887. if (!(Blind ? Blind_telepat : Unblind_telepat)) {
888. struct obj *obj;
889. const char *what;
890.
891. if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0) {
892. if (Blind && !obj->dknown)
893. what = something;
894. else if (is_pool(mtmp->mx, mtmp->my) && !Underwater)
895. what = "the water";
896. else
897. what = doname(obj);
898.
899. pline("%s was hidden under %s!", Amonnam(mtmp), what);
900. }
901. newsym(mtmp->mx, mtmp->my);
902. }
903. }
904.
905. /* First determine the base damage done */
906. dmg = d((int)mattk->damn, (int)mattk->damd);
907. if(is_undead(mdat) && midnight())
908. dmg += d((int)mattk->damn, (int)mattk->damd); /* extra damage */
909.
910. /* Next a cancellation factor */
911. /* Use uncancelled when the cancellation factor takes into account certain
912. * armor's special magic protection. Otherwise just use !mtmp->mcan.
913. */
914. armpro = magic_negation(&youmonst);
915. uncancelled = !mtmp->mcan && ((rn2(3) >= armpro) || !rn2(50));
916.
917. permdmg = 0;
918. /* Now, adjust damages via resistances or specific attacks */
919. switch(mattk->adtyp) {
920. case AD_PHYS:
921. if (mattk->aatyp == AT_HUGS && !sticks(youmonst.data)) {
922. if(!u.ustuck && rn2(2)) {
923. if (u_slip_free(mtmp, mattk)) {
924. dmg = 0;
925. } else {
926. u.ustuck = mtmp;
927. pline("%s grabs you!", Monnam(mtmp));
928. }
929. } else if(u.ustuck == mtmp) {
930. exercise(A_STR, FALSE);
931. You("are being %s.",
932. (mtmp->data == &mons[PM_ROPE_GOLEM])
933. ? "choked" : "crushed");
934. }
935. } else { /* hand to hand weapon */
936. if(mattk->aatyp == AT_WEAP && otmp) {
937. if (otmp->otyp == CORPSE
938. && touch_petrifies(&mons[otmp->corpsenm])) {
939. dmg = 1;
940. pline("%s hits you with the %s corpse.",
941. Monnam(mtmp), mons[otmp->corpsenm].mname);
942. if (!Stoned)
943. goto do_stone;
944. }
945. dmg += dmgval(otmp, &youmonst);
946. if (dmg <= 0) dmg = 1;
947. if (!(otmp->oartifact &&
948. artifact_hit(mtmp, &youmonst, otmp, &dmg,dieroll)))
949. hitmsg(mtmp, mattk);
950. if (!dmg) break;
951. if (u.mh > 1 && u.mh > ((u.uac>0) ? dmg : dmg+u.uac) &&
952. objects[otmp->otyp].oc_material == IRON &&
953. (u.umonnum==PM_BLACK_PUDDING
954. || u.umonnum==PM_BROWN_PUDDING)) {
955. /* This redundancy necessary because you have to
956. * take the damage _before_ being cloned.
957. */
958. if (u.uac < 0) dmg += u.uac;
959. if (dmg < 1) dmg = 1;
960. if (dmg > 1) exercise(A_STR, FALSE);
961. u.mh -= dmg;
962. flags.botl = 1;
963. dmg = 0;
964. if(cloneu())
965. You("divide as %s hits you!",mon_nam(mtmp));
966. }
967. urustm(mtmp, otmp);
968. } else if (mattk->aatyp != AT_TUCH || dmg != 0 ||
969. mtmp != u.ustuck)
970. hitmsg(mtmp, mattk);
971. }
972. break;
973. case AD_DISE:
974. hitmsg(mtmp, mattk);
975. if (!diseasemu(mdat)) dmg = 0;
976. break;
977. case AD_FIRE:
978. hitmsg(mtmp, mattk);
979. if (uncancelled) {
980. pline("You're %s!", on_fire(youmonst.data, mattk));
981. if (youmonst.data == &mons[PM_STRAW_GOLEM] ||
982. youmonst.data == &mons[PM_PAPER_GOLEM]) {
983. You("roast!");
984. /* KMH -- this is okay with unchanging */
985. rehumanize();
986. break;
987. } else if (Fire_resistance) {
988. pline_The("fire doesn't feel hot!");
989. dmg = 0;
990. }
991. if((int) mtmp->m_lev > rn2(20))
992. destroy_item(SCROLL_CLASS, AD_FIRE);
993. if((int) mtmp->m_lev > rn2(20))
994. destroy_item(POTION_CLASS, AD_FIRE);
995. if((int) mtmp->m_lev > rn2(25))
996. destroy_item(SPBOOK_CLASS, AD_FIRE);
997. burn_away_slime();
998. } else dmg = 0;
999. break;
1000. case AD_COLD:
1001. hitmsg(mtmp, mattk);
1002. if (uncancelled) {
1003. pline("You're covered in frost!");
1004. if (Cold_resistance) {
1005. pline_The("frost doesn't seem cold!");
1006. dmg = 0;
1007. }
1008. if((int) mtmp->m_lev > rn2(20))
1009. destroy_item(POTION_CLASS, AD_COLD);
1010. } else dmg = 0;
1011. break;
1012. case AD_ELEC:
1013. hitmsg(mtmp, mattk);
1014. if (uncancelled) {
1015. You("get zapped!");
1016. if (Shock_resistance) {
1017. pline_The("zap doesn't shock you!");
1018. dmg = 0;
1019. }
1020. if((int) mtmp->m_lev > rn2(20))
1021. destroy_item(WAND_CLASS, AD_ELEC);
1022. if((int) mtmp->m_lev > rn2(20))
1023. destroy_item(RING_CLASS, AD_ELEC);
1024. } else dmg = 0;
1025. break;
1026. case AD_SLEE:
1027. hitmsg(mtmp, mattk);
1028. if (uncancelled && multi >= 0 && !rn2(5)) {
1029. if (Sleep_resistance) break;
1030. fall_asleep(-rnd(10), TRUE);
1031. if (Blind) You("are put to sleep!");
1032. else You("are put to sleep by %s!", mon_nam(mtmp));
1033. }
1034. break;
1035. case AD_BLND:
1036. if (can_blnd(mtmp, &youmonst, mattk->aatyp, (struct obj*)0)) {
1037. if (!Blind) pline("%s blinds you!", Monnam(mtmp));
1038. make_blinded(Blinded+(long)dmg,FALSE);
1039. if (!Blind) Your(vision_clears);
1040. }
1041. dmg = 0;
1042. break;
1043. case AD_DRST:
1044. ptmp = A_STR;
1045. goto dopois;
1046. case AD_DRDX:
1047. ptmp = A_DEX;
1048. goto dopois;
1049. case AD_DRCO:
1050. ptmp = A_CON;
1051. dopois:
1052. hitmsg(mtmp, mattk);
1053. if (uncancelled && !rn2(8)) {
1054. Sprintf(buf, "%s %s",
1055. s_suffix(Monnam(mtmp)), mpoisons_subj(mtmp, mattk));
1056. poisoned(buf, ptmp, mdat->mname, 30);
1057. }
1058. break;
1059. case AD_DRIN:
1060. hitmsg(mtmp, mattk);
1061. if (defends(AD_DRIN, uwep) || !has_head(youmonst.data)) {
1062. You("don't seem harmed.");
1063. /* Not clear what to do for green slimes */
1064. break;
1065. }
1066. if (u_slip_free(mtmp,mattk)) break;
1067.
1068. if (uarmh && rn2(8)) {
1069. /* not body_part(HEAD) */
1070. Your("helmet blocks the attack to your head.");
1071. break;
1072. }
1073. if (Half_physical_damage) dmg = (dmg+1) / 2;
1074. mdamageu(mtmp, dmg);
1075.
1076. if (!uarmh || uarmh->otyp != DUNCE_CAP) {
1077. Your("brain is eaten!");
1078. /* No such thing as mindless players... */
1079. if (ABASE(A_INT) <= ATTRMIN(A_INT)) {
1080. int lifesaved = 0;
1081. struct obj *wore_amulet = uamul;
1082.
1083. while(1) {
1084. /* avoid looping on "die(y/n)?" */
1085. if (lifesaved && (discover || wizard)) {
1086. if (wore_amulet && !uamul) {
1087. /* used up AMULET_OF_LIFE_SAVING; still
1088. subject to dying from brainlessness */
1089. wore_amulet = 0;
1090. } else {
1091. /* explicitly chose not to die;
1092. arbitrarily boost intelligence */
1093. ABASE(A_INT) = ATTRMIN(A_INT) + 2;
1094. You_feel("like a scarecrow.");
1095. break;
1096. }
1097. }
1098.
1099. if (lifesaved)
1100. pline("Unfortunately your brain is still gone.");
1101. else
1102. Your("last thought fades away.");
1103. killer = "brainlessness";
1104. killer_format = KILLED_BY;
1105. done(DIED);
1106. lifesaved++;
1107. }
1108. }
1109. }
1110. /* adjattrib gives dunce cap message when appropriate */
1111. (void) adjattrib(A_INT, -rnd(2), FALSE);
1112. forget_levels(25); /* lose memory of 25% of levels */
1113. forget_objects(25); /* lose memory of 25% of objects */
1114. exercise(A_WIS, FALSE);
1115. break;
1116. case AD_PLYS:
1117. hitmsg(mtmp, mattk);
1118. if (uncancelled && multi >= 0 && !rn2(3)) {
1119. if (Free_action) {
1120. You("momentarily stiffen.");
1121. } else {
1122. if (Blind) You("are frozen!");
1123. else You("are frozen by %s!", mon_nam(mtmp));
1124. nomovemsg = 0; /* default: "you can move again" */
1125. nomul(-rnd(10));
1126. exercise(A_DEX, FALSE);
1127. }
1128. }
1129. break;
1130. case AD_DRLI:
1131. hitmsg(mtmp, mattk);
1132. if (uncancelled && !rn2(3) && !Drain_resistance) {
1133. losexp("life drainage");
1134. }
1135. break;
1136. case AD_LEGS:
1137. { register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
1138. const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left";
1139.
1140. /* This case is too obvious to ignore, but Nethack is not in
1141. * general very good at considering height--most short monsters
1142. * still _can_ attack you when you're flying or mounted.
1143. * [FIXME: why can't a flying attacker overcome this?]
1144. */
1145. if (
1146. #ifdef STEED
1147. u.usteed ||
1148. #endif
1149. Levitation || Flying) {
1150. pline("%s tries to reach your %s %s!", Monnam(mtmp),
1151. sidestr, body_part(LEG));
1152. dmg = 0;
1153. } else if (mtmp->mcan) {
1154. pline("%s nuzzles against your %s %s!", Monnam(mtmp),
1155. sidestr, body_part(LEG));
1156. dmg = 0;
1157. } else {
1158. if (uarmf) {
1159. if (rn2(2) && (uarmf->otyp == LOW_BOOTS ||
1160. uarmf->otyp == IRON_SHOES))
1161. pline("%s pricks the exposed part of your %s %s!",
1162. Monnam(mtmp), sidestr, body_part(LEG));
1163. else if (!rn2(5))
1164. pline("%s pricks through your %s boot!",
1165. Monnam(mtmp), sidestr);
1166. else {
1167. pline("%s scratches your %s boot!", Monnam(mtmp),
1168. sidestr);
1169. dmg = 0;
1170. break;
1171. }
1172. } else pline("%s pricks your %s %s!", Monnam(mtmp),
1173. sidestr, body_part(LEG));
1174. set_wounded_legs(side, rnd(60-ACURR(A_DEX)));
1175. exercise(A_STR, FALSE);
1176. exercise(A_DEX, FALSE);
1177. }
1178. break;
1179. }
1180. case AD_STON: /* cockatrice */
1181. hitmsg(mtmp, mattk);
1182. if(!rn2(3)) {
1183. if (mtmp->mcan) {
1184. if (flags.soundok)
1185. You_hear("a cough from %s!", mon_nam(mtmp));
1186. } else {
1187. if (flags.soundok)
1188. You_hear("%s hissing!", s_suffix(mon_nam(mtmp)));
1189. if(!rn2(10) ||
1190. (flags.moonphase == NEW_MOON && !have_lizard())) {
1191. do_stone:
1192. if (!Stoned && !Stone_resistance
1193. && !(poly_when_stoned(youmonst.data) &&
1194. polymon(PM_STONE_GOLEM))) {
1195. Stoned = 5;
1196. delayed_killer = mtmp->data->mname;
1197. if (mtmp->data->geno & G_UNIQ) {
1198. if (!type_is_pname(mtmp->data)) {
1199. static char kbuf[BUFSZ];
1200.
1201. /* "the" buffer may be reallocated */
1202. Strcpy(kbuf, the(delayed_killer));
1203. delayed_killer = kbuf;
1204. }
1205. killer_format = KILLED_BY;
1206. } else killer_format = KILLED_BY_AN;
1207. return(1);
1208. /* You("turn to stone..."); */
1209. /* done_in_by(mtmp); */
1210. }
1211. }
1212. }
1213. }
1214. break;
1215. case AD_STCK:
1216. hitmsg(mtmp, mattk);
1217. if (uncancelled && !u.ustuck && !sticks(youmonst.data))
1218. u.ustuck = mtmp;
1219. break;
1220. case AD_WRAP:
1221. if ((!mtmp->mcan || u.ustuck == mtmp) && !sticks(youmonst.data)) {
1222. if (!u.ustuck && !rn2(10)) {
1223. if (u_slip_free(mtmp, mattk)) {
1224. dmg = 0;
1225. } else {
1226. pline("%s swings itself around you!",
1227. Monnam(mtmp));
1228. u.ustuck = mtmp;
1229. }
1230. } else if(u.ustuck == mtmp) {
1231. if (is_pool(mtmp->mx,mtmp->my) && !Swimming
1232. && !Amphibious) {
1233. boolean moat =
1234. (levl[mtmp->mx][mtmp->my].typ != POOL) &&
1235. (levl[mtmp->mx][mtmp->my].typ != WATER) &&
1236. !Is_medusa_level(&u.uz) &&
1237. !Is_waterlevel(&u.uz);
1238.
1239. pline("%s drowns you...", Monnam(mtmp));
1240. killer_format = KILLED_BY_AN;
1241. Sprintf(buf, "%s by %s",
1242. moat ? "moat" : "pool of water",
1243. an(mtmp->data->mname));
1244. killer = buf;
1245. done(DROWNING);
1246. } else if(mattk->aatyp == AT_HUGS)
1247. You("are being crushed.");
1248. } else {
1249. dmg = 0;
1250. if(flags.verbose)
1251. pline("%s brushes against your %s.", Monnam(mtmp),
1252. body_part(LEG));
1253. }
1254. } else dmg = 0;
1255. break;
1256. case AD_WERE:
1257. hitmsg(mtmp, mattk);
1258. if (uncancelled && !rn2(4) && u.ulycn == NON_PM &&
1259. !Protection_from_shape_changers &&
1260. !defends(AD_WERE,uwep)) {
1261. You_feel("feverish.");
1262. exercise(A_CON, FALSE);
1263. u.ulycn = monsndx(mdat);
1264. }
1265. break;
1266. case AD_SGLD:
1267. hitmsg(mtmp, mattk);
1268. if (youmonst.data->mlet == mdat->mlet) break;
1269. if(!mtmp->mcan) stealgold(mtmp);
1270. break;
1271.
1272. case AD_SITM: /* for now these are the same */
1273. case AD_SEDU:
1274. if (is_animal(mtmp->data)) {
1275. hitmsg(mtmp, mattk);
1276. if (mtmp->mcan) break;
1277. /* Continue below */
1278. } else if (dmgtype(youmonst.data, AD_SEDU)
1279. #ifdef SEDUCE
1280. || dmgtype(youmonst.data, AD_SSEX)
1281. #endif
1282. ) {
1283. pline("%s %s.", Monnam(mtmp), mtmp->minvent ?
1284. "brags about the goods some dungeon explorer provided" :
1285. "makes some remarks about how difficult theft is lately");
1286. if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
1287. return 3;
1288. } else if (mtmp->mcan) {
1289. if (!Blind) {
1290. pline("%s tries to %s you, but you seem %s.",
1291. Adjmonnam(mtmp, "plain"),
1292. flags.female ? "charm" : "seduce",
1293. flags.female ? "unaffected" : "uninterested");
1294. }
1295. if(rn2(3)) {
1296. if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
1297. return 3;
1298. }
1299. break;
1300. }
1301. buf[0] = '\0';
1302. switch (steal(mtmp, buf)) {
1303. case -1:
1304. return 2;
1305. case 0:
1306. break;
1307. default:
1308. if (!is_animal(mtmp->data) && !tele_restrict(mtmp))
1309. (void) rloc(mtmp, FALSE);
1310. if (is_animal(mtmp->data) && *buf) {
1311. if (canseemon(mtmp))
1312. pline("%s tries to %s away with %s.",
1313. Monnam(mtmp),
1314. locomotion(mtmp->data, "run"),
1315. buf);
1316. }
1317. monflee(mtmp, 0, FALSE, FALSE);
1318. return 3;
1319. }
1320. break;
1321. #ifdef SEDUCE
1322. case AD_SSEX:
1323. if(could_seduce(mtmp, &youmonst, mattk) == 1
1324. && !mtmp->mcan)
1325. if (doseduce(mtmp))
1326. return 3;
1327. break;
1328. #endif
1329. case AD_SAMU:
1330. hitmsg(mtmp, mattk);
1331. /* when the Wiz hits, 1/20 steals the amulet */
1332. if (u.uhave.amulet ||
1333. u.uhave.bell || u.uhave.book || u.uhave.menorah
1334. || u.uhave.questart) /* carrying the Quest Artifact */
1335. if (!rn2(20)) stealamulet(mtmp);
1336. break;
1337.
1338. case AD_TLPT:
1339. hitmsg(mtmp, mattk);
1340. if (uncancelled) {
1341. if(flags.verbose)
1342. Your("position suddenly seems very uncertain!");
1343. tele();
1344. }
1345. break;
1346. case AD_RUST:
1347. hitmsg(mtmp, mattk);
1348. if (mtmp->mcan) break;
1349. if (u.umonnum == PM_IRON_GOLEM) {
1350. You("rust!");
1351. /* KMH -- this is okay with unchanging */
1352. rehumanize();
1353. break;
1354. }
1355. hurtarmor(AD_RUST);
1356. break;
1357. case AD_CORR:
1358. hitmsg(mtmp, mattk);
1359. if (mtmp->mcan) break;
1360. hurtarmor(AD_CORR);
1361. break;
1362. case AD_DCAY:
1363. hitmsg(mtmp, mattk);
1364. if (mtmp->mcan) break;
1365. if (u.umonnum == PM_WOOD_GOLEM ||
1366. u.umonnum == PM_LEATHER_GOLEM) {
1367. You("rot!");
1368. /* KMH -- this is okay with unchanging */
1369. rehumanize();
1370. break;
1371. }
1372. hurtarmor(AD_DCAY);
1373. break;
1374. case AD_HEAL:
1375. /* a cancelled nurse is just an ordinary monster */
1376. if (mtmp->mcan) {
1377. hitmsg(mtmp, mattk);
1378. break;
1379. }
1380. if(!uwep
1381. #ifdef TOURIST
1382. && !uarmu
1383. #endif
1384. && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) {
1385. boolean goaway = FALSE;
1386. pline("%s hits! (I hope you don't mind.)", Monnam(mtmp));
1387. if (Upolyd) {
1388. u.mh += rnd(7);
1389. if (!rn2(7)) {
1390. /* no upper limit necessary; effect is temporary */
1391. u.mhmax++;
1392. if (!rn2(13)) goaway = TRUE;
1393. }
1394. if (u.mh > u.mhmax) u.mh = u.mhmax;
1395. } else {
1396. u.uhp += rnd(7);
1397. if (!rn2(7)) {
1398. /* hard upper limit via nurse care: 25 * ulevel */
1399. if (u.uhpmax < 5 * u.ulevel + d(2 * u.ulevel, 10))
1400. u.uhpmax++;
1401. if (!rn2(13)) goaway = TRUE;
1402. }
1403. if (u.uhp > u.uhpmax) u.uhp = u.uhpmax;
1404. }
1405. if (!rn2(3)) exercise(A_STR, TRUE);
1406. if (!rn2(3)) exercise(A_CON, TRUE);
1407. if (Sick) make_sick(0L, (char *) 0, FALSE, SICK_ALL);
1408. flags.botl = 1;
1409. if (goaway) {
1410. mongone(mtmp);
1411. return 2;
1412. } else if (!rn2(33)) {
1413. if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
1414. monflee(mtmp, d(3, 6), TRUE, FALSE);
1415. return 3;
1416. }
1417. dmg = 0;
1418. } else {
1419. if (Role_if(PM_HEALER)) {
1420. if (flags.soundok && !(moves % 5))
1421. verbalize("Doc, I can't help you unless you cooperate.");
1422. dmg = 0;
1423. } else hitmsg(mtmp, mattk);
1424. }
1425. break;
1426. case AD_CURS:
1427. hitmsg(mtmp, mattk);
1428. if(!night() && mdat == &mons[PM_GREMLIN]) break;
1429. if(!mtmp->mcan && !rn2(10)) {
1430. if (flags.soundok) {
1431. if (Blind) You_hear("laughter.");
1432. else pline("%s chuckles.", Monnam(mtmp));
1433. }
1434. if (u.umonnum == PM_CLAY_GOLEM) {
1435. pline("Some writing vanishes from your head!");
1436. /* KMH -- this is okay with unchanging */
1437. rehumanize();
1438. break;
1439. }
1440. attrcurse();
1441. }
1442. break;
1443. case AD_STUN:
1444. hitmsg(mtmp, mattk);
1445. if(!mtmp->mcan && !rn2(4)) {
1446. make_stunned(HStun + dmg, TRUE);
1447. dmg /= 2;
1448. }
1449. break;
1450. case AD_ACID:
1451. hitmsg(mtmp, mattk);
1452. if (!mtmp->mcan && !rn2(3))
1453. if (Acid_resistance) {
1454. pline("You're covered in acid, but it seems harmless.");
1455. dmg = 0;
1456. } else {
1457. pline("You're covered in acid! It burns!");
1458. exercise(A_STR, FALSE);
1459. }
1460. else dmg = 0;
1461. break;
1462. case AD_SLOW:
1463. hitmsg(mtmp, mattk);
1464. if (uncancelled && HFast &&
1465. !defends(AD_SLOW, uwep) && !rn2(4))
1466. u_slow_down();
1467. break;
1468. case AD_DREN:
1469. hitmsg(mtmp, mattk);
1470. if (uncancelled && !rn2(4))
1471. drain_en(dmg);
1472. dmg = 0;
1473. break;
1474. case AD_CONF:
1475. hitmsg(mtmp, mattk);
1476. if(!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) {
1477. mtmp->mspec_used = mtmp->mspec_used + (dmg + rn2(6));
1478. if(Confusion)
1479. You("are getting even more confused.");
1480. else You("are getting confused.");
1481. make_confused(HConfusion + dmg, FALSE);
1482. }
1483. dmg = 0;
1484. break;
1485. case AD_DETH:
1486. pline("%s reaches out with its deadly touch.", Monnam(mtmp));
1487. if (is_undead(youmonst.data)) {
1488. /* Still does normal damage */
1489. pline("Was that the touch of death?");
1490. break;
1491. }
1492. switch (rn2(20)) {
1493. case 19: case 18: case 17:
1494. if (!Antimagic) {
1495. killer_format = KILLED_BY_AN;
1496. killer = "touch of death";
1497. done(DIED);
1498. dmg = 0;
1499. break;
1500. } /* else FALLTHRU */
1501. default: /* case 16: ... case 5: */
1502. You_feel("your life force draining away...");
1503. permdmg = 1; /* actual damage done below */
1504. break;
1505. case 4: case 3: case 2: case 1: case 0:
1506. if (Antimagic) shieldeff(u.ux, u.uy);
1507. pline("Lucky for you, it didn't work!");
1508. dmg = 0;
1509. break;
1510. }
1511. break;
1512. case AD_PEST:
1513. pline("%s reaches out, and you feel fever and chills.",
1514. Monnam(mtmp));
1515. (void) diseasemu(mdat); /* plus the normal damage */
1516. break;
1517. case AD_FAMN:
1518. pline("%s reaches out, and your body shrivels.",
1519. Monnam(mtmp));
1520. exercise(A_CON, FALSE);
1521. if (!is_fainted()) morehungry(rn1(40,40));
1522. /* plus the normal damage */
1523. break;
1524. case AD_SLIM:
1525. hitmsg(mtmp, mattk);
1526. if (!uncancelled) break;
1527. if (flaming(youmonst.data)) {
1528. pline_The("slime burns away!");
1529. dmg = 0;
1530. } else if (Unchanging ||
1531. youmonst.data == &mons[PM_GREEN_SLIME]) {
1532. You("are unaffected.");
1533. dmg = 0;
1534. } else if (!Slimed) {
1535. You("don't feel very well.");
1536. Slimed = 10L;
1537. flags.botl = 1;
1538. killer_format = KILLED_BY_AN;
1539. delayed_killer = mtmp->data->mname;
1540. } else
1541. pline("Yuck!");
1542. break;
1543. case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
1544. hitmsg(mtmp, mattk);
1545. /* uncancelled is sufficient enough; please
1546. don't make this attack less frequent */
1547. if (uncancelled) {
1548. struct obj *obj = some_armor(&youmonst);
1549.
1550. if (drain_item(obj)) {
1551. Your("%s less effective.", aobjnam(obj, "seem"));
1552. }
1553. }
1554. break;
1555. default: dmg = 0;
1556. break;
1557. }
1558. if(u.uhp < 1) done_in_by(mtmp);
1559.
1560. /* Negative armor class reduces damage done instead of fully protecting
1561. * against hits.
1562. */
1563. if (dmg && u.uac < 0) {
1564. dmg -= rnd(-u.uac);
1565. if (dmg < 1) dmg = 1;
1566. }
1567.
1568. if(dmg) {
1569. if (Half_physical_damage
1570. /* Mitre of Holiness */
1571. || (Role_if(PM_PRIEST) && uarmh && is_quest_artifact(uarmh) &&
1572. (is_undead(mtmp->data) || is_demon(mtmp->data))))
1573. dmg = (dmg+1) / 2;
1574.
1575. if (permdmg) { /* Death's life force drain */
1576. int lowerlimit, *hpmax_p;
1577. /*
1578. * Apply some of the damage to permanent hit points:
1579. * polymorphed 100% against poly'd hpmax
1580. * hpmax > 25*lvl 100% against normal hpmax
1581. * hpmax > 10*lvl 50..100%
1582. * hpmax > 5*lvl 25..75%
1583. * otherwise 0..50%
1584. * Never reduces hpmax below 1 hit point per level.
1585. */
1586. permdmg = rn2(dmg / 2 + 1);
1587. if (Upolyd || u.uhpmax > 25 * u.ulevel) permdmg = dmg;
1588. else if (u.uhpmax > 10 * u.ulevel) permdmg += dmg / 2;
1589. else if (u.uhpmax > 5 * u.ulevel) permdmg += dmg / 4;
1590.
1591. if (Upolyd) {
1592. hpmax_p = &u.mhmax;
1593. /* [can't use youmonst.m_lev] */
1594. lowerlimit = min((int)youmonst.data->mlevel, u.ulevel);
1595. } else {
1596. hpmax_p = &u.uhpmax;
1597. lowerlimit = u.ulevel;
1598. }
1599. if (*hpmax_p - permdmg > lowerlimit)
1600. *hpmax_p -= permdmg;
1601. else if (*hpmax_p > lowerlimit)
1602. *hpmax_p = lowerlimit;
1603. else /* unlikely... */
1604. ; /* already at or below minimum threshold; do nothing */
1605. flags.botl = 1;
1606. }
1607.
1608. mdamageu(mtmp, dmg);
1609. }
1610.
1611. if (dmg)
1612. res = passiveum(olduasmon, mtmp, mattk);
1613. else
1614. res = 1;
1615. stop_occupation();
1616. return res;
1617. }
1618.
1619. #endif /* OVL1 */
1620. #ifdef OVLB
1621.
1622. STATIC_OVL int
1623. gulpmu(mtmp, mattk) /* monster swallows you, or damage if u.uswallow */
1624. register struct monst *mtmp;
1625. register struct attack *mattk;
1626. {
1627. struct trap *t = t_at(u.ux, u.uy);
1628. int tmp = d((int)mattk->damn, (int)mattk->damd);
1629. int tim_tmp;
1630. register struct obj *otmp2;
1631. int i;
1632.
1633. if (!u.uswallow) { /* swallows you */
1634. if (youmonst.data->msize >= MZ_HUGE) return(0);
1635. if ((t && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))) &&
1636. sobj_at(BOULDER, u.ux, u.uy))
1637. return(0);
1638.
1639. if (Punished) unplacebc(); /* ball&chain go away */
1640. remove_monster(mtmp->mx, mtmp->my);
1641. mtmp->mtrapped = 0; /* no longer on old trap */
1642. place_monster(mtmp, u.ux, u.uy);
1643. u.ustuck = mtmp;
1644. newsym(mtmp->mx,mtmp->my);
1645. #ifdef STEED
1646. if (is_animal(mtmp->data) && u.usteed) {
1647. char buf[BUFSZ];
1648. /* Too many quirks presently if hero and steed
1649. * are swallowed. Pretend purple worms don't
1650. * like horses for now :-)
1651. */
1652. Strcpy(buf, mon_nam(u.usteed));
1653. pline ("%s lunges forward and plucks you off %s!",
1654. Monnam(mtmp), buf);
1655. dismount_steed(DISMOUNT_ENGULFED);
1656. } else
1657. #endif
1658. pline("%s engulfs you!", Monnam(mtmp));
1659. stop_occupation();
1660. reset_occupations(); /* behave as if you had moved */
1661.
1662. if (u.utrap) {
1663. You("are released from the %s!",
1664. u.utraptype==TT_WEB ? "web" : "trap");
1665. u.utrap = 0;
1666. }
1667.
1668. i = number_leashed();
1669. if (i > 0) {
1670. const char *s = (i > 1) ? "leashes" : "leash";
1671. pline_The("%s %s loose.", s, vtense(s, "snap"));
1672. unleash_all();
1673. }
1674.
1675. if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) {
1676. minstapetrify(mtmp, TRUE);
1677. if (mtmp->mhp > 0) return 0;
1678. else return 2;
1679. }
1680.
1681. display_nhwindow(WIN_MESSAGE, FALSE);
1682. vision_recalc(2); /* hero can't see anything */
1683. u.uswallow = 1;
1684. /* u.uswldtim always set > 1 */
1685. tim_tmp = 25 - (int)mtmp->m_lev;
1686. if (tim_tmp > 0) tim_tmp = rnd(tim_tmp) / 2;
1687. else if (tim_tmp < 0) tim_tmp = -(rnd(-tim_tmp) / 2);
1688. tim_tmp += -u.uac + 10;
1689. u.uswldtim = (unsigned)((tim_tmp < 2) ? 2 : tim_tmp);
1690. swallowed(1);
1691. for (otmp2 = invent; otmp2; otmp2 = otmp2->nobj)
1692. (void) snuff_lit(otmp2);
1693. }
1694.
1695. if (mtmp != u.ustuck) return(0);
1696. if (u.uswldtim > 0) u.uswldtim -= 1;
1697.
1698. switch(mattk->adtyp) {
1699.
1700. case AD_DGST:
1701. if (Slow_digestion) {
1702. /* Messages are handled below */
1703. u.uswldtim = 0;
1704. tmp = 0;
1705. } else if (u.uswldtim == 0) {
1706. pline("%s totally digests you!", Monnam(mtmp));
1707. tmp = u.uhp;
1708. if (Half_physical_damage) tmp *= 2; /* sorry */
1709. } else {
1710. pline("%s%s digests you!", Monnam(mtmp),
1711. (u.uswldtim == 2) ? " thoroughly" :
1712. (u.uswldtim == 1) ? " utterly" : "");
1713. exercise(A_STR, FALSE);
1714. }
1715. break;
1716. case AD_PHYS:
1717. if (mtmp->data == &mons[PM_FOG_CLOUD]) {
1718. You("are laden with moisture and %s",
1719. flaming(youmonst.data) ? "are smoldering out!" :
1720. Breathless ? "find it mildly uncomfortable." :
1721. amphibious(youmonst.data) ? "feel comforted." :
1722. "can barely breathe!");
1723. /* NB: Amphibious includes Breathless */
1724. if (Amphibious && !flaming(youmonst.data)) tmp = 0;
1725. } else {
1726. You("are pummeled with debris!");
1727. exercise(A_STR, FALSE);
1728. }
1729. break;
1730. case AD_ACID:
1731. if (Acid_resistance) {
1732. You("are covered with a seemingly harmless goo.");
1733. tmp = 0;
1734. } else {
1735. if (Hallucination) pline("Ouch! You've been slimed!");
1736. else You("are covered in slime! It burns!");
1737. exercise(A_STR, FALSE);
1738. }
1739. break;
1740. case AD_BLND:
1741. if (can_blnd(mtmp, &youmonst, mattk->aatyp, (struct obj*)0)) {
1742. if(!Blind) {
1743. You_cant("see in here!");
1744. make_blinded((long)tmp,FALSE);
1745. if (!Blind) Your(vision_clears);
1746. } else
1747. /* keep him blind until disgorged */
1748. make_blinded(Blinded+1,FALSE);
1749. }
1750. tmp = 0;
1751. break;
1752. case AD_ELEC:
1753. if(!mtmp->mcan && rn2(2)) {
1754. pline_The("air around you crackles with electricity.");
1755. if (Shock_resistance) {
1756. shieldeff(u.ux, u.uy);
1757. You("seem unhurt.");
1758. ugolemeffects(AD_ELEC,tmp);
1759. tmp = 0;
1760. }
1761. } else tmp = 0;
1762. break;
1763. case AD_COLD:
1764. if(!mtmp->mcan && rn2(2)) {
1765. if (Cold_resistance) {
1766. shieldeff(u.ux, u.uy);
1767. You_feel("mildly chilly.");
1768. ugolemeffects(AD_COLD,tmp);
1769. tmp = 0;
1770. } else You("are freezing to death!");
1771. } else tmp = 0;
1772. break;
1773. case AD_FIRE:
1774. if(!mtmp->mcan && rn2(2)) {
1775. if (Fire_resistance) {
1776. shieldeff(u.ux, u.uy);
1777. You_feel("mildly hot.");
1778. ugolemeffects(AD_FIRE,tmp);
1779. tmp = 0;
1780. } else You("are burning to a crisp!");
1781. burn_away_slime();
1782. } else tmp = 0;
1783. break;
1784. case AD_DISE:
1785. if (!diseasemu(mtmp->data)) tmp = 0;
1786. break;
1787. default:
1788. tmp = 0;
1789. break;
1790. }
1791.
1792. if (Half_physical_damage) tmp = (tmp+1) / 2;
1793.
1794. mdamageu(mtmp, tmp);
1795. if (tmp) stop_occupation();
1796.
1797. if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) {
1798. pline("%s very hurriedly %s you!", Monnam(mtmp),
1799. is_animal(mtmp->data)? "regurgitates" : "expels");
1800. expels(mtmp, mtmp->data, FALSE);
1801. } else if (!u.uswldtim || youmonst.data->msize >= MZ_HUGE) {
1802. You("get %s!", is_animal(mtmp->data)? "regurgitated" : "expelled");
1803. if (flags.verbose && (is_animal(mtmp->data) ||
1804. (dmgtype(mtmp->data, AD_DGST) && Slow_digestion)))
1805. pline("Obviously %s doesn't like your taste.", mon_nam(mtmp));
1806. expels(mtmp, mtmp->data, FALSE);
1807. }
1808. return(1);
1809. }
1810.
1811. STATIC_OVL int
1812. explmu(mtmp, mattk, ufound) /* monster explodes in your face */
1813. register struct monst *mtmp;
1814. register struct attack *mattk;
1815. boolean ufound;
1816. {
1817. if (mtmp->mcan) return(0);
1818.
1819. if (!ufound)
1820. pline("%s explodes at a spot in %s!",
1821. canseemon(mtmp) ? Monnam(mtmp) : "It",
1822. levl[mtmp->mux][mtmp->muy].typ == WATER
1823. ? "empty water" : "thin air");
1824. else {
1825. register int tmp = d((int)mattk->damn, (int)mattk->damd);
1826. register boolean not_affected = defends((int)mattk->adtyp, uwep);
1827.
1828. hitmsg(mtmp, mattk);
1829.
1830. switch (mattk->adtyp) {
1831. case AD_COLD:
1832. not_affected |= Cold_resistance;
1833. goto common;
1834. case AD_FIRE:
1835. not_affected |= Fire_resistance;
1836. goto common;
1837. case AD_ELEC:
1838. not_affected |= Shock_resistance;
1839. common:
1840.
1841. if (!not_affected) {
1842. if (ACURR(A_DEX) > rnd(20)) {
1843. You("duck some of the blast.");
1844. tmp = (tmp+1) / 2;
1845. } else {
1846. if (flags.verbose) You("get blasted!");
1847. }
1848. if (mattk->adtyp == AD_FIRE) burn_away_slime();
1849. if (Half_physical_damage) tmp = (tmp+1) / 2;
1850. mdamageu(mtmp, tmp);
1851. }
1852. break;
1853.
1854. case AD_BLND:
1855. not_affected = resists_blnd(&youmonst);
1856. if (!not_affected) {
1857. /* sometimes you're affected even if it's invisible */
1858. if (mon_visible(mtmp) || (rnd(tmp /= 2) > u.ulevel)) {
1859. You("are blinded by a blast of light!");
1860. make_blinded((long)tmp, FALSE);
1861. if (!Blind) Your(vision_clears);
1862. } else if (flags.verbose)
1863. You("get the impression it was not terribly bright.");
1864. }
1865. break;
1866.
1867. case AD_HALU:
1868. not_affected |= Blind ||
1869. (u.umonnum == PM_BLACK_LIGHT ||
1870. u.umonnum == PM_VIOLET_FUNGUS ||
1871. dmgtype(youmonst.data, AD_STUN));
1872. if (!not_affected) {
1873. boolean chg;
1874. if (!Hallucination)
1875. You("are caught in a blast of kaleidoscopic light!");
1876. chg = make_hallucinated(HHallucination + (long)tmp,FALSE,0L);
1877. You("%s.", chg ? "are freaked out" : "seem unaffected");
1878. }
1879. break;
1880.
1881. default:
1882. break;
1883. }
1884. if (not_affected) {
1885. You("seem unaffected by it.");
1886. ugolemeffects((int)mattk->adtyp, tmp);
1887. }
1888. }
1889. mondead(mtmp);
1890. wake_nearto(mtmp->mx, mtmp->my, 7*7);
1891. if (mtmp->mhp > 0) return(0);
1892. return(2); /* it dies */
1893. }
1894.
1895. int
1896. gazemu(mtmp, mattk) /* monster gazes at you */
1897. register struct monst *mtmp;
1898. register struct attack *mattk;
1899. {
1900. switch(mattk->adtyp) {
1901. case AD_STON:
1902. if (mtmp->mcan || !mtmp->mcansee) {
1903. if (!canseemon(mtmp)) break; /* silently */
1904. pline("%s %s.", Monnam(mtmp),
1905. (mtmp->data == &mons[PM_MEDUSA] && mtmp->mcan) ?
1906. "doesn't look all that ugly" :
1907. "gazes ineffectually");
1908. break;
1909. }
1910. if (Reflecting && couldsee(mtmp->mx, mtmp->my) &&
1911. mtmp->data == &mons[PM_MEDUSA]) {
1912. /* hero has line of sight to Medusa and she's not blind */
1913. boolean useeit = canseemon(mtmp);
1914.
1915. if (useeit)
1916. (void) ureflects("%s gaze is reflected by your %s.",
1917. s_suffix(Monnam(mtmp)));
1918. if (mon_reflects(mtmp, !useeit ? (char *)0 :
1919. "The gaze is reflected away by %s %s!"))
1920. break;
1921. if (!m_canseeu(mtmp)) { /* probably you're invisible */
1922. if (useeit)
1923. pline(
1924. "%s doesn't seem to notice that %s gaze was reflected.",
1925. Monnam(mtmp), mhis(mtmp));
1926. break;
1927. }
1928. if (useeit)
1929. pline("%s is turned to stone!", Monnam(mtmp));
1930. stoned = TRUE;
1931. killed(mtmp);
1932.
1933. if (mtmp->mhp > 0) break;
1934. return 2;
1935. }
1936. if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) &&
1937. !Stone_resistance) {
1938. You("meet %s gaze.", s_suffix(mon_nam(mtmp)));
1939. stop_occupation();
1940. if(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
1941. break;
1942. You("turn to stone...");
1943. killer_format = KILLED_BY;
1944. killer = mtmp->data->mname;
1945. done(STONING);
1946. }
1947. break;
1948. case AD_CONF:
1949. if(!mtmp->mcan && canseemon(mtmp) &&
1950. couldsee(mtmp->mx, mtmp->my) &&
1951. mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
1952. int conf = d(3,4);
1953.
1954. mtmp->mspec_used = mtmp->mspec_used + (conf + rn2(6));
1955. if(!Confusion)
1956. pline("%s gaze confuses you!",
1957. s_suffix(Monnam(mtmp)));
1958. else
1959. You("are getting more and more confused.");
1960. make_confused(HConfusion + conf, FALSE);
1961. stop_occupation();
1962. }
1963. break;
1964. case AD_STUN:
1965. if(!mtmp->mcan && canseemon(mtmp) &&
1966. couldsee(mtmp->mx, mtmp->my) &&
1967. mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
1968. int stun = d(2,6);
1969.
1970. mtmp->mspec_used = mtmp->mspec_used + (stun + rn2(6));
1971. pline("%s stares piercingly at you!", Monnam(mtmp));
1972. make_stunned(HStun + stun, TRUE);
1973. stop_occupation();
1974. }
1975. break;
1976. case AD_BLND:
1977. if (!mtmp->mcan && canseemon(mtmp) && !resists_blnd(&youmonst)
1978. && distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) {
1979. int blnd = d((int)mattk->damn, (int)mattk->damd);
1980.
1981. You("are blinded by %s radiance!",
1982. s_suffix(mon_nam(mtmp)));
1983. make_blinded((long)blnd,FALSE);
1984. stop_occupation();
1985. /* not blind at this point implies you're wearing
1986. the Eyes of the Overworld; make them block this
1987. particular stun attack too */
1988. if (!Blind) Your(vision_clears);
1989. else make_stunned((long)d(1,3),TRUE);
1990. }
1991. break;
1992. case AD_FIRE:
1993. if (!mtmp->mcan && canseemon(mtmp) &&
1994. couldsee(mtmp->mx, mtmp->my) &&
1995. mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
1996. int dmg = d(2,6);
1997.
1998. pline("%s attacks you with a fiery gaze!", Monnam(mtmp));
1999. stop_occupation();
2000. if (Fire_resistance) {
2001. pline_The("fire doesn't feel hot!");
2002. dmg = 0;
2003. }
2004. burn_away_slime();
2005. if ((int) mtmp->m_lev > rn2(20))
2006. destroy_item(SCROLL_CLASS, AD_FIRE);
2007. if ((int) mtmp->m_lev > rn2(20))
2008. destroy_item(POTION_CLASS, AD_FIRE);
2009. if ((int) mtmp->m_lev > rn2(25))
2010. destroy_item(SPBOOK_CLASS, AD_FIRE);
2011. if (dmg) mdamageu(mtmp, dmg);
2012. }
2013. break;
2014. #ifdef PM_BEHOLDER /* work in progress */
2015. case AD_SLEE:
2016. if(!mtmp->mcan && canseemon(mtmp) &&
2017. couldsee(mtmp->mx, mtmp->my) && mtmp->mcansee &&
2018. multi >= 0 && !rn2(5) && !Sleep_resistance) {
2019.
2020. fall_asleep(-rnd(10), TRUE);
2021. pline("%s gaze makes you very sleepy...",
2022. s_suffix(Monnam(mtmp)));
2023. }
2024. break;
2025. case AD_SLOW:
2026. if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee &&
2027. (HFast & (INTRINSIC|TIMEOUT)) &&
2028. !defends(AD_SLOW, uwep) && !rn2(4))
2029.
2030. u_slow_down();
2031. stop_occupation();
2032. break;
2033. #endif
2034. default: impossible("Gaze attack %d?", mattk->adtyp);
2035. break;
2036. }
2037. return(0);
2038. }
2039.
2040. #endif /* OVLB */
mdamageu
Edit
2041. #ifdef OVL1
2042.
2043. void
2044. mdamageu(mtmp, n) /* mtmp hits you for n points damage */
2045. register struct monst *mtmp;
2046. register int n;
2047. {
2048. flags.botl = 1;
2049. if (Upolyd) {
2050. u.mh -= n;
2051. if (u.mh < 1) rehumanize();
2052. } else {
2053. u.uhp -= n;
2054. if(u.uhp < 1) done_in_by(mtmp);
2055. }
2056. }
2057.
2058. #endif /* OVL1 */
2059. #ifdef OVLB
2060.
2061. STATIC_OVL void
2062. urustm(mon, obj)
2063. register struct monst *mon;
2064. register struct obj *obj;
2065. {
2066. boolean vis;
2067. boolean is_acid;
2068.
2069. if (!mon || !obj) return; /* just in case */
2070. if (dmgtype(youmonst.data, AD_CORR))
2071. is_acid = TRUE;
2072. else if (dmgtype(youmonst.data, AD_RUST))
2073. is_acid = FALSE;
2074. else
2075. return;
2076.
2077. vis = cansee(mon->mx, mon->my);
2078.
2079. if ((is_acid ? is_corrodeable(obj) : is_rustprone(obj)) &&
2080. (is_acid ? obj->oeroded2 : obj->oeroded) < MAX_ERODE) {
2081. if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) {
2082. if (vis)
2083. pline("Somehow, %s weapon is not affected.",
2084. s_suffix(mon_nam(mon)));
2085. if (obj->greased && !rn2(2)) obj->greased = 0;
2086. } else {
2087. if (vis)
2088. pline("%s %s%s!",
2089. s_suffix(Monnam(mon)),
2090. aobjnam(obj, (is_acid ? "corrode" : "rust")),
2091. (is_acid ? obj->oeroded2 : obj->oeroded)
2092. ? " further" : "");
2093. if (is_acid) obj->oeroded2++;
2094. else obj->oeroded++;
2095. }
2096. }
2097. }
2098.
2099. #endif /* OVLB */
could_seduce
Edit
2100. #ifdef OVL1
2101.
2102. int
2103. could_seduce(magr,mdef,mattk)
2104. struct monst *magr, *mdef;
2105. struct attack *mattk;
2106. /* returns 0 if seduction impossible,
2107. * 1 if fine,
2108. * 2 if wrong gender for nymph */
2109. {
2110. register struct permonst *pagr;
2111. boolean agrinvis, defperc;
2112. xchar genagr, gendef;
2113.
2114. if (is_animal(magr->data)) return (0);
2115. if(magr == &youmonst) {
2116. pagr = youmonst.data;
2117. agrinvis = (Invis != 0);
2118. genagr = poly_gender();
2119. } else {
2120. pagr = magr->data;
2121. agrinvis = magr->minvis;
2122. genagr = gender(magr);
2123. }
2124. if(mdef == &youmonst) {
2125. defperc = (See_invisible != 0);
2126. gendef = poly_gender();
2127. } else {
2128. defperc = perceives(mdef->data);
2129. gendef = gender(mdef);
2130. }
2131.
2132. if(agrinvis && !defperc
2133. #ifdef SEDUCE
2134. && mattk && mattk->adtyp != AD_SSEX
2135. #endif
2136. )
2137. return 0;
2138.
2139. if(pagr->mlet != S_NYMPH
2140. && ((pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS])
2141. #ifdef SEDUCE
2142. || (mattk && mattk->adtyp != AD_SSEX)
2143. #endif
2144. ))
2145. return 0;
2146.
2147. if(genagr == 1 - gendef)
2148. return 1;
2149. else
2150. return (pagr->mlet == S_NYMPH) ? 2 : 0;
2151. }
2152.
2153. #endif /* OVL1 */
doseduce
Edit
2154. #ifdef OVLB
2155.
2156. #ifdef SEDUCE
2157. /* Returns 1 if monster teleported */
2158. int
2159. doseduce(mon)
2160. register struct monst *mon;
2161. {
2162. register struct obj *ring, *nring;
2163. boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */
2164. char qbuf[QBUFSZ];
2165.
2166. if (mon->mcan || mon->mspec_used) {
2167. pline("%s acts as though %s has got a %sheadache.",
2168. Monnam(mon), mhe(mon),
2169. mon->mcan ? "severe " : "");
2170. return 0;
2171. }
2172.
2173. if (unconscious()) {
2174. pline("%s seems dismayed at your lack of response.",
2175. Monnam(mon));
2176. return 0;
2177. }
2178.
2179. if (Blind) pline("It caresses you...");
2180. else You_feel("very attracted to %s.", mon_nam(mon));
2181.
2182. for(ring = invent; ring; ring = nring) {
2183. nring = ring->nobj;
2184. if (ring->otyp != RIN_ADORNMENT) continue;
2185. if (fem) {
2186. if (rn2(20) < ACURR(A_CHA)) {
2187. Sprintf(qbuf, "\"That %s looks pretty. May I have it?\"",
2188. safe_qbuf("",sizeof("\"That looks pretty. May I have it?\""),
2189. xname(ring), simple_typename(ring->otyp), "ring"));
2190. makeknown(RIN_ADORNMENT);
2191. if (yn(qbuf) == 'n') continue;
2192. } else pline("%s decides she'd like your %s, and takes it.",
2193. Blind ? "She" : Monnam(mon), xname(ring));
2194. makeknown(RIN_ADORNMENT);
2195. if (ring==uleft || ring==uright) Ring_gone(ring);
2196. if (ring==uwep) setuwep((struct obj *)0);
2197. if (ring==uswapwep) setuswapwep((struct obj *)0);
2198. if (ring==uquiver) setuqwep((struct obj *)0);
2199. freeinv(ring);
2200. (void) mpickobj(mon,ring);
2201. } else {
2202. char buf[BUFSZ];
2203.
2204. if (uleft && uright && uleft->otyp == RIN_ADORNMENT
2205. && uright->otyp==RIN_ADORNMENT)
2206. break;
2207. if (ring==uleft || ring==uright) continue;
2208. if (rn2(20) < ACURR(A_CHA)) {
2209. Sprintf(qbuf,"\"That %s looks pretty. Would you wear it for me?\"",
2210. safe_qbuf("",
2211. sizeof("\"That looks pretty. Would you wear it for me?\""),
2212. xname(ring), simple_typename(ring->otyp), "ring"));
2213. makeknown(RIN_ADORNMENT);
2214. if (yn(qbuf) == 'n') continue;
2215. } else {
2216. pline("%s decides you'd look prettier wearing your %s,",
2217. Blind ? "He" : Monnam(mon), xname(ring));
2218. pline("and puts it on your finger.");
2219. }
2220. makeknown(RIN_ADORNMENT);
2221. if (!uright) {
2222. pline("%s puts %s on your right %s.",
2223. Blind ? "He" : Monnam(mon), the(xname(ring)), body_part(HAND));
2224. setworn(ring, RIGHT_RING);
2225. } else if (!uleft) {
2226. pline("%s puts %s on your left %s.",
2227. Blind ? "He" : Monnam(mon), the(xname(ring)), body_part(HAND));
2228. setworn(ring, LEFT_RING);
2229. } else if (uright && uright->otyp != RIN_ADORNMENT) {
2230. Strcpy(buf, xname(uright));
2231. pline("%s replaces your %s with your %s.",
2232. Blind ? "He" : Monnam(mon), buf, xname(ring));
2233. Ring_gone(uright);
2234. setworn(ring, RIGHT_RING);
2235. } else if (uleft && uleft->otyp != RIN_ADORNMENT) {
2236. Strcpy(buf, xname(uleft));
2237. pline("%s replaces your %s with your %s.",
2238. Blind ? "He" : Monnam(mon), buf, xname(ring));
2239. Ring_gone(uleft);
2240. setworn(ring, LEFT_RING);
2241. } else impossible("ring replacement");
2242. Ring_on(ring);
2243. prinv((char *)0, ring, 0L);
2244. }
2245. }
2246.
2247. if (!uarmc && !uarmf && !uarmg && !uarms && !uarmh
2248. #ifdef TOURIST
2249. && !uarmu
2250. #endif
2251. )
2252. pline("%s murmurs sweet nothings into your ear.",
2253. Blind ? (fem ? "She" : "He") : Monnam(mon));
2254. else
2255. pline("%s murmurs in your ear, while helping you undress.",
2256. Blind ? (fem ? "She" : "He") : Monnam(mon));
2257. mayberem(uarmc, cloak_simple_name(uarmc));
2258. if(!uarmc)
2259. mayberem(uarm, "suit");
2260. mayberem(uarmf, "boots");
2261. if(!uwep || !welded(uwep))
2262. mayberem(uarmg, "gloves");
2263. mayberem(uarms, "shield");
2264. mayberem(uarmh, "helmet");
2265. #ifdef TOURIST
2266. if(!uarmc && !uarm)
2267. mayberem(uarmu, "shirt");
2268. #endif
2269.
2270. if (uarm || uarmc) {
2271. verbalize("You're such a %s; I wish...",
2272. flags.female ? "sweet lady" : "nice guy");
2273. if (!tele_restrict(mon)) (void) rloc(mon, FALSE);
2274. return 1;
2275. }
2276. if (u.ualign.type == A_CHAOTIC)
2277. adjalign(1);
2278.
2279. /* by this point you have discovered mon's identity, blind or not... */
2280. pline("Time stands still while you and %s lie in each other's arms...",
2281. noit_mon_nam(mon));
2282. if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT)) {
2283. /* Don't bother with mspec_used here... it didn't get tired! */
2284. pline("%s seems to have enjoyed it more than you...",
2285. noit_Monnam(mon));
2286. switch (rn2(5)) {
2287. case 0: You_feel("drained of energy.");
2288. u.uen = 0;
2289. u.uenmax -= rnd(Half_physical_damage ? 5 : 10);
2290. exercise(A_CON, FALSE);
2291. if (u.uenmax < 0) u.uenmax = 0;
2292. break;
2293. case 1: You("are down in the dumps.");
2294. (void) adjattrib(A_CON, -1, TRUE);
2295. exercise(A_CON, FALSE);
2296. flags.botl = 1;
2297. break;
2298. case 2: Your("senses are dulled.");
2299. (void) adjattrib(A_WIS, -1, TRUE);
2300. exercise(A_WIS, FALSE);
2301. flags.botl = 1;
2302. break;
2303. case 3:
2304. if (!resists_drli(&youmonst)) {
2305. You_feel("out of shape.");
2306. losexp("overexertion");
2307. } else {
2308. You("have a curious feeling...");
2309. }
2310. break;
2311. case 4: {
2312. int tmp;
2313. You_feel("exhausted.");
2314. exercise(A_STR, FALSE);
2315. tmp = rn1(10, 6);
2316. if(Half_physical_damage) tmp = (tmp+1) / 2;
2317. losehp(tmp, "exhaustion", KILLED_BY);
2318. break;
2319. }
2320. }
2321. } else {
2322. mon->mspec_used = rnd(100); /* monster is worn out */
2323. You("seem to have enjoyed it more than %s...",
2324. noit_mon_nam(mon));
2325. switch (rn2(5)) {
2326. case 0: You_feel("raised to your full potential.");
2327. exercise(A_CON, TRUE);
2328. u.uen = (u.uenmax += rnd(5));
2329. break;
2330. case 1: You_feel("good enough to do it again.");
2331. (void) adjattrib(A_CON, 1, TRUE);
2332. exercise(A_CON, TRUE);
2333. flags.botl = 1;
2334. break;
2335. case 2: You("will always remember %s...", noit_mon_nam(mon));
2336. (void) adjattrib(A_WIS, 1, TRUE);
2337. exercise(A_WIS, TRUE);
2338. flags.botl = 1;
2339. break;
2340. case 3: pline("That was a very educational experience.");
2341. pluslvl(FALSE);
2342. exercise(A_WIS, TRUE);
2343. break;
2344. case 4: You_feel("restored to health!");
2345. u.uhp = u.uhpmax;
2346. if (Upolyd) u.mh = u.mhmax;
2347. exercise(A_STR, TRUE);
2348. flags.botl = 1;
2349. break;
2350. }
2351. }
2352.
2353. if (mon->mtame) /* don't charge */ ;
2354. else if (rn2(20) < ACURR(A_CHA)) {
2355. pline("%s demands that you pay %s, but you refuse...",
2356. noit_Monnam(mon),
2357. Blind ? (fem ? "her" : "him") : mhim(mon));
2358. } else if (u.umonnum == PM_LEPRECHAUN)
2359. pline("%s tries to take your money, but fails...",
2360. noit_Monnam(mon));
2361. else {
2362. #ifndef GOLDOBJ
2363. long cost;
2364.
2365. if (u.ugold > (long)LARGEST_INT - 10L)
2366. cost = (long) rnd(LARGEST_INT) + 500L;
2367. else
2368. cost = (long) rnd((int)u.ugold + 10) + 500L;
2369. if (mon->mpeaceful) {
2370. cost /= 5L;
2371. if (!cost) cost = 1L;
2372. }
2373. if (cost > u.ugold) cost = u.ugold;
2374. if (!cost) verbalize("It's on the house!");
2375. else {
2376. pline("%s takes %ld %s for services rendered!",
2377. noit_Monnam(mon), cost, currency(cost));
2378. u.ugold -= cost;
2379. mon->mgold += cost;
2380. flags.botl = 1;
2381. }
2382. #else
2383. long cost;
2384. long umoney = money_cnt(invent);
2385.
2386. if (umoney > (long)LARGEST_INT - 10L)
2387. cost = (long) rnd(LARGEST_INT) + 500L;
2388. else
2389. cost = (long) rnd((int)umoney + 10) + 500L;
2390. if (mon->mpeaceful) {
2391. cost /= 5L;
2392. if (!cost) cost = 1L;
2393. }
2394. if (cost > umoney) cost = umoney;
2395. if (!cost) verbalize("It's on the house!");
2396. else {
2397. pline("%s takes %ld %s for services rendered!",
2398. noit_Monnam(mon), cost, currency(cost));
2399. money2mon(mon, cost);
2400. flags.botl = 1;
2401. }
2402. #endif
2403. }
2404. if (!rn2(25)) mon->mcan = 1; /* monster is worn out */
2405. if (!tele_restrict(mon)) (void) rloc(mon, FALSE);
2406. return 1;
2407. }
2408.
mayberem
Edit
2409. STATIC_OVL void
2410. mayberem(obj, str)
2411. register struct obj *obj;
2412. const char *str;
2413. {
2414. char qbuf[QBUFSZ];
2415.
2416. if (!obj || !obj->owornmask) return;
2417.
2418. if (rn2(20) < ACURR(A_CHA)) {
2419. Sprintf(qbuf,"\"Shall I remove your %s, %s?\"",
2420. str,
2421. (!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart"));
2422. if (yn(qbuf) == 'n') return;
2423. } else {
2424. char hairbuf[BUFSZ];
2425.
2426. Sprintf(hairbuf, "let me run my fingers through your %s",
2427. body_part(HAIR));
2428. verbalize("Take off your %s; %s.", str,
2429. (obj == uarm) ? "let's get a little closer" :
2430. (obj == uarmc || obj == uarms) ? "it's in the way" :
2431. (obj == uarmf) ? "let me rub your feet" :
2432. (obj == uarmg) ? "they're too clumsy" :
2433. #ifdef TOURIST
2434. (obj == uarmu) ? "let me massage you" :
2435. #endif
2436. /* obj == uarmh */
2437. hairbuf);
2438. }
2439. remove_worn_item(obj, TRUE);
2440. }
2441. #endif /* SEDUCE */
2442.
2443. #endif /* OVLB */
2444.
passiveum
Edit
2445. #ifdef OVL1
2446.
2447. STATIC_OVL int
2448. passiveum(olduasmon,mtmp,mattk)
2449. struct permonst *olduasmon;
2450. register struct monst *mtmp;
2451. register struct attack *mattk;
2452. {
2453. int i, tmp;
2454.
2455. for (i = 0; ; i++) {
2456. if (i >= NATTK) return 1;
2457. if (olduasmon->mattk[i].aatyp == AT_NONE ||
2458. olduasmon->mattk[i].aatyp == AT_BOOM) break;
2459. }
2460. if (olduasmon->mattk[i].damn)
2461. tmp = d((int)olduasmon->mattk[i].damn,
2462. (int)olduasmon->mattk[i].damd);
2463. else if(olduasmon->mattk[i].damd)
2464. tmp = d((int)olduasmon->mlevel+1, (int)olduasmon->mattk[i].damd);
2465. else
2466. tmp = 0;
2467.
2468. /* These affect the enemy even if you were "killed" (rehumanized) */
2469. switch(olduasmon->mattk[i].adtyp) {
2470. case AD_ACID:
2471. if (!rn2(2)) {
2472. pline("%s is splashed by your acid!", Monnam(mtmp));
2473. if (resists_acid(mtmp)) {
2474. pline("%s is not affected.", Monnam(mtmp));
2475. tmp = 0;
2476. }
2477. } else tmp = 0;
2478. if (!rn2(30)) erode_armor(mtmp, TRUE);
2479. if (!rn2(6)) erode_obj(MON_WEP(mtmp), TRUE, TRUE);
2480. goto assess_dmg;
2481. case AD_STON: /* cockatrice */
2482. {
2483. long protector = attk_protection((int)mattk->aatyp),
2484. wornitems = mtmp->misc_worn_check;
2485.
2486. /* wielded weapon gives same protection as gloves here */
2487. if (MON_WEP(mtmp) != 0) wornitems |= W_ARMG;
2488.
2489. if (!resists_ston(mtmp) && (protector == 0L ||
2490. (protector != ~0L &&
2491. (wornitems & protector) != protector))) {
2492. if (poly_when_stoned(mtmp->data)) {
2493. mon_to_stone(mtmp);
2494. return (1);
2495. }
2496. pline("%s turns to stone!", Monnam(mtmp));
2497. stoned = 1;
2498. xkilled(mtmp, 0);
2499. if (mtmp->mhp > 0) return 1;
2500. return 2;
2501. }
2502. return 1;
2503. }
2504. case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
2505. if (otmp) {
2506. (void) drain_item(otmp);
2507. /* No message */
2508. }
2509. return (1);
2510. default:
2511. break;
2512. }
2513. if (!Upolyd) return 1;
2514.
2515. /* These affect the enemy only if you are still a monster */
2516. if (rn2(3)) switch(youmonst.data->mattk[i].adtyp) {
2517. case AD_PHYS:
2518. if (youmonst.data->mattk[i].aatyp == AT_BOOM) {
2519. You("explode!");
2520. /* KMH, balance patch -- this is okay with unchanging */
2521. rehumanize();
2522. goto assess_dmg;
2523. }
2524. break;
2525. case AD_PLYS: /* Floating eye */
2526. if (tmp > 127) tmp = 127;
2527. if (u.umonnum == PM_FLOATING_EYE) {
2528. if (!rn2(4)) tmp = 127;
2529. if (mtmp->mcansee && haseyes(mtmp->data) && rn2(3) &&
2530. (perceives(mtmp->data) || !Invis)) {
2531. if (Blind)
2532. pline("As a blind %s, you cannot defend yourself.",
2533. youmonst.data->mname);
2534. else {
2535. if (mon_reflects(mtmp,
2536. "Your gaze is reflected by %s %s."))
2537. return 1;
2538. pline("%s is frozen by your gaze!", Monnam(mtmp));
2539. mtmp->mcanmove = 0;
2540. mtmp->mfrozen = tmp;
2541. return 3;
2542. }
2543. }
2544. } else { /* gelatinous cube */
2545. pline("%s is frozen by you.", Monnam(mtmp));
2546. mtmp->mcanmove = 0;
2547. mtmp->mfrozen = tmp;
2548. return 3;
2549. }
2550. return 1;
2551. case AD_COLD: /* Brown mold or blue jelly */
2552. if (resists_cold(mtmp)) {
2553. shieldeff(mtmp->mx, mtmp->my);
2554. pline("%s is mildly chilly.", Monnam(mtmp));
2555. golemeffects(mtmp, AD_COLD, tmp);
2556. tmp = 0;
2557. break;
2558. }
2559. pline("%s is suddenly very cold!", Monnam(mtmp));
2560. u.mh += tmp / 2;
2561. if (u.mhmax < u.mh) u.mhmax = u.mh;
2562. if (u.mhmax > ((youmonst.data->mlevel+1) * 8))
2563. (void)split_mon(&youmonst, mtmp);
2564. break;
2565. case AD_STUN: /* Yellow mold */
2566. if (!mtmp->mstun) {
2567. mtmp->mstun = 1;
2568. pline("%s %s.", Monnam(mtmp),
2569. makeplural(stagger(mtmp->data, "stagger")));
2570. }
2571. tmp = 0;
2572. break;
2573. case AD_FIRE: /* Red mold */
2574. if (resists_fire(mtmp)) {
2575. shieldeff(mtmp->mx, mtmp->my);
2576. pline("%s is mildly warm.", Monnam(mtmp));
2577. golemeffects(mtmp, AD_FIRE, tmp);
2578. tmp = 0;
2579. break;
2580. }
2581. pline("%s is suddenly very hot!", Monnam(mtmp));
2582. break;
2583. case AD_ELEC:
2584. if (resists_elec(mtmp)) {
2585. shieldeff(mtmp->mx, mtmp->my);
2586. pline("%s is slightly tingled.", Monnam(mtmp));
2587. golemeffects(mtmp, AD_ELEC, tmp);
2588. tmp = 0;
2589. break;
2590. }
2591. pline("%s is jolted with your electricity!", Monnam(mtmp));
2592. break;
2593. default: tmp = 0;
2594. break;
2595. }
2596. else tmp = 0;
2597.
2598. assess_dmg:
2599. if((mtmp->mhp -= tmp) <= 0) {
2600. pline("%s dies!", Monnam(mtmp));
2601. xkilled(mtmp,0);
2602. if (mtmp->mhp > 0) return 1;
2603. return 2;
2604. }
2605. return 1;
2606. }
2607.
2608. #endif /* OVL1 */
2609. #ifdef OVLB
2610.
2611. #include "edog.h"
2612. struct monst *
2613. cloneu()
2614. {
2615. register struct monst *mon;
2616. int mndx = monsndx(youmonst.data);
2617.
2618. if (u.mh <= 1) return(struct monst *)0;
2619. if (mvitals[mndx].mvflags & G_EXTINCT) return(struct monst *)0;
2620. mon = makemon(youmonst.data, u.ux, u.uy, NO_MINVENT|MM_EDOG);
2621. mon = christen_monst(mon, plname);
2622. initedog(mon);
2623. mon->m_lev = youmonst.data->mlevel;
2624. mon->mhpmax = u.mhmax;
2625. mon->mhp = u.mh / 2;
2626. u.mh -= mon->mhp;
2627. flags.botl = 1;
2628. return(mon);
2629. }
2630.
2631. #endif /* OVLB */
2632.
2633. /*mhitu.c*/