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