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.")