Annotation of 43BSDTahoe/games/hack/hack.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
                      2: /* hack.c - version 1.0.3 */
                      3: 
                      4: #include "hack.h"
                      5: #include <stdio.h>
                      6: 
                      7: extern char news0();
                      8: extern char *nomovemsg;
                      9: extern char *exclam();
                     10: extern struct obj *addinv();
                     11: extern boolean hmon();
                     12: 
                     13: /* called on movement:
                     14:        1. when throwing ball+chain far away
                     15:        2. when teleporting
                     16:        3. when walking out of a lit room
                     17:  */
                     18: unsee() {
                     19:        register x,y;
                     20:        register struct rm *lev;
                     21: 
                     22: /*
                     23:        if(u.udispl){
                     24:                u.udispl = 0;
                     25:                newsym(u.udisx, u.udisy);
                     26:        }
                     27: */
                     28: #ifndef QUEST
                     29:        if(seehx){
                     30:                seehx = 0;
                     31:        } else
                     32: #endif QUEST
                     33:        for(x = u.ux-1; x < u.ux+2; x++)
                     34:          for(y = u.uy-1; y < u.uy+2; y++) {
                     35:                if(!isok(x, y)) continue;
                     36:                lev = &levl[x][y];
                     37:                if(!lev->lit && lev->scrsym == '.') {
                     38:                        lev->scrsym =' ';
                     39:                        lev->new = 1;
                     40:                        on_scr(x,y);
                     41:                }
                     42:        }
                     43: }
                     44: 
                     45: /* called:
                     46:        in hack.eat.c: seeoff(0) - blind after eating rotten food
                     47:        in hack.mon.c: seeoff(0) - blinded by a yellow light
                     48:        in hack.mon.c: seeoff(1) - swallowed
                     49:        in hack.do.c:  seeoff(0) - blind after drinking potion
                     50:        in hack.do.c:  seeoff(1) - go up or down the stairs
                     51:        in hack.trap.c:seeoff(1) - fall through trapdoor
                     52:  */
                     53: seeoff(mode)   /* 1 to redo @, 0 to leave them */
                     54: {      /* 1 means misc movement, 0 means blindness */
                     55:        register x,y;
                     56:        register struct rm *lev;
                     57: 
                     58:        if(u.udispl && mode){
                     59:                u.udispl = 0;
                     60:                levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy);
                     61:        }
                     62: #ifndef QUEST
                     63:        if(seehx) {
                     64:                seehx = 0;
                     65:        } else
                     66: #endif QUEST
                     67:        if(!mode) {
                     68:                for(x = u.ux-1; x < u.ux+2; x++)
                     69:                        for(y = u.uy-1; y < u.uy+2; y++) {
                     70:                                if(!isok(x, y)) continue;
                     71:                                lev = &levl[x][y];
                     72:                                if(!lev->lit && lev->scrsym == '.')
                     73:                                        lev->seen = 0;
                     74:                        }
                     75:        }
                     76: }
                     77: 
                     78: domove()
                     79: {
                     80:        xchar oldx,oldy;
                     81:        register struct monst *mtmp;
                     82:        register struct rm *tmpr,*ust;
                     83:        struct trap *trap;
                     84:        register struct obj *otmp;
                     85: 
                     86:        u_wipe_engr(rnd(5));
                     87: 
                     88:        if(inv_weight() > 0){
                     89:                pline("You collapse under your load.");
                     90:                nomul(0);
                     91:                return;
                     92:        }
                     93:        if(u.uswallow) {
                     94:                u.dx = u.dy = 0;
                     95:                u.ux = u.ustuck->mx;
                     96:                u.uy = u.ustuck->my;
                     97:        } else {
                     98:                if(Confusion) {
                     99:                        do {
                    100:                                confdir();
                    101:                        } while(!isok(u.ux+u.dx, u.uy+u.dy) ||
                    102:                            IS_ROCK(levl[u.ux+u.dx][u.uy+u.dy].typ));
                    103:                }
                    104:                if(!isok(u.ux+u.dx, u.uy+u.dy)){
                    105:                        nomul(0);
                    106:                        return;
                    107:                }
                    108:        }
                    109: 
                    110:        ust = &levl[u.ux][u.uy];
                    111:        oldx = u.ux;
                    112:        oldy = u.uy;
                    113:        if(!u.uswallow && (trap = t_at(u.ux+u.dx, u.uy+u.dy)) && trap->tseen)
                    114:                nomul(0);
                    115:        if(u.ustuck && !u.uswallow && (u.ux+u.dx != u.ustuck->mx ||
                    116:                u.uy+u.dy != u.ustuck->my)) {
                    117:                if(dist(u.ustuck->mx, u.ustuck->my) > 2){
                    118:                        /* perhaps it fled (or was teleported or ... ) */
                    119:                        u.ustuck = 0;
                    120:                } else {
                    121:                        if(Blind) pline("You cannot escape from it!");
                    122:                        else pline("You cannot escape from %s!",
                    123:                                monnam(u.ustuck));
                    124:                        nomul(0);
                    125:                        return;
                    126:                }
                    127:        }
                    128:        if(u.uswallow || (mtmp = m_at(u.ux+u.dx,u.uy+u.dy))) {
                    129:        /* attack monster */
                    130: 
                    131:                nomul(0);
                    132:                gethungry();
                    133:                if(multi < 0) return;   /* we just fainted */
                    134: 
                    135:                /* try to attack; note that it might evade */
                    136:                if(attack(u.uswallow ? u.ustuck : mtmp))
                    137:                        return;
                    138:        }
                    139:        /* not attacking an animal, so we try to move */
                    140:        if(u.utrap) {
                    141:                if(u.utraptype == TT_PIT) {
                    142:                        pline("You are still in a pit.");
                    143:                        u.utrap--;
                    144:                } else {
                    145:                        pline("You are caught in a beartrap.");
                    146:                        if((u.dx && u.dy) || !rn2(5)) u.utrap--;
                    147:                }
                    148:                return;
                    149:        }
                    150:        tmpr = &levl[u.ux+u.dx][u.uy+u.dy];
                    151:        if(IS_ROCK(tmpr->typ) ||
                    152:           (u.dx && u.dy && (tmpr->typ == DOOR || ust->typ == DOOR))){
                    153:                flags.move = 0;
                    154:                nomul(0);
                    155:                return;
                    156:        }
                    157:        while(otmp = sobj_at(ENORMOUS_ROCK, u.ux+u.dx, u.uy+u.dy)) {
                    158:                register xchar rx = u.ux+2*u.dx, ry = u.uy+2*u.dy;
                    159:                register struct trap *ttmp;
                    160:                nomul(0);
                    161:                if(isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) &&
                    162:                    (levl[rx][ry].typ != DOOR || !(u.dx && u.dy)) &&
                    163:                    !sobj_at(ENORMOUS_ROCK, rx, ry)) {
                    164:                        if(m_at(rx,ry)) {
                    165:                            pline("You hear a monster behind the rock.");
                    166:                            pline("Perhaps that's why you cannot move it.");
                    167:                            goto cannot_push;
                    168:                        }
                    169:                        if(ttmp = t_at(rx,ry))
                    170:                            switch(ttmp->ttyp) {
                    171:                            case PIT:
                    172:                                pline("You push the rock into a pit!");
                    173:                                deltrap(ttmp);
                    174:                                delobj(otmp);
                    175:                                pline("It completely fills the pit!");
                    176:                                continue;
                    177:                            case TELEP_TRAP:
                    178:                                pline("You push the rock and suddenly it disappears!");
                    179:                                delobj(otmp);
                    180:                                continue;
                    181:                            }
                    182:                        if(levl[rx][ry].typ == POOL) {
                    183:                                levl[rx][ry].typ = ROOM;
                    184:                                mnewsym(rx,ry);
                    185:                                prl(rx,ry);
                    186:                                pline("You push the rock into the water.");
                    187:                                pline("Now you can cross the water!");
                    188:                                delobj(otmp);
                    189:                                continue;
                    190:                        }
                    191:                        otmp->ox = rx;
                    192:                        otmp->oy = ry;
                    193:                        /* pobj(otmp); */
                    194:                        if(cansee(rx,ry)) atl(rx,ry,otmp->olet);
                    195:                        if(Invisible) newsym(u.ux+u.dx, u.uy+u.dy);
                    196: 
                    197:                        { static long lastmovetime;
                    198:                        /* note: this var contains garbage initially and
                    199:                           after a restore */
                    200:                        if(moves > lastmovetime+2 || moves < lastmovetime)
                    201:                        pline("With great effort you move the enormous rock.");
                    202:                        lastmovetime = moves;
                    203:                        }
                    204:                } else {
                    205:                    pline("You try to move the enormous rock, but in vain.");
                    206:            cannot_push:
                    207:                    if((!invent || inv_weight()+90 <= 0) &&
                    208:                        (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ)
                    209:                                        && IS_ROCK(levl[u.ux+u.dx][u.uy].typ)))){
                    210:                        pline("However, you can squeeze yourself into a small opening.");
                    211:                        break;
                    212:                    } else
                    213:                        return;
                    214:                }
                    215:            }
                    216:        if(u.dx && u.dy && IS_ROCK(levl[u.ux][u.uy+u.dy].typ) &&
                    217:                IS_ROCK(levl[u.ux+u.dx][u.uy].typ) &&
                    218:                invent && inv_weight()+40 > 0) {
                    219:                pline("You are carrying too much to get through.");
                    220:                nomul(0);
                    221:                return;
                    222:        }
                    223:        if(Punished &&
                    224:           DIST(u.ux+u.dx, u.uy+u.dy, uchain->ox, uchain->oy) > 2){
                    225:                if(carried(uball)) {
                    226:                        movobj(uchain, u.ux, u.uy);
                    227:                        goto nodrag;
                    228:                }
                    229: 
                    230:                if(DIST(u.ux+u.dx, u.uy+u.dy, uball->ox, uball->oy) < 3){
                    231:                        /* leave ball, move chain under/over ball */
                    232:                        movobj(uchain, uball->ox, uball->oy);
                    233:                        goto nodrag;
                    234:                }
                    235: 
                    236:                if(inv_weight() + (int) uball->owt/2 > 0) {
                    237:                        pline("You cannot %sdrag the heavy iron ball.",
                    238:                        invent ? "carry all that and also " : "");
                    239:                        nomul(0);
                    240:                        return;
                    241:                }
                    242: 
                    243:                movobj(uball, uchain->ox, uchain->oy);
                    244:                unpobj(uball);          /* BAH %% */
                    245:                uchain->ox = u.ux;
                    246:                uchain->oy = u.uy;
                    247:                nomul(-2);
                    248:                nomovemsg = "";
                    249:        nodrag: ;
                    250:        }
                    251:        u.ux += u.dx;
                    252:        u.uy += u.dy;
                    253:        if(flags.run) {
                    254:                if(tmpr->typ == DOOR ||
                    255:                (xupstair == u.ux && yupstair == u.uy) ||
                    256:                (xdnstair == u.ux && ydnstair == u.uy))
                    257:                        nomul(0);
                    258:        }
                    259: 
                    260:        if(tmpr->typ == POOL && !Levitation)
                    261:                drown();        /* not necessarily fatal */
                    262: 
                    263: /*
                    264:        if(u.udispl) {
                    265:                u.udispl = 0;
                    266:                newsym(oldx,oldy);
                    267:        }
                    268: */
                    269:        if(!Blind) {
                    270: #ifdef QUEST
                    271:                setsee();
                    272: #else
                    273:                if(ust->lit) {
                    274:                        if(tmpr->lit) {
                    275:                                if(tmpr->typ == DOOR)
                    276:                                        prl1(u.ux+u.dx,u.uy+u.dy);
                    277:                                else if(ust->typ == DOOR)
                    278:                                        nose1(oldx-u.dx,oldy-u.dy);
                    279:                        } else {
                    280:                                unsee();
                    281:                                prl1(u.ux+u.dx,u.uy+u.dy);
                    282:                        }
                    283:                } else {
                    284:                        if(tmpr->lit) setsee();
                    285:                        else {
                    286:                                prl1(u.ux+u.dx,u.uy+u.dy);
                    287:                                if(tmpr->typ == DOOR) {
                    288:                                        if(u.dy) {
                    289:                                                prl(u.ux-1,u.uy);
                    290:                                                prl(u.ux+1,u.uy);
                    291:                                        } else {
                    292:                                                prl(u.ux,u.uy-1);
                    293:                                                prl(u.ux,u.uy+1);
                    294:                                        }
                    295:                                }
                    296:                        }
                    297:                        nose1(oldx-u.dx,oldy-u.dy);
                    298:                }
                    299: #endif QUEST
                    300:        } else {
                    301:                pru();
                    302:        }
                    303:        if(!flags.nopick) pickup(1);
                    304:        if(trap) dotrap(trap);          /* fall into pit, arrow trap, etc. */
                    305:        (void) inshop();
                    306:        if(!Blind) read_engr_at(u.ux,u.uy);
                    307: }
                    308: 
                    309: movobj(obj, ox, oy)
                    310: register struct obj *obj;
                    311: register int ox, oy;
                    312: {
                    313:        /* Some dirty programming to get display right */
                    314:        freeobj(obj);
                    315:        unpobj(obj);
                    316:        obj->nobj = fobj;
                    317:        fobj = obj;
                    318:        obj->ox = ox;
                    319:        obj->oy = oy;
                    320: }
                    321: 
                    322: dopickup(){
                    323:        if(!g_at(u.ux,u.uy) && !o_at(u.ux,u.uy)) {
                    324:                pline("There is nothing here to pick up.");
                    325:                return(0);
                    326:        }
                    327:        if(Levitation) {
                    328:                pline("You cannot reach the floor.");
                    329:                return(1);
                    330:        }
                    331:        pickup(0);
                    332:        return(1);
                    333: }
                    334: 
                    335: pickup(all)
                    336: {
                    337:        register struct gold *gold;
                    338:        register struct obj *obj, *obj2;
                    339:        register int wt;
                    340: 
                    341:        if(Levitation) return;
                    342:        while(gold = g_at(u.ux,u.uy)) {
                    343:                pline("%ld gold piece%s.", gold->amount, plur(gold->amount));
                    344:                u.ugold += gold->amount;
                    345:                flags.botl = 1;
                    346:                freegold(gold);
                    347:                if(flags.run) nomul(0);
                    348:                if(Invisible) newsym(u.ux,u.uy);
                    349:        }
                    350: 
                    351:        /* check for more than one object */
                    352:        if(!all) {
                    353:                register int ct = 0;
                    354: 
                    355:                for(obj = fobj; obj; obj = obj->nobj)
                    356:                        if(obj->ox == u.ux && obj->oy == u.uy)
                    357:                                if(!Punished || obj != uchain)
                    358:                                        ct++;
                    359:                if(ct < 2)
                    360:                        all++;
                    361:                else
                    362:                        pline("There are several objects here.");
                    363:        }
                    364: 
                    365:        for(obj = fobj; obj; obj = obj2) {
                    366:            obj2 = obj->nobj;   /* perhaps obj will be picked up */
                    367:            if(obj->ox == u.ux && obj->oy == u.uy) {
                    368:                if(flags.run) nomul(0);
                    369: 
                    370:                /* do not pick up uchain */
                    371:                if(Punished && obj == uchain)
                    372:                        continue;
                    373: 
                    374:                if(!all) {
                    375:                        char c;
                    376: 
                    377:                        pline("Pick up %s ? [ynaq]", doname(obj));
                    378:                        while(!index("ynaq ", (c = readchar())))
                    379:                                bell();
                    380:                        if(c == 'q') return;
                    381:                        if(c == 'n') continue;
                    382:                        if(c == 'a') all = 1;
                    383:                }
                    384: 
                    385:                if(obj->otyp == DEAD_COCKATRICE && !uarmg){
                    386:                    pline("Touching the dead cockatrice is a fatal mistake.");
                    387:                    pline("You turn to stone.");
                    388:                    killer = "cockatrice cadaver";
                    389:                    done("died");
                    390:                }
                    391: 
                    392:                if(obj->otyp == SCR_SCARE_MONSTER){
                    393:                  if(!obj->spe) obj->spe = 1;
                    394:                  else {
                    395:                    /* Note: perhaps the 1st pickup failed: you cannot
                    396:                        carry anymore, and so we never dropped it -
                    397:                        let's assume that treading on it twice also
                    398:                        destroys the scroll */
                    399:                    pline("The scroll turns to dust as you pick it up.");
                    400:                    delobj(obj);
                    401:                    continue;
                    402:                  }
                    403:                }
                    404: 
                    405:                wt = inv_weight() + obj->owt;
                    406:                if(wt > 0) {
                    407:                        if(obj->quan > 1) {
                    408:                                /* see how many we can lift */
                    409:                                extern struct obj *splitobj();
                    410:                                int savequan = obj->quan;
                    411:                                int iw = inv_weight();
                    412:                                int qq;
                    413:                                for(qq = 1; qq < savequan; qq++){
                    414:                                        obj->quan = qq;
                    415:                                        if(iw + weight(obj) > 0)
                    416:                                                break;
                    417:                                }
                    418:                                obj->quan = savequan;
                    419:                                qq--;
                    420:                                /* we can carry qq of them */
                    421:                                if(!qq) goto too_heavy;
                    422:                        pline("You can only carry %s of the %s lying here.",
                    423:                                        (qq == 1) ? "one" : "some",
                    424:                                        doname(obj));
                    425:                                (void) splitobj(obj, qq);
                    426:                                /* note: obj2 is set already, so we'll never
                    427:                                 * encounter the other half; if it should be
                    428:                                 * otherwise then write
                    429:                                 *      obj2 = splitobj(obj,qq);
                    430:                                 */
                    431:                                goto lift_some;
                    432:                        }
                    433:                too_heavy:
                    434:                        pline("There %s %s here, but %s.",
                    435:                                (obj->quan == 1) ? "is" : "are",
                    436:                                doname(obj),
                    437:                                !invent ? "it is too heavy for you to lift"
                    438:                                        : "you cannot carry anymore");
                    439:                        break;
                    440:                }
                    441:        lift_some:
                    442:                if(inv_cnt() >= 52) {
                    443:                    pline("Your knapsack cannot accomodate anymore items.");
                    444:                    break;
                    445:                }
                    446:                if(wt > -5) pline("You have a little trouble lifting");
                    447:                freeobj(obj);
                    448:                if(Invisible) newsym(u.ux,u.uy);
                    449:                addtobill(obj);       /* sets obj->unpaid if necessary */
                    450:                { int pickquan = obj->quan;
                    451:                  int mergquan;
                    452:                if(!Blind) obj->dknown = 1;     /* this is done by prinv(),
                    453:                                 but addinv() needs it already for merging */
                    454:                obj = addinv(obj);    /* might merge it with other objects */
                    455:                  mergquan = obj->quan;
                    456:                  obj->quan = pickquan; /* to fool prinv() */
                    457:                prinv(obj);
                    458:                  obj->quan = mergquan;
                    459:                }
                    460:            }
                    461:        }
                    462: }
                    463: 
                    464: /* stop running if we see something interesting */
                    465: /* turn around a corner if that is the only way we can proceed */
                    466: /* do not turn left or right twice */
                    467: lookaround(){
                    468: register x,y,i,x0,y0,m0,i0 = 9;
                    469: register int corrct = 0, noturn = 0;
                    470: register struct monst *mtmp;
                    471: #ifdef lint
                    472:        /* suppress "used before set" message */
                    473:        x0 = y0 = 0;
                    474: #endif lint
                    475:        if(Blind || flags.run == 0) return;
                    476:        if(flags.run == 1 && levl[u.ux][u.uy].typ == ROOM) return;
                    477: #ifdef QUEST
                    478:        if(u.ux0 == u.ux+u.dx && u.uy0 == u.uy+u.dy) goto stop;
                    479: #endif QUEST
                    480:        for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){
                    481:                if(x == u.ux && y == u.uy) continue;
                    482:                if(!levl[x][y].typ) continue;
                    483:                if((mtmp = m_at(x,y)) && !mtmp->mimic &&
                    484:                    (!mtmp->minvis || See_invisible)){
                    485:                        if(!mtmp->mtame || (x == u.ux+u.dx && y == u.uy+u.dy))
                    486:                                goto stop;
                    487:                } else mtmp = 0; /* invisible M cannot influence us */
                    488:                if(x == u.ux-u.dx && y == u.uy-u.dy) continue;
                    489:                switch(levl[x][y].scrsym){
                    490:                case '|':
                    491:                case '-':
                    492:                case '.':
                    493:                case ' ':
                    494:                        break;
                    495:                case '+':
                    496:                        if(x != u.ux && y != u.uy) break;
                    497:                        if(flags.run != 1) goto stop;
                    498:                        /* fall into next case */
                    499:                case CORR_SYM:
                    500:                corr:
                    501:                        if(flags.run == 1 || flags.run == 3) {
                    502:                                i = DIST(x,y,u.ux+u.dx,u.uy+u.dy);
                    503:                                if(i > 2) break;
                    504:                                if(corrct == 1 && DIST(x,y,x0,y0) != 1)
                    505:                                        noturn = 1;
                    506:                                if(i < i0) {
                    507:                                        i0 = i;
                    508:                                        x0 = x;
                    509:                                        y0 = y;
                    510:                                        m0 = mtmp ? 1 : 0;
                    511:                                }
                    512:                        }
                    513:                        corrct++;
                    514:                        break;
                    515:                case '^':
                    516:                        if(flags.run == 1) goto corr;   /* if you must */
                    517:                        if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop;
                    518:                        break;
                    519:                default:        /* e.g. objects or trap or stairs */
                    520:                        if(flags.run == 1) goto corr;
                    521:                        if(mtmp) break;         /* d */
                    522:                stop:
                    523:                        nomul(0);
                    524:                        return;
                    525:                }
                    526:        }
                    527: #ifdef QUEST
                    528:        if(corrct > 0 && (flags.run == 4 || flags.run == 5)) goto stop;
                    529: #endif QUEST
                    530:        if(corrct > 1 && flags.run == 2) goto stop;
                    531:        if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 &&
                    532:                (corrct == 1 || (corrct == 2 && i0 == 1))) {
                    533:                /* make sure that we do not turn too far */
                    534:                if(i0 == 2) {
                    535:                    if(u.dx == y0-u.uy && u.dy == u.ux-x0)
                    536:                        i = 2;          /* straight turn right */
                    537:                    else
                    538:                        i = -2;         /* straight turn left */
                    539:                } else if(u.dx && u.dy) {
                    540:                    if((u.dx == u.dy && y0 == u.uy) ||
                    541:                        (u.dx != u.dy && y0 != u.uy))
                    542:                        i = -1;         /* half turn left */
                    543:                    else
                    544:                        i = 1;          /* half turn right */
                    545:                } else {
                    546:                    if((x0-u.ux == y0-u.uy && !u.dy) ||
                    547:                        (x0-u.ux != y0-u.uy && u.dy))
                    548:                        i = 1;          /* half turn right */
                    549:                    else
                    550:                        i = -1;         /* half turn left */
                    551:                }
                    552:                i += u.last_str_turn;
                    553:                if(i <= 2 && i >= -2) {
                    554:                        u.last_str_turn = i;
                    555:                        u.dx = x0-u.ux, u.dy = y0-u.uy;
                    556:                }
                    557:        }
                    558: }
                    559: 
                    560: /* something like lookaround, but we are not running */
                    561: /* react only to monsters that might hit us */
                    562: monster_nearby() {
                    563: register int x,y;
                    564: register struct monst *mtmp;
                    565:        if(!Blind)
                    566:        for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){
                    567:                if(x == u.ux && y == u.uy) continue;
                    568:                if((mtmp = m_at(x,y)) && !mtmp->mimic && !mtmp->mtame &&
                    569:                        !mtmp->mpeaceful && !index("Ea", mtmp->data->mlet) &&
                    570:                        !mtmp->mfroz && !mtmp->msleep &&  /* aplvax!jcn */
                    571:                        (!mtmp->minvis || See_invisible))
                    572:                        return(1);
                    573:        }
                    574:        return(0);
                    575: }
                    576: 
                    577: #ifdef QUEST
                    578: cansee(x,y) xchar x,y; {
                    579: register int dx,dy,adx,ady,sdx,sdy,dmax,d;
                    580:        if(Blind) return(0);
                    581:        if(!isok(x,y)) return(0);
                    582:        d = dist(x,y);
                    583:        if(d < 3) return(1);
                    584:        if(d > u.uhorizon*u.uhorizon) return(0);
                    585:        if(!levl[x][y].lit)
                    586:                return(0);
                    587:        dx = x - u.ux;  adx = abs(dx);  sdx = sgn(dx);
                    588:        dy = y - u.uy;  ady = abs(dy);  sdy = sgn(dy);
                    589:        if(dx == 0 || dy == 0 || adx == ady){
                    590:                dmax = (dx == 0) ? ady : adx;
                    591:                for(d = 1; d <= dmax; d++)
                    592:                        if(!rroom(sdx*d,sdy*d))
                    593:                                return(0);
                    594:                return(1);
                    595:        } else if(ady > adx){
                    596:                for(d = 1; d <= ady; d++){
                    597:                        if(!rroom(sdx*( (d*adx)/ady ), sdy*d) ||
                    598:                           !rroom(sdx*( (d*adx-1)/ady+1 ), sdy*d))
                    599:                                return(0);
                    600:                }
                    601:                return(1);
                    602:        } else {
                    603:                for(d = 1; d <= adx; d++){
                    604:                        if(!rroom(sdx*d, sdy*( (d*ady)/adx )) ||
                    605:                           !rroom(sdx*d, sdy*( (d*ady-1)/adx+1 )))
                    606:                                return(0);
                    607:                }
                    608:                return(1);
                    609:        }
                    610: }
                    611: 
                    612: rroom(x,y) register int x,y; {
                    613:        return(IS_ROOM(levl[u.ux+x][u.uy+y].typ));
                    614: }
                    615: 
                    616: #else
                    617: 
                    618: cansee(x,y) xchar x,y; {
                    619:        if(Blind || u.uswallow) return(0);
                    620:        if(dist(x,y) < 3) return(1);
                    621:        if(levl[x][y].lit && seelx <= x && x <= seehx && seely <= y &&
                    622:                y <= seehy) return(1);
                    623:        return(0);
                    624: }
                    625: #endif QUEST
                    626: 
                    627: sgn(a) register int a; {
                    628:        return((a > 0) ? 1 : (a == 0) ? 0 : -1);
                    629: }
                    630: 
                    631: #ifdef QUEST
                    632: setsee()
                    633: {
                    634:        register x,y;
                    635: 
                    636:        if(Blind) {
                    637:                pru();
                    638:                return;
                    639:        }
                    640:        for(y = u.uy-u.uhorizon; y <= u.uy+u.uhorizon; y++)
                    641:                for(x = u.ux-u.uhorizon; x <= u.ux+u.uhorizon; x++) {
                    642:                        if(cansee(x,y))
                    643:                                prl(x,y);
                    644:        }
                    645: }
                    646: 
                    647: #else
                    648: 
                    649: setsee()
                    650: {
                    651:        register x,y;
                    652: 
                    653:        if(Blind) {
                    654:                pru();
                    655:                return;
                    656:        }
                    657:        if(!levl[u.ux][u.uy].lit) {
                    658:                seelx = u.ux-1;
                    659:                seehx = u.ux+1;
                    660:                seely = u.uy-1;
                    661:                seehy = u.uy+1;
                    662:        } else {
                    663:                for(seelx = u.ux; levl[seelx-1][u.uy].lit; seelx--);
                    664:                for(seehx = u.ux; levl[seehx+1][u.uy].lit; seehx++);
                    665:                for(seely = u.uy; levl[u.ux][seely-1].lit; seely--);
                    666:                for(seehy = u.uy; levl[u.ux][seehy+1].lit; seehy++);
                    667:        }
                    668:        for(y = seely; y <= seehy; y++)
                    669:                for(x = seelx; x <= seehx; x++) {
                    670:                        prl(x,y);
                    671:        }
                    672:        if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */
                    673:        else {
                    674:            if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1);
                    675:            if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1);
                    676:            if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y);
                    677:            if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y);
                    678:        }
                    679: }
                    680: #endif QUEST
                    681: 
                    682: nomul(nval)
                    683: register nval;
                    684: {
                    685:        if(multi < 0) return;
                    686:        multi = nval;
                    687:        flags.mv = flags.run = 0;
                    688: }
                    689: 
                    690: abon()
                    691: {
                    692:        if(u.ustr == 3) return(-3);
                    693:        else if(u.ustr < 6) return(-2);
                    694:        else if(u.ustr < 8) return(-1);
                    695:        else if(u.ustr < 17) return(0);
                    696:        else if(u.ustr < 69) return(1); /* up to 18/50 */
                    697:        else if(u.ustr < 118) return(2);
                    698:        else return(3);
                    699: }
                    700: 
                    701: dbon()
                    702: {
                    703:        if(u.ustr < 6) return(-1);
                    704:        else if(u.ustr < 16) return(0);
                    705:        else if(u.ustr < 18) return(1);
                    706:        else if(u.ustr == 18) return(2);        /* up to 18 */
                    707:        else if(u.ustr < 94) return(3);         /* up to 18/75 */
                    708:        else if(u.ustr < 109) return(4);        /* up to 18/90 */
                    709:        else if(u.ustr < 118) return(5);        /* up to 18/99 */
                    710:        else return(6);
                    711: }
                    712: 
                    713: losestr(num)   /* may kill you; cause may be poison or monster like 'A' */
                    714: register num;
                    715: {
                    716:        u.ustr -= num;
                    717:        while(u.ustr < 3) {
                    718:                u.ustr++;
                    719:                u.uhp -= 6;
                    720:                u.uhpmax -= 6;
                    721:        }
                    722:        flags.botl = 1;
                    723: }
                    724: 
                    725: losehp(n,knam)
                    726: register n;
                    727: register char *knam;
                    728: {
                    729:        u.uhp -= n;
                    730:        if(u.uhp > u.uhpmax)
                    731:                u.uhpmax = u.uhp;       /* perhaps n was negative */
                    732:        flags.botl = 1;
                    733:        if(u.uhp < 1) {
                    734:                killer = knam;  /* the thing that killed you */
                    735:                done("died");
                    736:        }
                    737: }
                    738: 
                    739: losehp_m(n,mtmp)
                    740: register n;
                    741: register struct monst *mtmp;
                    742: {
                    743:        u.uhp -= n;
                    744:        flags.botl = 1;
                    745:        if(u.uhp < 1)
                    746:                done_in_by(mtmp);
                    747: }
                    748: 
                    749: losexp()       /* hit by V or W */
                    750: {
                    751:        register num;
                    752:        extern long newuexp();
                    753: 
                    754:        if(u.ulevel > 1)
                    755:                pline("Goodbye level %u.", u.ulevel--);
                    756:        else
                    757:                u.uhp = -1;
                    758:        num = rnd(10);
                    759:        u.uhp -= num;
                    760:        u.uhpmax -= num;
                    761:        u.uexp = newuexp();
                    762:        flags.botl = 1;
                    763: }
                    764: 
                    765: inv_weight(){
                    766: register struct obj *otmp = invent;
                    767: register int wt = (u.ugold + 500)/1000;
                    768: register int carrcap;
                    769:        if(Levitation)                  /* pugh@cornell */
                    770:                carrcap = MAX_CARR_CAP;
                    771:        else {
                    772:                carrcap = 5*(((u.ustr > 18) ? 20 : u.ustr) + u.ulevel);
                    773:                if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP;
                    774:                if(Wounded_legs & LEFT_SIDE) carrcap -= 10;
                    775:                if(Wounded_legs & RIGHT_SIDE) carrcap -= 10;
                    776:        }
                    777:        while(otmp){
                    778:                wt += otmp->owt;
                    779:                otmp = otmp->nobj;
                    780:        }
                    781:        return(wt - carrcap);
                    782: }
                    783: 
                    784: inv_cnt(){
                    785: register struct obj *otmp = invent;
                    786: register int ct = 0;
                    787:        while(otmp){
                    788:                ct++;
                    789:                otmp = otmp->nobj;
                    790:        }
                    791:        return(ct);
                    792: }
                    793: 
                    794: long
                    795: newuexp()
                    796: {
                    797:        return(10*(1L << (u.ulevel-1)));
                    798: }

unix.superglobalmegacorp.com

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