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

Defined functions

doddrop defined in line 79; used 2 times
dodown defined in line 83; used 2 times
dodrop defined in line 15; used 2 times
donull defined in line 242; used 4 times
dopray defined in line 246; used 2 times
dothrow defined in line 253; used 2 times
doup defined in line 102; used 2 times
drop defined in line 24; used 2 times
dropx defined in line 57; used 5 times
dropy defined in line 64; used 3 times
goto_level defined in line 121; used 5 times
set_wounded_legs defined in line 471; used 2 times
splitobj defined in line 443; used 11 times
Last modified: 1985-10-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3858
Valid CSS Valid XHTML 1.0 Strict