|
|
1.1 ! root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ ! 2: /* hack.do.c - version 1.0.3 */ ! 3: ! 4: /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) and 't' (throw) */ ! 5: ! 6: #include "hack.h" ! 7: ! 8: extern struct obj *splitobj(), *addinv(); ! 9: extern boolean hmon(); ! 10: extern boolean level_exists[]; ! 11: extern struct monst youmonst; ! 12: extern char *Doname(); ! 13: extern char *nomovemsg; ! 14: ! 15: dodrop() { ! 16: return(drop(getobj("0$#", "drop"))); ! 17: } ! 18: ! 19: static ! 20: drop(obj) register struct obj *obj; { ! 21: if(!obj) return(0); ! 22: if(obj->olet == '$') { /* pseudo object */ ! 23: register long amount = OGOLD(obj); ! 24: ! 25: if(amount == 0) ! 26: pline("You didn't drop any gold pieces."); ! 27: else { ! 28: mkgold(amount, u.ux, u.uy); ! 29: pline("You dropped %ld gold piece%s.", ! 30: amount, plur(amount)); ! 31: if(Invisible) newsym(u.ux, u.uy); ! 32: } ! 33: free((char *) obj); ! 34: return(1); ! 35: } ! 36: if(obj->owornmask & (W_ARMOR | W_RING)){ ! 37: pline("You cannot drop something you are wearing."); ! 38: return(0); ! 39: } ! 40: if(obj == uwep) { ! 41: if(uwep->cursed) { ! 42: pline("Your weapon is welded to your hand!"); ! 43: return(0); ! 44: } ! 45: setuwep((struct obj *) 0); ! 46: } ! 47: pline("You dropped %s.", doname(obj)); ! 48: dropx(obj); ! 49: return(1); ! 50: } ! 51: ! 52: /* Called in several places - should not produce texts */ ! 53: dropx(obj) ! 54: register struct obj *obj; ! 55: { ! 56: freeinv(obj); ! 57: dropy(obj); ! 58: } ! 59: ! 60: dropy(obj) ! 61: register struct obj *obj; ! 62: { ! 63: if(obj->otyp == CRYSKNIFE) ! 64: obj->otyp = WORM_TOOTH; ! 65: obj->ox = u.ux; ! 66: obj->oy = u.uy; ! 67: obj->nobj = fobj; ! 68: fobj = obj; ! 69: if(Invisible) newsym(u.ux,u.uy); ! 70: subfrombill(obj); ! 71: stackobj(obj); ! 72: } ! 73: ! 74: /* drop several things */ ! 75: doddrop() { ! 76: return(ggetobj("drop", drop, 0)); ! 77: } ! 78: ! 79: dodown() ! 80: { ! 81: if(u.ux != xdnstair || u.uy != ydnstair) { ! 82: pline("You can't go down here."); ! 83: return(0); ! 84: } ! 85: if(u.ustuck) { ! 86: pline("You are being held, and cannot go down."); ! 87: return(1); ! 88: } ! 89: if(Levitation) { ! 90: pline("You're floating high above the stairs."); ! 91: return(0); ! 92: } ! 93: ! 94: goto_level(dlevel+1, TRUE); ! 95: return(1); ! 96: } ! 97: ! 98: doup() ! 99: { ! 100: if(u.ux != xupstair || u.uy != yupstair) { ! 101: pline("You can't go up here."); ! 102: return(0); ! 103: } ! 104: if(u.ustuck) { ! 105: pline("You are being held, and cannot go up."); ! 106: return(1); ! 107: } ! 108: if(!Levitation && inv_weight() + 5 > 0) { ! 109: pline("Your load is too heavy to climb the stairs."); ! 110: return(1); ! 111: } ! 112: ! 113: goto_level(dlevel-1, TRUE); ! 114: return(1); ! 115: } ! 116: ! 117: goto_level(newlevel, at_stairs) ! 118: register int newlevel; ! 119: register boolean at_stairs; ! 120: { ! 121: register fd; ! 122: register boolean up = (newlevel < dlevel); ! 123: ! 124: if(newlevel <= 0) done("escaped"); /* in fact < 0 is impossible */ ! 125: if(newlevel > MAXLEVEL) newlevel = MAXLEVEL; /* strange ... */ ! 126: if(newlevel == dlevel) return; /* this can happen */ ! 127: ! 128: glo(dlevel); ! 129: fd = creat(lock, FMASK); ! 130: if(fd < 0) { ! 131: /* ! 132: * This is not quite impossible: e.g., we may have ! 133: * exceeded our quota. If that is the case then we ! 134: * cannot leave this level, and cannot save either. ! 135: * Another possibility is that the directory was not ! 136: * writable. ! 137: */ ! 138: pline("A mysterious force prevents you from going %s.", ! 139: up ? "up" : "down"); ! 140: return; ! 141: } ! 142: ! 143: if(Punished) unplacebc(); ! 144: u.utrap = 0; /* needed in level_tele */ ! 145: u.ustuck = 0; /* idem */ ! 146: keepdogs(); ! 147: seeoff(1); ! 148: if(u.uswallow) /* idem */ ! 149: u.uswldtim = u.uswallow = 0; ! 150: flags.nscrinh = 1; ! 151: u.ux = FAR; /* hack */ ! 152: (void) inshop(); /* probably was a trapdoor */ ! 153: ! 154: savelev(fd,dlevel); ! 155: (void) close(fd); ! 156: ! 157: dlevel = newlevel; ! 158: if(maxdlevel < dlevel) ! 159: maxdlevel = dlevel; ! 160: glo(dlevel); ! 161: ! 162: if(!level_exists[dlevel]) ! 163: mklev(); ! 164: else { ! 165: extern int hackpid; ! 166: ! 167: if((fd = open(lock,0)) < 0) { ! 168: pline("Cannot open %s .", lock); ! 169: pline("Probably someone removed it."); ! 170: done("tricked"); ! 171: } ! 172: getlev(fd, hackpid, dlevel); ! 173: (void) close(fd); ! 174: } ! 175: ! 176: if(at_stairs) { ! 177: if(up) { ! 178: u.ux = xdnstair; ! 179: u.uy = ydnstair; ! 180: if(!u.ux) { /* entering a maze from below? */ ! 181: u.ux = xupstair; /* this will confuse the player! */ ! 182: u.uy = yupstair; ! 183: } ! 184: if(Punished && !Levitation){ ! 185: pline("With great effort you climb the stairs."); ! 186: placebc(1); ! 187: } ! 188: } else { ! 189: u.ux = xupstair; ! 190: u.uy = yupstair; ! 191: if(inv_weight() + 5 > 0 || Punished){ ! 192: pline("You fall down the stairs."); /* %% */ ! 193: losehp(rnd(3), "fall"); ! 194: if(Punished) { ! 195: if(uwep != uball && rn2(3)){ ! 196: pline("... and are hit by the iron ball."); ! 197: losehp(rnd(20), "iron ball"); ! 198: } ! 199: placebc(1); ! 200: } ! 201: selftouch("Falling, you"); ! 202: } ! 203: } ! 204: { register struct monst *mtmp = m_at(u.ux, u.uy); ! 205: if(mtmp) ! 206: mnexto(mtmp); ! 207: } ! 208: } else { /* trapdoor or level_tele */ ! 209: do { ! 210: u.ux = rnd(COLNO-1); ! 211: u.uy = rn2(ROWNO); ! 212: } while(levl[u.ux][u.uy].typ != ROOM || ! 213: m_at(u.ux,u.uy)); ! 214: if(Punished){ ! 215: if(uwep != uball && !up /* %% */ && rn2(5)){ ! 216: pline("The iron ball falls on your head."); ! 217: losehp(rnd(25), "iron ball"); ! 218: } ! 219: placebc(1); ! 220: } ! 221: selftouch("Falling, you"); ! 222: } ! 223: (void) inshop(); ! 224: initrack(); ! 225: ! 226: losedogs(); ! 227: { register struct monst *mtmp; ! 228: if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp); /* riv05!a3 */ ! 229: } ! 230: flags.nscrinh = 0; ! 231: setsee(); ! 232: seeobjs(); /* make old cadavers disappear - riv05!a3 */ ! 233: docrt(); ! 234: pickup(1); ! 235: read_engr_at(u.ux,u.uy); ! 236: } ! 237: ! 238: donull() { ! 239: return(1); /* Do nothing, but let other things happen */ ! 240: } ! 241: ! 242: dopray() { ! 243: nomovemsg = "You finished your prayer."; ! 244: nomul(-3); ! 245: return(1); ! 246: } ! 247: ! 248: struct monst *bhit(), *boomhit(); ! 249: dothrow() ! 250: { ! 251: register struct obj *obj; ! 252: register struct monst *mon; ! 253: register tmp; ! 254: ! 255: obj = getobj("#)", "throw"); /* it is also possible to throw food */ ! 256: /* (or jewels, or iron balls ... ) */ ! 257: if(!obj || !getdir(1)) /* ask "in what direction?" */ ! 258: return(0); ! 259: if(obj->owornmask & (W_ARMOR | W_RING)){ ! 260: pline("You can't throw something you are wearing."); ! 261: return(0); ! 262: } ! 263: ! 264: u_wipe_engr(2); ! 265: ! 266: if(obj == uwep){ ! 267: if(obj->cursed){ ! 268: pline("Your weapon is welded to your hand."); ! 269: return(1); ! 270: } ! 271: if(obj->quan > 1) ! 272: setuwep(splitobj(obj, 1)); ! 273: else ! 274: setuwep((struct obj *) 0); ! 275: } ! 276: else if(obj->quan > 1) ! 277: (void) splitobj(obj, 1); ! 278: freeinv(obj); ! 279: if(u.uswallow) { ! 280: mon = u.ustuck; ! 281: bhitpos.x = mon->mx; ! 282: bhitpos.y = mon->my; ! 283: } else if(u.dz) { ! 284: if(u.dz < 0) { ! 285: pline("%s hits the ceiling, then falls back on top of your head.", ! 286: Doname(obj)); /* note: obj->quan == 1 */ ! 287: if(obj->olet == POTION_SYM) ! 288: potionhit(&youmonst, obj); ! 289: else { ! 290: if(uarmh) pline("Fortunately, you are wearing a helmet!"); ! 291: losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object"); ! 292: dropy(obj); ! 293: } ! 294: } else { ! 295: pline("%s hits the floor.", Doname(obj)); ! 296: if(obj->otyp == EXPENSIVE_CAMERA) { ! 297: pline("It is shattered in a thousand pieces!"); ! 298: obfree(obj, Null(obj)); ! 299: } else if(obj->otyp == EGG) { ! 300: pline("\"Splash!\""); ! 301: obfree(obj, Null(obj)); ! 302: } else if(obj->olet == POTION_SYM) { ! 303: pline("The flask breaks, and you smell a peculiar odor ..."); ! 304: potionbreathe(obj); ! 305: obfree(obj, Null(obj)); ! 306: } else { ! 307: dropy(obj); ! 308: } ! 309: } ! 310: return(1); ! 311: } else if(obj->otyp == BOOMERANG) { ! 312: mon = boomhit(u.dx, u.dy); ! 313: if(mon == &youmonst) { /* the thing was caught */ ! 314: (void) addinv(obj); ! 315: return(1); ! 316: } ! 317: } else { ! 318: if(obj->otyp == PICK_AXE && shkcatch(obj)) ! 319: return(1); ! 320: ! 321: mon = bhit(u.dx, u.dy, (obj->otyp == ICE_BOX) ? 1 : ! 322: (!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1, ! 323: obj->olet, ! 324: (int (*)()) 0, (int (*)()) 0, obj); ! 325: } ! 326: if(mon) { ! 327: /* awake monster if sleeping */ ! 328: wakeup(mon); ! 329: ! 330: if(obj->olet == WEAPON_SYM) { ! 331: tmp = -1+u.ulevel+mon->data->ac+abon(); ! 332: if(obj->otyp < ROCK) { ! 333: if(!uwep || ! 334: uwep->otyp != obj->otyp+(BOW-ARROW)) ! 335: tmp -= 4; ! 336: else { ! 337: tmp += uwep->spe; ! 338: } ! 339: } else ! 340: if(obj->otyp == BOOMERANG) tmp += 4; ! 341: tmp += obj->spe; ! 342: if(u.uswallow || tmp >= rnd(20)) { ! 343: if(hmon(mon,obj,1) == TRUE){ ! 344: /* mon still alive */ ! 345: #ifndef NOWORM ! 346: cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp); ! 347: #endif NOWORM ! 348: } else mon = 0; ! 349: /* weapons thrown disappear sometimes */ ! 350: if(obj->otyp < BOOMERANG && rn2(3)) { ! 351: /* check bill; free */ ! 352: obfree(obj, (struct obj *) 0); ! 353: return(1); ! 354: } ! 355: } else miss(objects[obj->otyp].oc_name, mon); ! 356: } else if(obj->otyp == HEAVY_IRON_BALL) { ! 357: tmp = -1+u.ulevel+mon->data->ac+abon(); ! 358: if(!Punished || obj != uball) tmp += 2; ! 359: if(u.utrap) tmp -= 2; ! 360: if(u.uswallow || tmp >= rnd(20)) { ! 361: if(hmon(mon,obj,1) == FALSE) ! 362: mon = 0; /* he died */ ! 363: } else miss("iron ball", mon); ! 364: } else if(obj->olet == POTION_SYM && u.ulevel > rn2(15)) { ! 365: potionhit(mon, obj); ! 366: return(1); ! 367: } else { ! 368: if(cansee(bhitpos.x,bhitpos.y)) ! 369: pline("You miss %s.",monnam(mon)); ! 370: else pline("You miss it."); ! 371: if(obj->olet == FOOD_SYM && mon->data->mlet == 'd') ! 372: if(tamedog(mon,obj)) return(1); ! 373: if(obj->olet == GEM_SYM && mon->data->mlet == 'u' && ! 374: !mon->mtame){ ! 375: if(obj->dknown && objects[obj->otyp].oc_name_known){ ! 376: if(objects[obj->otyp].g_val > 0){ ! 377: u.uluck += 5; ! 378: goto valuable; ! 379: } else { ! 380: pline("%s is not interested in your junk.", ! 381: Monnam(mon)); ! 382: } ! 383: } else { /* value unknown to @ */ ! 384: u.uluck++; ! 385: valuable: ! 386: if(u.uluck > LUCKMAX) /* dan@ut-ngp */ ! 387: u.uluck = LUCKMAX; ! 388: pline("%s graciously accepts your gift.", ! 389: Monnam(mon)); ! 390: mpickobj(mon, obj); ! 391: rloc(mon); ! 392: return(1); ! 393: } ! 394: } ! 395: } ! 396: } ! 397: /* the code following might become part of dropy() */ ! 398: if(obj->otyp == CRYSKNIFE) ! 399: obj->otyp = WORM_TOOTH; ! 400: obj->ox = bhitpos.x; ! 401: obj->oy = bhitpos.y; ! 402: obj->nobj = fobj; ! 403: fobj = obj; ! 404: /* prevent him from throwing articles to the exit and escaping */ ! 405: /* subfrombill(obj); */ ! 406: stackobj(obj); ! 407: if(Punished && obj == uball && ! 408: (bhitpos.x != u.ux || bhitpos.y != u.uy)){ ! 409: freeobj(uchain); ! 410: unpobj(uchain); ! 411: if(u.utrap){ ! 412: if(u.utraptype == TT_PIT) ! 413: pline("The ball pulls you out of the pit!"); ! 414: else { ! 415: register long side = ! 416: rn2(3) ? LEFT_SIDE : RIGHT_SIDE; ! 417: pline("The ball pulls you out of the bear trap."); ! 418: pline("Your %s leg is severely damaged.", ! 419: (side == LEFT_SIDE) ? "left" : "right"); ! 420: set_wounded_legs(side, 500+rn2(1000)); ! 421: losehp(2, "thrown ball"); ! 422: } ! 423: u.utrap = 0; ! 424: } ! 425: unsee(); ! 426: uchain->nobj = fobj; ! 427: fobj = uchain; ! 428: u.ux = uchain->ox = bhitpos.x - u.dx; ! 429: u.uy = uchain->oy = bhitpos.y - u.dy; ! 430: setsee(); ! 431: (void) inshop(); ! 432: } ! 433: if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y); ! 434: return(1); ! 435: } ! 436: ! 437: /* split obj so that it gets size num */ ! 438: /* remainder is put in the object structure delivered by this call */ ! 439: struct obj * ! 440: splitobj(obj, num) register struct obj *obj; register int num; { ! 441: register struct obj *otmp; ! 442: otmp = newobj(0); ! 443: *otmp = *obj; /* copies whole structure */ ! 444: otmp->o_id = flags.ident++; ! 445: otmp->onamelth = 0; ! 446: obj->quan = num; ! 447: obj->owt = weight(obj); ! 448: otmp->quan -= num; ! 449: otmp->owt = weight(otmp); /* -= obj->owt ? */ ! 450: obj->nobj = otmp; ! 451: if(obj->unpaid) splitbill(obj,otmp); ! 452: return(otmp); ! 453: } ! 454: ! 455: more_experienced(exp,rexp) ! 456: register int exp, rexp; ! 457: { ! 458: extern char pl_character[]; ! 459: ! 460: u.uexp += exp; ! 461: u.urexp += 4*exp + rexp; ! 462: if(exp) flags.botl = 1; ! 463: if(u.urexp >= ((pl_character[0] == 'W') ? 1000 : 2000)) ! 464: flags.beginner = 0; ! 465: } ! 466: ! 467: set_wounded_legs(side, timex) ! 468: register long side; ! 469: register int timex; ! 470: { ! 471: if(!Wounded_legs || (Wounded_legs & TIMEOUT)) ! 472: Wounded_legs |= side + timex; ! 473: else ! 474: Wounded_legs |= side; ! 475: } ! 476: ! 477: heal_legs() ! 478: { ! 479: if(Wounded_legs) { ! 480: if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES) ! 481: pline("Your legs feel somewhat better."); ! 482: else ! 483: pline("Your leg feels somewhat better."); ! 484: Wounded_legs = 0; ! 485: } ! 486: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.