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