Annotation of 43BSDReno/games/hack/hack.do.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.