1 /* $NetBSD: hack.mhitu.c,v 1.5 2001/03/25 20:44:01 jsm Exp $ */ 2 3 /* 4 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. 5 */ 6 7 #include <sys/cdefs.h> 8 #ifndef lint 9 __RCSID("$NetBSD: hack.mhitu.c,v 1.5 2001/03/25 20:44:01 jsm Exp $"); 10 #endif /* not lint */ 11 12 #include "hack.h" 13 #include "extern.h" 14 15 /* 16 * mhitu: monster hits you 17 * returns 1 if monster dies (e.g. 'y', 'F'), 0 otherwise 18 */ 19 int 20 mhitu(mtmp) 21 struct monst *mtmp; 22 { 23 const struct permonst *mdat = mtmp->data; 24 int tmp, ctmp; 25 26 nomul(0); 27 28 /* If swallowed, can only be affected by hissers and by u.ustuck */ 29 if (u.uswallow) { 30 if (mtmp != u.ustuck) { 31 if (mdat->mlet == 'c' && !rn2(13)) { 32 pline("Outside, you hear %s's hissing!", 33 monnam(mtmp)); 34 pline("%s gets turned to stone!", 35 Monnam(u.ustuck)); 36 pline("And the same fate befalls you."); 37 done_in_by(mtmp); 38 /* "notreached": not return(1); */ 39 } 40 return (0); 41 } 42 switch (mdat->mlet) { /* now mtmp == u.ustuck */ 43 case ',': 44 youswld(mtmp, (u.uac > 0) ? u.uac + 4 : 4, 45 5, "The trapper"); 46 break; 47 case '\'': 48 youswld(mtmp, rnd(6), 7, "The lurker above"); 49 break; 50 case 'P': 51 youswld(mtmp, d(2, 4), 12, "The purple worm"); 52 break; 53 default: 54 /* This is not impossible! */ 55 pline("The mysterious monster totally digests you."); 56 u.uhp = 0; 57 } 58 if (u.uhp < 1) 59 done_in_by(mtmp); 60 return (0); 61 } 62 if (mdat->mlet == 'c' && Stoned) 63 return (0); 64 65 /* make eels visible the moment they hit/miss us */ 66 if (mdat->mlet == ';' && mtmp->minvis && cansee(mtmp->mx, mtmp->my)) { 67 mtmp->minvis = 0; 68 pmon(mtmp); 69 } 70 if (!strchr("1&DuxynNF", mdat->mlet)) 71 tmp = hitu(mtmp, d(mdat->damn, mdat->damd)); 72 else 73 tmp = 0; 74 if (strchr(UNDEAD, mdat->mlet) && midnight()) 75 tmp += hitu(mtmp, d(mdat->damn, mdat->damd)); 76 77 ctmp = tmp && !mtmp->mcan && 78 (!uarm || objects[uarm->otyp].a_can < rnd(3) || !rn2(50)); 79 switch (mdat->mlet) { 80 case '1': 81 if (wiz_hit(mtmp)) 82 return (1); /* he disappeared */ 83 break; 84 case '&': 85 if (!mtmp->cham && !mtmp->mcan && !rn2(13)) { 86 (void) makemon(PM_DEMON, u.ux, u.uy); 87 } else { 88 (void) hitu(mtmp, d(2, 6)); 89 (void) hitu(mtmp, d(2, 6)); 90 (void) hitu(mtmp, rnd(3)); 91 (void) hitu(mtmp, rnd(3)); 92 (void) hitu(mtmp, rn1(4, 2)); 93 } 94 break; 95 case ',': 96 if (tmp) 97 justswld(mtmp, "The trapper"); 98 break; 99 case '\'': 100 if (tmp) 101 justswld(mtmp, "The lurker above"); 102 break; 103 case ';': 104 if (ctmp) { 105 if (!u.ustuck && !rn2(10)) { 106 pline("%s swings itself around you!", 107 Monnam(mtmp)); 108 u.ustuck = mtmp; 109 } else if (u.ustuck == mtmp && 110 levl[mtmp->mx][mtmp->my].typ == POOL) { 111 pline("%s drowns you ...", Monnam(mtmp)); 112 done("drowned"); 113 } 114 } 115 break; 116 case 'A': 117 if (ctmp && rn2(2)) { 118 if (Poison_resistance) 119 pline("The sting doesn't seem to affect you."); 120 else { 121 pline("You feel weaker!"); 122 losestr(1); 123 } 124 } 125 break; 126 case 'C': 127 (void) hitu(mtmp, rnd(6)); 128 break; 129 case 'c': 130 if (!rn2(5)) { 131 pline("You hear %s's hissing!", monnam(mtmp)); 132 if (ctmp || !rn2(20) || (flags.moonphase == NEW_MOON 133 && !carrying(DEAD_LIZARD))) { 134 Stoned = 5; 135 /* pline("You get turned to stone!"); */ 136 /* done_in_by(mtmp); */ 137 } 138 } 139 break; 140 case 'D': 141 if (rn2(6) || mtmp->mcan) { 142 (void) hitu(mtmp, d(3, 10)); 143 (void) hitu(mtmp, rnd(8)); 144 (void) hitu(mtmp, rnd(8)); 145 break; 146 } 147 kludge("%s breathes fire!", "The dragon"); 148 buzz(-1, mtmp->mx, mtmp->my, u.ux - mtmp->mx, u.uy - mtmp->my); 149 break; 150 case 'd': 151 (void) hitu(mtmp, d(2, (flags.moonphase == FULL_MOON) ? 3 : 4)); 152 break; 153 case 'e': 154 (void) hitu(mtmp, d(3, 6)); 155 break; 156 case 'F': 157 if (mtmp->mcan) 158 break; 159 kludge("%s explodes!", "The freezing sphere"); 160 if (Cold_resistance) 161 pline("You don't seem affected by it."); 162 else { 163 xchar dn; 164 if (17 - (u.ulevel / 2) > rnd(20)) { 165 pline("You get blasted!"); 166 dn = 6; 167 } else { 168 pline("You duck the blast..."); 169 dn = 3; 170 } 171 losehp_m(d(dn, 6), mtmp); 172 } 173 mondead(mtmp); 174 return (1); 175 case 'g': 176 if (ctmp && multi >= 0 && !rn2(3)) { 177 kludge("You are frozen by %ss juices", "the cube'"); 178 nomul(-rnd(10)); 179 } 180 break; 181 case 'h': 182 if (ctmp && multi >= 0 && !rn2(5)) { 183 nomul(-rnd(10)); 184 kludge("You are put to sleep by %ss bite!", 185 "the homunculus'"); 186 } 187 break; 188 case 'j': 189 tmp = hitu(mtmp, rnd(3)); 190 tmp &= hitu(mtmp, rnd(3)); 191 if (tmp) { 192 (void) hitu(mtmp, rnd(4)); 193 (void) hitu(mtmp, rnd(4)); 194 } 195 break; 196 case 'k': 197 if ((hitu(mtmp, rnd(4)) || !rn2(3)) && ctmp) { 198 poisoned("bee's sting", mdat->mname); 199 } 200 break; 201 case 'L': 202 if (tmp) 203 stealgold(mtmp); 204 break; 205 case 'N': 206 if (mtmp->mcan && !Blind) { 207 pline("%s tries to seduce you, but you seem not interested.", 208 Amonnam(mtmp, "plain")); 209 if (rn2(3)) 210 rloc(mtmp); 211 } else if (steal(mtmp)) { 212 rloc(mtmp); 213 mtmp->mflee = 1; 214 } 215 break; 216 case 'n': 217 if (!uwep && !uarm && !uarmh && !uarms && !uarmg) { 218 pline("%s hits! (I hope you don't mind)", 219 Monnam(mtmp)); 220 u.uhp += rnd(7); 221 if (!rn2(7)) 222 u.uhpmax++; 223 if (u.uhp > u.uhpmax) 224 u.uhp = u.uhpmax; 225 flags.botl = 1; 226 if (!rn2(50)) 227 rloc(mtmp); 228 } else { 229 (void) hitu(mtmp, d(2, 6)); 230 (void) hitu(mtmp, d(2, 6)); 231 } 232 break; 233 case 'o': 234 tmp = hitu(mtmp, rnd(6)); 235 if (hitu(mtmp, rnd(6)) && tmp && /* hits with both paws */ 236 !u.ustuck && rn2(2)) { 237 u.ustuck = mtmp; 238 kludge("%s has grabbed you!", "The owlbear"); 239 u.uhp -= d(2, 8); 240 } else if (u.ustuck == mtmp) { 241 u.uhp -= d(2, 8); 242 pline("You are being crushed."); 243 } 244 break; 245 case 'P': 246 if (ctmp && !rn2(4)) 247 justswld(mtmp, "The purple worm"); 248 else 249 (void) hitu(mtmp, d(2, 4)); 250 break; 251 case 'Q': 252 (void) hitu(mtmp, rnd(2)); 253 (void) hitu(mtmp, rnd(2)); 254 break; 255 case 'R': 256 if (tmp && uarmh && !uarmh->rustfree && 257 (int) uarmh->spe >= -1) { 258 pline("Your helmet rusts!"); 259 uarmh->spe--; 260 } else if (ctmp && uarm && !uarm->rustfree && /* Mike Newton */ 261 uarm->otyp < STUDDED_LEATHER_ARMOR && 262 (int) uarm->spe >= -1) { 263 pline("Your armor rusts!"); 264 uarm->spe--; 265 } 266 break; 267 case 'S': 268 if (ctmp && !rn2(8)) { 269 poisoned("snake's bite", mdat->mname); 270 } 271 break; 272 case 's': 273 if (tmp && !rn2(8)) { 274 poisoned("scorpion's sting", mdat->mname); 275 } 276 (void) hitu(mtmp, rnd(8)); 277 (void) hitu(mtmp, rnd(8)); 278 break; 279 case 'T': 280 (void) hitu(mtmp, rnd(6)); 281 (void) hitu(mtmp, rnd(6)); 282 break; 283 case 't': 284 if (!rn2(5)) 285 rloc(mtmp); 286 break; 287 case 'u': 288 mtmp->mflee = 1; 289 break; 290 case 'U': 291 (void) hitu(mtmp, d(3, 4)); 292 (void) hitu(mtmp, d(3, 4)); 293 break; 294 case 'v': 295 if (ctmp && !u.ustuck) 296 u.ustuck = mtmp; 297 break; 298 case 'V': 299 if (tmp) 300 u.uhp -= 4; 301 if (ctmp) 302 losexp(); 303 break; 304 case 'W': 305 if (ctmp) 306 losexp(); 307 break; 308 #ifndef NOWORM 309 case 'w': 310 if (tmp) 311 wormhit(mtmp); 312 #endif /* NOWORM */ 313 break; 314 case 'X': 315 (void) hitu(mtmp, rnd(5)); 316 (void) hitu(mtmp, rnd(5)); 317 (void) hitu(mtmp, rnd(5)); 318 break; 319 case 'x': 320 { 321 long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; 322 pline("%s pricks in your %s leg!", 323 Monnam(mtmp), (side == RIGHT_SIDE) ? "right" : "left"); 324 set_wounded_legs(side, rnd(50)); 325 losehp_m(2, mtmp); 326 break; 327 } 328 case 'y': 329 if (mtmp->mcan) 330 break; 331 mondead(mtmp); 332 if (!Blind) { 333 pline("You are blinded by a blast of light!"); 334 Blind = d(4, 12); 335 seeoff(0); 336 } 337 return (1); 338 case 'Y': 339 (void) hitu(mtmp, rnd(6)); 340 break; 341 } 342 if (u.uhp < 1) 343 done_in_by(mtmp); 344 return (0); 345 } 346 347 int 348 hitu(mtmp, dam) 349 struct monst *mtmp; 350 int dam; 351 { 352 int tmp, res; 353 354 nomul(0); 355 if (u.uswallow) 356 return (0); 357 358 if (mtmp->mhide && mtmp->mundetected) { 359 mtmp->mundetected = 0; 360 if (!Blind) { 361 struct obj *obj; 362 if ((obj = o_at(mtmp->mx, mtmp->my)) != NULL) 363 pline("%s was hidden under %s!", 364 Xmonnam(mtmp), doname(obj)); 365 } 366 } 367 tmp = u.uac; 368 /* give people with Ac = -10 at least some vulnerability */ 369 if (tmp < 0) { 370 dam += tmp; /* decrease damage */ 371 if (dam <= 0) 372 dam = 1; 373 tmp = -rn2(-tmp); 374 } 375 tmp += mtmp->data->mlevel; 376 if (multi < 0) 377 tmp += 4; 378 if ((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee) 379 tmp -= 2; 380 if (mtmp->mtrapped) 381 tmp -= 2; 382 if (tmp <= rnd(20)) { 383 if (Blind) 384 pline("It misses."); 385 else 386 pline("%s misses.", Monnam(mtmp)); 387 res = 0; 388 } else { 389 if (Blind) 390 pline("It hits!"); 391 else 392 pline("%s hits!", Monnam(mtmp)); 393 losehp_m(dam, mtmp); 394 res = 1; 395 } 396 stop_occupation(); 397 return (res); 398 } 399