games-request@tekred.TEK.COM (12/02/87)
Submitted by: mike@genat.UUCP (Mike Stephenson) Comp.sources.games: Volume 3, Issue 12 Archive-name: nethack2.2/Part12 #! /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 12 (of 20)." # Contents: pcmain.c pri.c unixmain.c version.c wizard.c # Wrapped by billr@tekred on Tue Dec 1 16:25:05 1987 PATH=/bin:/usr/bin:/usr/ucb ; export PATH 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\" \(11972 characters\) sed "s/^X//" >pcmain.c <<'END_OF_pcmain.c' X/* SCCS Id: @(#)pcmain.c 2.1 87/10/18 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* main.c - (PC) version */ 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 X#ifdef GRAPHICS X /* Set the default values of the presentation characters */ X memcpy((char *) &showsyms, (char *) &defsyms, sizeof(struct symbols)); X#endif X#ifdef DGK X if ((dir = getenv("HACKDIR")) != (char *) NULL) { X (void) strcpy(hackdir, dir); X chdirx (dir, 1); X } X zero_finfo(); 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 settty("Sorry, you can't operate in debug mode.\n"); X clearlocks(); X exit(0); X } 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 (uptodate(fd) || !unlink(SAVEF))) { 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 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#ifdef HARD X if(!rn2(u.udemigod?25:(dlevel>30)?50:70)) X#else X if(!rn2(70)) X#endif 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 defined(KAA) && defined(BVH) X if(Polymorph && !rn2(100)) polyself(); X#endif X if(Searching && multi >= 0) (void) dosearch(); X gethungry(); X invault(); X amulet(); X#ifdef HARD X if (!rn2(50+(u.ulevel*3))) u_wipe_engr(rnd(3)); 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# ifdef REDO X else X pushch(ch); X# endif 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 REDO X multi = 0; X pushch(0); X#endif X } X} X X#ifdef DGK Xstruct finfo zfinfo = ZFINFO; X Xzero_finfo() { /* zero "fileinfo" array to prevent crashes on level change */ X int i; X X for (i = 0 ; i <= MAXLEVEL; i++) X fileinfo[i] = zfinfo; X} X#endif END_OF_pcmain.c if test 11972 -ne `wc -c <pcmain.c`; then echo shar: \"pcmain.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f pri.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"pri.c\" else echo shar: Extracting \"pri.c\" \(12732 characters\) sed "s/^X//" >pri.c <<'END_OF_pri.c' X/* SCCS Id: @(#)pri.c 2.1 87/11/09 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X X#include <stdio.h> X#include "hack.h" X#ifdef GENIX X#define void int /* jhn - mod to prevent compiler from bombing */ X#endif X#ifdef MSDOSCOLOR Xextern int hilite(); X#endif X Xxchar scrlx, scrhx, scrly, scrhy; /* corners of new area on screen */ X Xextern char *hu_stat[]; /* in eat.c */ Xextern char *CD; Xextern struct monst *makemon(); X Xswallowed() X{ X char *ulook = "|@|"; X ulook[1] = u.usym; X X cls(); X curs(u.ux-1, u.uy+1); X fputs("/-\\", stdout); X curx = u.ux+2; X curs(u.ux-1, u.uy+2); X fputs(ulook, stdout); X curx = u.ux+2; X curs(u.ux-1, u.uy+3); X fputs("\\-/", stdout); X curx = u.ux+2; X u.udispl = 1; X u.udisx = u.ux; X u.udisy = u.uy; X} X Xsetclipped(){ X error("Hack needs a screen of size at least %d by %d.\n", X ROWNO+2, COLNO); X} X X#ifdef DGK Xstatic int multipleAts; /* TRUE if we have many at()'s to do */ Xstatic int DECgraphics; /* The graphics mode toggle */ X X#define DECgraphicsON() ((void) putchar('\16'), DECgraphics = TRUE) X#define DECgraphicsOFF() ((void) putchar('\17'), DECgraphics = FALSE) X#endif X Xat(x,y,ch) Xregister xchar x,y; Xchar ch; X{ X#ifndef LINT X /* if xchar is unsigned, lint will complain about if(x < 0) */ X if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1) { X impossible("At gets 0%o at %d %d.", ch, x, y); X return; X } X#endif X if(!ch) { X impossible("At gets null at %d %d.", x, y); X return; X } X y += 2; X curs(x,y); X#ifdef DGK X if (flags.DECRainbow) { X /* If there are going to be many at()s in a row without X * intervention, only change the graphics mode when the X * character changes between graphic and regular. X */ X if (multipleAts) { X if (ch & 0x80) { X if (!DECgraphics) X DECgraphicsON(); X (void) putchar(ch ^ 0x80); /* Strip 8th bit */ X } else { X if (DECgraphics) X DECgraphicsOFF(); X (void) putchar(ch); X } X /* Otherwise, we don't know how many at()s will be happening X * before printing of normal strings, so change to graphics X * mode when necessary, then change right back. X */ X } else { X if (ch & 0x80) { X DECgraphicsON(); X (void) putchar(ch ^ 0x80); /* Strip 8th bit */ X DECgraphicsOFF(); X } else X (void) putchar(ch); X } X } else X#endif X#ifdef MSDOSCOLOR X hilite(ch); X#else X (void) putchar(ch); X#endif X curx++; X} X Xprme(){ X if(!Invisible) at(u.ux,u.uy,u.usym); X} X Xdoredraw() X{ X docrt(); X return(0); X} X Xdocrt() X{ X register x,y; X register struct rm *room; X register struct monst *mtmp; X X if(u.uswallow) { X swallowed(); X return; X } X cls(); X X/* Some ridiculous code to get display of @ and monsters (almost) right */ X if(!Invisible) { X levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym; X levl[u.udisx][u.udisy].seen = 1; X u.udispl = 1; X } else u.udispl = 0; X X seemons(); /* reset old positions */ X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) X mtmp->mdispl = 0; X seemons(); /* force new positions to be shown */ X/* This nonsense should disappear soon --------------------------------- */ X X#if defined(DGK) && !defined(MSDOSCOLOR) X /* I don't know DEC Rainbows, but if HILITE_COLOR is applicable, X * the !defined(HILITE_COLOR) will have to be compensated for. X * -kjs */ X /* For DEC Rainbows, we must translate each character to strip X * out the 8th bit if necessary. X */ X if (flags.DECRainbow) { X multipleAts = TRUE; X for(y = 0; y < ROWNO; y++) X for(x = 0; x < COLNO; x++) X if((room = &levl[x][y])->new) { X room->new = 0; X at(x,y,room->scrsym); X } else if(room->seen) X at(x,y,room->scrsym); X multipleAts = FALSE; X if (DECgraphics) X DECgraphicsOFF(); X } else { X /* Otherwise, line buffer the output to do the redraw in X * about 2/3 of the time. X */ X for(y = 0; y < ROWNO; y++) { X char buf[COLNO+1]; X int start, end; X X memset(buf, ' ', COLNO); X for(x = 0, start = -1, end = -1; x < COLNO; x++) X if((room = &levl[x][y])->new) { X room->new = 0; X buf[x] = room->scrsym; X if (start < 0) X start = x; X end = x; X } else if(room->seen) { X buf[x] = room->scrsym; X if (start < 0) X start = x; X end = x; X } X if (end >= 0) { X buf[end + 1] = '\0'; X curs(start, y + 2); X fputs(buf + start, stdout); X curx = end + 1; X } X } X } X#else X for(y = 0; y < ROWNO; y++) X for(x = 0; x < COLNO; x++) X if((room = &levl[x][y])->new) { X room->new = 0; X at(x,y,room->scrsym); X } else if(room->seen) X at(x,y,room->scrsym); X#endif X scrlx = COLNO; X scrly = ROWNO; X scrhx = scrhy = 0; X flags.botlx = 1; X bot(); X} X Xdocorner(xmin,ymax) register xmin,ymax; { X register x,y; X register struct rm *room; X register struct monst *mtmp; X X if(u.uswallow) { /* Can be done more efficiently */ X swallowed(); X return; X } X X seemons(); /* reset old positions */ X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) X if(mtmp->mx >= xmin && mtmp->my < ymax) X mtmp->mdispl = 0; X seemons(); /* force new positions to be shown */ X X#ifdef DGK X if (flags.DECRainbow) X multipleAts = TRUE; X#endif X for(y = 0; y < ymax; y++) { X if(y > ROWNO && CD) break; X curs(xmin,y+2); X cl_end(); X if(y < ROWNO) { X for(x = xmin; x < COLNO; x++) { X if((room = &levl[x][y])->new) { X room->new = 0; X at(x,y,room->scrsym); X } else X if(room->seen) X at(x,y,room->scrsym); X } X } X } X#ifdef DGK X if (flags.DECRainbow) { X multipleAts = FALSE; X if (DECgraphics) X DECgraphicsOFF(); X } X#endif X if(ymax > ROWNO) { X cornbot(xmin-1); X if(ymax > ROWNO+1 && CD) { X curs(1,ROWNO+3); X cl_eos(); X } X } X} X X/* Trolls now regenerate thanks to KAA */ X Xseeobjs(){ Xregister struct obj *obj, *obj2; X for(obj = fobj; obj; obj = obj2) { X obj2 = obj->nobj; X if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE) { X X if (obj->otyp == DEAD_TROLL && obj->age + 20 < moves) { X delobj(obj); X if (cansee(obj->ox, obj->oy)) X pline("The troll rises from the dead!"); X (void) makemon(PM_TROLL,obj->ox, obj->oy); X } else if (obj->age + 250 < moves) delobj(obj); X } X } X X for(obj = invent; obj; obj = obj2) { X obj2 = obj->nobj; X if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE) { X X if (obj->otyp == DEAD_TROLL && obj->age + 20 < moves) { X if (obj == uwep) X pline("The dead troll writhes out of your grasp!"); X else X pline("You feel squirming in your backpack!"); X (void)makemon(PM_TROLL,u.ux,u.uy); X useup(obj); X } else if (obj->age + 250 < moves) useup(obj); X } X } X} X Xseemons(){ Xregister struct monst *mtmp; X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){ X if(mtmp->data->mlet == ';') X mtmp->minvis = (u.ustuck != mtmp && X levl[mtmp->mx][mtmp->my].typ == POOL); X pmon(mtmp); X#ifndef NOWORM X if(mtmp->wormno) wormsee(mtmp->wormno); X#endif X } X} X Xpmon(mon) register struct monst *mon; { Xregister int show = (Blind && Telepat) || canseemon(mon); X if(mon->mdispl){ X if(mon->mdx != mon->mx || mon->mdy != mon->my || !show) X unpmon(mon); X } X X/* If you're hallucinating, the monster must be redrawn even if it has X already been printed. Problem: the monster must also be redrawn right X after hallucination is over, so it looks normal again. Therefore X code similar to pmon is in timeout.c. */ X if(show && (!mon->mdispl || Hallucination)) { X if (Hallucination) X atl(mon->mx,mon->my, X (!mon->mimic || Protection_from_shape_changers) ? X rndmonsym() : X (mon->mappearance == DOOR_SYM) ? DOOR_SYM X : rndobjsym()); X else X X atl(mon->mx,mon->my, X (!mon->mappearance X || u.uprops[PROP(RIN_PROTECTION_FROM_SHAPE_CHAN)].p_flgs X ) ? mon->data->mlet : mon->mappearance); X mon->mdispl = 1; X mon->mdx = mon->mx; X mon->mdy = mon->my; X } X} X Xunpmon(mon) register struct monst *mon; { X if(mon->mdispl){ X newsym(mon->mdx, mon->mdy); X mon->mdispl = 0; X } X} X Xnscr() X{ X register x,y; X register struct rm *room; X X if(u.uswallow || u.ux == FAR || flags.nscrinh) return; X pru(); X for(y = scrly; y <= scrhy; y++) X for(x = scrlx; x <= scrhx; x++) X if((room = &levl[x][y])->new) { X room->new = 0; X at(x,y,room->scrsym); X } X scrhx = scrhy = 0; X scrlx = COLNO; X scrly = ROWNO; X} X X/* 100 suffices for bot(); no relation with COLNO */ Xchar oldbot[100], newbot[100]; Xcornbot(lth) Xregister int lth; X{ X if(lth < sizeof(oldbot)) { X oldbot[lth] = 0; X flags.botl = 1; X } X} X Xbot() X{ Xregister char *ob = oldbot, *nb = newbot; Xregister int i; Xextern char *eos(); X if(flags.botlx) *ob = 0; X flags.botl = flags.botlx = 0; X (void) sprintf(newbot, X#ifdef GOLD_ON_BOTL X# ifdef SPELLS X "Lev %-2d Gp %-5lu Hp %3d(%d) Ep %3d(%d) Ac %-2d ", X dlevel, u.ugold, X# ifdef KAA X u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax : u.uhpmax, X u.uen, u.uenmax, u.uac); X# else X u.uhp, u.uhpmax, u.uen, u.uenmax, u.uac); X# endif X# else X "Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d ", X dlevel, u.ugold, X# ifdef KAA X u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax : u.uhpmax, X u.uac); X# else X u.uhp, u.uhpmax, u.uac); X# endif X# endif X#else X# ifdef SPELLS X "Level %-2d Hp %3d(%d) Energy %3d(%d) Ac %-2d ", X dlevel, X# ifdef KAA X u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax, u.uhpmax, X u.uen, u.uenmax, u.uac); X# else X u.uhp, u.uhpmax, u.uen, u.uenmax, u.uac); X# endif X# else X "Level %-2d Hp %3d(%d) Ac %-2d ", X dlevel, X# ifdef KAA X u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax, u.uhpmax, X u.uac); X# else X u.uhp, u.uhpmax, u.uac); X# endif X# endif X#endif X#ifdef KAA X if (u.mtimedone) X (void) sprintf(eos(newbot), "HD %d", mons[u.umonnum].mlevel); X else X#endif X if(u.ustr>18) { X if(u.ustr>117) X (void) strcat(newbot,"Str 18/**"); X else X (void) sprintf(eos(newbot), "Str 18/%02d",u.ustr-18); X } else X (void) sprintf(eos(newbot), "Str %-2d ",u.ustr); X#ifdef EXP_ON_BOTL X (void) sprintf(eos(newbot), " Exp %2d/%-5lu ", u.ulevel,u.uexp); X#else X (void) sprintf(eos(newbot), " Exp %2u ", u.ulevel); X#endif X (void) strcat(newbot, hu_stat[u.uhs]); X if(flags.time) X (void) sprintf(eos(newbot), " %ld", moves); X if(strlen(newbot) >= COLNO) { X register char *bp0, *bp1; X bp0 = bp1 = newbot; X do { X if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ') X *bp1++ = *bp0; X } while(*bp0++); X } X for(i = 1; i<COLNO; i++) { X if(*ob != *nb){ X curs(i,ROWNO+2); X (void) putchar(*nb ? *nb : ' '); X curx++; X } X if(*ob) ob++; X if(*nb) nb++; X } X (void) strcpy(oldbot, newbot); X} X X#if defined(WAN_PROBING) || defined(KAA) Xmstatusline(mtmp) register struct monst *mtmp; { X pline("Status of %s: ", monnam(mtmp)); X pline("Level %-2d Gold %-5lu Hp %3d(%d)", X mtmp->data->mlevel, mtmp->mgold, mtmp->mhp, mtmp->mhpmax); X pline("Ac %-2d Dam %d %s %s", X mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1), X mtmp->mcan ? ", cancelled" : "" ,mtmp->mtame ? " (tame)" : ""); X} X Xextern char plname[]; Xustatusline() { X pline("Status of %s ", plname); X pline("Level %d, gold %lu, hit points %d(%d), AC %d.", X# ifdef KAA X u.ulevel, u.ugold, u.mtimedone ? u.mh : u.uhp, X u.mtimedone ? u.mhmax : u.uhpmax, u.uac); X# else X u.ulevel, u.ugold, u.uhp, u.uhpmax, u.uac); X# endif X} X#endif X Xcls(){ X if(flags.toplin == 1) X more(); X flags.toplin = 0; X X clear_screen(); X X flags.botlx = 1; X} X Xrndmonsym() { X register int x; X if((x=rn2(58)) < 26) X return('a'+x); X else if (x<52) X return('A'+x-26); X else switch(x) { X case 52: return(';'); X case 53: return('&'); X case 54: return(':'); X case 55: return('\''); X case 56: return(','); X case 57: return('9'); X default: impossible("Bad random monster %d",x); return('{'); X } X} X Xrndobjsym() { X char *rndsym=")[!?%/=*($`"; X return *(rndsym+rn2(11)); X} X Xchar *hcolors[] = { "ultraviolet","infrared","hot pink", "psychedelic", X"bluish-orange","reddish-green","dark white","light black","loud", X"salty","sweet","sour","bitter","luminescent","striped","polka-dotted", X"square","round","triangular","brilliant","navy blue","cerise", X"chartreuse","copper","sea green","spiral","swirly","blotchy", X"fluorescent green","burnt orange","indigo","amber","tan", X"sky blue-pink","lemon yellow" }; X Xchar * Xhcolor() { X return hcolors[rn2(35)]; X} X X#ifdef MSDOSCOLOR X/* what if a level character is the same as an object/monster? */ X Xextern char obj_symbols[]; X Xhilite(let) Xchar let; X{ X char *isobjct = index(obj_symbols, let); X int ismnst(); X X if (!HI || !HE) { X (void) putchar(let); X return; X } X if (isobjct != NULL || let == GOLD_SYM) { X /* is an object */ X printf("%s%c%s", HI_OBJ, let, HE); X } else if (ismnst(let)) { X /* is a monster */ X printf("%s%c%s", HI_MON, let, HE); X } else { X /* default */ X (void) putchar(let); X } X} X Xint Xismnst(let) Xchar let; X{ X register int ct; X register struct permonst *ptr; X X for (ct = 0 ; ct < CMNUM + 2 ; ct++) { X ptr = &mons[ct]; X if(ptr->mlet == let) return(1); X } X if (let == '1') return(1); X else if (let == '2') return(1); X else if (let == ';') return(1); X else return(0); X} X#endif END_OF_pri.c if test 12732 -ne `wc -c <pri.c`; then echo shar: \"pri.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f unixmain.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"unixmain.c\" else echo shar: Extracting \"unixmain.c\" \(12402 characters\) sed "s/^X//" >unixmain.c <<'END_OF_unixmain.c' X/* SCCS Id: @(#)unixmain.c 2.1 87/10/18 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* main.c - (Unix) version */ X X#include <stdio.h> X#include <signal.h> X#include "hack.h" X X#ifdef QUEST X#define gamename "NetQuest" X#else X#define gamename "NetHack" X#endif X Xextern char *getlogin(), *getenv(); Xextern char plname[PL_NSIZ], pl_character[PL_CSIZ]; X Xint (*afternmv)(); Xint (*occupation)(); X Xint done1(); Xint hangup(); X Xint hackpid; /* current pid */ Xint locknum; /* max num of players */ X#ifdef DEF_PAGER Xchar *catmore; /* default pager */ X#endif Xchar SAVEF[PL_NSIZ + 11] = "save/"; /* save/99999player */ Xchar *hname; /* name of the game (argv[0] of call) */ Xchar obuf[BUFSIZ]; /* BUFSIZ is defined in stdio.h */ X Xextern char *nomovemsg; Xextern long wailmsg; X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X register int fd; X#ifdef CHDIR X register char *dir; X#endif X X hname = argv[0]; X hackpid = getpid(); X X#ifdef CHDIR /* otherwise no chdir() */ X /* X * See if we must change directory to the playground. X * (Perhaps hack runs suid and playground is inaccessible X * for the player.) X * The environment variable HACKDIR is overridden by a X * -d command line option (must be the first option given) X */ X 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 /* CHDIR /**/ X#ifdef GRAPHICS X /* Set the default values of the presentation characters */ X memcpy((char *) &showsyms, (char *) &defsyms, sizeof(struct symbols)); X#endif X#ifdef HACKOPTIONS X initoptions(); X#endif X whoami(); 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#ifdef CHDIR X chdirx(dir,0); X#endif 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 (void) signal(SIGHUP, hangup); X X /* X * Find the creation date of this game, X * so as to avoid restoring outdated savefiles. X */ X gethdate(hname); X X /* X * We cannot do chdir earlier, otherwise gethdate will fail. X */ X#ifdef CHDIR X chdirx(dir,1); X#endif 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 if(!strcmp(getlogin(), WIZARD)) X wizard = TRUE; X else { X settty("Sorry, you can't operate in debug mode.\n"); X clearlocks(); X exit(0); X } X break; X#endif X#ifdef NEWS X case 'n': X flags.nonews = TRUE; 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 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 if(argc > 1) X locknum = atoi(argv[1]); X#ifdef MAX_NR_OF_PLAYERS X if(!locknum || locknum > MAX_NR_OF_PLAYERS) X locknum = MAX_NR_OF_PLAYERS; X#endif X#ifdef DEF_PAGER X if(!(catmore = getenv("HACKPAGER")) && !(catmore = getenv("PAGER"))) X catmore = DEF_PAGER; X#endif X#ifdef MAIL X getmailstatus(); X#endif X#ifdef WIZARD X if(wizard) (void) strcpy(plname, "wizard"); else X#endif X if(!*plname || !strncmp(plname, "player", 4) X || !strncmp(plname, "games", 4)) 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#endif X /* X * check for multiple games under the same name X * (if !locknum) or check max nr of players (otherwise) X */ X (void) signal(SIGQUIT,SIG_IGN); X (void) signal(SIGINT,SIG_IGN); X if(!locknum) X (void) strcpy(lock,plname); X getlock(); /* sets lock if locknum != 0 */ X#ifdef WIZARD X } else { X register char *sfoo; X extern char genocided[], fut_geno[]; X (void) strcpy(lock,plname); 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 extern struct permonst mons[CMNUM+2]; 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 setftty(); 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 (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, gamename); X flags.move = 0; X } else { Xnot_recovered: X newgame(); X /* give welcome message before pickup messages */ X pline("Hello %s, welcome to %s!", plname, gamename); X X pickup(1); X read_engr_at(u.ux,u.uy); X flags.move = 1; X } 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 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#ifdef HARD X if(!rn2(u.udemigod?25:(dlevel>30)?50:70)) X#else X if(!rn2(70)) X#endif 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 if(flags.time) flags.botl = 1; 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 defined(KAA) && defined(BVH) X if(Polymorph && !rn2(100)) polyself(); X#endif X if(Searching && multi >= 0) (void) dosearch(); X gethungry(); X invault(); X amulet(); X#ifdef HARD X if (!rn2(50+(u.ulevel*3))) u_wipe_engr(rnd(3)); 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 X if (monster_nearby()) X stop_occupation(); X else if ((*occupation)() == 0) X occupation = 0; 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#ifdef MAIL X ckmailstatus(); X#endif X rhack((char *) 0); X } X if(multi && multi%7 == 0) X (void) fflush(stdout); X } X} 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 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 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 Xstatic Xchdirx(dir, wr) Xchar *dir; Xboolean wr; X{ X X# ifdef SECURE X if(dir /* User specified directory? */ X# ifdef HACKDIR X && strcmp(dir, HACKDIR) /* and not the default? */ X# endif X ) { X (void) setuid(getuid()); /* Ron Wessels */ X (void) setgid(getgid()); X } X# endif X X# ifdef HACKDIR X if(dir == NULL) X dir = HACKDIR; X# endif X X if(dir && chdir(dir) < 0) { X perror(dir); X error("Cannot chdir to %s.", dir); X } 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 printf("Warning: cannot write %s/%s", dir, RECORD); X getret(); 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 REDO X multi = 0; X pushch(0); X#endif X } X} X Xwhoami() { X /* X * Who am i? Algorithm: 1. Use name as specified in HACKOPTIONS X * 2. Use $USER or $LOGNAME (if 1. fails) X * 3. Use getlogin() (if 2. fails) X * The resulting name is overridden by command line options. X * If everything fails, or if the resulting name is some generic X * account like "games", "play", "player", "hack" then eventually X * we'll ask him. X * Note that we trust him here; it is possible to play under X * somebody else's name. X */ X register char *s; X X#ifndef DGKMOD X initoptions(); X#endif X if(!*plname && (s = getenv("USER"))) X (void) strncpy(plname, s, sizeof(plname)-1); X if(!*plname && (s = getenv("LOGNAME"))) X (void) strncpy(plname, s, sizeof(plname)-1); X if(!*plname && (s = getlogin())) X (void) strncpy(plname, s, sizeof(plname)-1); X} X Xnewgame() { 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 { X register struct monst *mtmp; X X /* Move the monster from under you or else X * makedog() will fail when it calls makemon(). X * - ucsfcgl!kneller X */ X if (mtmp = m_at(u.ux, u.uy)) mnexto(mtmp); X } X (void) makedog(); X seemons(); X#ifdef NEWS X if(flags.nonews || !readnews()) X /* after reading news we did docrt() already */ X#endif X docrt(); X return(0); X} X X#ifdef GENIX Xjhndist(x1,y1,x2,y2) X{ X int x,y; X x=x1-x2; X y=y1-y2; X return (x*x + y*y); X} X#endif END_OF_unixmain.c if test 12402 -ne `wc -c <unixmain.c`; then echo shar: \"unixmain.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f version.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"version.c\" else echo shar: Extracting \"version.c\" \(1830 characters\) sed "s/^X//" >version.c <<'END_OF_version.c' X/* SCCS Id: @(#)version.c 2.1 87/11/09 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X X#include "hack.h" X#include "date.h" X Xdoversion(){ X X#ifdef BETA X pline("%s Net%s Beta Version %s - last build %s.", X#else X pline("%s Net%s Version %s - last build %s.", X#endif X#ifdef UNIX X "Unix" X#endif X#ifdef MSDOS X "PC" X#endif X#ifdef QUEST X , "Quest" X#else X , "Hack" X#endif X , VERSION, datestring); X return(0); X} X X#ifdef DGKMOD X X#define pg_line(x) if(page_line(x)) goto quit; X XdoMSCversion() X{ X char buf[BUFSZ]; X X set_pager(0); X sprintf(buf, "Behold mortal, the origins of %s Net%s...", X#ifdef UNIX X "Unix" X#endif X#ifdef MSDOS X "PC" X#endif X#ifdef QUEST X , "Quest"); X#else X , "Hack"); X#endif X pg_line(""); X pg_line(buf); pg_line(""); pg_line(""); X X pg_line("The original HACK was written by Jay Fenlason with help from"); X pg_line("Kenny Woodland, Mike Thome and Jon Payne."); X X pg_line(""); X pg_line("Andries Brouwer did a major re-write and published (at least)"); X pg_line("two versions (1.0.2 and 1.0.3) to the Usenet."); X X pg_line(""); X pg_line("PC HACK 3.51K was an MSDOS(tm) version of HACK 1.03."); X pg_line("The PC implementation was done in Microsoft(tm) C by Don Kneller"); X pg_line("and modified by Ken Arromdee."); X X pg_line(""); X pg_line("PC and UNIX HACK were merged by Mike Stephenson and Ken Arromdee"); X pg_line("incorporating many modifications and features made by the above,"); X pg_line("as well as the following honored hackers:"); X X pg_line(""); X pg_line(" Scott R. Turner Tom Almy John S. Bien"); X pg_line(" Gil Neiger Ralf Brown Eric S. Raymond"); X pg_line(" Eric Backus Roland McGrath Greg Laskin"); X pg_line(" Bruce Holloway Richard P. Hughey Kevin Sweet"); X set_pager(1); X return(0); Xquit: X set_pager(2); X return(0); X} X X#endif END_OF_version.c if test 1830 -ne `wc -c <version.c`; then echo shar: \"version.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\" \(11805 characters\) sed "s/^X//" >wizard.c <<'END_OF_wizard.c' X/* SCCS Id: @(#)wizard.c 2.2 87/11/29 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 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(); Xextern struct obj *carrying(); X X#if defined(HARD) || defined(DGKMOD) X# ifdef SAC Xchar nasties[] = "cdDeImoPTUVwxXz3&,:;"; X# else Xchar nasties[] = "cdDeImoPTUVwxXz&,:;"; X# endif 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_SYM)) { 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 /* KAA /**/ 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 /* blindfold keeps pie filling out of your eyes */ X if (!Blindfolded) { X u.ucreamed += (blindinc = rnd(25)); X Blinded += blindinc; X seeoff(0); X } 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#ifndef RPH X if(inroom(u.ux,u.uy) != inroom(mtmp->mx,mtmp->my)) return(1); X#endif 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(10) 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#ifdef HARD X nasty(); X#endif X aggravate(); /* aggravate all the monsters */ X /* fall into next case */ X case 2: X if (flags.no_of_wizards == 1 && !rn2(3)) { X /* if only 1 wizard, clone himself */ X pline("Double Trouble..."); X clonewiz(mtmp); X } 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, u.ux, u.uy)) { X flags.no_of_wizards = 2; X mtmp2->mtame = mtmp2->mpeaceful = 0; 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, tmp; X X nastynum = sizeof(nasties) - 1; X tmp = (u.ulevel > 3) ? u.ulevel/3 : 1; /* just in case -- rph */ X X for(i = rnd(tmp); i > 0; --i) X if((mtmp = mkmon_at(nasties[rn2(nastynum)], u.ux, u.uy))) { X 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 flags.no_of_wizards--; 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 = mtmp->mtame = mtmp->mpeaceful = 0; X flags.no_of_wizards++; 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 11805 -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 12 \(of 20\). cp /dev/null ark12isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 20 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 0