Below is the full text to src/mhitm.c from NetHack 3.4.3. To link to a particular line, write [[mhitm.c#line123]], for example.
Top of file
Edit
1. /* SCCS Id: @(#)mhitm.c 3.4 2003/01/02 */
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. #include "edog.h"
8.
9. extern boolean notonhead;
10.
11. #ifdef OVLB
12.
13. static NEARDATA boolean vis, far_noise;
14. static NEARDATA long noisetime;
15. static NEARDATA struct obj *otmp;
16.
17. static const char brief_feeling[] =
18. "have a %s feeling for a moment, then it passes.";
19.
20. STATIC_DCL char *FDECL(mon_nam_too, (char *,struct monst *,struct monst *));
21. STATIC_DCL void FDECL(mrustm, (struct monst *, struct monst *, struct obj *));
22. STATIC_DCL int FDECL(hitmm, (struct monst *,struct monst *,struct attack *));
23. STATIC_DCL int FDECL(gazemm, (struct monst *,struct monst *,struct attack *));
24. STATIC_DCL int FDECL(gulpmm, (struct monst *,struct monst *,struct attack *));
25. STATIC_DCL int FDECL(explmm, (struct monst *,struct monst *,struct attack *));
26. STATIC_DCL int FDECL(mdamagem, (struct monst *,struct monst *,struct attack *));
27. STATIC_DCL void FDECL(mswingsm, (struct monst *, struct monst *, struct obj *));
28. STATIC_DCL void FDECL(noises,(struct monst *,struct attack *));
29. STATIC_DCL void FDECL(missmm,(struct monst *,struct monst *,struct attack *));
30. STATIC_DCL int FDECL(passivemm, (struct monst *, struct monst *, BOOLEAN_P, int));
31.
32. /* Needed for the special case of monsters wielding vorpal blades (rare).
33. * If we use this a lot it should probably be a parameter to mdamagem()
34. * instead of a global variable.
35. */
36. static int dieroll;
37.
mon_name_too
Edit
38. /* returns mon_nam(mon) relative to other_mon; normal name unless they're
39. the same, in which case the reference is to {him|her|it} self */
40. STATIC_OVL char *
41. mon_nam_too(outbuf, mon, other_mon)
42. char *outbuf;
43. struct monst *mon, *other_mon;
44. {
45. Strcpy(outbuf, mon_nam(mon));
46. if (mon == other_mon)
47. switch (pronoun_gender(mon)) {
48. case 0: Strcpy(outbuf, "himself"); break;
49. case 1: Strcpy(outbuf, "herself"); break;
50. default: Strcpy(outbuf, "itself"); break;
51. }
52. return outbuf;
53. }
54.
55. STATIC_OVL void
56. noises(magr, mattk)
57. register struct monst *magr;
58. register struct attack *mattk;
59. {
60. boolean farq = (distu(magr->mx, magr->my) > 15);
61.
62. if(flags.soundok && (farq != far_noise || moves-noisetime > 10)) {
63. far_noise = farq;
64. noisetime = moves;
65. You_hear("%s%s.",
66. (mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises",
67. farq ? " in the distance" : "");
68. }
69. }
70.
71. STATIC_OVL
72. void
73. missmm(magr, mdef, mattk)
74. register struct monst *magr, *mdef;
75. struct attack *mattk;
76. {
77. const char *fmt;
78. char buf[BUFSZ], mdef_name[BUFSZ];
79.
80. if (vis) {
81. if (!canspotmon(magr))
82. map_invisible(magr->mx, magr->my);
83. if (!canspotmon(mdef))
84. map_invisible(mdef->mx, mdef->my);
85. if (mdef->m_ap_type) seemimic(mdef);
86. if (magr->m_ap_type) seemimic(magr);
87. fmt = (could_seduce(magr,mdef,mattk) && !magr->mcan) ?
88. "%s pretends to be friendly to" : "%s misses";
89. Sprintf(buf, fmt, Monnam(magr));
90. pline("%s %s.", buf, mon_nam_too(mdef_name, mdef, magr));
91. } else noises(magr, mattk);
92. }
93.
94. /*
95. * fightm() -- fight some other monster
96. *
97. * Returns:
98. * 0 - Monster did nothing.
99. * 1 - If the monster made an attack. The monster might have died.
100. *
101. * There is an exception to the above. If mtmp has the hero swallowed,
102. * then we report that the monster did nothing so it will continue to
103. * digest the hero.
104. */
105. int
106. fightm(mtmp) /* have monsters fight each other */
107. register struct monst *mtmp;
108. {
109. register struct monst *mon, *nmon;
110. int result, has_u_swallowed;
111. #ifdef LINT
112. nmon = 0;
113. #endif
114. /* perhaps the monster will resist Conflict */
115. if(resist(mtmp, RING_CLASS, 0, 0))
116. return(0);
117.
118. if(u.ustuck == mtmp) {
119. /* perhaps we're holding it... */
120. if(itsstuck(mtmp))
121. return(0);
122. }
123. has_u_swallowed = (u.uswallow && (mtmp == u.ustuck));
124.
125. for(mon = fmon; mon; mon = nmon) {
126. nmon = mon->nmon;
127. if(nmon == mtmp) nmon = mtmp->nmon;
128. /* Be careful to ignore monsters that are already dead, since we
129. * might be calling this before we've cleaned them up. This can
130. * happen if the monster attacked a cockatrice bare-handedly, for
131. * instance.
132. */
133. if(mon != mtmp && !DEADMONSTER(mon)) {
134. if(monnear(mtmp,mon->mx,mon->my)) {
135. if(!u.uswallow && (mtmp == u.ustuck)) {
136. if(!rn2(4)) {
137. pline("%s releases you!", Monnam(mtmp));
138. u.ustuck = 0;
139. } else
140. break;
141. }
142.
143. /* mtmp can be killed */
144. bhitpos.x = mon->mx;
145. bhitpos.y = mon->my;
146. notonhead = 0;
147. result = mattackm(mtmp,mon);
148.
149. if (result & MM_AGR_DIED) return 1; /* mtmp died */
150. /*
151. * If mtmp has the hero swallowed, lie and say there
152. * was no attack (this allows mtmp to digest the hero).
153. */
154. if (has_u_swallowed) return 0;
155.
156. /* Allow attacked monsters a chance to hit back. Primarily
157. * to allow monsters that resist conflict to respond.
158. */
159. if ((result & MM_HIT) && !(result & MM_DEF_DIED) &&
160. rn2(4) && mon->movement >= NORMAL_SPEED) {
161. mon->movement -= NORMAL_SPEED;
162. notonhead = 0;
163. (void) mattackm(mon, mtmp); /* return attack */
164. }
165.
166. return ((result & MM_HIT) ? 1 : 0);
167. }
168. }
169. }
170. return 0;
171. }
172.
mattackm
Edit
173. /*
174. * mattackm() -- a monster attacks another monster.
175. *
176. * This function returns a result bitfield:
177. *
178. * --------- aggressor died
179. * / ------- defender died
180. * / / ----- defender was hit
181. * / / /
182. * x x x
183. *
184. * 0x4 MM_AGR_DIED
185. * 0x2 MM_DEF_DIED
186. * 0x1 MM_HIT
187. * 0x0 MM_MISS
188. *
189. * Each successive attack has a lower probability of hitting. Some rely on the
190. * success of previous attacks. ** this doen't seem to be implemented -dl **
191. *
192. * In the case of exploding monsters, the monster dies as well.
193. */
194. int
195. mattackm(magr, mdef)
196. register struct monst *magr,*mdef;
197. {
198. int i, /* loop counter */
199. tmp, /* amour class difference */
200. strike, /* hit this attack */
201. attk, /* attack attempted this time */
202. struck = 0, /* hit at least once */
203. res[NATTK]; /* results of all attacks */
204. struct attack *mattk, alt_attk;
205. struct permonst *pa, *pd;
206.
207. if (!magr || !mdef) return(MM_MISS); /* mike@genat */
208. if (!magr->mcanmove || magr->msleeping) return(MM_MISS);
209. pa = magr->data; pd = mdef->data;
210.
211. /* Grid bugs cannot attack at an angle. */
212. if (pa == &mons[PM_GRID_BUG] && magr->mx != mdef->mx
213. && magr->my != mdef->my)
214. return(MM_MISS);
215.
216. /* Calculate the armour class differential. */
217. tmp = find_mac(mdef) + magr->m_lev;
218. if (mdef->mconf || !mdef->mcanmove || mdef->msleeping) {
219. tmp += 4;
220. mdef->msleeping = 0;
221. }
222.
223. /* undetect monsters become un-hidden if they are attacked */
224. if (mdef->mundetected) {
225. mdef->mundetected = 0;
226. newsym(mdef->mx, mdef->my);
227. if(canseemon(mdef) && !sensemon(mdef)) {
228. if (u.usleep) You("dream of %s.",
229. (mdef->data->geno & G_UNIQ) ?
230. a_monnam(mdef) : makeplural(m_monnam(mdef)));
231. else pline("Suddenly, you notice %s.", a_monnam(mdef));
232. }
233. }
234.
235. /* Elves hate orcs. */
236. if (is_elf(pa) && is_orc(pd)) tmp++;
237.
238.
239. /* Set up the visibility of action */
240. vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my) && (canspotmon(magr) || canspotmon(mdef)));
241.
242. /* Set flag indicating monster has moved this turn. Necessary since a
243. * monster might get an attack out of sequence (i.e. before its move) in
244. * some cases, in which case this still counts as its move for the round
245. * and it shouldn't move again.
246. */
247. magr->mlstmv = monstermoves;
248.
249. /* Now perform all attacks for the monster. */
250. for (i = 0; i < NATTK; i++) {
251. res[i] = MM_MISS;
252. mattk = getmattk(pa, i, res, &alt_attk);
253. otmp = (struct obj *)0;
254. attk = 1;
255. switch (mattk->aatyp) {
256. case AT_WEAP: /* "hand to hand" attacks */
257. if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) {
258. magr->weapon_check = NEED_HTH_WEAPON;
259. if (mon_wield_item(magr) != 0) return 0;
260. }
261. possibly_unwield(magr, FALSE);
262. otmp = MON_WEP(magr);
263.
264. if (otmp) {
265. if (vis) mswingsm(magr, mdef, otmp);
266. tmp += hitval(otmp, mdef);
267. }
268. /* fall through */
269. case AT_CLAW:
270. case AT_KICK:
271. case AT_BITE:
272. case AT_STNG:
273. case AT_TUCH:
274. case AT_BUTT:
275. case AT_TENT:
276. /* Nymph that teleported away on first attack? */
277. if (distmin(magr->mx,magr->my,mdef->mx,mdef->my) > 1)
278. return MM_MISS;
279. /* Monsters won't attack cockatrices physically if they
280. * have a weapon instead. This instinct doesn't work for
281. * players, or under conflict or confusion.
282. */
283. if (!magr->mconf && !Conflict && otmp &&
284. mattk->aatyp != AT_WEAP && touch_petrifies(mdef->data)) {
285. strike = 0;
286. break;
287. }
288. dieroll = rnd(20 + i);
289. strike = (tmp > dieroll);
290. /* KMH -- don't accumulate to-hit bonuses */
291. if (otmp)
292. tmp -= hitval(otmp, mdef);
293. if (strike) {
294. res[i] = hitmm(magr, mdef, mattk);
295. if((mdef->data == &mons[PM_BLACK_PUDDING] || mdef->data == &mons[PM_BROWN_PUDDING])
296. && otmp && objects[otmp->otyp].oc_material == IRON
297. && mdef->mhp > 1 && !mdef->mcan)
298. {
299. if (clone_mon(mdef, 0, 0)) {
300. if (vis) {
301. char buf[BUFSZ];
302.
303. Strcpy(buf, Monnam(mdef));
304. pline("%s divides as %s hits it!", buf, mon_nam(magr));
305. }
306. }
307. }
308. } else
309. missmm(magr, mdef, mattk);
310. break;
311.
312. case AT_HUGS: /* automatic if prev two attacks succeed */
313. strike = (i >= 2 && res[i-1] == MM_HIT && res[i-2] == MM_HIT);
314. if (strike)
315. res[i] = hitmm(magr, mdef, mattk);
316.
317. break;
318.
319. case AT_GAZE:
320. strike = 0; /* will not wake up a sleeper */
321. res[i] = gazemm(magr, mdef, mattk);
322. break;
323.
324. case AT_EXPL:
325. res[i] = explmm(magr, mdef, mattk);
326. if (res[i] == MM_MISS) { /* cancelled--no attack */
327. strike = 0;
328. attk = 0;
329. } else
330. strike = 1; /* automatic hit */
331. break;
332.
333. case AT_ENGL:
334. #ifdef STEED
335. if (u.usteed && (mdef == u.usteed)) {
336. strike = 0;
337. break;
338. }
339. #endif
340. /* Engulfing attacks are directed at the hero if
341. * possible. -dlc
342. */
343. if (u.uswallow && magr == u.ustuck)
344. strike = 0;
345. else {
346. if ((strike = (tmp > rnd(20+i))))
347. res[i] = gulpmm(magr, mdef, mattk);
348. else
349. missmm(magr, mdef, mattk);
350. }
351. break;
352.
353. default: /* no attack */
354. strike = 0;
355. attk = 0;
356. break;
357. }
358.
359. if (attk && !(res[i] & MM_AGR_DIED))
360. res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED);
361.
362. if (res[i] & MM_DEF_DIED) return res[i];
363.
364. /*
365. * Wake up the defender. NOTE: this must follow the check
366. * to see if the defender died. We don't want to modify
367. * unallocated monsters!
368. */
369. if (strike) mdef->msleeping = 0;
370.
371. if (res[i] & MM_AGR_DIED) return res[i];
372. /* return if aggressor can no longer attack */
373. if (!magr->mcanmove || magr->msleeping) return res[i];
374. if (res[i] & MM_HIT) struck = 1; /* at least one hit */
375. }
376.
377. return(struck ? MM_HIT : MM_MISS);
378. }
379.
380. /* Returns the result of mdamagem(). */
381. STATIC_OVL int
382. hitmm(magr, mdef, mattk)
383. register struct monst *magr,*mdef;
384. struct attack *mattk;
385. {
386. if(vis){
387. int compat;
388. char buf[BUFSZ], mdef_name[BUFSZ];
389.
390. if (!canspotmon(magr))
391. map_invisible(magr->mx, magr->my);
392. if (!canspotmon(mdef))
393. map_invisible(mdef->mx, mdef->my);
394. if(mdef->m_ap_type) seemimic(mdef);
395. if(magr->m_ap_type) seemimic(magr);
396. if((compat = could_seduce(magr,mdef,mattk)) && !magr->mcan) {
397. Sprintf(buf, "%s %s", Monnam(magr),
398. mdef->mcansee ? "smiles at" : "talks to");
399. pline("%s %s %s.", buf, mon_nam(mdef),
400. compat == 2 ?
401. "engagingly" : "seductively");
402. } else {
403. char magr_name[BUFSZ];
404.
405. Strcpy(magr_name, Monnam(magr));
406. switch (mattk->aatyp) {
407. case AT_BITE:
408. Sprintf(buf,"%s bites", magr_name);
409. break;
410. case AT_STNG:
411. Sprintf(buf,"%s stings", magr_name);
412. break;
413. case AT_BUTT:
414. Sprintf(buf,"%s butts", magr_name);
415. break;
416. case AT_TUCH:
417. Sprintf(buf,"%s touches", magr_name);
418. break;
419. case AT_TENT:
420. Sprintf(buf, "%s tentacles suck",
421. s_suffix(magr_name));
422. break;
423. case AT_HUGS:
424. if (magr != u.ustuck) {
425. Sprintf(buf,"%s squeezes", magr_name);
426. break;
427. }
428. default:
429. Sprintf(buf,"%s hits", magr_name);
430. }
431. pline("%s %s.", buf, mon_nam_too(mdef_name, mdef, magr));
432. }
433. } else noises(magr, mattk);
434. return(mdamagem(magr, mdef, mattk));
435. }
436.
437. /* Returns the same values as mdamagem(). */
438. STATIC_OVL int
439. gazemm(magr, mdef, mattk)
440. register struct monst *magr, *mdef;
441. struct attack *mattk;
442. {
443. char buf[BUFSZ];
444.
445. if(vis) {
446. Sprintf(buf,"%s gazes at", Monnam(magr));
447. pline("%s %s...", buf, mon_nam(mdef));
448. }
449.
450. if (magr->mcan || !magr->mcansee ||
451. (magr->minvis && !perceives(mdef->data)) ||
452. !mdef->mcansee || mdef->msleeping) {
453. if(vis) pline("but nothing happens.");
454. return(MM_MISS);
455. }
456. /* call mon_reflects 2x, first test, then, if visible, print message */
457. if (magr->data == &mons[PM_MEDUSA] && mon_reflects(mdef, (char *)0)) {
458. if (canseemon(mdef))
459. (void) mon_reflects(mdef,
460. "The gaze is reflected away by %s %s.");
461. if (mdef->mcansee) {
462. if (mon_reflects(magr, (char *)0)) {
463. if (canseemon(magr))
464. (void) mon_reflects(magr,
465. "The gaze is reflected away by %s %s.");
466. return (MM_MISS);
467. }
468. if (mdef->minvis && !perceives(magr->data)) {
469. if (canseemon(magr)) {
470. pline("%s doesn't seem to notice that %s gaze was reflected.",
471. Monnam(magr), mhis(magr));
472. }
473. return (MM_MISS);
474. }
475. if (canseemon(magr))
476. pline("%s is turned to stone!", Monnam(magr));
477. monstone(magr);
478. if (magr->mhp > 0) return (MM_MISS);
479. return (MM_AGR_DIED);
480. }
481. }
482.
483. return(mdamagem(magr, mdef, mattk));
484. }
485.
486. /* Returns the same values as mattackm(). */
487. STATIC_OVL int
488. gulpmm(magr, mdef, mattk)
489. register struct monst *magr, *mdef;
490. register struct attack *mattk;
491. {
492. xchar ax, ay, dx, dy;
493. int status;
494. char buf[BUFSZ];
495. struct obj *obj;
496.
497. if (mdef->data->msize >= MZ_HUGE) return MM_MISS;
498.
499. if (vis) {
500. Sprintf(buf,"%s swallows", Monnam(magr));
501. pline("%s %s.", buf, mon_nam(mdef));
502. }
503. for (obj = mdef->minvent; obj; obj = obj->nobj)
504. (void) snuff_lit(obj);
505.
506. /*
507. * All of this maniuplation is needed to keep the display correct.
508. * There is a flush at the next pline().
509. */
510. ax = magr->mx;
511. ay = magr->my;
512. dx = mdef->mx;
513. dy = mdef->my;
514. /*
515. * Leave the defender in the monster chain at it's current position,
516. * but don't leave it on the screen. Move the agressor to the def-
517. * ender's position.
518. */
519. remove_monster(ax, ay);
520. place_monster(magr, dx, dy);
521. newsym(ax,ay); /* erase old position */
522. newsym(dx,dy); /* update new position */
523.
524. status = mdamagem(magr, mdef, mattk);
525.
526. if ((status & MM_AGR_DIED) && (status & MM_DEF_DIED)) {
527. ; /* both died -- do nothing */
528. }
529. else if (status & MM_DEF_DIED) { /* defender died */
530. /*
531. * Note: remove_monster() was called in relmon(), wiping out
532. * magr from level.monsters[mdef->mx][mdef->my]. We need to
533. * put it back and display it. -kd
534. */
535. place_monster(magr, dx, dy);
536. newsym(dx, dy);
537. }
538. else if (status & MM_AGR_DIED) { /* agressor died */
539. place_monster(mdef, dx, dy);
540. newsym(dx, dy);
541. }
542. else { /* both alive, put them back */
543. if (cansee(dx, dy))
544. pline("%s is regurgitated!", Monnam(mdef));
545.
546. place_monster(magr, ax, ay);
547. place_monster(mdef, dx, dy);
548. newsym(ax, ay);
549. newsym(dx, dy);
550. }
551.
552. return status;
553. }
554.
555. STATIC_OVL int
556. explmm(magr, mdef, mattk)
557. register struct monst *magr, *mdef;
558. register struct attack *mattk;
559. {
560. int result;
561.
562. if (magr->mcan)
563. return MM_MISS;
564.
565. if(cansee(magr->mx, magr->my))
566. pline("%s explodes!", Monnam(magr));
567. else noises(magr, mattk);
568.
569. result = mdamagem(magr, mdef, mattk);
570.
571. /* Kill off agressor if it didn't die. */
572. if (!(result & MM_AGR_DIED)) {
573. mondead(magr);
574. if (magr->mhp > 0) return result; /* life saved */
575. result |= MM_AGR_DIED;
576. }
577. if (magr->mtame) /* give this one even if it was visible */
578. You(brief_feeling, "melancholy");
579.
580. return result;
581. }
582.
mdamagem
Edit
583. /*
584. * See comment at top of mattackm(), for return values.
585. */
586. STATIC_OVL int
587. mdamagem(magr, mdef, mattk)
588. register struct monst *magr, *mdef;
589. register struct attack *mattk;
590. {
591. struct obj *obj;
592. char buf[BUFSZ];
593. struct permonst *pa = magr->data, *pd = mdef->data;
594. int armpro, num, tmp = d((int)mattk->damn, (int)mattk->damd);
595. boolean cancelled;
596.
597. if (touch_petrifies(pd) && !resists_ston(magr)) {
598. long protector = attk_protection((int)mattk->aatyp),
599. wornitems = magr->misc_worn_check;
600.
601. /* wielded weapon gives same protection as gloves here */
602. if (otmp != 0) wornitems |= W_ARMG;
603.
604. if (protector == 0L ||
605. (protector != ~0L && (wornitems & protector) != protector)) {
606. if (poly_when_stoned(pa)) {
607. mon_to_stone(magr);
608. return MM_HIT; /* no damage during the polymorph */
609. }
610. if (vis) pline("%s turns to stone!", Monnam(magr));
611. monstone(magr);
612. if (magr->mhp > 0) return 0;
613. else if (magr->mtame && !vis)
614. You(brief_feeling, "peculiarly sad");
615. return MM_AGR_DIED;
616. }
617. }
618.
619. /* cancellation factor is the same as when attacking the hero */
620. armpro = magic_negation(mdef);
621. cancelled = magr->mcan || !((rn2(3) >= armpro) || !rn2(50));
622.
623. switch(mattk->adtyp) {
624. case AD_DGST:
625. /* eating a Rider or its corpse is fatal */
626. if (is_rider(mdef->data)) {
627. if (vis)
628. pline("%s %s!", Monnam(magr),
629. mdef->data == &mons[PM_FAMINE] ?
630. "belches feebly, shrivels up and dies" :
631. mdef->data == &mons[PM_PESTILENCE] ?
632. "coughs spasmodically and collapses" :
633. "vomits violently and drops dead");
634. mondied(magr);
635. if (magr->mhp > 0) return 0; /* lifesaved */
636. else if (magr->mtame && !vis)
637. You(brief_feeling, "queasy");
638. return MM_AGR_DIED;
639. }
640. if(flags.verbose && flags.soundok) verbalize("Burrrrp!");
641. tmp = mdef->mhp;
642. /* Use up amulet of life saving */
643. if (!!(obj = mlifesaver(mdef))) m_useup(mdef, obj);
644.
645. /* Is a corpse for nutrition possible? It may kill magr */
646. if (!corpse_chance(mdef, magr, TRUE) || magr->mhp < 1)
647. break;
648.
649. /* Pets get nutrition from swallowing monster whole.
650. * No nutrition from G_NOCORPSE monster, eg, undead.
651. * DGST monsters don't die from undead corpses
652. */
653. num = monsndx(mdef->data);
654. if (magr->mtame && !magr->isminion &&
655. !(mvitals[num].mvflags & G_NOCORPSE)) {
656. struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE);
657. int nutrit;
658.
659. virtualcorpse->corpsenm = num;
660. virtualcorpse->owt = weight(virtualcorpse);
661. nutrit = dog_nutrition(magr, virtualcorpse);
662. dealloc_obj(virtualcorpse);
663.
664. /* only 50% nutrition, 25% of normal eating time */
665. if (magr->meating > 1) magr->meating = (magr->meating+3)/4;
666. if (nutrit > 1) nutrit /= 2;
667. EDOG(magr)->hungrytime += nutrit;
668. }
669. break;
670. case AD_STUN:
671. if (magr->mcan) break;
672. if (canseemon(mdef))
673. pline("%s %s for a moment.", Monnam(mdef),
674. makeplural(stagger(mdef->data, "stagger")));
675. mdef->mstun = 1;
676. goto physical;
677. case AD_LEGS:
678. if (magr->mcan) {
679. tmp = 0;
680. break;
681. }
682. goto physical;
683. case AD_WERE:
684. case AD_HEAL:
685. case AD_PHYS:
686. physical:
687. if (mattk->aatyp == AT_KICK && thick_skinned(pd)) {
688. tmp = 0;
689. } else if(mattk->aatyp == AT_WEAP) {
690. if(otmp) {
691. if (otmp->otyp == CORPSE &&
692. touch_petrifies(&mons[otmp->corpsenm]))
693. goto do_stone;
694. tmp += dmgval(otmp, mdef);
695. if (otmp->oartifact) {
696. (void)artifact_hit(magr,mdef, otmp, &tmp, dieroll);
697. if (mdef->mhp <= 0)
698. return (MM_DEF_DIED |
699. (grow_up(magr,mdef) ? 0 : MM_AGR_DIED));
700. }
701. if (tmp)
702. mrustm(magr, mdef, otmp);
703. }
704. } else if (magr->data == &mons[PM_PURPLE_WORM] &&
705. mdef->data == &mons[PM_SHRIEKER]) {
706. /* hack to enhance mm_aggression(); we don't want purple
707. worm's bite attack to kill a shrieker because then it
708. won't swallow the corpse; but if the target survives,
709. the subsequent engulf attack should accomplish that */
710. if (tmp >= mdef->mhp) tmp = mdef->mhp - 1;
711. }
712. break;
713. case AD_FIRE:
714. if (cancelled) {
715. tmp = 0;
716. break;
717. }
718. if (vis)
719. pline("%s is %s!", Monnam(mdef),
720. on_fire(mdef->data, mattk));
721. if (pd == &mons[PM_STRAW_GOLEM] ||
722. pd == &mons[PM_PAPER_GOLEM]) {
723. if (vis) pline("%s burns completely!", Monnam(mdef));
724. mondied(mdef);
725. if (mdef->mhp > 0) return 0;
726. else if (mdef->mtame && !vis)
727. pline("May %s roast in peace.", mon_nam(mdef));
728. return (MM_DEF_DIED | (grow_up(magr,mdef) ?
729. 0 : MM_AGR_DIED));
730. }
731. tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
732. tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
733. if (resists_fire(mdef)) {
734. if (vis)
735. pline_The("fire doesn't seem to burn %s!",
736. mon_nam(mdef));
737. shieldeff(mdef->mx, mdef->my);
738. golemeffects(mdef, AD_FIRE, tmp);
739. tmp = 0;
740. }
741. /* only potions damage resistant players in destroy_item */
742. tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
743. break;
744. case AD_COLD:
745. if (cancelled) {
746. tmp = 0;
747. break;
748. }
749. if (vis) pline("%s is covered in frost!", Monnam(mdef));
750. if (resists_cold(mdef)) {
751. if (vis)
752. pline_The("frost doesn't seem to chill %s!",
753. mon_nam(mdef));
754. shieldeff(mdef->mx, mdef->my);
755. golemeffects(mdef, AD_COLD, tmp);
756. tmp = 0;
757. }
758. tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
759. break;
760. case AD_ELEC:
761. if (cancelled) {
762. tmp = 0;
763. break;
764. }
765. if (vis) pline("%s gets zapped!", Monnam(mdef));
766. tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
767. if (resists_elec(mdef)) {
768. if (vis) pline_The("zap doesn't shock %s!", mon_nam(mdef));
769. shieldeff(mdef->mx, mdef->my);
770. golemeffects(mdef, AD_ELEC, tmp);
771. tmp = 0;
772. }
773. /* only rings damage resistant players in destroy_item */
774. tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
775. break;
776. case AD_ACID:
777. if (magr->mcan) {
778. tmp = 0;
779. break;
780. }
781. if (resists_acid(mdef)) {
782. if (vis)
783. pline("%s is covered in acid, but it seems harmless.",
784. Monnam(mdef));
785. tmp = 0;
786. } else if (vis) {
787. pline("%s is covered in acid!", Monnam(mdef));
788. pline("It burns %s!", mon_nam(mdef));
789. }
790. if (!rn2(30)) erode_armor(mdef, TRUE);
791. if (!rn2(6)) erode_obj(MON_WEP(mdef), TRUE, TRUE);
792. break;
793. case AD_RUST:
794. if (magr->mcan) break;
795. if (pd == &mons[PM_IRON_GOLEM]) {
796. if (vis) pline("%s falls to pieces!", Monnam(mdef));
797. mondied(mdef);
798. if (mdef->mhp > 0) return 0;
799. else if (mdef->mtame && !vis)
800. pline("May %s rust in peace.", mon_nam(mdef));
801. return (MM_DEF_DIED | (grow_up(magr,mdef) ?
802. 0 : MM_AGR_DIED));
803. }
804. hurtmarmor(mdef, AD_RUST);
805. mdef->mstrategy &= ~STRAT_WAITFORU;
806. tmp = 0;
807. break;
808. case AD_CORR:
809. if (magr->mcan) break;
810. hurtmarmor(mdef, AD_CORR);
811. mdef->mstrategy &= ~STRAT_WAITFORU;
812. tmp = 0;
813. break;
814. case AD_DCAY:
815. if (magr->mcan) break;
816. if (pd == &mons[PM_WOOD_GOLEM] ||
817. pd == &mons[PM_LEATHER_GOLEM]) {
818. if (vis) pline("%s falls to pieces!", Monnam(mdef));
819. mondied(mdef);
820. if (mdef->mhp > 0) return 0;
821. else if (mdef->mtame && !vis)
822. pline("May %s rot in peace.", mon_nam(mdef));
823. return (MM_DEF_DIED | (grow_up(magr,mdef) ?
824. 0 : MM_AGR_DIED));
825. }
826. hurtmarmor(mdef, AD_DCAY);
827. mdef->mstrategy &= ~STRAT_WAITFORU;
828. tmp = 0;
829. break;
830. case AD_STON:
831. if (magr->mcan) break;
832. do_stone:
833. /* may die from the acid if it eats a stone-curing corpse */
834. if (munstone(mdef, FALSE)) goto post_stone;
835. if (poly_when_stoned(pd)) {
836. mon_to_stone(mdef);
837. tmp = 0;
838. break;
839. }
840. if (!resists_ston(mdef)) {
841. if (vis) pline("%s turns to stone!", Monnam(mdef));
842. monstone(mdef);
843. post_stone: if (mdef->mhp > 0) return 0;
844. else if (mdef->mtame && !vis)
845. You(brief_feeling, "peculiarly sad");
846. return (MM_DEF_DIED | (grow_up(magr,mdef) ?
847. 0 : MM_AGR_DIED));
848. }
849. tmp = (mattk->adtyp == AD_STON ? 0 : 1);
850. break;
851. case AD_TLPT:
852. if (!cancelled && tmp < mdef->mhp && !tele_restrict(mdef)) {
853. char mdef_Monnam[BUFSZ];
854. /* save the name before monster teleports, otherwise
855. we'll get "it" in the suddenly disappears message */
856. if (vis) Strcpy(mdef_Monnam, Monnam(mdef));
857. mdef->mstrategy &= ~STRAT_WAITFORU;
858. (void) rloc(mdef, FALSE);
859. if (vis && !canspotmon(mdef)
860. #ifdef STEED
861. && mdef != u.usteed
862. #endif
863. )
864. pline("%s suddenly disappears!", mdef_Monnam);
865. }
866. break;
867. case AD_SLEE:
868. if (!cancelled && !mdef->msleeping &&
869. sleep_monst(mdef, rnd(10), -1)) {
870. if (vis) {
871. Strcpy(buf, Monnam(mdef));
872. pline("%s is put to sleep by %s.", buf, mon_nam(magr));
873. }
874. mdef->mstrategy &= ~STRAT_WAITFORU;
875. slept_monst(mdef);
876. }
877. break;
878. case AD_PLYS:
879. if(!cancelled && mdef->mcanmove) {
880. if (vis) {
881. Strcpy(buf, Monnam(mdef));
882. pline("%s is frozen by %s.", buf, mon_nam(magr));
883. }
884. mdef->mcanmove = 0;
885. mdef->mfrozen = rnd(10);
886. mdef->mstrategy &= ~STRAT_WAITFORU;
887. }
888. break;
889. case AD_SLOW:
890. if (!cancelled && mdef->mspeed != MSLOW) {
891. unsigned int oldspeed = mdef->mspeed;
892.
893. mon_adjust_speed(mdef, -1, (struct obj *)0);
894. mdef->mstrategy &= ~STRAT_WAITFORU;
895. if (mdef->mspeed != oldspeed && vis)
896. pline("%s slows down.", Monnam(mdef));
897. }
898. break;
899. case AD_CONF:
900. /* Since confusing another monster doesn't have a real time
901. * limit, setting spec_used would not really be right (though
902. * we still should check for it).
903. */
904. if (!magr->mcan && !mdef->mconf && !magr->mspec_used) {
905. if (vis) pline("%s looks confused.", Monnam(mdef));
906. mdef->mconf = 1;
907. mdef->mstrategy &= ~STRAT_WAITFORU;
908. }
909. break;
910. case AD_BLND:
911. if (can_blnd(magr, mdef, mattk->aatyp, (struct obj*)0)) {
912. register unsigned rnd_tmp;
913.
914. if (vis && mdef->mcansee)
915. pline("%s is blinded.", Monnam(mdef));
916. rnd_tmp = d((int)mattk->damn, (int)mattk->damd);
917. if ((rnd_tmp += mdef->mblinded) > 127) rnd_tmp = 127;
918. mdef->mblinded = rnd_tmp;
919. mdef->mcansee = 0;
920. mdef->mstrategy &= ~STRAT_WAITFORU;
921. }
922. tmp = 0;
923. break;
924. case AD_HALU:
925. if (!magr->mcan && haseyes(pd) && mdef->mcansee) {
926. if (vis) pline("%s looks %sconfused.",
927. Monnam(mdef), mdef->mconf ? "more " : "");
928. mdef->mconf = 1;
929. mdef->mstrategy &= ~STRAT_WAITFORU;
930. }
931. tmp = 0;
932. break;
933. case AD_CURS:
934. if (!night() && (pa == &mons[PM_GREMLIN])) break;
935. if (!magr->mcan && !rn2(10)) {
936. mdef->mcan = 1; /* cancelled regardless of lifesave */
937. mdef->mstrategy &= ~STRAT_WAITFORU;
938. if (is_were(pd) && pd->mlet != S_HUMAN)
939. were_change(mdef);
940. if (pd == &mons[PM_CLAY_GOLEM]) {
941. if (vis) {
942. pline("Some writing vanishes from %s head!",
943. s_suffix(mon_nam(mdef)));
944. pline("%s is destroyed!", Monnam(mdef));
945. }
946. mondied(mdef);
947. if (mdef->mhp > 0) return 0;
948. else if (mdef->mtame && !vis)
949. You(brief_feeling, "strangely sad");
950. return (MM_DEF_DIED | (grow_up(magr,mdef) ?
951. 0 : MM_AGR_DIED));
952. }
953. if (flags.soundok) {
954. if (!vis) You_hear("laughter.");
955. else pline("%s chuckles.", Monnam(magr));
956. }
957. }
958. break;
959. case AD_SGLD:
960. tmp = 0;
961. #ifndef GOLDOBJ
962. if (magr->mcan || !mdef->mgold) break;
963. /* technically incorrect; no check for stealing gold from
964. * between mdef's feet...
965. */
966. magr->mgold += mdef->mgold;
967. mdef->mgold = 0;
968. #else
969. if (magr->mcan) break;
970. /* technically incorrect; no check for stealing gold from
971. * between mdef's feet...
972. */
973. {
974. struct obj *gold = findgold(mdef->minvent);
975. if (!gold) break;
976. obj_extract_self(gold);
977. add_to_minv(magr, gold);
978. }
979. #endif
980. mdef->mstrategy &= ~STRAT_WAITFORU;
981. if (vis) {
982. Strcpy(buf, Monnam(magr));
983. pline("%s steals some gold from %s.", buf, mon_nam(mdef));
984. }
985. if (!tele_restrict(magr)) {
986. (void) rloc(magr, FALSE);
987. if (vis && !canspotmon(magr))
988. pline("%s suddenly disappears!", buf);
989. }
990. break;
991. case AD_DRLI:
992. if (!cancelled && !rn2(3) && !resists_drli(mdef)) {
993. tmp = d(2,6);
994. if (vis)
995. pline("%s suddenly seems weaker!", Monnam(mdef));
996. mdef->mhpmax -= tmp;
997. if (mdef->m_lev == 0)
998. tmp = mdef->mhp;
999. else mdef->m_lev--;
1000. /* Automatic kill if drained past level 0 */
1001. }
1002. break;
1003. #ifdef SEDUCE
1004. case AD_SSEX:
1005. #endif
1006. case AD_SITM: /* for now these are the same */
1007. case AD_SEDU:
1008. if (magr->mcan) break;
1009. /* find an object to steal, non-cursed if magr is tame */
1010. for (obj = mdef->minvent; obj; obj = obj->nobj)
1011. if (!magr->mtame || !obj->cursed)
1012. break;
1013.
1014. if (obj) {
1015. char onambuf[BUFSZ], mdefnambuf[BUFSZ];
1016.
1017. /* make a special x_monnam() call that never omits
1018. the saddle, and save it for later messages */
1019. Strcpy(mdefnambuf, x_monnam(mdef, ARTICLE_THE, (char *)0, 0, FALSE));
1020.
1021. otmp = obj;
1022. #ifdef STEED
1023. if (u.usteed == mdef &&
1024. otmp == which_armor(mdef, W_SADDLE))
1025. /* "You can no longer ride <steed>." */
1026. dismount_steed(DISMOUNT_POLY);
1027. #endif
1028. obj_extract_self(otmp);
1029. if (otmp->owornmask) {
1030. mdef->misc_worn_check &= ~otmp->owornmask;
1031. if (otmp->owornmask & W_WEP)
1032. setmnotwielded(mdef,otmp);
1033. otmp->owornmask = 0L;
1034. update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
1035. }
1036. /* add_to_minv() might free otmp [if it merges] */
1037. if (vis)
1038. Strcpy(onambuf, doname(otmp));
1039. (void) add_to_minv(magr, otmp);
1040. if (vis) {
1041. Strcpy(buf, Monnam(magr));
1042. pline("%s steals %s from %s!", buf,
1043. onambuf, mdefnambuf);
1044. }
1045. possibly_unwield(mdef, FALSE);
1046. mdef->mstrategy &= ~STRAT_WAITFORU;
1047. mselftouch(mdef, (const char *)0, FALSE);
1048. if (mdef->mhp <= 0)
1049. return (MM_DEF_DIED | (grow_up(magr,mdef) ?
1050. 0 : MM_AGR_DIED));
1051. if (magr->data->mlet == S_NYMPH &&
1052. !tele_restrict(magr)) {
1053. (void) rloc(magr, FALSE);
1054. if (vis && !canspotmon(magr))
1055. pline("%s suddenly disappears!", buf);
1056. }
1057. }
1058. tmp = 0;
1059. break;
1060. case AD_DRST:
1061. case AD_DRDX:
1062. case AD_DRCO:
1063. if (!cancelled && !rn2(8)) {
1064. if (vis)
1065. pline("%s %s was poisoned!", s_suffix(Monnam(magr)),
1066. mpoisons_subj(magr, mattk));
1067. if (resists_poison(mdef)) {
1068. if (vis)
1069. pline_The("poison doesn't seem to affect %s.",
1070. mon_nam(mdef));
1071. } else {
1072. if (rn2(10)) tmp += rn1(10,6);
1073. else {
1074. if (vis) pline_The("poison was deadly...");
1075. tmp = mdef->mhp;
1076. }
1077. }
1078. }
1079. break;
1080. case AD_DRIN:
1081. if (notonhead || !has_head(pd)) {
1082. if (vis) pline("%s doesn't seem harmed.", Monnam(mdef));
1083. /* Not clear what to do for green slimes */
1084. tmp = 0;
1085. break;
1086. }
1087. if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) {
1088. if (vis) {
1089. Strcpy(buf, s_suffix(Monnam(mdef)));
1090. pline("%s helmet blocks %s attack to %s head.",
1091. buf, s_suffix(mon_nam(magr)),
1092. mhis(mdef));
1093. }
1094. break;
1095. }
1096. if (vis) pline("%s brain is eaten!", s_suffix(Monnam(mdef)));
1097. if (mindless(pd)) {
1098. if (vis) pline("%s doesn't notice.", Monnam(mdef));
1099. break;
1100. }
1101. tmp += rnd(10); /* fakery, since monsters lack INT scores */
1102. if (magr->mtame && !magr->isminion) {
1103. EDOG(magr)->hungrytime += rnd(60);
1104. magr->mconf = 0;
1105. }
1106. if (tmp >= mdef->mhp && vis)
1107. pline("%s last thought fades away...",
1108. s_suffix(Monnam(mdef)));
1109. break;
1110. case AD_SLIM:
1111. if (cancelled) break; /* physical damage only */
1112. if (!rn2(4) && !flaming(mdef->data) &&
1113. mdef->data != &mons[PM_GREEN_SLIME]) {
1114. (void) newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, vis);
1115. mdef->mstrategy &= ~STRAT_WAITFORU;
1116. tmp = 0;
1117. }
1118. break;
1119. case AD_STCK:
1120. if (cancelled) tmp = 0;
1121. break;
1122. case AD_WRAP: /* monsters cannot grab one another, it's too hard */
1123. if (magr->mcan) tmp = 0;
1124. break;
1125. case AD_ENCH:
1126. /* there's no msomearmor() function, so just do damage */
1127. /* if (cancelled) break; */
1128. break;
1129. default: tmp = 0;
1130. break;
1131. }
1132. if(!tmp) return(MM_MISS);
1133.
1134. if((mdef->mhp -= tmp) < 1) {
1135. if (m_at(mdef->mx, mdef->my) == magr) { /* see gulpmm() */
1136. remove_monster(mdef->mx, mdef->my);
1137. mdef->mhp = 1; /* otherwise place_monster will complain */
1138. place_monster(mdef, mdef->mx, mdef->my);
1139. mdef->mhp = 0;
1140. }
1141. monkilled(mdef, "", (int)mattk->adtyp);
1142. if (mdef->mhp > 0) return 0; /* mdef lifesaved */
1143.
1144. if (mattk->adtyp == AD_DGST) {
1145. /* various checks similar to dog_eat and meatobj.
1146. * after monkilled() to provide better message ordering */
1147. if (mdef->cham != CHAM_ORDINARY) {
1148. (void) newcham(magr, (struct permonst *)0, FALSE, TRUE);
1149. } else if (mdef->data == &mons[PM_GREEN_SLIME]) {
1150. (void) newcham(magr, &mons[PM_GREEN_SLIME], FALSE, TRUE);
1151. } else if (mdef->data == &mons[PM_WRAITH]) {
1152. (void) grow_up(magr, (struct monst *)0);
1153. /* don't grow up twice */
1154. return (MM_DEF_DIED | (magr->mhp > 0 ? 0 : MM_AGR_DIED));
1155. } else if (mdef->data == &mons[PM_NURSE]) {
1156. magr->mhp = magr->mhpmax;
1157. }
1158. }
1159.
1160. return (MM_DEF_DIED | (grow_up(magr,mdef) ? 0 : MM_AGR_DIED));
1161. }
1162. return(MM_HIT);
1163. }
1164.
1165. #endif /* OVLB */
1166.
1167.
noattacks
Edit
1168. #ifdef OVL0
1169.
1170. int
1171. noattacks(ptr) /* returns 1 if monster doesn't attack */
1172. struct permonst *ptr;
1173. {
1174. int i;
1175.
1176. for(i = 0; i < NATTK; i++)
1177. if(ptr->mattk[i].aatyp) return(0);
1178.
1179. return(1);
1180. }
1181.
sleep_monst
Edit
1182. /* `mon' is hit by a sleep attack; return 1 if it's affected, 0 otherwise */
1183. int
1184. sleep_monst(mon, amt, how)
1185. struct monst *mon;
1186. int amt, how;
1187. {
1188. if (resists_sleep(mon) ||
1189. (how >= 0 && resist(mon, (char)how, 0, NOTELL))) {
1190. shieldeff(mon->mx, mon->my);
1191. } else if (mon->mcanmove) {
1192. amt += (int) mon->mfrozen;
1193. if (amt > 0) { /* sleep for N turns */
1194. mon->mcanmove = 0;
1195. mon->mfrozen = min(amt, 127);
1196. } else { /* sleep until awakened */
1197. mon->msleeping = 1;
1198. }
1199. return 1;
1200. }
1201. return 0;
1202. }
1203.
slept_monst
Edit
1204. /* sleeping grabber releases, engulfer doesn't; don't use for paralysis! */
1205. void
1206. slept_monst(mon)
1207. struct monst *mon;
1208. {
1209. if ((mon->msleeping || !mon->mcanmove) && mon == u.ustuck &&
1210. !sticks(youmonst.data) && !u.uswallow) {
1211. pline("%s grip relaxes.", s_suffix(Monnam(mon)));
1212. unstuck(mon);
1213. }
1214. }
1215.
1216. #endif /* OVL0 */
1217. #ifdef OVLB
1218.
1219. STATIC_OVL void
1220. mrustm(magr, mdef, obj)
1221. register struct monst *magr, *mdef;
1222. register struct obj *obj;
1223. {
1224. boolean is_acid;
1225.
1226. if (!magr || !mdef || !obj) return; /* just in case */
1227.
1228. if (dmgtype(mdef->data, AD_CORR))
1229. is_acid = TRUE;
1230. else if (dmgtype(mdef->data, AD_RUST))
1231. is_acid = FALSE;
1232. else
1233. return;
1234.
1235. if (!mdef->mcan &&
1236. (is_acid ? is_corrodeable(obj) : is_rustprone(obj)) &&
1237. (is_acid ? obj->oeroded2 : obj->oeroded) < MAX_ERODE) {
1238. if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) {
1239. if (cansee(mdef->mx, mdef->my) && flags.verbose)
1240. pline("%s weapon is not affected.",
1241. s_suffix(Monnam(magr)));
1242. if (obj->greased && !rn2(2)) obj->greased = 0;
1243. } else {
1244. if (cansee(mdef->mx, mdef->my)) {
1245. pline("%s %s%s!", s_suffix(Monnam(magr)),
1246. aobjnam(obj, (is_acid ? "corrode" : "rust")),
1247. (is_acid ? obj->oeroded2 : obj->oeroded)
1248. ? " further" : "");
1249. }
1250. if (is_acid) obj->oeroded2++;
1251. else obj->oeroded++;
1252. }
1253. }
1254. }
1255.
mswingsm
Edit
1256. STATIC_OVL void
1257. mswingsm(magr, mdef, otemp)
1258. register struct monst *magr, *mdef;
1259. register struct obj *otemp;
1260. {
1261. char buf[BUFSZ];
1262. if (!flags.verbose || Blind || !mon_visible(magr)) return;
1263. Strcpy(buf, mon_nam(mdef));
1264. pline("%s %s %s %s at %s.", Monnam(magr),
1265. (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",
1266. mhis(magr), singular(otemp, xname), buf);
1267. }
1268.
passivemm
Edit
1269. /*
1270. * Passive responses by defenders. Does not replicate responses already
1271. * handled above. Returns same values as mattackm.
1272. */
1273. STATIC_OVL int
1274. passivemm(magr,mdef,mhit,mdead)
1275. register struct monst *magr, *mdef;
1276. boolean mhit;
1277. int mdead;
1278. {
1279. register struct permonst *mddat = mdef->data;
1280. register struct permonst *madat = magr->data;
1281. char buf[BUFSZ];
1282. int i, tmp;
1283.
1284. for(i = 0; ; i++) {
1285. if(i >= NATTK) return (mdead | mhit); /* no passive attacks */
1286. if(mddat->mattk[i].aatyp == AT_NONE) break;
1287. }
1288. if (mddat->mattk[i].damn)
1289. tmp = d((int)mddat->mattk[i].damn,
1290. (int)mddat->mattk[i].damd);
1291. else if(mddat->mattk[i].damd)
1292. tmp = d((int)mddat->mlevel+1, (int)mddat->mattk[i].damd);
1293. else
1294. tmp = 0;
1295.
1296. /* These affect the enemy even if defender killed */
1297. switch(mddat->mattk[i].adtyp) {
1298. case AD_ACID:
1299. if (mhit && !rn2(2)) {
1300. Strcpy(buf, Monnam(magr));
1301. if(canseemon(magr))
1302. pline("%s is splashed by %s acid!",
1303. buf, s_suffix(mon_nam(mdef)));
1304. if (resists_acid(magr)) {
1305. if(canseemon(magr))
1306. pline("%s is not affected.", Monnam(magr));
1307. tmp = 0;
1308. }
1309. } else tmp = 0;
1310. goto assess_dmg;
1311. case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
1312. if (mhit && !mdef->mcan && otmp) {
1313. (void) drain_item(otmp);
1314. /* No message */
1315. }
1316. break;
1317. default:
1318. break;
1319. }
1320. if (mdead || mdef->mcan) return (mdead|mhit);
1321.
1322. /* These affect the enemy only if defender is still alive */
1323. if (rn2(3)) switch(mddat->mattk[i].adtyp) {
1324. case AD_PLYS: /* Floating eye */
1325. if (tmp > 127) tmp = 127;
1326. if (mddat == &mons[PM_FLOATING_EYE]) {
1327. if (!rn2(4)) tmp = 127;
1328. if (magr->mcansee && haseyes(madat) && mdef->mcansee &&
1329. (perceives(madat) || !mdef->minvis)) {
1330. Sprintf(buf, "%s gaze is reflected by %%s %%s.",
1331. s_suffix(mon_nam(mdef)));
1332. if (mon_reflects(magr,
1333. canseemon(magr) ? buf : (char *)0))
1334. return(mdead|mhit);
1335. Strcpy(buf, Monnam(magr));
1336. if(canseemon(magr))
1337. pline("%s is frozen by %s gaze!",
1338. buf, s_suffix(mon_nam(mdef)));
1339. magr->mcanmove = 0;
1340. magr->mfrozen = tmp;
1341. return (mdead|mhit);
1342. }
1343. } else { /* gelatinous cube */
1344. Strcpy(buf, Monnam(magr));
1345. if(canseemon(magr))
1346. pline("%s is frozen by %s.", buf, mon_nam(mdef));
1347. magr->mcanmove = 0;
1348. magr->mfrozen = tmp;
1349. return (mdead|mhit);
1350. }
1351. return 1;
1352. case AD_COLD:
1353. if (resists_cold(magr)) {
1354. if (canseemon(magr)) {
1355. pline("%s is mildly chilly.", Monnam(magr));
1356. golemeffects(magr, AD_COLD, tmp);
1357. }
1358. tmp = 0;
1359. break;
1360. }
1361. if(canseemon(magr))
1362. pline("%s is suddenly very cold!", Monnam(magr));
1363. mdef->mhp += tmp / 2;
1364. if (mdef->mhpmax < mdef->mhp) mdef->mhpmax = mdef->mhp;
1365. if (mdef->mhpmax > ((int) (mdef->m_lev+1) * 8))
1366. (void)split_mon(mdef, magr);
1367. break;
1368. case AD_STUN:
1369. if (!magr->mstun) {
1370. magr->mstun = 1;
1371. if (canseemon(magr))
1372. pline("%s %s...", Monnam(magr),
1373. makeplural(stagger(magr->data, "stagger")));
1374. }
1375. tmp = 0;
1376. break;
1377. case AD_FIRE:
1378. if (resists_fire(magr)) {
1379. if (canseemon(magr)) {
1380. pline("%s is mildly warmed.", Monnam(magr));
1381. golemeffects(magr, AD_FIRE, tmp);
1382. }
1383. tmp = 0;
1384. break;
1385. }
1386. if(canseemon(magr))
1387. pline("%s is suddenly very hot!", Monnam(magr));
1388. break;
1389. case AD_ELEC:
1390. if (resists_elec(magr)) {
1391. if (canseemon(magr)) {
1392. pline("%s is mildly tingled.", Monnam(magr));
1393. golemeffects(magr, AD_ELEC, tmp);
1394. }
1395. tmp = 0;
1396. break;
1397. }
1398. if(canseemon(magr))
1399. pline("%s is jolted with electricity!", Monnam(magr));
1400. break;
1401. default: tmp = 0;
1402. break;
1403. }
1404. else tmp = 0;
1405.
1406. assess_dmg:
1407. if((magr->mhp -= tmp) <= 0) {
1408. monkilled(magr, "", (int)mddat->mattk[i].adtyp);
1409. return (mdead | mhit | MM_AGR_DIED);
1410. }
1411. return (mdead | mhit);
1412. }
1413.
attk_protection
Edit
1414. /* "aggressive defense"; what type of armor prevents specified attack
1415. from touching its target? */
1416. long
1417. attk_protection(aatyp)
1418. int aatyp;
1419. {
1420. long w_mask = 0L;
1421.
1422. switch (aatyp) {
1423. case AT_NONE:
1424. case AT_SPIT:
1425. case AT_EXPL:
1426. case AT_BOOM:
1427. case AT_GAZE:
1428. case AT_BREA:
1429. case AT_MAGC:
1430. w_mask = ~0L; /* special case; no defense needed */
1431. break;
1432. case AT_CLAW:
1433. case AT_TUCH:
1434. case AT_WEAP:
1435. w_mask = W_ARMG; /* caller needs to check for weapon */
1436. break;
1437. case AT_KICK:
1438. w_mask = W_ARMF;
1439. break;
1440. case AT_BUTT:
1441. w_mask = W_ARMH;
1442. break;
1443. case AT_HUGS:
1444. w_mask = (W_ARMC|W_ARMG); /* attacker needs both to be protected */
1445. break;
1446. case AT_BITE:
1447. case AT_STNG:
1448. case AT_ENGL:
1449. case AT_TENT:
1450. default:
1451. w_mask = 0L; /* no defense available */
1452. break;
1453. }
1454. return w_mask;
1455. }
1456.
1457. #endif /* OVLB */
1458.
1459. /*mhitm.c*/
1460.