|
|
1.1 ! root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ ! 2: /* hack.fight.c - version 1.0.3 */ ! 3: ! 4: #include "hack.h" ! 5: extern struct permonst li_dog, dog, la_dog; ! 6: extern char *exclam(), *xname(); ! 7: extern struct obj *mkobj_at(); ! 8: ! 9: static boolean far_noise; ! 10: static long noisetime; ! 11: ! 12: /* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */ ! 13: hitmm(magr,mdef) register struct monst *magr,*mdef; { ! 14: register struct permonst *pa = magr->data, *pd = mdef->data; ! 15: int hit; ! 16: schar tmp; ! 17: boolean vis; ! 18: if(index("Eauy", pa->mlet)) return(0); ! 19: if(magr->mfroz) return(0); /* riv05!a3 */ ! 20: tmp = pd->ac + pa->mlevel; ! 21: if(mdef->mconf || mdef->mfroz || mdef->msleep){ ! 22: tmp += 4; ! 23: if(mdef->msleep) mdef->msleep = 0; ! 24: } ! 25: hit = (tmp > rnd(20)); ! 26: if(hit) mdef->msleep = 0; ! 27: vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my)); ! 28: if(vis){ ! 29: char buf[BUFSZ]; ! 30: if(mdef->mimic) seemimic(mdef); ! 31: if(magr->mimic) seemimic(magr); ! 32: (void) sprintf(buf,"%s %s", Monnam(magr), ! 33: hit ? "hits" : "misses"); ! 34: pline("%s %s.", buf, monnam(mdef)); ! 35: } else { ! 36: boolean far = (dist(magr->mx, magr->my) > 15); ! 37: if(far != far_noise || moves-noisetime > 10) { ! 38: far_noise = far; ! 39: noisetime = moves; ! 40: pline("You hear some noises%s.", ! 41: far ? " in the distance" : ""); ! 42: } ! 43: } ! 44: if(hit){ ! 45: if(magr->data->mlet == 'c' && !magr->cham) { ! 46: magr->mhpmax += 3; ! 47: if(vis) pline("%s is turned to stone!", Monnam(mdef)); ! 48: else if(mdef->mtame) ! 49: pline("You have a peculiarly sad feeling for a moment, then it passes."); ! 50: monstone(mdef); ! 51: hit = 2; ! 52: } else ! 53: if((mdef->mhp -= d(pa->damn,pa->damd)) < 1) { ! 54: magr->mhpmax += 1 + rn2(pd->mlevel+1); ! 55: if(magr->mtame && magr->mhpmax > 8*pa->mlevel){ ! 56: if(pa == &li_dog) magr->data = pa = &dog; ! 57: else if(pa == &dog) magr->data = pa = &la_dog; ! 58: } ! 59: if(vis) pline("%s is killed!", Monnam(mdef)); ! 60: else if(mdef->mtame) ! 61: pline("You have a sad feeling for a moment, then it passes."); ! 62: mondied(mdef); ! 63: hit = 2; ! 64: } ! 65: } ! 66: return(hit); ! 67: } ! 68: ! 69: /* drop (perhaps) a cadaver and remove monster */ ! 70: mondied(mdef) register struct monst *mdef; { ! 71: register struct permonst *pd = mdef->data; ! 72: if(letter(pd->mlet) && rn2(3)){ ! 73: (void) mkobj_at(pd->mlet,mdef->mx,mdef->my); ! 74: if(cansee(mdef->mx,mdef->my)){ ! 75: unpmon(mdef); ! 76: atl(mdef->mx,mdef->my,fobj->olet); ! 77: } ! 78: stackobj(fobj); ! 79: } ! 80: mondead(mdef); ! 81: } ! 82: ! 83: /* drop a rock and remove monster */ ! 84: monstone(mdef) register struct monst *mdef; { ! 85: extern char mlarge[]; ! 86: if(index(mlarge, mdef->data->mlet)) ! 87: mksobj_at(ENORMOUS_ROCK, mdef->mx, mdef->my); ! 88: else ! 89: mksobj_at(ROCK, mdef->mx, mdef->my); ! 90: if(cansee(mdef->mx, mdef->my)){ ! 91: unpmon(mdef); ! 92: atl(mdef->mx,mdef->my,fobj->olet); ! 93: } ! 94: mondead(mdef); ! 95: } ! 96: ! 97: ! 98: fightm(mtmp) register struct monst *mtmp; { ! 99: register struct monst *mon; ! 100: for(mon = fmon; mon; mon = mon->nmon) if(mon != mtmp) { ! 101: if(DIST(mon->mx,mon->my,mtmp->mx,mtmp->my) < 3) ! 102: if(rn2(4)) ! 103: return(hitmm(mtmp,mon)); ! 104: } ! 105: return(-1); ! 106: } ! 107: ! 108: /* u is hit by sth, but not a monster */ ! 109: thitu(tlev,dam,name) ! 110: register tlev,dam; ! 111: register char *name; ! 112: { ! 113: char buf[BUFSZ]; ! 114: setan(name,buf); ! 115: if(u.uac + tlev <= rnd(20)) { ! 116: if(Blind) pline("It misses."); ! 117: else pline("You are almost hit by %s!", buf); ! 118: return(0); ! 119: } else { ! 120: if(Blind) pline("You are hit!"); ! 121: else pline("You are hit by %s!", buf); ! 122: losehp(dam,name); ! 123: return(1); ! 124: } ! 125: } ! 126: ! 127: char mlarge[] = "bCDdegIlmnoPSsTUwY',&"; ! 128: ! 129: boolean ! 130: hmon(mon,obj,thrown) /* return TRUE if mon still alive */ ! 131: register struct monst *mon; ! 132: register struct obj *obj; ! 133: register thrown; ! 134: { ! 135: register tmp; ! 136: boolean hittxt = FALSE; ! 137: ! 138: if(!obj){ ! 139: tmp = rnd(2); /* attack with bare hands */ ! 140: if(mon->data->mlet == 'c' && !uarmg){ ! 141: pline("You hit the cockatrice with your bare hands."); ! 142: pline("You turn to stone ..."); ! 143: done_in_by(mon); ! 144: } ! 145: } else if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE) { ! 146: if(obj == uwep && (obj->otyp > SPEAR || obj->otyp < BOOMERANG)) ! 147: tmp = rnd(2); ! 148: else { ! 149: if(index(mlarge, mon->data->mlet)) { ! 150: tmp = rnd(objects[obj->otyp].wldam); ! 151: if(obj->otyp == TWO_HANDED_SWORD) tmp += d(2,6); ! 152: else if(obj->otyp == FLAIL) tmp += rnd(4); ! 153: } else { ! 154: tmp = rnd(objects[obj->otyp].wsdam); ! 155: } ! 156: tmp += obj->spe; ! 157: if(!thrown && obj == uwep && obj->otyp == BOOMERANG ! 158: && !rn2(3)){ ! 159: pline("As you hit %s, the boomerang breaks into splinters.", ! 160: monnam(mon)); ! 161: freeinv(obj); ! 162: setworn((struct obj *) 0, obj->owornmask); ! 163: obfree(obj, (struct obj *) 0); ! 164: tmp++; ! 165: } ! 166: } ! 167: if(mon->data->mlet == 'O' && obj->otyp == TWO_HANDED_SWORD && ! 168: !strcmp(ONAME(obj), "Orcrist")) ! 169: tmp += rnd(10); ! 170: } else switch(obj->otyp) { ! 171: case HEAVY_IRON_BALL: ! 172: tmp = rnd(25); break; ! 173: case EXPENSIVE_CAMERA: ! 174: pline("You succeed in destroying your camera. Congratulations!"); ! 175: freeinv(obj); ! 176: if(obj->owornmask) ! 177: setworn((struct obj *) 0, obj->owornmask); ! 178: obfree(obj, (struct obj *) 0); ! 179: return(TRUE); ! 180: case DEAD_COCKATRICE: ! 181: pline("You hit %s with the cockatrice corpse.", ! 182: monnam(mon)); ! 183: if(mon->data->mlet == 'c') { ! 184: tmp = 1; ! 185: hittxt = TRUE; ! 186: break; ! 187: } ! 188: pline("%s is turned to stone!", Monnam(mon)); ! 189: killed(mon); ! 190: return(FALSE); ! 191: case CLOVE_OF_GARLIC: /* no effect against demons */ ! 192: if(index(UNDEAD, mon->data->mlet)) ! 193: mon->mflee = 1; ! 194: tmp = 1; ! 195: break; ! 196: default: ! 197: /* non-weapons can damage because of their weight */ ! 198: /* (but not too much) */ ! 199: tmp = obj->owt/10; ! 200: if(tmp < 1) tmp = 1; ! 201: else tmp = rnd(tmp); ! 202: if(tmp > 6) tmp = 6; ! 203: } ! 204: ! 205: /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) */ ! 206: ! 207: tmp += u.udaminc + dbon(); ! 208: if(u.uswallow) { ! 209: if((tmp -= u.uswldtim) <= 0) { ! 210: pline("Your arms are no longer able to hit."); ! 211: return(TRUE); ! 212: } ! 213: } ! 214: if(tmp < 1) tmp = 1; ! 215: mon->mhp -= tmp; ! 216: if(mon->mhp < 1) { ! 217: killed(mon); ! 218: return(FALSE); ! 219: } ! 220: if(mon->mtame && (!mon->mflee || mon->mfleetim)) { ! 221: mon->mflee = 1; /* Rick Richardson */ ! 222: mon->mfleetim += 10*rnd(tmp); ! 223: } ! 224: ! 225: if(!hittxt) { ! 226: if(thrown) ! 227: /* this assumes that we cannot throw plural things */ ! 228: hit( xname(obj) /* or: objects[obj->otyp].oc_name */, ! 229: mon, exclam(tmp) ); ! 230: else if(Blind) ! 231: pline("You hit it."); ! 232: else ! 233: pline("You hit %s%s", monnam(mon), exclam(tmp)); ! 234: } ! 235: ! 236: if(u.umconf && !thrown) { ! 237: if(!Blind) { ! 238: pline("Your hands stop glowing blue."); ! 239: if(!mon->mfroz && !mon->msleep) ! 240: pline("%s appears confused.",Monnam(mon)); ! 241: } ! 242: mon->mconf = 1; ! 243: u.umconf = 0; ! 244: } ! 245: return(TRUE); /* mon still alive */ ! 246: } ! 247: ! 248: /* try to attack; return FALSE if monster evaded */ ! 249: /* u.dx and u.dy must be set */ ! 250: attack(mtmp) ! 251: register struct monst *mtmp; ! 252: { ! 253: schar tmp; ! 254: boolean malive = TRUE; ! 255: register struct permonst *mdat; ! 256: mdat = mtmp->data; ! 257: ! 258: u_wipe_engr(3); /* andrew@orca: prevent unlimited pick-axe attacks */ ! 259: ! 260: if(mdat->mlet == 'L' && !mtmp->mfroz && !mtmp->msleep && ! 261: !mtmp->mconf && mtmp->mcansee && !rn2(7) && ! 262: (m_move(mtmp, 0) == 2 /* he died */ || /* he moved: */ ! 263: mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) ! 264: return(FALSE); ! 265: ! 266: if(mtmp->mimic){ ! 267: if(!u.ustuck && !mtmp->mflee) u.ustuck = mtmp; ! 268: switch(levl[u.ux+u.dx][u.uy+u.dy].scrsym){ ! 269: case '+': ! 270: pline("The door actually was a Mimic."); ! 271: break; ! 272: case '$': ! 273: pline("The chest was a Mimic!"); ! 274: break; ! 275: default: ! 276: pline("Wait! That's a Mimic!"); ! 277: } ! 278: wakeup(mtmp); /* clears mtmp->mimic */ ! 279: return(TRUE); ! 280: } ! 281: ! 282: wakeup(mtmp); ! 283: ! 284: if(mtmp->mhide && mtmp->mundetected){ ! 285: register struct obj *obj; ! 286: ! 287: mtmp->mundetected = 0; ! 288: if((obj = o_at(mtmp->mx,mtmp->my)) && !Blind) ! 289: pline("Wait! There's a %s hiding under %s!", ! 290: mdat->mname, doname(obj)); ! 291: return(TRUE); ! 292: } ! 293: ! 294: tmp = u.uluck + u.ulevel + mdat->ac + abon(); ! 295: if(uwep) { ! 296: if(uwep->olet == WEAPON_SYM || uwep->otyp == PICK_AXE) ! 297: tmp += uwep->spe; ! 298: if(uwep->otyp == TWO_HANDED_SWORD) tmp -= 1; ! 299: else if(uwep->otyp == DAGGER) tmp += 2; ! 300: else if(uwep->otyp == CRYSKNIFE) tmp += 3; ! 301: else if(uwep->otyp == SPEAR && ! 302: index("XDne", mdat->mlet)) tmp += 2; ! 303: } ! 304: if(mtmp->msleep) { ! 305: mtmp->msleep = 0; ! 306: tmp += 2; ! 307: } ! 308: if(mtmp->mfroz) { ! 309: tmp += 4; ! 310: if(!rn2(10)) mtmp->mfroz = 0; ! 311: } ! 312: if(mtmp->mflee) tmp += 2; ! 313: if(u.utrap) tmp -= 3; ! 314: ! 315: /* with a lot of luggage, your agility diminishes */ ! 316: tmp -= (inv_weight() + 40)/20; ! 317: ! 318: if(tmp <= rnd(20) && !u.uswallow){ ! 319: if(Blind) pline("You miss it."); ! 320: else pline("You miss %s.",monnam(mtmp)); ! 321: } else { ! 322: /* we hit the monster; be careful: it might die! */ ! 323: ! 324: if((malive = hmon(mtmp,uwep,0)) == TRUE) { ! 325: /* monster still alive */ ! 326: if(!rn2(25) && mtmp->mhp < mtmp->mhpmax/2) { ! 327: mtmp->mflee = 1; ! 328: if(!rn2(3)) mtmp->mfleetim = rnd(100); ! 329: if(u.ustuck == mtmp && !u.uswallow) ! 330: u.ustuck = 0; ! 331: } ! 332: #ifndef NOWORM ! 333: if(mtmp->wormno) ! 334: cutworm(mtmp, u.ux+u.dx, u.uy+u.dy, ! 335: uwep ? uwep->otyp : 0); ! 336: #endif NOWORM ! 337: } ! 338: if(mdat->mlet == 'a') { ! 339: if(rn2(2)) { ! 340: pline("You are splashed by the blob's acid!"); ! 341: losehp_m(rnd(6), mtmp); ! 342: if(!rn2(30)) corrode_armor(); ! 343: } ! 344: if(!rn2(6)) corrode_weapon(); ! 345: } ! 346: } ! 347: if(malive && mdat->mlet == 'E' && canseemon(mtmp) ! 348: && !mtmp->mcan && rn2(3)) { ! 349: if(mtmp->mcansee) { ! 350: pline("You are frozen by the floating eye's gaze!"); ! 351: nomul((u.ulevel > 6 || rn2(4)) ? rn1(20,-21) : -200); ! 352: } else { ! 353: pline("The blinded floating eye cannot defend itself."); ! 354: if(!rn2(500)) if((int)u.uluck > LUCKMIN) u.uluck--; ! 355: } ! 356: } ! 357: return(TRUE); ! 358: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.