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