From fortune!hpda!hplabs!hao!seismo!mcvax!aeb Sun Apr 14 14:12:04 1985 Relay-Version: version B 2.10.2 9/18/84; site wdl1.UUCP Posting-Version: version B 2.10.1 6/24/83 (MC840302); site mcvax.UUCP Path: wdl1!fortune!hpda!hplabs!hao!seismo!mcvax!aeb From: aeb@mcvax.UUCP (Andries Brouwer) Newsgroups: net.sources.games Subject: Hack 1.0.2 - part 10 of 10 Message-ID: <601@mcvax.UUCP> Date: 14 Apr 85 22:12:04 GMT Article-I.D.: mcvax.601 Posted: Sun Apr 14 14:12:04 1985 Date-Received: 17 Apr 85 17:08:37 GMT Reply-To: aeb@mcvax.UUCP (Andries Brouwer) Followup-To: net.games.hack Organization: CWI, Amsterdam Lines: 1701 # This is the tenth and last part of the Hack 1.0.2 distribution. # Unpack it (the 9 other files must already have been unpacked), # edit Makefile in case your termcap library is not found with -ltermlib # (perhaps with -ltermcap ?), edit config.h to reflect your local # situation, and run Makefile. # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # alloc.c rnd.c makedefs.c hack.c hack.wizard.c # and an edit script updating previous parts of the distribution. echo x - alloc.c cat > "alloc.c" << '//E*O*F alloc.c//' /* alloc.c - version 1.0.2 */ #ifdef LINT /* a ridiculous definition, suppressing "possible pointer alignment problem" for (long *) malloc() "enlarg defined but never used" "ftell defined (in ) but never used" from lint */ #include long * alloc(n) unsigned n; { long dummy = ftell(stderr); if(n) dummy = 0; /* make sure arg is used */ return(&dummy); } #else extern char *malloc(); extern char *realloc(); long * alloc(lth) register unsigned lth; { register char *ptr; if(!(ptr = malloc(lth))) panic("Cannot get %d bytes", lth); return((long *) ptr); } long * enlarge(ptr,lth) register char *ptr; register unsigned lth; { register char *nptr; if(!(nptr = realloc(ptr,lth))) panic("Cannot reallocate %d bytes", lth); return((long *) nptr); } #endif LINT //E*O*F alloc.c// echo x - rnd.c cat > "rnd.c" << '//E*O*F rnd.c//' /* rnd.c - version 1.0.2 */ #define RND(x) ((rand()>>3) % x) rn1(x,y) register x,y; { return(RND(x)+y); } rn2(x) register x; { return(RND(x)); } rnd(x) register x; { return(RND(x)+1); } d(n,x) register n,x; { register tmp = n; while(n--) tmp += RND(x); return(tmp); } //E*O*F rnd.c// echo x - makedefs.c cat > "makedefs.c" << '//E*O*F makedefs.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* makedefs.c - version 1.0.2 */ /* construct definitions of object constants */ #define DEF_FILE "def.objects.h" #define LINSZ 1000 #define STRSZ 40 int fd; char string[STRSZ]; main(){ register int index = 0; register int propct = 0; register char *sp; fd = open(DEF_FILE, 0); if(fd < 0) { perror(DEF_FILE); exit(1); } skipuntil("objects[] = {"); while(getentry()) { if(!*string){ index++; continue; } for(sp = string; *sp; sp++) if(*sp == ' ' || *sp == '\t' || *sp == '-') *sp = '_'; if(!strncmp(string, "RIN_", 4)){ capitalize(string+4); printf("#define %s u.uprops[%d].p_flgs\n", string+4, propct++); } for(sp = string; *sp; sp++) capitalize(sp); /* avoid trouble with stupid C preprocessors */ if(!strncmp(string, "WORTHLESS_PIECE_OF_", 19)) printf("/* #define %s %d */\n", string, index); else printf("#define %s %d\n", string, index); index++; } printf("\n#define CORPSE DEAD_HUMAN\n"); printf("#define LAST_GEM (JADE+1)\n"); printf("#define LAST_RING %d\n", propct); printf("#define NROFOBJECTS %d\n", index-1); exit(0); } char line[LINSZ], *lp = line, *lp0 = line, *lpe = line; int eof; readline(){ register int n = read(fd, lp0, (line+LINSZ)-lp0); if(n < 0){ printf("Input error.\n"); exit(1); } if(n == 0) eof++; lpe = lp0+n; } char nextchar(){ if(lp == lpe){ readline(); lp = lp0; } return((lp == lpe) ? 0 : *lp++); } skipuntil(s) char *s; { register char *sp0, *sp1; loop: while(*s != nextchar()) if(eof) { printf("Cannot skipuntil %s\n", s); exit(1); } if(strlen(s) > lpe-lp+1){ register char *lp1, *lp2; lp2 = lp; lp1 = lp = lp0; while(lp2 != lpe) *lp1++ = *lp2++; lp2 = lp0; /* save value */ lp0 = lp1; readline(); lp0 = lp2; if(strlen(s) > lpe-lp+1) { printf("error in skipuntil"); exit(1); } } sp0 = s+1; sp1 = lp; while(*sp0 && *sp0 == *sp1) sp0++, sp1++; if(!*sp0){ lp = sp1; return(1); } goto loop; } getentry(){ int inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0; int prefix = 0; char ch; #define NSZ 10 char identif[NSZ], *ip; string[0] = string[4] = 0; /* read until {...} or XXX(...) followed by , skip comment and #define lines deliver 0 on failure */ while(1) { ch = nextchar(); swi: if(letter(ch)){ ip = identif; do { if(ip < identif+NSZ-1) *ip++ = ch; ch = nextchar(); } while(letter(ch) || digit(ch)); *ip = 0; while(ch == ' ' || ch == '\t') ch = nextchar(); if(ch == '(' && !inparens && !stringseen) if(!strcmp(identif, "WAND") || !strcmp(identif, "RING") || !strcmp(identif, "POTION") || !strcmp(identif, "SCROLL")) (void) strncpy(string, identif, 3), string[3] = '_', prefix = 4; } switch(ch) { case '/': /* watch for comment */ if((ch = nextchar()) == '*') skipuntil("*/"); goto swi; case '{': inbraces++; continue; case '(': inparens++; continue; case '}': inbraces--; if(inbraces < 0) return(0); continue; case ')': inparens--; if(inparens < 0) { printf("too many ) ?"); exit(1); } continue; case '\n': /* watch for #define at begin of line */ if((ch = nextchar()) == '#'){ register char pch; /* skip until '\n' not preceded by '\\' */ do { pch = ch; ch = nextchar(); } while(ch != '\n' || pch == '\\'); continue; } goto swi; case ',': if(!inparens && !inbraces){ if(prefix && !string[prefix]) string[0] = 0; if(stringseen) return(1); printf("unexpected ,\n"); exit(1); } commaseen++; continue; case '\'': if((ch = nextchar()) == '\\') ch = nextchar(); if(nextchar() != '\''){ printf("strange character denotation?\n"); exit(1); } continue; case '"': { register char *sp = string + prefix; register char pch; register int store = (inbraces || inparens) && !stringseen++ && !commaseen; do { pch = ch; ch = nextchar(); if(store && sp < string+STRSZ) *sp++ = ch; } while(ch != '"' || pch == '\\'); if(store) *--sp = 0; continue; } } } } capitalize(sp) register char *sp; { if('a' <= *sp && *sp <= 'z') *sp += 'A'-'a'; } letter(ch) register char ch; { return( ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ); } digit(ch) register char ch; { return( '0' <= ch && ch <= '9' ); } //E*O*F makedefs.c// echo x - hack.c cat > "hack.c" << '//E*O*F hack.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* hack.c - version 1.0.2 */ #include "hack.h" #include 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; if(!u.uswallow) wipe_engr_at(u.ux, u.uy, 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(Invis) 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) { pline("You fall into a pool!"); pline("You can't swim!"); pline("You drown ..."); killer = "pool of water"; done("drowned"); } /* 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(Invis) 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) 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); 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; } } /* do not pick up uchain */ if(Punished && obj == uchain) 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(Invis) 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.dx) 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->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); } pow(num) /* returns 2 to the num */ register unsigned num; { return(1 << num); } #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; 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 = 10*pow(u.ulevel-1); flags.botl = 1; } inv_weight(){ register struct obj *otmp = invent; register int wt = (u.ugold + 500)/1000; register int 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); } //E*O*F hack.c// echo x - hack.wizard.c cat > "hack.wizard.c" << '//E*O*F hack.wizard.c//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* hack.wizard.c - version 1.0.2 */ /* wizard code - inspired by rogue code from Merlyn Leroy (digi-g!brian) */ #include "hack.h" extern struct permonst pm_wizard; extern struct monst *makemon(); #define WIZSHOT 6 /* one chance in WIZSHOT that wizard will try magic */ #define BOLT_LIM 8 /* from this distance D and 1 will try to hit you */ char wizapp[] = "@DNPTUVXcemntx"; /* If he has found the Amulet, make the wizard appear after some time */ amulet(){ register struct obj *otmp; register struct monst *mtmp; if(!flags.made_amulet || !flags.no_of_wizards) return; /* find wizard, and wake him if necessary */ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->data->mlet == '2' && mtmp->msleep && !rn2(40)) for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp->olet == AMULET_SYM && !otmp->spe) { mtmp->msleep = 0; if(dist(mtmp->mx,mtmp->my) > 2) pline( "You get the creepy feeling that somebody noticed your taking the Amulet." ); return; } } wiz_hit(mtmp) register struct monst *mtmp; { /* if we have stolen or found the amulet, we disappear */ if(mtmp->minvent && mtmp->minvent->olet == AMULET_SYM && mtmp->minvent->spe == 0) { /* vanish -- very primitive */ fall_down(mtmp); return(1); } /* if it is lying around someplace, we teleport to it */ if(!carrying(AMULET_OF_YENDOR)) { register struct obj *otmp; for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp->olet == AMULET_SYM && !otmp->spe) { if((u.ux != otmp->ox || u.uy != otmp->oy) && !m_at(otmp->ox, otmp->oy)) { /* teleport to it and pick it up */ mtmp->mx = otmp->ox; mtmp->my = otmp->oy; freeobj(otmp); mpickobj(mtmp, otmp); pmon(mtmp); return(0); } goto hithim; } return(0); /* we don't know where it is */ } hithim: if(rn2(2)) { /* hit - perhaps steal */ /* if hit 1/20 chance of stealing amulet & vanish - amulet is on level 26 again. */ if(hitu(mtmp, d(mtmp->data->damn,mtmp->data->damd)) && !rn2(20) && stealamulet(mtmp)) ; } else inrange(mtmp); /* try magic */ return(0); } inrange(mtmp) register struct monst *mtmp; { register schar tx,ty; /* do nothing if cancelled (but make '1' say something) */ if(mtmp->data->mlet != '1' && mtmp->mcan) return; /* spit fire only when both in a room or both in a corridor */ if(inroom(u.ux,u.uy) != inroom(mtmp->mx,mtmp->my)) return; tx = u.ux - mtmp->mx; ty = u.uy - mtmp->my; if((!tx && abs(ty) < BOLT_LIM) || (!ty && abs(tx) < BOLT_LIM) || (abs(tx) == abs(ty) && abs(tx) < BOLT_LIM)){ switch(mtmp->data->mlet) { case 'D': /* spit fire in the direction of @ (not nec. hitting) */ buzz(-1,mtmp->mx,mtmp->my,sgn(tx),sgn(ty)); break; case '1': if(rn2(WIZSHOT)) break; /* if you zapped wizard with wand of cancellation, he has to shake off the effects before he can throw spells successfully. 1/2 the time they fail anyway */ if(mtmp->mcan || rn2(2)) { if(canseemon(mtmp)) pline("%s makes a gesture, then curses.", Monnam(mtmp)); else pline("You hear mumbled cursing."); if(!rn2(3)) { mtmp->mspeed = 0; mtmp->minvis = 0; } if(!rn2(3)) mtmp->mcan = 0; } else { if(canseemon(mtmp)){ if(!rn2(6) && !Invis) { pline("%s hypnotizes you.", Monnam(mtmp)); nomul(rn2(3) + 3); break; } else pline("%s chants an incantation.", Monnam(mtmp)); } else pline("You hear a mumbled incantation."); switch(rn2(Invis ? 5 : 6)) { case 0: /* create a nasty monster from a deep level */ /* (for the moment, 'nasty' is not implemented) */ (void) makemon((struct permonst *)0, u.ux, u.uy); break; case 1: pline("\"Destroy the thief, my pets!\""); aggravate(); /* aggravate all the monsters */ /* fall into next case */ case 2: if (flags.no_of_wizards == 1 && rnd(5) == 0) /* if only 1 wizard, clone himself */ clonewiz(mtmp); break; case 3: if(mtmp->mspeed == MSLOW) mtmp->mspeed = 0; else mtmp->mspeed = MFAST; break; case 4: mtmp->minvis = 1; break; case 5: /* Only if not Invisible */ pline("You hear a clap of thunder!"); /* shoot a bolt of fire or cold, or a sleep ray */ buzz(-rnd(3),mtmp->mx,mtmp->my,sgn(tx),sgn(ty)); break; } } } if(u.uhp < 1) done_in_by(mtmp); } } aggravate() { register struct monst *mtmp; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { mtmp->msleep = 0; if(mtmp->mfroz && !rn2(5)) mtmp->mfroz = 0; } } clonewiz(mtmp) register struct monst *mtmp; { register struct monst *mtmp2; if(mtmp2 = makemon(PM_WIZARD, mtmp->mx, mtmp->my)) { flags.no_of_wizards = 2; unpmon(mtmp2); mtmp2->mappearance = wizapp[rn2(sizeof(wizapp)-1)]; pmon(mtmp); } } //E*O*F hack.wizard.c// echo editing Makefile ed - Makefile << 'EOI' 76,77c cmp -s $$i $D/$$i || \ ( echo diff $D/$$i $$i ; diff $D/$$i $$i ; echo ) ; done . w q EOI echo editing config.h ed - config.h << 'EOI' 32a #define RUMORFILE "rumors" /* a file with fortune cookies */ #define DATAFILE "data" /* a file giving the meaning of symbols used */ . w q EOI echo editing date.h ed - date.h << 'EOI' 2c char datestring[] = "Sun Apr 14 1985"; . w q EOI echo editing def.flag.h ed - def.flag.h << 'EOI' 17a unsigned female:1; . w q EOI echo editing hack.6 ed - hack.6 << 'EOI' 117a .br xlock.dd Description of a dungeon level. .br safelock Lock file for xlock. .br record_lock Lock file for record. . w q EOI echo editing hack.bones.c ed - hack.bones.c << 'EOI' 17a if(dlevel <= 0 || dlevel >= 30) return; . w q EOI echo editing hack.cmd.c ed - hack.cmd.c << 'EOI' 192a if(buf[0] == '\033') return(0); . 39,40c 'I', dotypeinv, /* Robert Viduya */ 'i', ddoinv, . w q EOI echo editing hack.do.c ed - hack.do.c << 'EOI' 230,232d 225a { register struct monst *mtmp; if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp); /* riv05!a3 */ } . 168d 124c if(newlevel == dlevel) return; /* this can happen */ . w q EOI echo editing hack.do_name.c ed - hack.do_name.c << 'EOI' 164c if(!*buf || *buf == '\033') return; . 159a otemp.onamelth = 0; . 142c break; default: . 138,139c pline("Do you want to name an individual object? [ny] "); switch(readchar()) { case '\033': break; case 'y': . 105c if(!*buf || *buf == '\033') return; . 77c if(!*buf || *buf == '\033') return(1); . w q EOI echo editing hack.eat.c ed - hack.eat.c << 'EOI' 94a if(!Levitation) . w q EOI echo editing hack.end.c ed - hack.end.c << 'EOI' 250c t0->sex = (flags.female ? 'F' : 'M'); . 10d w q EOI echo editing hack.engrave.c ed - hack.engrave.c << 'EOI' 249a head_engr = 0; . 184c if(!len || *buf == '\033') { . w q EOI echo editing hack.invent.c ed - hack.invent.c << 'EOI' 593c if((c == 'u' || c == 'U') && !unpd) { . 585c if(c == 'x' || c == 'X') { . 416,417c if(sym == 'a' || sym == 'A') allflag = TRUE; else if(sym == 'u' || sym == 'U') ckfn = ckunpaid; else . 404a if(buf[0] == '\033') { clrlin(); return(0); } . w q EOI echo editing hack.main.c ed - hack.main.c << 'EOI' 464a (void) fflush(stdout); . 275,279d 269a /* give welcome message before pickup messages */ pline("Hello %s, welcome to %s!", plname, gamename); . 241a pline("Hello %s, welcome to %s!", plname, gamename); . 238c pline("Restoring old save file..."); . 232,234c (void) sprintf(SAVEF, "save/%d%s", getuid(), plname); . 112a u.uhp = 1; /* prevent RIP on early quits */ u.ux = FAR; /* prevent nscr() */ . 25c char SAVEF[PL_NSIZ + 11] = "save/"; /* save/99999player */ . 8a #ifdef QUEST #define gamename "quest" #else #define gamename "hack" #endif QUEST . w q EOI echo editing hack.mklev.c ed - hack.mklev.c << 'EOI' 270,273c rsp->rlx = lx; rsp->rly = ly; rsp->rhx = hx; rsp->rhy = hy; . 252,253c if(lx >= rsp->rlx && hx <= rsp->rhx && ly >= rsp->rly && hy <= rsp->rhy) . 221,222c if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy || (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy) . 161,164c hx = rsp->rhx; hy = rsp->rhy; lx = rsp->rlx; ly = rsp->rly; . 146,148c rsp->rlx = rsp->rly = 0; rsp->rhx = COLNO-1; rsp->rhy = ROWNO-1; . 32c xchar rlx,rly,rhx,rhy; . w q EOI echo editing hack.objnam.c ed - hack.objnam.c << 'EOI' 536c spe = (rn2(10) ? -1 : 0); . 502c if(un && (!(zn = objects[i].oc_uname) || strcmp(un, zn))) . 500c if(dn && (!(zn = objects[i].oc_descr) || strcmp(dn, zn))) . 498c register char *zn = objects[i].oc_name; if(!zn) goto nxti; if(an && strcmp(an, zn)) . w q EOI echo editing hack.options.c ed - hack.options.c << 'EOI' 174c (void) strcat(buf, flags.female ? "female," : "male,"); . 172c if(!buf[0] || buf[0] == '\033') { . 85c flags.female = !negated; . 81c flags.female = negated; . 19c flags.female = FALSE; /* players are usually male */ . 7d w q EOI echo editing hack.pager.c ed - hack.pager.c << 'EOI' 24c if(!(fp = fopen(DATAFILE, "r"))) . w q EOI echo editing hack.rumors.c ed - hack.rumors.c << 'EOI' 7d w q EOI echo editing hack.trap.c ed - hack.trap.c << 'EOI' 382,383c do { pline("To what level do you want to teleport? [type a number] "); getlin(buf); } while(!digit(buf[0])); . w q EOI echo editing hack.tty.c ed - hack.tty.c << 'EOI' 100a return; } if(c == '\033') { *obufp = c; obufp[1] = 0; . 89a /* * Read a line closed with '\n' into the array char bufp[BUFSZ]. * (The '\n' is not stored. The string is closed with a '\0'.) * Reading can be interrupted by an escape ('\033') - now the * resulting string is "\033". */ . w q EOI echo editing hack.u_init.c ed - hack.u_init.c << 'EOI' 100c if(flags.female) /* should have been set in HACKOPTIONS */ . 14d w q EOI echo editing hack.vault.c ed - hack.vault.c << 'EOI' 134,135c do { pline("\"Hello stranger, who are you?\" - "); getlin(buf); } while (!letter(buf[0])); . w q EOI echo editing hack.zap.c ed - hack.zap.c << 'EOI' 172a if(buf[0] == '\033') buf[0] = 0; . w q EOI echo editing help ed - help << 'EOI' 58,63c i print your inventory. I print selected parts of your inventory, like in I* - print all gems in inventory; IU - print all unpaid items; IX - print all used up items that are on your shopping bill; I$ - count your money. . w q EOI echo editing hh ed - hh << 'EOI' 27,31c i invent list the inventory (all objects you are carrying) I invent list selected parts of the inventory IU: list unpaid objects IX: list unpaid but used up items I$: count your money . w q EOI echo editing rumors ed - rumors << 'EOI' 295a Where do you think all those demons come from? From Hell, of course. Where do you think the hell is located? It must be deep, deep down. . 281a Try the fall back end run play against ghosts. . 58a Do you want to visit hell? Dig a *very* deep hole. . w q EOI exit 0