hack.mhitu.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /* $NetBSD: hack.mhitu.c,v 1.6 2003/04/02 18:36:37 jsm Exp $ */
  2. /*
  3. * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
  4. * Amsterdam
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are
  9. * met:
  10. *
  11. * - Redistributions of source code must retain the above copyright notice,
  12. * this list of conditions and the following disclaimer.
  13. *
  14. * - Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. *
  18. * - Neither the name of the Stichting Centrum voor Wiskunde en
  19. * Informatica, nor the names of its contributors may be used to endorse or
  20. * promote products derived from this software without specific prior
  21. * written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  24. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  25. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  26. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  27. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  28. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  29. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  30. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  31. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  32. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  33. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. /*
  36. * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
  37. * All rights reserved.
  38. *
  39. * Redistribution and use in source and binary forms, with or without
  40. * modification, are permitted provided that the following conditions
  41. * are met:
  42. * 1. Redistributions of source code must retain the above copyright
  43. * notice, this list of conditions and the following disclaimer.
  44. * 2. Redistributions in binary form must reproduce the above copyright
  45. * notice, this list of conditions and the following disclaimer in the
  46. * documentation and/or other materials provided with the distribution.
  47. * 3. The name of the author may not be used to endorse or promote products
  48. * derived from this software without specific prior written permission.
  49. *
  50. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  51. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  52. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  53. * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  54. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  55. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  56. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  57. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  58. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  59. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60. */
  61. #include <sys/cdefs.h>
  62. #ifndef lint
  63. __RCSID("$NetBSD: hack.mhitu.c,v 1.6 2003/04/02 18:36:37 jsm Exp $");
  64. #endif /* not lint */
  65. #include "hack.h"
  66. #include "extern.h"
  67. /*
  68. * mhitu: monster hits you
  69. * returns 1 if monster dies (e.g. 'y', 'F'), 0 otherwise
  70. */
  71. int
  72. mhitu(mtmp)
  73. struct monst *mtmp;
  74. {
  75. const struct permonst *mdat = mtmp->data;
  76. int tmp, ctmp;
  77. nomul(0);
  78. /* If swallowed, can only be affected by hissers and by u.ustuck */
  79. if (u.uswallow) {
  80. if (mtmp != u.ustuck) {
  81. if (mdat->mlet == 'c' && !rn2(13)) {
  82. pline("Outside, you hear %s's hissing!",
  83. monnam(mtmp));
  84. pline("%s gets turned to stone!",
  85. Monnam(u.ustuck));
  86. pline("And the same fate befalls you.");
  87. done_in_by(mtmp);
  88. /* "notreached": not return(1); */
  89. }
  90. return (0);
  91. }
  92. switch (mdat->mlet) { /* now mtmp == u.ustuck */
  93. case ',':
  94. youswld(mtmp, (u.uac > 0) ? u.uac + 4 : 4,
  95. 5, "The trapper");
  96. break;
  97. case '\'':
  98. youswld(mtmp, rnd(6), 7, "The lurker above");
  99. break;
  100. case 'P':
  101. youswld(mtmp, d(2, 4), 12, "The purple worm");
  102. break;
  103. default:
  104. /* This is not impossible! */
  105. pline("The mysterious monster totally digests you.");
  106. u.uhp = 0;
  107. }
  108. if (u.uhp < 1)
  109. done_in_by(mtmp);
  110. return (0);
  111. }
  112. if (mdat->mlet == 'c' && Stoned)
  113. return (0);
  114. /* make eels visible the moment they hit/miss us */
  115. if (mdat->mlet == ';' && mtmp->minvis && cansee(mtmp->mx, mtmp->my)) {
  116. mtmp->minvis = 0;
  117. pmon(mtmp);
  118. }
  119. if (!strchr("1&DuxynNF", mdat->mlet))
  120. tmp = hitu(mtmp, d(mdat->damn, mdat->damd));
  121. else
  122. tmp = 0;
  123. if (strchr(UNDEAD, mdat->mlet) && midnight())
  124. tmp += hitu(mtmp, d(mdat->damn, mdat->damd));
  125. ctmp = tmp && !mtmp->mcan &&
  126. (!uarm || objects[uarm->otyp].a_can < rnd(3) || !rn2(50));
  127. switch (mdat->mlet) {
  128. case '1':
  129. if (wiz_hit(mtmp))
  130. return (1); /* he disappeared */
  131. break;
  132. case '&':
  133. if (!mtmp->cham && !mtmp->mcan && !rn2(13)) {
  134. (void) makemon(PM_DEMON, u.ux, u.uy);
  135. } else {
  136. (void) hitu(mtmp, d(2, 6));
  137. (void) hitu(mtmp, d(2, 6));
  138. (void) hitu(mtmp, rnd(3));
  139. (void) hitu(mtmp, rnd(3));
  140. (void) hitu(mtmp, rn1(4, 2));
  141. }
  142. break;
  143. case ',':
  144. if (tmp)
  145. justswld(mtmp, "The trapper");
  146. break;
  147. case '\'':
  148. if (tmp)
  149. justswld(mtmp, "The lurker above");
  150. break;
  151. case ';':
  152. if (ctmp) {
  153. if (!u.ustuck && !rn2(10)) {
  154. pline("%s swings itself around you!",
  155. Monnam(mtmp));
  156. u.ustuck = mtmp;
  157. } else if (u.ustuck == mtmp &&
  158. levl[mtmp->mx][mtmp->my].typ == POOL) {
  159. pline("%s drowns you ...", Monnam(mtmp));
  160. done("drowned");
  161. }
  162. }
  163. break;
  164. case 'A':
  165. if (ctmp && rn2(2)) {
  166. if (Poison_resistance)
  167. pline("The sting doesn't seem to affect you.");
  168. else {
  169. pline("You feel weaker!");
  170. losestr(1);
  171. }
  172. }
  173. break;
  174. case 'C':
  175. (void) hitu(mtmp, rnd(6));
  176. break;
  177. case 'c':
  178. if (!rn2(5)) {
  179. pline("You hear %s's hissing!", monnam(mtmp));
  180. if (ctmp || !rn2(20) || (flags.moonphase == NEW_MOON
  181. && !carrying(DEAD_LIZARD))) {
  182. Stoned = 5;
  183. /* pline("You get turned to stone!"); */
  184. /* done_in_by(mtmp); */
  185. }
  186. }
  187. break;
  188. case 'D':
  189. if (rn2(6) || mtmp->mcan) {
  190. (void) hitu(mtmp, d(3, 10));
  191. (void) hitu(mtmp, rnd(8));
  192. (void) hitu(mtmp, rnd(8));
  193. break;
  194. }
  195. kludge("%s breathes fire!", "The dragon");
  196. buzz(-1, mtmp->mx, mtmp->my, u.ux - mtmp->mx, u.uy - mtmp->my);
  197. break;
  198. case 'd':
  199. (void) hitu(mtmp, d(2, (flags.moonphase == FULL_MOON) ? 3 : 4));
  200. break;
  201. case 'e':
  202. (void) hitu(mtmp, d(3, 6));
  203. break;
  204. case 'F':
  205. if (mtmp->mcan)
  206. break;
  207. kludge("%s explodes!", "The freezing sphere");
  208. if (Cold_resistance)
  209. pline("You don't seem affected by it.");
  210. else {
  211. xchar dn;
  212. if (17 - (u.ulevel / 2) > rnd(20)) {
  213. pline("You get blasted!");
  214. dn = 6;
  215. } else {
  216. pline("You duck the blast...");
  217. dn = 3;
  218. }
  219. losehp_m(d(dn, 6), mtmp);
  220. }
  221. mondead(mtmp);
  222. return (1);
  223. case 'g':
  224. if (ctmp && multi >= 0 && !rn2(3)) {
  225. kludge("You are frozen by %ss juices", "the cube'");
  226. nomul(-rnd(10));
  227. }
  228. break;
  229. case 'h':
  230. if (ctmp && multi >= 0 && !rn2(5)) {
  231. nomul(-rnd(10));
  232. kludge("You are put to sleep by %ss bite!",
  233. "the homunculus'");
  234. }
  235. break;
  236. case 'j':
  237. tmp = hitu(mtmp, rnd(3));
  238. tmp &= hitu(mtmp, rnd(3));
  239. if (tmp) {
  240. (void) hitu(mtmp, rnd(4));
  241. (void) hitu(mtmp, rnd(4));
  242. }
  243. break;
  244. case 'k':
  245. if ((hitu(mtmp, rnd(4)) || !rn2(3)) && ctmp) {
  246. poisoned("bee's sting", mdat->mname);
  247. }
  248. break;
  249. case 'L':
  250. if (tmp)
  251. stealgold(mtmp);
  252. break;
  253. case 'N':
  254. if (mtmp->mcan && !Blind) {
  255. pline("%s tries to seduce you, but you seem not interested.",
  256. Amonnam(mtmp, "plain"));
  257. if (rn2(3))
  258. rloc(mtmp);
  259. } else if (steal(mtmp)) {
  260. rloc(mtmp);
  261. mtmp->mflee = 1;
  262. }
  263. break;
  264. case 'n':
  265. if (!uwep && !uarm && !uarmh && !uarms && !uarmg) {
  266. pline("%s hits! (I hope you don't mind)",
  267. Monnam(mtmp));
  268. u.uhp += rnd(7);
  269. if (!rn2(7))
  270. u.uhpmax++;
  271. if (u.uhp > u.uhpmax)
  272. u.uhp = u.uhpmax;
  273. flags.botl = 1;
  274. if (!rn2(50))
  275. rloc(mtmp);
  276. } else {
  277. (void) hitu(mtmp, d(2, 6));
  278. (void) hitu(mtmp, d(2, 6));
  279. }
  280. break;
  281. case 'o':
  282. tmp = hitu(mtmp, rnd(6));
  283. if (hitu(mtmp, rnd(6)) && tmp && /* hits with both paws */
  284. !u.ustuck && rn2(2)) {
  285. u.ustuck = mtmp;
  286. kludge("%s has grabbed you!", "The owlbear");
  287. u.uhp -= d(2, 8);
  288. } else if (u.ustuck == mtmp) {
  289. u.uhp -= d(2, 8);
  290. pline("You are being crushed.");
  291. }
  292. break;
  293. case 'P':
  294. if (ctmp && !rn2(4))
  295. justswld(mtmp, "The purple worm");
  296. else
  297. (void) hitu(mtmp, d(2, 4));
  298. break;
  299. case 'Q':
  300. (void) hitu(mtmp, rnd(2));
  301. (void) hitu(mtmp, rnd(2));
  302. break;
  303. case 'R':
  304. if (tmp && uarmh && !uarmh->rustfree &&
  305. (int) uarmh->spe >= -1) {
  306. pline("Your helmet rusts!");
  307. uarmh->spe--;
  308. } else if (ctmp && uarm && !uarm->rustfree && /* Mike Newton */
  309. uarm->otyp < STUDDED_LEATHER_ARMOR &&
  310. (int) uarm->spe >= -1) {
  311. pline("Your armor rusts!");
  312. uarm->spe--;
  313. }
  314. break;
  315. case 'S':
  316. if (ctmp && !rn2(8)) {
  317. poisoned("snake's bite", mdat->mname);
  318. }
  319. break;
  320. case 's':
  321. if (tmp && !rn2(8)) {
  322. poisoned("scorpion's sting", mdat->mname);
  323. }
  324. (void) hitu(mtmp, rnd(8));
  325. (void) hitu(mtmp, rnd(8));
  326. break;
  327. case 'T':
  328. (void) hitu(mtmp, rnd(6));
  329. (void) hitu(mtmp, rnd(6));
  330. break;
  331. case 't':
  332. if (!rn2(5))
  333. rloc(mtmp);
  334. break;
  335. case 'u':
  336. mtmp->mflee = 1;
  337. break;
  338. case 'U':
  339. (void) hitu(mtmp, d(3, 4));
  340. (void) hitu(mtmp, d(3, 4));
  341. break;
  342. case 'v':
  343. if (ctmp && !u.ustuck)
  344. u.ustuck = mtmp;
  345. break;
  346. case 'V':
  347. if (tmp)
  348. u.uhp -= 4;
  349. if (ctmp)
  350. losexp();
  351. break;
  352. case 'W':
  353. if (ctmp)
  354. losexp();
  355. break;
  356. #ifndef NOWORM
  357. case 'w':
  358. if (tmp)
  359. wormhit(mtmp);
  360. #endif /* NOWORM */
  361. break;
  362. case 'X':
  363. (void) hitu(mtmp, rnd(5));
  364. (void) hitu(mtmp, rnd(5));
  365. (void) hitu(mtmp, rnd(5));
  366. break;
  367. case 'x':
  368. {
  369. long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
  370. pline("%s pricks in your %s leg!",
  371. Monnam(mtmp), (side == RIGHT_SIDE) ? "right" : "left");
  372. set_wounded_legs(side, rnd(50));
  373. losehp_m(2, mtmp);
  374. break;
  375. }
  376. case 'y':
  377. if (mtmp->mcan)
  378. break;
  379. mondead(mtmp);
  380. if (!Blind) {
  381. pline("You are blinded by a blast of light!");
  382. Blind = d(4, 12);
  383. seeoff(0);
  384. }
  385. return (1);
  386. case 'Y':
  387. (void) hitu(mtmp, rnd(6));
  388. break;
  389. }
  390. if (u.uhp < 1)
  391. done_in_by(mtmp);
  392. return (0);
  393. }
  394. int
  395. hitu(mtmp, dam)
  396. struct monst *mtmp;
  397. int dam;
  398. {
  399. int tmp, res;
  400. nomul(0);
  401. if (u.uswallow)
  402. return (0);
  403. if (mtmp->mhide && mtmp->mundetected) {
  404. mtmp->mundetected = 0;
  405. if (!Blind) {
  406. struct obj *obj;
  407. if ((obj = o_at(mtmp->mx, mtmp->my)) != NULL)
  408. pline("%s was hidden under %s!",
  409. Xmonnam(mtmp), doname(obj));
  410. }
  411. }
  412. tmp = u.uac;
  413. /* give people with Ac = -10 at least some vulnerability */
  414. if (tmp < 0) {
  415. dam += tmp; /* decrease damage */
  416. if (dam <= 0)
  417. dam = 1;
  418. tmp = -rn2(-tmp);
  419. }
  420. tmp += mtmp->data->mlevel;
  421. if (multi < 0)
  422. tmp += 4;
  423. if ((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee)
  424. tmp -= 2;
  425. if (mtmp->mtrapped)
  426. tmp -= 2;
  427. if (tmp <= rnd(20)) {
  428. if (Blind)
  429. pline("It misses.");
  430. else
  431. pline("%s misses.", Monnam(mtmp));
  432. res = 0;
  433. } else {
  434. if (Blind)
  435. pline("It hits!");
  436. else
  437. pline("%s hits!", Monnam(mtmp));
  438. losehp_m(dam, mtmp);
  439. res = 1;
  440. }
  441. stop_occupation();
  442. return (res);
  443. }