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