diff options
Diffstat (limited to 'games/hack/hack.c')
-rw-r--r-- | games/hack/hack.c | 798 |
1 files changed, 0 insertions, 798 deletions
diff --git a/games/hack/hack.c b/games/hack/hack.c deleted file mode 100644 index 5c8288144ed8..000000000000 --- a/games/hack/hack.c +++ /dev/null @@ -1,798 +0,0 @@ -/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ -/* hack.c - version 1.0.3 */ - -#include "hack.h" -#include <stdio.h> - -extern char news0(); -extern char *nomovemsg; -extern char *exclam(); -extern struct obj *addinv(); -extern boolean hmon(); - -/* called on movement: - 1. when throwing ball+chain far away - 2. when teleporting - 3. when walking out of a lit room - */ -unsee() { - register x,y; - register struct rm *lev; - -/* - if(u.udispl){ - u.udispl = 0; - newsym(u.udisx, u.udisy); - } -*/ -#ifndef QUEST - if(seehx){ - seehx = 0; - } else -#endif QUEST - for(x = u.ux-1; x < u.ux+2; x++) - for(y = u.uy-1; y < u.uy+2; y++) { - if(!isok(x, y)) continue; - lev = &levl[x][y]; - if(!lev->lit && lev->scrsym == '.') { - lev->scrsym =' '; - lev->new = 1; - on_scr(x,y); - } - } -} - -/* called: - in hack.eat.c: seeoff(0) - blind after eating rotten food - in hack.mon.c: seeoff(0) - blinded by a yellow light - in hack.mon.c: seeoff(1) - swallowed - in hack.do.c: seeoff(0) - blind after drinking potion - in hack.do.c: seeoff(1) - go up or down the stairs - in hack.trap.c:seeoff(1) - fall through trapdoor - */ -seeoff(mode) /* 1 to redo @, 0 to leave them */ -{ /* 1 means misc movement, 0 means blindness */ - register x,y; - register struct rm *lev; - - if(u.udispl && mode){ - u.udispl = 0; - levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy); - } -#ifndef QUEST - if(seehx) { - seehx = 0; - } else -#endif QUEST - if(!mode) { - for(x = u.ux-1; x < u.ux+2; x++) - for(y = u.uy-1; y < u.uy+2; y++) { - if(!isok(x, y)) continue; - lev = &levl[x][y]; - if(!lev->lit && lev->scrsym == '.') - lev->seen = 0; - } - } -} - -domove() -{ - xchar oldx,oldy; - register struct monst *mtmp; - register struct rm *tmpr,*ust; - struct trap *trap; - register struct obj *otmp; - - u_wipe_engr(rnd(5)); - - if(inv_weight() > 0){ - pline("You collapse under your load."); - nomul(0); - return; - } - if(u.uswallow) { - u.dx = u.dy = 0; - u.ux = u.ustuck->mx; - u.uy = u.ustuck->my; - } else { - if(Confusion) { - do { - confdir(); - } while(!isok(u.ux+u.dx, u.uy+u.dy) || - IS_ROCK(levl[u.ux+u.dx][u.uy+u.dy].typ)); - } - if(!isok(u.ux+u.dx, u.uy+u.dy)){ - nomul(0); - return; - } - } - - ust = &levl[u.ux][u.uy]; - oldx = u.ux; - oldy = u.uy; - if(!u.uswallow && (trap = t_at(u.ux+u.dx, u.uy+u.dy)) && trap->tseen) - nomul(0); - if(u.ustuck && !u.uswallow && (u.ux+u.dx != u.ustuck->mx || - u.uy+u.dy != u.ustuck->my)) { - if(dist(u.ustuck->mx, u.ustuck->my) > 2){ - /* perhaps it fled (or was teleported or ... ) */ - u.ustuck = 0; - } else { - if(Blind) pline("You cannot escape from it!"); - else pline("You cannot escape from %s!", - monnam(u.ustuck)); - nomul(0); - return; - } - } - if(u.uswallow || (mtmp = m_at(u.ux+u.dx,u.uy+u.dy))) { - /* attack monster */ - - nomul(0); - gethungry(); - if(multi < 0) return; /* we just fainted */ - - /* try to attack; note that it might evade */ - if(attack(u.uswallow ? u.ustuck : mtmp)) - return; - } - /* not attacking an animal, so we try to move */ - if(u.utrap) { - if(u.utraptype == TT_PIT) { - pline("You are still in a pit."); - u.utrap--; - } else { - pline("You are caught in a beartrap."); - if((u.dx && u.dy) || !rn2(5)) u.utrap--; - } - return; - } - tmpr = &levl[u.ux+u.dx][u.uy+u.dy]; - if(IS_ROCK(tmpr->typ) || - (u.dx && u.dy && (tmpr->typ == DOOR || ust->typ == DOOR))){ - flags.move = 0; - nomul(0); - return; - } - while(otmp = sobj_at(ENORMOUS_ROCK, u.ux+u.dx, u.uy+u.dy)) { - register xchar rx = u.ux+2*u.dx, ry = u.uy+2*u.dy; - register struct trap *ttmp; - nomul(0); - if(isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) && - (levl[rx][ry].typ != DOOR || !(u.dx && u.dy)) && - !sobj_at(ENORMOUS_ROCK, rx, ry)) { - if(m_at(rx,ry)) { - pline("You hear a monster behind the rock."); - pline("Perhaps that's why you cannot move it."); - goto cannot_push; - } - if(ttmp = t_at(rx,ry)) - switch(ttmp->ttyp) { - case PIT: - pline("You push the rock into a pit!"); - deltrap(ttmp); - delobj(otmp); - pline("It completely fills the pit!"); - continue; - case TELEP_TRAP: - pline("You push the rock and suddenly it disappears!"); - delobj(otmp); - continue; - } - if(levl[rx][ry].typ == POOL) { - levl[rx][ry].typ = ROOM; - mnewsym(rx,ry); - prl(rx,ry); - pline("You push the rock into the water."); - pline("Now you can cross the water!"); - delobj(otmp); - continue; - } - otmp->ox = rx; - otmp->oy = ry; - /* pobj(otmp); */ - if(cansee(rx,ry)) atl(rx,ry,otmp->olet); - if(Invisible) newsym(u.ux+u.dx, u.uy+u.dy); - - { static long lastmovetime; - /* note: this var contains garbage initially and - after a restore */ - if(moves > lastmovetime+2 || moves < lastmovetime) - pline("With great effort you move the enormous rock."); - lastmovetime = moves; - } - } else { - pline("You try to move the enormous rock, but in vain."); - cannot_push: - if((!invent || inv_weight()+90 <= 0) && - (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ) - && IS_ROCK(levl[u.ux+u.dx][u.uy].typ)))){ - pline("However, you can squeeze yourself into a small opening."); - break; - } else - return; - } - } - if(u.dx && u.dy && IS_ROCK(levl[u.ux][u.uy+u.dy].typ) && - IS_ROCK(levl[u.ux+u.dx][u.uy].typ) && - invent && inv_weight()+40 > 0) { - pline("You are carrying too much to get through."); - nomul(0); - return; - } - if(Punished && - DIST(u.ux+u.dx, u.uy+u.dy, uchain->ox, uchain->oy) > 2){ - if(carried(uball)) { - movobj(uchain, u.ux, u.uy); - goto nodrag; - } - - if(DIST(u.ux+u.dx, u.uy+u.dy, uball->ox, uball->oy) < 3){ - /* leave ball, move chain under/over ball */ - movobj(uchain, uball->ox, uball->oy); - goto nodrag; - } - - if(inv_weight() + (int) uball->owt/2 > 0) { - pline("You cannot %sdrag the heavy iron ball.", - invent ? "carry all that and also " : ""); - nomul(0); - return; - } - - movobj(uball, uchain->ox, uchain->oy); - unpobj(uball); /* BAH %% */ - uchain->ox = u.ux; - uchain->oy = u.uy; - nomul(-2); - nomovemsg = ""; - nodrag: ; - } - u.ux += u.dx; - u.uy += u.dy; - if(flags.run) { - if(tmpr->typ == DOOR || - (xupstair == u.ux && yupstair == u.uy) || - (xdnstair == u.ux && ydnstair == u.uy)) - nomul(0); - } - - if(tmpr->typ == POOL && !Levitation) - drown(); /* not necessarily fatal */ - -/* - if(u.udispl) { - u.udispl = 0; - newsym(oldx,oldy); - } -*/ - if(!Blind) { -#ifdef QUEST - setsee(); -#else - if(ust->lit) { - if(tmpr->lit) { - if(tmpr->typ == DOOR) - prl1(u.ux+u.dx,u.uy+u.dy); - else if(ust->typ == DOOR) - nose1(oldx-u.dx,oldy-u.dy); - } else { - unsee(); - prl1(u.ux+u.dx,u.uy+u.dy); - } - } else { - if(tmpr->lit) setsee(); - else { - prl1(u.ux+u.dx,u.uy+u.dy); - if(tmpr->typ == DOOR) { - if(u.dy) { - prl(u.ux-1,u.uy); - prl(u.ux+1,u.uy); - } else { - prl(u.ux,u.uy-1); - prl(u.ux,u.uy+1); - } - } - } - nose1(oldx-u.dx,oldy-u.dy); - } -#endif QUEST - } else { - pru(); - } - if(!flags.nopick) pickup(1); - if(trap) dotrap(trap); /* fall into pit, arrow trap, etc. */ - (void) inshop(); - if(!Blind) read_engr_at(u.ux,u.uy); -} - -movobj(obj, ox, oy) -register struct obj *obj; -register int ox, oy; -{ - /* Some dirty programming to get display right */ - freeobj(obj); - unpobj(obj); - obj->nobj = fobj; - fobj = obj; - obj->ox = ox; - obj->oy = oy; -} - -dopickup(){ - if(!g_at(u.ux,u.uy) && !o_at(u.ux,u.uy)) { - pline("There is nothing here to pick up."); - return(0); - } - if(Levitation) { - pline("You cannot reach the floor."); - return(1); - } - pickup(0); - return(1); -} - -pickup(all) -{ - register struct gold *gold; - register struct obj *obj, *obj2; - register int wt; - - if(Levitation) return; - while(gold = g_at(u.ux,u.uy)) { - pline("%ld gold piece%s.", gold->amount, plur(gold->amount)); - u.ugold += gold->amount; - flags.botl = 1; - freegold(gold); - if(flags.run) nomul(0); - if(Invisible) newsym(u.ux,u.uy); - } - - /* check for more than one object */ - if(!all) { - register int ct = 0; - - for(obj = fobj; obj; obj = obj->nobj) - if(obj->ox == u.ux && obj->oy == u.uy) - if(!Punished || obj != uchain) - ct++; - if(ct < 2) - all++; - else - pline("There are several objects here."); - } - - for(obj = fobj; obj; obj = obj2) { - obj2 = obj->nobj; /* perhaps obj will be picked up */ - if(obj->ox == u.ux && obj->oy == u.uy) { - if(flags.run) nomul(0); - - /* do not pick up uchain */ - if(Punished && obj == uchain) - continue; - - if(!all) { - char c; - - pline("Pick up %s ? [ynaq]", doname(obj)); - while(!index("ynaq ", (c = readchar()))) - bell(); - if(c == 'q') return; - if(c == 'n') continue; - if(c == 'a') all = 1; - } - - if(obj->otyp == DEAD_COCKATRICE && !uarmg){ - pline("Touching the dead cockatrice is a fatal mistake."); - pline("You turn to stone."); - killer = "cockatrice cadaver"; - done("died"); - } - - if(obj->otyp == SCR_SCARE_MONSTER){ - if(!obj->spe) obj->spe = 1; - else { - /* Note: perhaps the 1st pickup failed: you cannot - carry anymore, and so we never dropped it - - let's assume that treading on it twice also - destroys the scroll */ - pline("The scroll turns to dust as you pick it up."); - delobj(obj); - continue; - } - } - - wt = inv_weight() + obj->owt; - if(wt > 0) { - if(obj->quan > 1) { - /* see how many we can lift */ - extern struct obj *splitobj(); - int savequan = obj->quan; - int iw = inv_weight(); - int qq; - for(qq = 1; qq < savequan; qq++){ - obj->quan = qq; - if(iw + weight(obj) > 0) - break; - } - obj->quan = savequan; - qq--; - /* we can carry qq of them */ - if(!qq) goto too_heavy; - pline("You can only carry %s of the %s lying here.", - (qq == 1) ? "one" : "some", - doname(obj)); - (void) splitobj(obj, qq); - /* note: obj2 is set already, so we'll never - * encounter the other half; if it should be - * otherwise then write - * obj2 = splitobj(obj,qq); - */ - goto lift_some; - } - too_heavy: - pline("There %s %s here, but %s.", - (obj->quan == 1) ? "is" : "are", - doname(obj), - !invent ? "it is too heavy for you to lift" - : "you cannot carry anymore"); - break; - } - lift_some: - if(inv_cnt() >= 52) { - pline("Your knapsack cannot accomodate anymore items."); - break; - } - if(wt > -5) pline("You have a little trouble lifting"); - freeobj(obj); - if(Invisible) newsym(u.ux,u.uy); - addtobill(obj); /* sets obj->unpaid if necessary */ - { int pickquan = obj->quan; - int mergquan; - if(!Blind) obj->dknown = 1; /* this is done by prinv(), - but addinv() needs it already for merging */ - obj = addinv(obj); /* might merge it with other objects */ - mergquan = obj->quan; - obj->quan = pickquan; /* to fool prinv() */ - prinv(obj); - obj->quan = mergquan; - } - } - } -} - -/* stop running if we see something interesting */ -/* turn around a corner if that is the only way we can proceed */ -/* do not turn left or right twice */ -lookaround(){ -register x,y,i,x0,y0,m0,i0 = 9; -register int corrct = 0, noturn = 0; -register struct monst *mtmp; -#ifdef lint - /* suppress "used before set" message */ - x0 = y0 = 0; -#endif lint - if(Blind || flags.run == 0) return; - if(flags.run == 1 && levl[u.ux][u.uy].typ == ROOM) return; -#ifdef QUEST - if(u.ux0 == u.ux+u.dx && u.uy0 == u.uy+u.dy) goto stop; -#endif QUEST - for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){ - if(x == u.ux && y == u.uy) continue; - if(!levl[x][y].typ) continue; - if((mtmp = m_at(x,y)) && !mtmp->mimic && - (!mtmp->minvis || See_invisible)){ - if(!mtmp->mtame || (x == u.ux+u.dx && y == u.uy+u.dy)) - goto stop; - } else mtmp = 0; /* invisible M cannot influence us */ - if(x == u.ux-u.dx && y == u.uy-u.dy) continue; - switch(levl[x][y].scrsym){ - case '|': - case '-': - case '.': - case ' ': - break; - case '+': - if(x != u.ux && y != u.uy) break; - if(flags.run != 1) goto stop; - /* fall into next case */ - case CORR_SYM: - corr: - if(flags.run == 1 || flags.run == 3) { - i = DIST(x,y,u.ux+u.dx,u.uy+u.dy); - if(i > 2) break; - if(corrct == 1 && DIST(x,y,x0,y0) != 1) - noturn = 1; - if(i < i0) { - i0 = i; - x0 = x; - y0 = y; - m0 = mtmp ? 1 : 0; - } - } - corrct++; - break; - case '^': - if(flags.run == 1) goto corr; /* if you must */ - if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; - break; - default: /* e.g. objects or trap or stairs */ - if(flags.run == 1) goto corr; - if(mtmp) break; /* d */ - stop: - nomul(0); - return; - } - } -#ifdef QUEST - if(corrct > 0 && (flags.run == 4 || flags.run == 5)) goto stop; -#endif QUEST - if(corrct > 1 && flags.run == 2) goto stop; - if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 && - (corrct == 1 || (corrct == 2 && i0 == 1))) { - /* make sure that we do not turn too far */ - if(i0 == 2) { - if(u.dx == y0-u.uy && u.dy == u.ux-x0) - i = 2; /* straight turn right */ - else - i = -2; /* straight turn left */ - } else if(u.dx && u.dy) { - if((u.dx == u.dy && y0 == u.uy) || - (u.dx != u.dy && y0 != u.uy)) - i = -1; /* half turn left */ - else - i = 1; /* half turn right */ - } else { - if((x0-u.ux == y0-u.uy && !u.dy) || - (x0-u.ux != y0-u.uy && u.dy)) - i = 1; /* half turn right */ - else - i = -1; /* half turn left */ - } - i += u.last_str_turn; - if(i <= 2 && i >= -2) { - u.last_str_turn = i; - u.dx = x0-u.ux, u.dy = y0-u.uy; - } - } -} - -/* something like lookaround, but we are not running */ -/* react only to monsters that might hit us */ -monster_nearby() { -register int x,y; -register struct monst *mtmp; - if(!Blind) - for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){ - if(x == u.ux && y == u.uy) continue; - if((mtmp = m_at(x,y)) && !mtmp->mimic && !mtmp->mtame && - !mtmp->mpeaceful && !index("Ea", mtmp->data->mlet) && - !mtmp->mfroz && !mtmp->msleep && /* aplvax!jcn */ - (!mtmp->minvis || See_invisible)) - return(1); - } - return(0); -} - -#ifdef QUEST -cansee(x,y) xchar x,y; { -register int dx,dy,adx,ady,sdx,sdy,dmax,d; - if(Blind) return(0); - if(!isok(x,y)) return(0); - d = dist(x,y); - if(d < 3) return(1); - if(d > u.uhorizon*u.uhorizon) return(0); - if(!levl[x][y].lit) - return(0); - dx = x - u.ux; adx = abs(dx); sdx = sgn(dx); - dy = y - u.uy; ady = abs(dy); sdy = sgn(dy); - if(dx == 0 || dy == 0 || adx == ady){ - dmax = (dx == 0) ? ady : adx; - for(d = 1; d <= dmax; d++) - if(!rroom(sdx*d,sdy*d)) - return(0); - return(1); - } else if(ady > adx){ - for(d = 1; d <= ady; d++){ - if(!rroom(sdx*( (d*adx)/ady ), sdy*d) || - !rroom(sdx*( (d*adx-1)/ady+1 ), sdy*d)) - return(0); - } - return(1); - } else { - for(d = 1; d <= adx; d++){ - if(!rroom(sdx*d, sdy*( (d*ady)/adx )) || - !rroom(sdx*d, sdy*( (d*ady-1)/adx+1 ))) - return(0); - } - return(1); - } -} - -rroom(x,y) register int x,y; { - return(IS_ROOM(levl[u.ux+x][u.uy+y].typ)); -} - -#else - -cansee(x,y) xchar x,y; { - if(Blind || u.uswallow) return(0); - if(dist(x,y) < 3) return(1); - if(levl[x][y].lit && seelx <= x && x <= seehx && seely <= y && - y <= seehy) return(1); - return(0); -} -#endif QUEST - -sgn(a) register int a; { - return((a > 0) ? 1 : (a == 0) ? 0 : -1); -} - -#ifdef QUEST -setsee() -{ - register x,y; - - if(Blind) { - pru(); - return; - } - for(y = u.uy-u.uhorizon; y <= u.uy+u.uhorizon; y++) - for(x = u.ux-u.uhorizon; x <= u.ux+u.uhorizon; x++) { - if(cansee(x,y)) - prl(x,y); - } -} - -#else - -setsee() -{ - register x,y; - - if(Blind) { - pru(); - return; - } - if(!levl[u.ux][u.uy].lit) { - seelx = u.ux-1; - seehx = u.ux+1; - seely = u.uy-1; - seehy = u.uy+1; - } else { - for(seelx = u.ux; levl[seelx-1][u.uy].lit; seelx--); - for(seehx = u.ux; levl[seehx+1][u.uy].lit; seehx++); - for(seely = u.uy; levl[u.ux][seely-1].lit; seely--); - for(seehy = u.uy; levl[u.ux][seehy+1].lit; seehy++); - } - for(y = seely; y <= seehy; y++) - for(x = seelx; x <= seehx; x++) { - prl(x,y); - } - if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */ - else { - if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1); - if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1); - if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y); - if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y); - } -} -#endif QUEST - -nomul(nval) -register nval; -{ - if(multi < 0) return; - multi = nval; - flags.mv = flags.run = 0; -} - -abon() -{ - if(u.ustr == 3) return(-3); - else if(u.ustr < 6) return(-2); - else if(u.ustr < 8) return(-1); - else if(u.ustr < 17) return(0); - else if(u.ustr < 69) return(1); /* up to 18/50 */ - else if(u.ustr < 118) return(2); - else return(3); -} - -dbon() -{ - if(u.ustr < 6) return(-1); - else if(u.ustr < 16) return(0); - else if(u.ustr < 18) return(1); - else if(u.ustr == 18) return(2); /* up to 18 */ - else if(u.ustr < 94) return(3); /* up to 18/75 */ - else if(u.ustr < 109) return(4); /* up to 18/90 */ - else if(u.ustr < 118) return(5); /* up to 18/99 */ - else return(6); -} - -losestr(num) /* may kill you; cause may be poison or monster like 'A' */ -register num; -{ - u.ustr -= num; - while(u.ustr < 3) { - u.ustr++; - u.uhp -= 6; - u.uhpmax -= 6; - } - flags.botl = 1; -} - -losehp(n,knam) -register n; -register char *knam; -{ - u.uhp -= n; - if(u.uhp > u.uhpmax) - u.uhpmax = u.uhp; /* perhaps n was negative */ - flags.botl = 1; - if(u.uhp < 1) { - killer = knam; /* the thing that killed you */ - done("died"); - } -} - -losehp_m(n,mtmp) -register n; -register struct monst *mtmp; -{ - u.uhp -= n; - flags.botl = 1; - if(u.uhp < 1) - done_in_by(mtmp); -} - -losexp() /* hit by V or W */ -{ - register num; - extern long newuexp(); - - if(u.ulevel > 1) - pline("Goodbye level %u.", u.ulevel--); - else - u.uhp = -1; - num = rnd(10); - u.uhp -= num; - u.uhpmax -= num; - u.uexp = newuexp(); - flags.botl = 1; -} - -inv_weight(){ -register struct obj *otmp = invent; -register int wt = (u.ugold + 500)/1000; -register int carrcap; - if(Levitation) /* pugh@cornell */ - carrcap = MAX_CARR_CAP; - else { - carrcap = 5*(((u.ustr > 18) ? 20 : u.ustr) + u.ulevel); - if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP; - if(Wounded_legs & LEFT_SIDE) carrcap -= 10; - if(Wounded_legs & RIGHT_SIDE) carrcap -= 10; - } - while(otmp){ - wt += otmp->owt; - otmp = otmp->nobj; - } - return(wt - carrcap); -} - -inv_cnt(){ -register struct obj *otmp = invent; -register int ct = 0; - while(otmp){ - ct++; - otmp = otmp->nobj; - } - return(ct); -} - -long -newuexp() -{ - return(10*(1L << (u.ulevel-1))); -} |