games-request@tekred.TEK.COM (07/28/87)
Submitted by: mike@genat.UUCP (Mike Stephenson)
Comp.sources.games: Volume 2, Issue 10
Archive-name: nethack/Part10
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 10 (of 16)."
# Contents: gen.h monmove.c pcmain.c topten.c vault.c wizard.c
# Wrapped by billr@tekred on Tue Jul 28 09:49:38 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f gen.h -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"gen.h\"
else
echo shar: Extracting \"gen.h\" \(446 characters\)
sed "s/^X//" >gen.h <<'END_OF_gen.h'
X/* SCCS Id: @(#)gen.h 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* gen.h version 1.0.1: added ONCE flag */
X
Xstruct gen {
X struct gen *ngen;
X xchar gx,gy;
X unsigned gflag; /* 037: trap type; 040: SEEN flag */
X /* 0100: ONCE only */
X#define TRAPTYPE 037
X#define SEEN 040
X#define ONCE 0100
X};
Xextern struct gen *fgold, *ftrap;
Xstruct gen *g_at();
X#define newgen() (struct gen *) alloc(sizeof(struct gen))
END_OF_gen.h
if test 446 -ne `wc -c <gen.h`; then
echo shar: \"gen.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f monmove.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"monmove.c\"
else
echo shar: Extracting \"monmove.c\" \(10327 characters\)
sed "s/^X//" >monmove.c <<'END_OF_monmove.c'
X/* SCCS Id: @(#)monmove.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* monmove.c - version 1.0 */
X
X#include "hack.h"
X#include "mfndpos.h"
X#define NULL (char *) 0
X
Xextern int warnlevel; /* defined in mon.c */
X
Xdochugw(mtmp) register struct monst *mtmp; {
Xregister x = mtmp->mx;
Xregister y = mtmp->my;
Xregister d = dochug(mtmp);
Xregister dd;
X if(!d) /* monster still alive */
X if(Warning)
X if(!mtmp->mpeaceful)
X if(mtmp->data->mlevel > warnlevel)
X if((dd = dist(mtmp->mx,mtmp->my)) < dist(x,y))
X if(dd < 100)
X if(!canseemon(mtmp))
X warnlevel = mtmp->data->mlevel;
X return(d);
X}
X
X/* returns 1 if monster died moving, 0 otherwise */
Xdochug(mtmp)
Xregister struct monst *mtmp;
X{
X register struct permonst *mdat;
X register tmp, nearby, scared, onscary;
X
X if(mtmp->cham && !rn2(6))
X (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
X mdat = mtmp->data;
X if(mdat->mlevel < 0)
X panic("bad monster %c (%d)",mdat->mlet,mdat->mlevel);
X
X /* regenerate monsters */
X if((!(moves%20) || index(MREGEN, mdat->mlet)) &&
X mtmp->mhp < mtmp->mhpmax)
X mtmp->mhp++;
X
X if(mtmp->mfroz) {
X if (Hallucination) pmon(mtmp);
X return(0); /* frozen monsters don't do anything */
X }
X
X if(mtmp->msleep) /* there is a chance we will wake it */
X if(!disturb(mtmp)) return(0);
X
X /* not frozen or sleeping: wipe out texts written in the dust */
X wipe_engr_at(mtmp->mx, mtmp->my, 1);
X
X /* confused monsters get unconfused with small probability */
X if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0;
X
X /* some monsters teleport */
X if(mtmp->mflee && index("tNL", mdat->mlet) && !rn2(40)){
X rloc(mtmp);
X return(0);
X }
X if(mdat->mmove < rnd(6)) return(0);
X
X /* fleeing monsters might regain courage */
X if(mtmp->mflee && !mtmp->mfleetim
X && mtmp->mhp == mtmp->mhpmax && !rn2(25))
X mtmp->mflee = 0;
X
X nearby = (dist(mtmp->mx, mtmp->my) < 3);
X onscary = (sengr_at("Elbereth", u.ux, u.uy) ||
X sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy));
X scared = (nearby && onscary && !mtmp->mtame && mtmp->mcansee);
X if(scared && !mtmp->mflee) {
X mtmp->mflee = 1;
X mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
X }
X
X if(!nearby ||
X mtmp->mflee || scared ||
X mtmp->mconf ||
X (mtmp->minvis && !rn2(3)) ||
X#ifndef KOPS
X (index("BIuy", mdat->mlet) && !rn2(4)) ||
X#else
X (index("KBIuy", mdat->mlet) && !rn2(4)) ||
X#endif
X (mdat->mlet == 'L' && !u.ugold && (mtmp->mgold || rn2(2))) ||
X (!mtmp->mcansee && !rn2(4)) ||
X mtmp->mpeaceful
X ) {
X tmp = m_move(mtmp,0); /* 2: monster died moving */
X if(tmp == 2 || (tmp && mdat->mmove <= 12))
X return(tmp == 2);
X
X if(Hallucination && tmp==0) pmon(mtmp);
X/* If 0, this means the monster didn't move. During hallucination, its
X appearance should still change. */
X
X#ifdef HARD
X /* Without this line, fast monsters don't hit you when they've
X * caught up to you. -dgk
X */
X nearby = (dist(mtmp->mx, mtmp->my) < 3);
X scared = (nearby && onscary);
X if(scared && !mtmp->mflee) {
X mtmp->mflee = 1;
X mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
X }
X#endif
X }
X#ifdef HARD /* Demonic Blackmail!!! */
X if(mdat->mlet == '&' && mtmp->mpeaceful && !mtmp->mtame)
X if(demon_talk(mtmp))
X return(1); /* you paid it off */
X#endif
X if(!index("Ea", mdat->mlet) && nearby &&
X !mtmp->mpeaceful && u.uhp > 0 && !scared) {
X if(mhitu(mtmp))
X return(1); /* monster died (e.g. 'y' or 'F') */
X }
X /* extra movement for fast monsters */
X if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp,1);
X return(tmp == 2);
X}
X
Xm_move(mtmp,after)
Xregister struct monst *mtmp;
X{
X#ifndef REGBUG
X register
X#endif
X struct monst *mtmp2;
X#ifndef REGBUG
X register
X#endif
X int nx,ny,omx,omy,appr,nearer,cnt,i,j;
X xchar gx,gy,nix,niy,chcnt;
X schar chi;
X boolean likegold, likegems, likeobjs;
X#ifdef KAA
X boolean likerock;
X#endif
X char msym = mtmp->data->mlet;
X schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */
X coord poss[9];
X long info[9];
X
X if(mtmp->mfroz || mtmp->msleep)
X return(0);
X if(mtmp->mtrapped) {
X i = mintrap(mtmp);
X if(i == 2) return(2); /* he died */
X if(i == 1) return(0); /* still in trap, so didnt move */
X }
X if(mtmp->mhide && o_at(mtmp->mx,mtmp->my) && rn2(10))
X return(0); /* do not leave hiding place */
X
X#ifndef NOWORM
X if(mtmp->wormno)
X goto not_special;
X#endif
X
X /* my dog gets a special treatment */
X if(mtmp->mtame) {
X return( dog_move(mtmp, after) );
X }
X
X /* likewise for shopkeeper */
X if(mtmp->isshk) {
X mmoved = shk_move(mtmp);
X if(mmoved >= 0)
X goto postmov;
X mmoved = 0; /* follow player outside shop */
X }
X
X /* and for the guard */
X if(mtmp->isgd) {
X mmoved = gd_move();
X goto postmov;
X }
X
X/* teleport if that lies in our nature ('t') or when badly wounded ('1') */
X if((msym == 't' && !rn2(5))
X || (msym == '1' && (mtmp->mhp < 7 || (!xdnstair && !rn2(5))
X || levl[u.ux][u.uy].typ == STAIRS))) {
X if(mtmp->mhp < 7 || (msym == 't' && rn2(2)))
X rloc(mtmp);
X else
X mnexto(mtmp);
X mmoved = 1;
X goto postmov;
X }
X
X /* spit fire ('D') or use a wand ('1') when appropriate */
X#ifdef DGKMOD
X /* Add arrow and bolt throwing monsters */
X if (index(
X# ifdef KAA
X# ifdef KOPS
X "D1OKC9",
X# else
X "D1KC9",
X# endif
X# else
X# ifdef KOPS
X "D1OKC",
X# else
X "D1KC",
X# endif
X# endif
X msym))
X
X if (!inrange(mtmp)) /* inrange returns 1 if OK for mon */
X return(0); /* to move after it zaps or throws */
X#else
X if(index("D1", msym))
X inrange(mtmp);
X#endif
X
X if(msym == 'U' && !mtmp->mcan && canseemon(mtmp) &&
X mtmp->mcansee && rn2(5)) {
X if(!Confusion)
X pline("%s's gaze has confused you!", Monnam(mtmp));
X else
X pline("You are getting more and more confused.");
X if(rn2(3)) mtmp->mcan = 1;
X HConfusion += d(3,4); /* timeout */
X }
Xnot_special:
X if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1);
X appr = 1;
X if(mtmp->mflee) appr = -1;
X if(mtmp->mconf || Invis || !mtmp->mcansee ||
X (index("BIy", msym) && !rn2(3)))
X appr = 0;
X omx = mtmp->mx;
X omy = mtmp->my;
X gx = u.ux;
X gy = u.uy;
X if(msym == 'L' && appr == 1 && mtmp->mgold > u.ugold)
X appr = -1;
X
X /* random criterion for 'smell' or track finding ability
X should use mtmp->msmell or sth
X */
X if(msym == '@' ||
X ('a' <= msym && msym <= 'z')) {
X extern coord *gettrack();
X register coord *cp;
X schar mroom;
X mroom = inroom(omx,omy);
X if(mroom < 0 || mroom != inroom(u.ux,u.uy)){
X cp = gettrack(omx,omy);
X if(cp){
X gx = cp->x;
X gy = cp->y;
X }
X }
X }
X
X /* look for gold or jewels nearby */
X#ifdef ROCKMOLE
X likegold = (index("LODr", msym) != NULL);
X likegems = (index("ODu", msym) != NULL);
X likeobjs = (mtmp->mhide || msym == 'r');
X#else
X likegold = (index("LOD", msym) != NULL);
X likegems = (index("ODu", msym) != NULL);
X likeobjs = mtmp->mhide;
X#endif
X#ifdef KAA
X likerock = (msym == '9');
X#endif
X#define SRCHRADIUS 25
X { xchar mind = SRCHRADIUS; /* not too far away */
X register int dd;
X if(likegold){
X register struct gold *gold;
X for(gold = fgold; gold; gold = gold->ngold)
X if((dd = DIST(omx,omy,gold->gx,gold->gy)) < mind){
X mind = dd;
X gx = gold->gx;
X gy = gold->gy;
X }
X }
X if(likegems || likeobjs
X#ifdef KAA
X || likerock
X#endif
X ) {
X register struct obj *otmp;
X for(otmp = fobj; otmp; otmp = otmp->nobj)
X if(likeobjs
X || (likegems && otmp->olet == GEM_SYM)
X#ifdef KAA
X || (likerock && otmp->olet == ROCK_SYM)
X#endif
X ) {
X if(msym != 'u' || objects[otmp->otyp].g_val != 0)
X if((dd = DIST(omx,omy,otmp->ox,otmp->oy)) < mind){
X mind = dd;
X gx = otmp->ox;
X gy = otmp->oy;
X }
X }
X }
X if(mind < SRCHRADIUS && appr == -1) {
X if(dist(omx,omy) < 10) {
X gx = u.ux;
X gy = u.uy;
X } else
X appr = 1;
X }
X }
X nix = omx;
X niy = omy;
X cnt = mfndpos(mtmp,poss,info,
X msym == 'u' ? NOTONL :
X#ifdef ROCKMOLE
X msym == 'r' ? ALLOW_WALL :
X#endif
X (msym == '@' || msym == '1') ? (ALLOW_SSM | ALLOW_TRAPS) :
X index(UNDEAD, msym) ? NOGARLIC :
X#ifdef KAA
X (msym == '9') ? (ALLOW_ROCK | ALLOW_TRAPS) : ALLOW_TRAPS);
X#else
X ALLOW_TRAPS);
X#endif
X chcnt = 0;
X chi = -1;
X for(i=0; i<cnt; i++) {
X nx = poss[i].x;
X ny = poss[i].y;
X for(j=0; j<MTSZ && j<cnt-1; j++)
X if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
X if(rn2(4*(cnt-j))) goto nxti;
X#ifdef STUPID
X /* some stupid compilers think that this is too complicated */
X { int d1 = DIST(nx,ny,gx,gy);
X int d2 = DIST(nix,niy,gx,gy);
X nearer = (d1 < d2);
X }
X#else
X nearer = (DIST(nx,ny,gx,gy) < DIST(nix,niy,gx,gy));
X#endif
X if((appr == 1 && nearer) || (appr == -1 && !nearer) ||
X !mmoved ||
X (!appr && !rn2(++chcnt))){
X nix = nx;
X niy = ny;
X chi = i;
X mmoved = 1;
X }
X nxti: ;
X }
X if(mmoved){
X if(info[chi] & ALLOW_M){
X mtmp2 = m_at(nix,niy);
X if(hitmm(mtmp,mtmp2) == 1 && rn2(4) &&
X hitmm(mtmp2,mtmp) == 2) return(2);
X return(0);
X }
X if(info[chi] & ALLOW_U){
X (void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd)+1);
X return(0);
X }
X mtmp->mx = nix;
X mtmp->my = niy;
X for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];
X mtmp->mtrack[0].x = omx;
X mtmp->mtrack[0].y = omy;
X#ifndef NOWORM
X if(mtmp->wormno) worm_move(mtmp);
X#endif
X } else {
X if(msym == 'u' && rn2(2)){
X rloc(mtmp);
X return(0);
X }
X#ifndef NOWORM
X if(mtmp->wormno) worm_nomove(mtmp);
X#endif
X }
Xpostmov:
X if(mmoved == 1) {
X if(mintrap(mtmp) == 2) /* he died */
X return(2);
X#ifdef ROCKMOLE
X /* Maybe a rock mole just ate something? */
X if(msym == 'r' && IS_ROCK(levl[mtmp->mx][mtmp->my].typ) &&
X levl[mtmp->mx][mtmp->my].typ != POOL){
X register int pile = rnd(25);
X /* Just ate something. */
X if(levl[mtmp->mx][mtmp->my].typ == 0)
X levl[mtmp->mx][mtmp->my].typ = CORR;
X else if(IS_WALL(levl[mtmp->mx][mtmp->my].typ))
X levl[mtmp->mx][mtmp->my].typ = DOOR;
X mnewsym(mtmp->mx,mtmp->my);
X /* Left behind a pile? */
X if(pile < 5) {
X if(pile == 1)
X mksobj_at(ENORMOUS_ROCK, mtmp->mx, mtmp->my);
X else
X mksobj_at(ROCK, mtmp->mx, mtmp->my);
X }
X if(cansee(mtmp->mx, mtmp->my))
X atl(mtmp->mx,mtmp->my,fobj->olet);
X }
X /* Maybe a rock mole just ate some gold or armor? */
X if(msym == 'r') meatgold(mtmp);
X#endif /* ROCKMOLE /**/
X if(likegold) mpickgold(mtmp);
X#ifdef KAA
X if(likerock || likegems) mpickgems(mtmp);
X#else
X if(likegems) mpickgems(mtmp);
X#endif
X if(mtmp->mhide) mtmp->mundetected = 1;
X }
X pmon(mtmp);
X return(mmoved);
X}
X
END_OF_monmove.c
if test 10327 -ne `wc -c <monmove.c`; then
echo shar: \"monmove.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f pcmain.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"pcmain.c\"
else
echo shar: Extracting \"pcmain.c\" \(11187 characters\)
sed "s/^X//" >pcmain.c <<'END_OF_pcmain.c'
X/* SCCS Id: @(#)pcmain.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* main.c - (PC) version 1.0.3 */
X
X#include <stdio.h>
X#include <signal.h>
X#include "hack.h"
X
X#ifdef QUEST
X#define gamename "PC NetQuest"
X#else
X#define gamename "PC NetHack"
X#endif
X
Xchar orgdir[PATHLEN], *getcwd();
X
Xextern struct permonst mons[CMNUM+2];
Xextern char genocided[], fut_geno[];
Xextern char *getlogin(), *getenv();
Xextern char plname[PL_NSIZ], pl_character[PL_CSIZ];
X
Xint (*afternmv)(), done1(), (*occupation)();
X
Xchar SAVEF[FILENAME];
Xchar *hname = gamename;
Xchar obuf[BUFSIZ]; /* BUFSIZ is defined in stdio.h */
Xint hackpid; /* not used anymore, but kept in for save files */
X
Xextern char *nomovemsg;
Xextern long wailmsg;
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X register int fd;
X register char *dir;
X#ifdef MSDOS
X static void moveloop(); /* a helper function for MSC optimizer */
X
X /* Save current directory and make sure it gets restored when
X * the game is exited.
X */
X int (*funcp)();
X
X if (getcwd(orgdir, sizeof orgdir) == NULL) {
X xputs("hack: current directory path too long\n");
X _exit(1);
X }
X funcp = exit; /* Kludge to get around LINT_ARGS of signal.
X * This will produce a compiler warning, but that's OK.
X */
X signal(SIGINT, funcp); /* restore original directory */
X#endif
X#ifdef DGK
X initoptions();
X if (!hackdir[0])
X (void) strcpy(hackdir, orgdir);
X dir = hackdir;
X#else
X dir = getenv("HACKDIR");
X if(argc > 1 && !strncmp(argv[1], "-d", 2)) {
X argc--;
X argv++;
X dir = argv[0]+2;
X if(*dir == '=' || *dir == ':') dir++;
X if(!*dir && argc > 1) {
X argc--;
X argv++;
X dir = argv[0];
X }
X if(!*dir)
X error("Flag -d must be followed by a directory name.");
X }
X#endif /* DGK */
X
X /*
X * Now we know the directory containing 'record' and
X * may do a prscore().
X */
X if(argc > 1 && !strncmp(argv[1], "-s", 2)) {
X chdirx(dir,0);
X prscore(argc, argv);
X exit(0);
X }
X
X /*
X * It seems he really wants to play.
X * Remember tty modes, to be restored on exit.
X */
X gettty();
X setbuf(stdout,obuf);
X setrandom();
X startup();
X init_corpses(); /* initialize optional corpse names */
X cls();
X u.uhp = 1; /* prevent RIP on early quits */
X u.ux = FAR; /* prevent nscr() */
X
X /*
X * We cannot do chdir earlier, otherwise gethdate will fail.
X */
X chdirx(dir,1);
X
X /*
X * Process options.
X */
X while(argc > 1 && argv[1][0] == '-'){
X argv++;
X argc--;
X switch(argv[0][1]){
X#ifdef WIZARD
X case 'D':
X# ifdef MSDOS
X wizard = TRUE;
X# else
X if(!strcmp(getlogin(), WIZARD))
X wizard = TRUE;
X else
X printf("Sorry.\n");
X# endif
X break;
X#endif
X case 'u':
X if(argv[0][2])
X (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
X else if(argc > 1) {
X argc--;
X argv++;
X (void) strncpy(plname, argv[0], sizeof(plname)-1);
X } else
X printf("Player name expected after -u\n");
X break;
X#ifdef DGK
X /* Person does not want to use a ram disk
X */
X case 'R':
X ramdisk = FALSE;
X break;
X#endif
X default:
X /* allow -T for Tourist, etc. */
X (void) strncpy(pl_character, argv[0]+1,
X sizeof(pl_character)-1);
X
X /* printf("Unknown option: %s\n", *argv); */
X }
X }
X
X#ifdef DGK
X set_lock_and_bones();
X copybones(FROMPERM);
X#endif
X#ifdef WIZARD
X if (wizard)
X (void) strcpy(plname, "wizard");
X else
X#endif
X if (!*plname)
X askname();
X plnamesuffix(); /* strip suffix from name; calls askname() */
X /* again if suffix was whole name */
X /* accepts any suffix */
X#ifdef WIZARD
X if(wizard) {
X register char *sfoo;
X# ifndef DGK
X /* lock is set in read_config_file */
X (void) strcpy(lock,plname);
X# endif
X if(sfoo = getenv("MAGIC"))
X while(*sfoo) {
X switch(*sfoo++) {
X case 'n': (void) srand(*sfoo++);
X break;
X }
X }
X if(sfoo = getenv("GENOCIDED")){
X if(*sfoo == '!'){
X register struct permonst *pm = mons;
X register char *gp = genocided;
X
X while(pm < mons+CMNUM+2){
X if(!index(sfoo, pm->mlet))
X *gp++ = pm->mlet;
X pm++;
X }
X *gp = 0;
X } else
X (void) strcpy(genocided, sfoo);
X (void) strcpy(fut_geno, genocided);
X }
X }
X#endif /* WIZARD */
X start_screen();
X#ifdef DGK
X strncat(SAVEF, plname, 8);
X strcat(SAVEF, ".sav");
X cls();
X if (saveDiskPrompt(1) && ((fd = open(SAVEF, 0)) >= 0)) {
X#else
X (void) sprintf(SAVEF, "save/%d%s", getuid(), plname);
X regularize(SAVEF+5); /* avoid . or / in name */
X if((fd = open(SAVEF,0)) >= 0 &&
X (uptodate(fd) || unlink(SAVEF) == 666)) {
X#endif /* DGK */
X (void) signal(SIGINT,done1);
X pline("Restoring old save file...");
X (void) fflush(stdout);
X if(!dorecover(fd))
X goto not_recovered;
X pline("Hello %s, welcome to %s!", plname, hname);
X flags.move = 0;
X } else {
Xnot_recovered:
X#ifdef DGK
X gameDiskPrompt();
X#endif
X fobj = fcobj = invent = 0;
X fmon = fallen_down = 0;
X ftrap = 0;
X fgold = 0;
X flags.ident = 1;
X init_objects();
X u_init();
X
X (void) signal(SIGINT,done1);
X mklev();
X u.ux = xupstair;
X u.uy = yupstair;
X (void) inshop();
X setsee();
X flags.botlx = 1;
X /* Fix bug with dog not being made because a monster
X * was on the level 1 staircase
X */
X {
X struct monst *mtmp;
X
X if (mtmp = m_at(u.ux, u.uy))
X mnexto(mtmp);
X }
X makedog();
X { register struct monst *mtmp;
X if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp); /* riv05!a3 */
X }
X seemons();
X docrt();
X
X /* give welcome message before pickup messages */
X pline("Hello %s, welcome to %s!", plname, hname);
X
X pickup(1);
X if(!Blind) read_engr_at(u.ux,u.uy);
X flags.move = 1;
X }
X flags.moonphase = phase_of_the_moon();
X if(flags.moonphase == FULL_MOON) {
X pline("You are lucky! Full moon tonight.");
X if(!u.uluck) u.uluck++;
X } else if(flags.moonphase == NEW_MOON) {
X pline("Be careful! New moon tonight.");
X }
X
X initrack();
X (void) signal(SIGINT, SIG_IGN);
X#ifdef MSDOS
X /* Help for Microsoft optimizer. Otherwise main is too large -dgk*/
X moveloop();
X}
X
Xstatic void
Xmoveloop()
X{
X char ch;
X int abort;
X#endif /* MSDOS */
X for(;;) {
X if(flags.move) { /* actual time passed */
X
X settrack();
X
X if(moves%2 == 0 ||
X (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) {
X extern struct monst *makemon();
X movemon();
X if(!rn2(70))
X (void) makemon((struct permonst *)0, 0, 0);
X }
X if(Glib) glibr();
X timeout();
X ++moves;
X#ifdef PRAYERS
X if (u.ublesscnt) u.ublesscnt--;
X#endif
X#ifndef DGK
X if(flags.time) flags.botl = 1;
X#endif
X#ifdef KAA
X if(u.mtimedone)
X if(u.mh < 1) rehumanize();
X else
X#endif
X if(u.uhp < 1) {
X pline("You die...");
X done("died");
X }
X if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50){
X wailmsg = moves;
X#ifdef KAA
X if(index("WEV", pl_character[0])) {
X if (u.uhp == 1)
X pline("%s is about to die.", pl_character);
X else
X pline("%s, your life force is running out.",
X pl_character);
X } else {
X#endif
X if(u.uhp == 1)
X pline("You hear the wailing of the Banshee...");
X else
X pline("You hear the howling of the CwnAnnwn...");
X#ifdef KAA
X }
X#endif
X }
X#ifdef KAA
X if (u.mtimedone) {
X if (u.mh < u.mhmax) {
X if (Regeneration || !(moves%20)) {
X flags.botl = 1;
X u.mh++;
X }
X }
X }
X#endif
X if(u.uhp < u.uhpmax) {
X if(u.ulevel > 9) {
X if(HRegeneration || !(moves%3)) {
X flags.botl = 1;
X u.uhp += rnd((int) u.ulevel-9);
X if(u.uhp > u.uhpmax)
X u.uhp = u.uhpmax;
X }
X } else if(HRegeneration ||
X (!(moves%(22-u.ulevel*2)))) {
X flags.botl = 1;
X u.uhp++;
X }
X }
X#ifdef SPELLS
X if ((u.uen<u.uenmax) && (!(moves%(21-u.ulevel/2)))) {
X u.uen += rn2(u.ulevel/4 + 1) + 1;
X if (u.uen > u.uenmax) u.uen = u.uenmax;
X flags.botl = 1;
X }
X#endif
X if(Teleportation && !rn2(85)) tele();
X if(Searching && multi >= 0) (void) dosearch();
X gethungry();
X invault();
X amulet();
X#ifdef HARD
X if (u.udemigod) {
X
X u.udg_cnt--;
X if(u.udg_cnt <= 0) {
X
X intervene();
X u.udg_cnt = rn1(200, 50);
X }
X }
X#endif
X }
X if(multi < 0) {
X if(!++multi){
X pline(nomovemsg ? nomovemsg :
X "You can move again.");
X nomovemsg = 0;
X if(afternmv) (*afternmv)();
X afternmv = 0;
X }
X }
X
X find_ac();
X#ifndef QUEST
X if(!flags.mv || Blind)
X#endif
X {
X seeobjs();
X seemons();
X nscr();
X }
X#ifdef DGK
X if(flags.time) flags.botl = 1;
X#endif
X if(flags.botl || flags.botlx) bot();
X
X flags.move = 1;
X
X if(multi >= 0 && occupation) {
X#ifdef DGK
X abort = 0;
X if (kbhit()) {
X if ((ch = getchar()) == ABORT)
X abort++;
X else
X pushch(ch);
X }
X if (abort || monster_nearby())
X stop_occupation();
X else if ((*occupation)() == 0)
X occupation = 0;
X if (!(++occtime % 7))
X (void) fflush(stdout);
X#else
X if (monster_nearby())
X stop_occupation();
X else if ((*occupation)() == 0)
X occupation = 0;
X#endif
X continue;
X }
X
X if(multi > 0) {
X#ifdef QUEST
X if(flags.run >= 4) finddir();
X#endif
X lookaround();
X if(!multi) { /* lookaround may clear multi */
X flags.move = 0;
X continue;
X }
X if(flags.mv) {
X if(multi < COLNO && !--multi)
X flags.mv = flags.run = 0;
X domove();
X } else {
X --multi;
X rhack(save_cm);
X }
X } else if(multi == 0) {
X rhack((char *) 0);
X }
X if(multi && multi%7 == 0)
X (void) fflush(stdout);
X }
X}
X
X#ifndef DGK
X/* This function is unnecessary and incompatible with the #define
X * of glo(x) in config.h -dgk
X */
Xglo(foo)
Xregister foo;
X{
X /* construct the string xlock.n */
X register char *tf;
X
X tf = lock;
X while(*tf && *tf != '.') tf++;
X (void) sprintf(tf, ".%d", foo);
X}
X#endif
X
X/*
X * plname is filled either by an option (-u Player or -uPlayer) or
X * explicitly (-w implies wizard) or by askname.
X * It may still contain a suffix denoting pl_character.
X */
Xaskname(){
Xregister int c,ct;
X printf("\nWho are you? ");
X (void) fflush(stdout);
X ct = 0;
X while((c = getchar()) != '\n'){
X#ifdef MSDOS
X msmsg("%c", c);
X#endif
X if(c == EOF) error("End of input\n");
X /* some people get confused when their erase char is not ^H */
X if(c == '\010') {
X if(ct) ct--;
X continue;
X }
X if(c != '-')
X if(c < 'A' || (c > 'Z' && c < 'a') || c > 'z') c = '_';
X if(ct < sizeof(plname)-1) plname[ct++] = c;
X }
X plname[ct] = 0;
X if(ct == 0) askname();
X}
X
X/*VARARGS1*/
Ximpossible(s,x1,x2)
Xregister char *s;
X{
X pline(s,x1,x2);
X pline("Program in disorder - perhaps you'd better Quit.");
X}
X
X#ifdef CHDIR
Xchdirx(dir, wr)
Xchar *dir;
Xboolean wr;
X{
X
X if(dir && chdir(dir) < 0) {
X error("Cannot chdir to %s.", dir);
X }
X
X#ifdef DGK
X /* Change the default drive as well.
X */
X chdrive(dir);
X#endif
X
X /* warn the player if he cannot write the record file */
X /* perhaps we should also test whether . is writable */
X /* unfortunately the access systemcall is worthless */
X if(wr) {
X register fd;
X
X if(dir == NULL)
X dir = ".";
X if((fd = open(RECORD, 2)) < 0) {
X#ifdef DGK
X char tmp[PATHLEN];
X
X strcpy(tmp, dir);
X append_slash(tmp);
X msmsg("Warning: cannot write %s%s\n", tmp, RECORD);
X getreturn("to continue");
X#else
X printf("Warning: cannot write %s/%s", dir, RECORD);
X getret();
X#endif
X } else
X (void) close(fd);
X }
X}
X#endif /* CHDIR /**/
X
Xstop_occupation()
X{
X if(occupation) {
X pline("You stop %s.", occtxt);
X occupation = 0;
X#ifdef DGK
X multi = 0;
X pushch(0);
X#endif
X }
X}
END_OF_pcmain.c
if test 11187 -ne `wc -c <pcmain.c`; then
echo shar: \"pcmain.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f topten.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"topten.c\"
else
echo shar: Extracting \"topten.c\" \(11138 characters\)
sed "s/^X//" >topten.c <<'END_OF_topten.c'
X/* SCCS Id: @(#)topten.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* topten.c - version 1.0 */
X
X#include <stdio.h>
X#include "hack.h"
X#define Sprintf (void) sprintf
Xextern char plname[], pl_character[];
Xextern char *itoa(), *ordin(), *eos();
Xextern int done_hup, done_stopprint;
X
X#define newttentry() (struct toptenentry *) alloc(sizeof(struct toptenentry))
X#define NAMSZ 10
X#define DTHSZ 40
X#define PERSMAX 3
X#define POINTSMIN 1 /* must be > 0 */
X#define ENTRYMAX 100 /* must be >= 10 */
X#ifndef MSDOS
X#define PERS_IS_UID /* delete for PERSMAX per name; now per uid */
X#endif
Xstruct toptenentry {
X struct toptenentry *tt_next;
X long int points;
X int level,maxlvl,hp,maxhp;
X int uid;
X char plchar;
X char sex;
X char name[NAMSZ+1];
X char death[DTHSZ+1];
X char date[7]; /* yymmdd */
X} *tt_head;
X
Xtopten(){
X int uid = getuid();
X int rank, rank0 = -1, rank1 = 0;
X int occ_cnt = PERSMAX;
X register struct toptenentry *t0, *t1, *tprev;
X char *recfile = RECORD;
X#ifdef UNIX
X char *reclock = "record_lock";
X#endif
X int sleepct = 300;
X FILE *rfile;
X register flg = 0;
X extern char *getdate();
X#ifndef DGK
X#define HUP if(!done_hup)
X#else
X#define
X#endif
X#ifdef UNIX
X while(link(recfile, reclock) == -1) {
X HUP perror(reclock);
X if(!sleepct--) {
X HUP puts("I give up. Sorry.");
X HUP puts("Perhaps there is an old record_lock around?");
X return;
X }
X HUP printf("Waiting for access to record file. (%d)\n",
X sleepct);
X HUP (void) fflush(stdout);
X sleep(1);
X }
X#endif
X if(!(rfile = fopen(recfile,"r"))){
X HUP puts("Cannot open record file!");
X goto unlock;
X }
X HUP (void) putchar('\n');
X
X /* create a new 'topten' entry */
X t0 = newttentry();
X t0->level = dlevel;
X t0->maxlvl = maxdlevel;
X t0->hp = u.uhp;
X t0->maxhp = u.uhpmax;
X t0->points = u.urexp;
X t0->plchar = pl_character[0];
X t0->sex = (flags.female ? 'F' : 'M');
X t0->uid = uid;
X (void) strncpy(t0->name, plname, NAMSZ);
X (t0->name)[NAMSZ] = 0;
X (void) strncpy(t0->death, killer, DTHSZ);
X (t0->death)[DTHSZ] = 0;
X (void) strcpy(t0->date, getdate());
X
X /* assure minimum number of points */
X if(t0->points < POINTSMIN)
X t0->points = 0;
X
X t1 = tt_head = newttentry();
X tprev = 0;
X /* rank0: -1 undefined, 0 not_on_list, n n_th on list */
X for(rank = 1; ; ) {
X if(fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]",
X t1->date, &t1->uid,
X &t1->level, &t1->maxlvl,
X &t1->hp, &t1->maxhp, &t1->points,
X &t1->plchar, &t1->sex, t1->name, t1->death) != 11
X || t1->points < POINTSMIN)
X t1->points = 0;
X if(rank0 < 0 && t1->points < t0->points) {
X rank0 = rank++;
X if(tprev == 0)
X tt_head = t0;
X else
X tprev->tt_next = t0;
X t0->tt_next = t1;
X occ_cnt--;
X flg++; /* ask for a rewrite */
X } else
X tprev = t1;
X if(t1->points == 0) break;
X if(
X#ifdef PERS_IS_UID
X t1->uid == t0->uid &&
X#else
X strncmp(t1->name, t0->name, NAMSZ) == 0 &&
X#endif
X t1->plchar == t0->plchar && --occ_cnt <= 0){
X if(rank0 < 0){
X rank0 = 0;
X rank1 = rank;
X HUP printf("You didn't beat your previous score of %ld points.\n\n",
X t1->points);
X }
X if(occ_cnt < 0){
X flg++;
X continue;
X }
X }
X if(rank <= ENTRYMAX){
X t1 = t1->tt_next = newttentry();
X rank++;
X }
X if(rank > ENTRYMAX){
X t1->points = 0;
X break;
X }
X }
X if(flg) { /* rewrite record file */
X (void) fclose(rfile);
X if(!(rfile = fopen(recfile,"w"))){
X HUP puts("Cannot write record file\n");
X goto unlock;
X }
X
X if(!done_stopprint) if(rank0 > 0){
X if(rank0 <= 10)
X puts("You made the top ten list!\n");
X else
X printf("You reached the %d%s place on the top %d list.\n\n",
X rank0, ordin(rank0), ENTRYMAX);
X }
X }
X if(rank0 == 0) rank0 = rank1;
X if(rank0 <= 0) rank0 = rank;
X if(!done_stopprint) outheader();
X t1 = tt_head;
X for(rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) {
X if(flg) fprintf(rfile,"%6s %d %d %d %d %d %ld %c%c %s,%s\n",
X t1->date, t1->uid,
X t1->level, t1->maxlvl,
X t1->hp, t1->maxhp, t1->points,
X t1->plchar, t1->sex, t1->name, t1->death);
X if(done_stopprint) continue;
X if(rank > flags.end_top &&
X (rank < rank0-flags.end_around || rank > rank0+flags.end_around)
X && (!flags.end_own ||
X#ifdef PERS_IS_UID
X t1->uid != t0->uid ))
X#else
X strncmp(t1->name, t0->name, NAMSZ)))
X#endif
X continue;
X if(rank == rank0-flags.end_around &&
X rank0 > flags.end_top+flags.end_around+1 &&
X !flags.end_own)
X (void) putchar('\n');
X if(rank != rank0)
X (void) outentry(rank, t1, 0);
X else if(!rank1)
X (void) outentry(rank, t1, 1);
X else {
X int t0lth = outentry(0, t0, -1);
X int t1lth = outentry(rank, t1, t0lth);
X if(t1lth > t0lth) t0lth = t1lth;
X (void) outentry(0, t0, t0lth);
X }
X }
X if(rank0 >= rank) if(!done_stopprint)
X (void) outentry(0, t0, 1);
X (void) fclose(rfile);
Xunlock: ;
X#ifdef UNIX
X (void) unlink(reclock);
X#endif
X}
X
Xoutheader() {
Xchar linebuf[BUFSZ];
Xregister char *bp;
X (void) strcpy(linebuf, "Number Points Name");
X bp = eos(linebuf);
X while(bp < linebuf + COLNO - 9) *bp++ = ' ';
X (void) strcpy(bp, "Hp [max]");
X puts(linebuf);
X}
X
X/* so>0: standout line; so=0: ordinary line; so<0: no output, return lth */
Xint
Xoutentry(rank,t1,so) register struct toptenentry *t1; {
Xboolean quit = FALSE, killed = FALSE, starv = FALSE;
Xchar linebuf[BUFSZ];
X linebuf[0] = 0;
X if(rank) Sprintf(eos(linebuf), "%3d", rank);
X else Sprintf(eos(linebuf), " ");
X#ifdef DGKMOD
X Sprintf(eos(linebuf), " %6ld %10s", t1->points, t1->name);
X#else
X Sprintf(eos(linebuf), " %6ld %8s", t1->points, t1->name);
X#endif
X if(t1->plchar == 'X') Sprintf(eos(linebuf), " ");
X else Sprintf(eos(linebuf), "-%c ", t1->plchar);
X if(!strncmp("escaped", t1->death, 7)) {
X if(!strcmp(" (with amulet)", t1->death+7))
X Sprintf(eos(linebuf), "escaped the dungeon with amulet");
X else
X Sprintf(eos(linebuf), "escaped the dungeon [max level %d]",
X t1->maxlvl);
X } else {
X if(!strncmp(t1->death,"quit",4)) {
X quit = TRUE;
X if(t1->maxhp < 3*t1->hp && t1->maxlvl < 4)
X Sprintf(eos(linebuf), "cravenly gave up");
X else
X Sprintf(eos(linebuf), "quit");
X }
X else if(!strcmp(t1->death,"choked"))
X Sprintf(eos(linebuf), "choked on %s food",
X (t1->sex == 'F') ? "her" : "his");
X else if(!strncmp(t1->death,"starv",5))
X Sprintf(eos(linebuf), "starved to death"), starv = TRUE;
X else Sprintf(eos(linebuf), "was killed"), killed = TRUE;
X Sprintf(eos(linebuf), " on%s level %d",
X (killed || starv) ? "" : " dungeon", t1->level);
X if(t1->maxlvl != t1->level)
X Sprintf(eos(linebuf), " [max %d]", t1->maxlvl);
X if(quit && t1->death[4]) Sprintf(eos(linebuf), t1->death + 4);
X }
X if(killed) Sprintf(eos(linebuf), " by %s%s",
X (!strncmp(t1->death, "trick", 5) || !strncmp(t1->death, "the ", 4))
X ? "" :
X index(vowels,*t1->death) ? "an " : "a ",
X t1->death);
X Sprintf(eos(linebuf), ".");
X if(t1->maxhp) {
X register char *bp = eos(linebuf);
X char hpbuf[10];
X int hppos;
X Sprintf(hpbuf, (t1->hp > 0) ? itoa(t1->hp) : "-");
X hppos = COLNO - 7 - strlen(hpbuf);
X if(bp <= linebuf + hppos) {
X while(bp < linebuf + hppos) *bp++ = ' ';
X (void) strcpy(bp, hpbuf);
X Sprintf(eos(bp), " [%d]", t1->maxhp);
X }
X }
X if(so == 0) puts(linebuf);
X else if(so > 0) {
X register char *bp = eos(linebuf);
X if(so >= COLNO) so = COLNO-1;
X while(bp < linebuf + so) *bp++ = ' ';
X *bp = 0;
X standoutbeg();
X fputs(linebuf,stdout);
X standoutend();
X (void) putchar('\n');
X }
X return(strlen(linebuf));
X}
X
Xchar *
Xitoa(a) int a; {
Xstatic char buf[12];
X Sprintf(buf,"%d",a);
X return(buf);
X}
X
Xchar *
Xordin(n) int n; {
Xregister int d = n%10;
X return((d==0 || d>3 || n/10==1) ? "th" : (d==1) ? "st" :
X (d==2) ? "nd" : "rd");
X}
X
Xchar *
Xeos(s)
Xregister char *s;
X{
X while(*s) s++;
X return(s);
X}
X
X/*
X * Called with args from main if argc >= 0. In this case, list scores as
X * requested. Otherwise, find scores for the current player (and list them
X * if argc == -1).
X */
Xprscore(argc,argv) int argc; char **argv; {
X extern char *hname;
X char **players;
X int playerct;
X int rank;
X register struct toptenentry *t1, *t2;
X char *recfile = RECORD;
X FILE *rfile;
X register flg = 0;
X register int i;
X#ifdef nonsense
X long total_score = 0L;
X char totchars[10];
X int totcharct = 0;
X#endif
X int outflg = (argc >= -1);
X#ifdef PERS_IS_UID
X int uid = -1;
X#else
X char *player0;
X#endif
X
X if(!(rfile = fopen(recfile,"r"))){
X puts("Cannot open record file!");
X return;
X }
X
X if(argc > 1 && !strncmp(argv[1], "-s", 2)){
X if(!argv[1][2]){
X argc--;
X argv++;
X } else if(!argv[1][3] && index("CFKSTWX", argv[1][2])) {
X argv[1]++;
X argv[1][0] = '-';
X } else argv[1] += 2;
X }
X if(argc <= 1){
X#ifdef PERS_IS_UID
X uid = getuid();
X playerct = 0;
X#else
X player0 = plname;
X if(!*player0)
X player0 = "hackplayer";
X playerct = 1;
X players = &player0;
X#endif
X } else {
X playerct = --argc;
X players = ++argv;
X }
X if(outflg) putchar('\n');
X
X t1 = tt_head = newttentry();
X for(rank = 1; ; rank++) {
X if(fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]",
X t1->date, &t1->uid,
X &t1->level, &t1->maxlvl,
X &t1->hp, &t1->maxhp, &t1->points,
X &t1->plchar, &t1->sex, t1->name, t1->death) != 11)
X t1->points = 0;
X if(t1->points == 0) break;
X#ifdef PERS_IS_UID
X if(!playerct && t1->uid == uid)
X flg++;
X else
X#endif
X for(i = 0; i < playerct; i++){
X if(strcmp(players[i], "all") == 0 ||
X strncmp(t1->name, players[i], NAMSZ) == 0 ||
X (players[i][0] == '-' &&
X players[i][1] == t1->plchar &&
X players[i][2] == 0) ||
X (digit(players[i][0]) && rank <= atoi(players[i])))
X flg++;
X }
X t1 = t1->tt_next = newttentry();
X }
X (void) fclose(rfile);
X if(!flg) {
X if(outflg) {
X printf("Cannot find any entries for ");
X if(playerct < 1) printf("you.\n");
X else {
X if(playerct > 1) printf("any of ");
X for(i=0; i<playerct; i++)
X printf("%s%s", players[i], (i<playerct-1)?", ":".\n");
X printf("Call is: %s -s [playernames]\n", hname);
X }
X }
X return;
X }
X
X if(outflg) outheader();
X t1 = tt_head;
X for(rank = 1; t1->points != 0; rank++, t1 = t2) {
X t2 = t1->tt_next;
X#ifdef PERS_IS_UID
X if(!playerct && t1->uid == uid)
X goto outwithit;
X else
X#endif
X for(i = 0; i < playerct; i++){
X if(strcmp(players[i], "all") == 0 ||
X strncmp(t1->name, players[i], NAMSZ) == 0 ||
X (players[i][0] == '-' &&
X players[i][1] == t1->plchar &&
X players[i][2] == 0) ||
X (digit(players[i][0]) && rank <= atoi(players[i]))){
X outwithit:
X if(outflg)
X (void) outentry(rank, t1, 0);
X#ifdef nonsense
X total_score += t1->points;
X if(totcharct < sizeof(totchars)-1)
X totchars[totcharct++] = t1->plchar;
X#endif
X break;
X }
X }
X free((char *) t1);
X }
X#ifdef nonsense
X totchars[totcharct] = 0;
X
X /* We would like to determine whether he is experienced. However,
X the information collected here only tells about the scores/roles
X that got into the topten (top 100?). We should maintain a
X .hacklog or something in his home directory. */
X flags.beginner = (total_score < 6000);
X for(i=0; i<6; i++)
X if(!index(totchars, "CFKSTWX"[i])) {
X flags.beginner = 1;
X if(!pl_character[0]) pl_character[0] = "CFKSTWX"[i];
X break;
X }
X#endif /* nonsense /**/
X}
END_OF_topten.c
if test 11138 -ne `wc -c <topten.c`; then
echo shar: \"topten.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f vault.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"vault.c\"
else
echo shar: Extracting \"vault.c\" \(5920 characters\)
sed "s/^X//" >vault.c <<'END_OF_vault.c'
X/* SCCS Id: @(#)vault.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* vault.c - version 1.0.2 */
X
X#include "hack.h"
X#ifdef QUEST
Xsetgd(/* mtmp */) /* struct monst *mtmp; */ {}
Xgd_move() { return(2); }
Xgddead(mtmp) struct monst *mtmp; {}
Xreplgd(mtmp,mtmp2) struct monst *mtmp, *mtmp2; {}
Xinvault(){}
X
X#else
X
X
X#include "mkroom.h"
Xextern struct monst *makemon();
X#define FCSIZ (ROWNO+COLNO)
Xstruct fakecorridor {
X xchar fx,fy,ftyp;
X};
X
Xstruct egd {
X int fcbeg, fcend; /* fcend: first unused pos */
X xchar gdx, gdy; /* goal of guard's walk */
X unsigned gddone:1;
X struct fakecorridor fakecorr[FCSIZ];
X};
X
Xstatic struct permonst pm_guard =
X { "guard", '@', 12, 12, -1, 40, 4, 10, sizeof(struct egd) };
X
Xstatic struct monst *guard;
Xstatic int gdlevel;
X#define EGD ((struct egd *)(&(guard->mextra[0])))
X
Xstatic
Xrestfakecorr()
X{
X register fcx,fcy,fcbeg;
X register struct rm *crm;
X
X while((fcbeg = EGD->fcbeg) < EGD->fcend) {
X fcx = EGD->fakecorr[fcbeg].fx;
X fcy = EGD->fakecorr[fcbeg].fy;
X if((u.ux == fcx && u.uy == fcy) || cansee(fcx,fcy) ||
X m_at(fcx,fcy))
X return;
X crm = &levl[fcx][fcy];
X crm->typ = EGD->fakecorr[fcbeg].ftyp;
X if(!crm->typ) crm->seen = 0;
X newsym(fcx,fcy);
X EGD->fcbeg++;
X }
X /* it seems he left the corridor - let the guard disappear */
X mondead(guard);
X guard = 0;
X}
X
Xstatic
Xgoldincorridor()
X{
X register int fci;
X
X for(fci = EGD->fcbeg; fci < EGD->fcend; fci++)
X if(g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy))
X return(1);
X return(0);
X}
X
Xsetgd(){
Xregister struct monst *mtmp;
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->isgd){
X guard = mtmp;
X gdlevel = dlevel;
X return;
X }
X guard = 0;
X}
X
Xinvault(){
Xregister tmp = inroom(u.ux, u.uy);
X if(tmp < 0 || rooms[tmp].rtype != VAULT) {
X u.uinvault = 0;
X return;
X }
X if(++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
X char buf[BUFSZ];
X register x,y,dd,gx,gy;
X
X /* first find the goal for the guard */
X for(dd = 1; (dd < ROWNO || dd < COLNO); dd++) {
X for(y = u.uy-dd; y <= u.uy+dd; y++) {
X if(y < 0 || y > ROWNO-1) continue;
X for(x = u.ux-dd; x <= u.ux+dd; x++) {
X if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd)
X x = u.ux+dd;
X if(x < 0 || x > COLNO-1) continue;
X if(levl[x][y].typ == CORR) goto fnd;
X }
X }
X }
X impossible("Not a single corridor on this level??");
X tele();
X return;
Xfnd:
X gx = x; gy = y;
X
X /* next find a good place for a door in the wall */
X x = u.ux; y = u.uy;
X while(levl[x][y].typ == ROOM) {
X register int dx,dy;
X
X dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
X dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
X if(abs(gx-x) >= abs(gy-y))
X x += dx;
X else
X y += dy;
X }
X
X /* make something interesting happen */
X if(!(guard = makemon(&pm_guard,x,y))) return;
X guard->isgd = guard->mpeaceful = 1;
X EGD->gddone = 0;
X gdlevel = dlevel;
X if(!cansee(guard->mx, guard->my)) {
X mondead(guard);
X guard = 0;
X return;
X }
X
X pline("Suddenly one of the Vault's guards enters!");
X pmon(guard);
X do {
X pline("\"Hello stranger, who are you?\" - ");
X getlin(buf);
X } while (!letter(buf[0]));
X
X if(!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
X pline("\"Oh, yes - of course. Sorry to have disturbed you.\"");
X mondead(guard);
X guard = 0;
X return;
X }
X clrlin();
X pline("\"I don't know you.\"");
X if(!u.ugold)
X pline("\"Please follow me.\"");
X else {
X pline("\"Most likely all that gold was stolen from this vault.\"");
X pline("\"Please drop your gold (say d$ ) and follow me.\"");
X }
X EGD->gdx = gx;
X EGD->gdy = gy;
X EGD->fcbeg = 0;
X EGD->fakecorr[0].fx = x;
X EGD->fakecorr[0].fy = y;
X EGD->fakecorr[0].ftyp = levl[x][y].typ;
X levl[x][y].typ = DOOR;
X EGD->fcend = 1;
X }
X}
X
Xgd_move(){
Xregister int x,y,dx,dy,gx,gy,nx,ny,typ;
Xregister struct fakecorridor *fcp;
Xregister struct rm *crm;
X if(!guard || gdlevel != dlevel){
X impossible("Where is the guard?");
X return(2); /* died */
X }
X if(u.ugold || goldincorridor())
X return(0); /* didnt move */
X if(dist(guard->mx,guard->my) > 1 || EGD->gddone) {
X restfakecorr();
X return(0); /* didnt move */
X }
X x = guard->mx;
X y = guard->my;
X /* look around (hor & vert only) for accessible places */
X for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) {
X if(nx == x || ny == y) if(nx != x || ny != y)
X if(isok(nx,ny))
X if(!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) {
X register int i;
X for(i = EGD->fcbeg; i < EGD->fcend; i++)
X if(EGD->fakecorr[i].fx == nx &&
X EGD->fakecorr[i].fy == ny)
X goto nextnxy;
X if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT)
X goto nextnxy;
X /* seems we found a good place to leave him alone */
X EGD->gddone = 1;
X if(ACCESSIBLE(typ)) goto newpos;
X crm->typ = (typ == SCORR) ? CORR : DOOR;
X goto proceed;
X }
X nextnxy: ;
X }
X nx = x;
X ny = y;
X gx = EGD->gdx;
X gy = EGD->gdy;
X dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
X dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
X if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
X
X while((typ = (crm = &levl[nx][ny])->typ) != 0) {
X /* in view of the above we must have IS_WALL(typ) or typ == POOL */
X /* must be a wall here */
X if(isok(nx+nx-x,ny+ny-y) && typ != POOL &&
X ZAP_POS(levl[nx+nx-x][ny+ny-y].typ)){
X crm->typ = DOOR;
X goto proceed;
X }
X if(dy && nx != x) {
X nx = x; ny = y+dy;
X continue;
X }
X if(dx && ny != y) {
X ny = y; nx = x+dx; dy = 0;
X continue;
X }
X /* I don't like this, but ... */
X crm->typ = DOOR;
X goto proceed;
X }
X crm->typ = CORR;
Xproceed:
X if(cansee(nx,ny)) {
X mnewsym(nx,ny);
X prl(nx,ny);
X }
X fcp = &(EGD->fakecorr[EGD->fcend]);
X if(EGD->fcend++ == FCSIZ) panic("fakecorr overflow");
X fcp->fx = nx;
X fcp->fy = ny;
X fcp->ftyp = typ;
Xnewpos:
X if(EGD->gddone) nx = ny = 0;
X guard->mx = nx;
X guard->my = ny;
X pmon(guard);
X restfakecorr();
X return(1);
X}
X
Xgddead(){
X guard = 0;
X}
X
Xreplgd(mtmp,mtmp2)
Xregister struct monst *mtmp, *mtmp2;
X{
X if(mtmp == guard)
X guard = mtmp2;
X}
X
X#endif /* QUEST /**/
END_OF_vault.c
if test 5920 -ne `wc -c <vault.c`; then
echo shar: \"vault.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f wizard.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"wizard.c\"
else
echo shar: Extracting \"wizard.c\" \(11381 characters\)
sed "s/^X//" >wizard.c <<'END_OF_wizard.c'
X/* SCCS Id: @(#)wizard.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* wizard.c - version 1.0.3 */
X
X/* wizard code - inspired by rogue code from Merlyn Leroy (digi-g!brian) */
X/* - heavily modified to give the wiz balls. (genat!mike) */
X
X#include "hack.h"
Xextern struct permonst pm_wizard;
Xextern struct monst *makemon();
X
X#if defined(HARD) || defined(DGKMOD)
Xchar nasties[] = "cdDeImoPTUVwxXz&\\,:;";
X#define WIZSHOT 2
X#else
X#define WIZSHOT 6 /* one chance in WIZSHOT that wizard will try magic */
X#endif
X
X#define BOLT_LIM 8 /* from this distance D and 1 will try to hit you */
X
Xchar wizapp[] = "@&DNPTUVXcemntx";
X
X#ifdef DGKMOD
X#define URETREATING(x,y) (movedist(u.ux,u.uy,x,y) > movedist(u.ux0,u.uy0,x,y))
Xextern char mlarge[];
X
Xmovedist(x0, x1, y0, y1)
X{
X register int absdx, absdy;
X
X absdx = abs(x1 - x0);
X absdy = abs(y1 - y0);
X
X return (absdx + absdy - min(absdx, absdy));
X}
X#endif
X
X/* If he has found the Amulet, make the wizard appear after some time */
Xamulet(){
X register struct obj *otmp;
X register struct monst *mtmp;
X
X if(!flags.made_amulet || !flags.no_of_wizards)
X return;
X /* find wizard, and wake him if necessary */
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(mtmp->data->mlet == '1' && mtmp->msleep && !rn2(40))
X for(otmp = invent; otmp; otmp = otmp->nobj)
X if(otmp->olet == AMULET_SYM && !otmp->spe) {
X mtmp->msleep = 0;
X if(dist(mtmp->mx,mtmp->my) > 2)
X pline(
X "You get the creepy feeling that somebody noticed your taking the Amulet."
X );
X return;
X }
X}
X
Xwiz_hit(mtmp)
Xregister struct monst *mtmp;
X{
X /* if we have stolen or found the amulet, we disappear */
X if(mtmp->minvent && mtmp->minvent->olet == AMULET_SYM &&
X mtmp->minvent->spe == 0) {
X /* vanish -- very primitive */
X fall_down(mtmp);
X return(1);
X }
X
X /* if it is lying around someplace, we teleport to it */
X if(!carrying(AMULET_OF_YENDOR)) {
X register struct obj *otmp;
X
X for(otmp = fobj; otmp; otmp = otmp->nobj)
X if(otmp->olet == AMULET_SYM && !otmp->spe) {
X if((u.ux != otmp->ox || u.uy != otmp->oy) &&
X !m_at(otmp->ox, otmp->oy)) {
X
X /* teleport to it and pick it up */
X mtmp->mx = otmp->ox;
X mtmp->my = otmp->oy;
X freeobj(otmp);
X mpickobj(mtmp, otmp);
X pmon(mtmp);
X return(0);
X }
X goto hithim;
X }
X return(0); /* we don't know where it is */
X }
Xhithim:
X if(rn2(2)) { /* hit - perhaps steal */
X
X /* if hit 1/20 chance of stealing amulet & vanish
X - amulet is on level 26 again. */
X if(hitu(mtmp, d(mtmp->data->damn,mtmp->data->damd))
X && !rn2(20) && stealamulet(mtmp))
X ;
X }
X else inrange(mtmp); /* try magic */
X return(0);
X}
X
X#ifdef DGKMOD
X/* Check if a monster is carrying a particular item.
X */
Xstruct obj *
Xm_carrying(mtmp, type)
Xstruct monst *mtmp;
Xint type;
X{
X register struct obj *otmp;
X
X for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
X if(otmp->otyp == type)
X return(otmp);
X return((struct obj *) 0);
X}
X
X/* Remove an item from the monster's inventory.
X */
Xm_useup(mon, obj)
Xstruct monst *mon;
Xstruct obj *obj;
X{
X struct obj *otmp, *prev;
X
X prev = ((struct obj *) 0);
X for (otmp = mon->minvent; otmp; otmp = otmp->nobj) {
X if (otmp == obj) {
X if (prev)
X prev->nobj = obj->nobj;
X else
X mon->minvent = obj->nobj;
X free((char *) obj);
X break;
X }
X prev = otmp;
X }
X}
X
Xm_throw(x, y, dx, dy, range, obj)
Xregister int x,y,dx,dy,range; /* direction and range */
Xregister struct obj *obj;
X{
X register struct monst *mtmp;
X struct objclass *oclass = &objects[obj->otyp];
X char sym = obj->olet;
X int damage;
X extern char *exclam();
X
X bhitpos.x = x;
X bhitpos.y = y;
X
X if(sym) tmp_at(-1, sym); /* open call */
X while(range-- > 0) {
X bhitpos.x += dx;
X bhitpos.y += dy;
X if(mtmp = m_at(bhitpos.x,bhitpos.y)) {
X damage = index(mlarge, mtmp->data->mlet)
X ? oclass->wldam
X : oclass->wsdam;
X#ifdef KAA
X# ifdef KOPS
X if(obj->otyp == CREAM_PIE) damage = 0;
X# endif
X if(mtmp->data->ac + 8 <= rnd(20))
X miss(oclass->oc_name, mtmp);
X else {
X#endif
X hit(oclass->oc_name, mtmp, exclam(damage));
X mtmp->mhp -= damage;
X if(mtmp->mhp < 1) {
X pline("%s is killed!", (Blind) ? "It" : Monnam(mtmp));
X mondied(mtmp);
X }
X range = 0;
X#ifdef KAA
X# ifdef KOPS
X if(obj->otyp == CREAM_PIE) {
X
X pline("%s is blinded by the pie.", (Blind) ? "It" : Monnam(mtmp));
X if(mtmp->msleep) mtmp->msleep = 0;
X setmangry(mtmp);
X mtmp->mcansee = 0;
X mtmp->mblinded += rnd(25);
X if (mtmp->mblinded <= 0)
X mtmp->mblinded = 127;
X } else
X# endif
X if(obj->otyp == ENORMOUS_ROCK) {
X mksobj_at(ENORMOUS_ROCK, bhitpos.x, bhitpos.y);
X fobj->quan=1;
X stackobj(fobj);
X }
X }
X#endif
X }
X if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
X if (multi)
X nomul(0);
X#ifdef KAA
X/* For giants throwing rocks, the rock which hits you shouldn't disappear. */
X# ifdef KOPS
X/* Cream pies must disappear if they hit or miss. */
X { int hit, blindinc, thitu();
X if (!(hit = thitu(8, (obj->otyp != CREAM_PIE) ? rnd(oclass->wldam) : 0, oclass->oc_name))
X && obj->otyp != CREAM_PIE
X# else
X if (!thitu(8, rnd(oclass->wldam), oclass->oc_name)
X# endif KOPS
X || obj->otyp == ENORMOUS_ROCK) {
X#else
X if (!thitu(8, rnd(oclass->wldam), oclass->oc_name)) {
X#endif
X mksobj_at(obj->otyp, u.ux, u.uy);
X fobj->quan = 1;
X stackobj(fobj);
X }
X#if defined(KAA) && defined(KOPS)
X if(hit && obj->otyp == CREAM_PIE) {
X if(!Blind) pline("Yeech! You've been creamed.");
X else pline("There's something sticky all over your face.");
X u.ucreamed += (blindinc = rnd(25));
X Blind += blindinc;
X seeoff(0);
X }
X }
X#endif
X range = 0;
X }
X tmp_at(bhitpos.x, bhitpos.y);
X }
X tmp_at(-1, -1);
X}
X#endif
X
X/* Return 1 if it's OK for the monster to move as well as (throw,
X * zap, etc).
X */
Xinrange(mtmp)
Xregister struct monst *mtmp;
X{
X register schar tx,ty;
X#ifdef DGKMOD
X struct obj *otmp;
X register xchar x, y;
X#endif
X /* do nothing if cancelled (but make '1' say something) */
X if(mtmp->data->mlet != '1' && mtmp->mcan) return(1);
X
X /* spit fire only when both in a room or both in a corridor */
X if(inroom(u.ux,u.uy) != inroom(mtmp->mx,mtmp->my)) return(1);
X tx = u.ux - mtmp->mx;
X ty = u.uy - mtmp->my;
X#ifdef DGKMOD
X if ((!tx || !ty || abs(tx) == abs(ty)) /* straight line or diagonal */
X && movedist(tx, 0, ty, 0) < BOLT_LIM) {
X /* Check if there are any dead squares between. If so,
X * it won't be possible to shoot.
X */
X for (x = mtmp->mx, y = mtmp->my; x != u.ux || y != u.uy;
X x += sgn(tx), y += sgn(ty))
X if (!ACCESSIBLE(levl[x][y].typ))
X return(1);
X
X switch(mtmp->data->mlet) {
X#ifdef KOPS
X case 'O':
X#endif
X#ifdef KAA
X case '9':
X#endif
X case 'K':
X case 'C':
X /* If you're coming toward the monster, the monster
X * should try to soften you up with arrows. If you're
X * going away, you are probably hurt or running. Give
X * chase, but if you're getting too far away, throw.
X */
X x = mtmp->mx;
X y = mtmp->my;
X#ifdef KOPS
X otmp = (mtmp->data->mlet == 'O') ? m_carrying(mtmp, DART)
X# ifdef KAA
X : (mtmp->data->mlet == 'K') ? m_carrying(mtmp, CREAM_PIE)
X# endif
X#else
X otmp = (mtmp->data->mlet == 'K') ? m_carrying(mtmp, DART)
X#endif
X#ifdef KAA
X : (mtmp->data->mlet == '9') ? m_carrying(mtmp, ENORMOUS_ROCK)
X#endif
X : m_carrying(mtmp, CROSSBOW_BOLT);
X if (otmp && (!URETREATING(x,y)
X || !rn2(BOLT_LIM - movedist(x, u.ux, y, u.uy)))) {
X m_throw(mtmp->mx, mtmp->my, sgn(tx), sgn(ty),
X BOLT_LIM, otmp);
X if (!--otmp->quan )
X m_useup(mtmp, otmp);
X return(0);
X }
X break;
X#else
X if((!tx && abs(ty) < BOLT_LIM) || (!ty && abs(tx) < BOLT_LIM)
X || (abs(tx) == abs(ty) && abs(tx) < BOLT_LIM)){
X switch(mtmp->mappearance) {
X#endif
X case 'D':
X /* spit fire in the direction of @ (not nec. hitting) */
X buzz(-1,mtmp->mx,mtmp->my,sgn(tx),sgn(ty));
X break;
X#ifdef HARD
X case '&':
X demon_hit(mtmp);
X break;
X#endif
X case '1':
X if(rn2(WIZSHOT)) break;
X /* if you zapped wizard with wand of cancellation,
X he has to shake off the effects before he can throw
X spells successfully. Sometimes they fail anyway */
X if(mtmp->mcan ||
X#ifdef HARD
X rn2(4)
X#else
X rn2(2)
X#endif
X ) {
X if(canseemon(mtmp))
X pline("%s makes a gesture, then curses.",
X Monnam(mtmp));
X else pline("You hear mumbled cursing.");
X
X if(!rn2(3)) {
X mtmp->mspeed = 0;
X mtmp->minvis = 0;
X }
X if(!rn2(3)) mtmp->mcan = 0;
X
X } else {
X if(canseemon(mtmp)){
X if(!rn2(6) && !Invis) {
X pline("%s hypnotizes you.", Monnam(mtmp));
X nomul(-rn2(3) + 3); /* bug fix by ab@unido */
X break;
X } else
X pline("%s chants an incantation.", Monnam(mtmp));
X } else
X pline("You hear a mumbled incantation.");
X switch(rn2(Invis ? 5 : 6)) {
X case 0:
X /* create a nasty monster from a deep level */
X nasty();
X break;
X case 1:
X pline("\"Destroy the thief, my pets!\"");
X aggravate(); /* aggravate all the monsters */
X /* fall into next case */
X case 2:
X if (flags.no_of_wizards == 1 && rnd(5) == 0)
X /* if only 1 wizard, clone himself */
X clonewiz(mtmp);
X break;
X case 3:
X if(mtmp->mspeed == MSLOW) mtmp->mspeed = 0;
X else mtmp->mspeed = MFAST;
X break;
X case 4:
X mtmp->minvis = 1;
X break;
X case 5:
X /* Only if not Invisible */
X pline("You hear a clap of thunder!");
X /* shoot a bolt of fire or cold, or a sleep ray */
X buzz(-rnd(3),mtmp->mx,mtmp->my,sgn(tx),sgn(ty));
X break;
X }
X }
X }
X if(u.uhp < 1) done_in_by(mtmp);
X }
X return(1);
X}
X
Xaggravate()
X{
X register struct monst *mtmp;
X
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
X mtmp->msleep = 0;
X if(mtmp->mfroz && !rn2(5))
X mtmp->mfroz = 0;
X }
X}
X
Xclonewiz(mtmp)
Xregister struct monst *mtmp;
X{
X register struct monst *mtmp2;
X
X if(mtmp2 = makemon(PM_WIZARD, mtmp->mx, mtmp->my)) {
X flags.no_of_wizards = 2;
X unpmon(mtmp2);
X mtmp2->mappearance = wizapp[rn2(sizeof(wizapp)-1)];
X pmon(mtmp2);
X }
X}
X
Xnasty() {
X
X#ifdef HARD
X register struct monst *mtmp;
X struct monst *mkmon_at();
X register int i, nastynum;
X
X nastynum = sizeof(nasties);
X
X for(i = rnd(u.ulevel/3); i > 0; --i) {
X
X mtmp = mkmon_at(nasties[rn2(nastynum)], u.ux, u.uy);
X mtmp->msleep = 0;
X mtmp->mpeaceful = 0;
X }
X#else
X (void) makemon((struct permonst *)0, u.ux, u.uy);
X#endif
X return(0);
X}
X
X#ifdef HARD
X/* Here, we make trouble for the poor shmuck who actually */
X/* managed to do in the Wizard. */
Xintervene() {
X
X switch(rn2(6)) {
X
X case 0:
X case 1: pline("You feel vaguely nervous.");
X break;
X case 2: pline("You notice a black glow surrounding you.");
X rndcurse();
X break;
X case 3: aggravate();
X break;
X case 4: nasty();
X break;
X case 5: resurrect();
X break;
X }
X}
X
Xwizdead(mtmp)
Xregister struct monst *mtmp;
X{
X if(! u.udemigod) {
X
X u.udemigod = TRUE;
X u.udg_cnt = rn1(250, 50);
X
X /* Make the wizard meaner the next time he appears */
X mtmp->data->mlevel++;
X mtmp->data->ac--;
X } else
X mtmp->data->mlevel++;
X}
X
X
X/* Let's resurrect the wizard, for some unexpected fun. */
Xresurrect() {
Xregister struct monst *mtmp;
X
X if(mtmp = makemon(PM_WIZARD, u.ux, u.uy)) {
X
X mtmp->msleep = 1;
X flags.no_of_wizards = 1;
X pline("A voice booms out...");
X pline("\"So you thought you could kill me, fool.\"");
X }
X
X}
X#endif /* HARD /**/
END_OF_wizard.c
if test 11381 -ne `wc -c <wizard.c`; then
echo shar: \"wizard.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 10 \(of 16\).
cp /dev/null ark10isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 16 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit.")