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