Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: Notesfiles $Revision: 1.6.2.16 $; site pbear.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!think!pbear!peterb From: peterb@pbear.UUCP Newsgroups: net.sources.games Subject: PC/IX Hack (3 of 5) Message-ID: <2900006@pbear.UUCP> Date: Tue, 28-May-85 18:06:00 EDT Article-I.D.: pbear.2900006 Posted: Tue May 28 18:06:00 1985 Date-Received: Thu, 30-May-85 20:13:23 EDT Lines: 2723 Nf-ID: #N:pbear:2900006:000:57989 Nf-From: pbear!peterb May 28 18:06:00 1985 #!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # hack.h # hack.invent.c # hack.invinit.c # hack.io.c # hack.lev.c # hack.main.c # hack.mkobj.c # hack.mon.c # hack.mon.do.c # This archive created: Tue May 28 17:52:45 1985 export PATH; PATH=/bin:$PATH echo shar: extracting "'hack.h'" '(6911 characters)' if test -f 'hack.h' then echo shar: over-writing existing file "'hack.h'" fi sed 's/^X//' << \SHAR_EOF > 'hack.h' X/* X * Hack.h X */ X X/* #define NORMAL_IO */ X#ifdef NORMAL_IO X X#include X#define flush() fflush( stdout ) X X#else X X#undef putchar X#undef getchar X#define NULL 0 X#define STDOUT 0 /* Defines print in I/O packet */ X X#endif NORMAL_IO X X#include "envir.h" X#include "hack.name.h" Xchar *strchr(); X#define index(s,c) strchr(s,c) X Xlong pow (); X X#define BUFSZ 256 X X X/* Arguments for panic to give just an error message or a core dump */ X#define NOCORE 0 X#define CORE 1 X X#define ON 1 X#define OFF 0 X X#define WALL 1 X#define SDOOR 2 X#define DOOR 3 X#define CORR 4 X#define ROOM 5 X#define POOL 7 X#define VAULT 9 X X#define TRAPNUM 9 X X#define MSLOW 1 X#define MFAST 2 X X#define BEAR 0 X#define ARROW 1 X#define DART 2 X#define TDOOR 3 X#define TELE 4 X#define PIT 5 X#define SLPTRP 6 X#define PIERC 7 X#define MIMIC 8 X#define SEEN 32 X X#define UWEP 0 X#define UARM 1 X#define UARM2 2 X#define ULEFT 3 X#define URIGHT 4 X X#define POTN 1 X#define SCRN 2 X#define WANN 4 X#define RINN 8 X X#define UNC 1 /* unCoff(): */ X#define COFF 0 X X#define SETC 1 /* setCon(): */ X#define CON 0 X X#define IT1 1 X#define THEIT2 2 /* kluns */ X X#define CHOKED 0 X#define DIED 1 X#define STARVED 2 X#define DROWNED 3 X#define QUIT 4 /* Michiel args how you died */ X#define ESCAPED 5 X X#define NOMOVE 0 X#define MOVE 1 X#define DEAD 2 X X#define MISS 0 X#define HIT 1 X#define KILL 2 X X X Xtypedef struct func_tab { X char f_char; X int (*f_funct) (); X} FUNCTIONS; Xextern FUNCTIONS list[]; X X X Xstruct rm { X unsigned scrsym; X unsigned typ; X unsigned new: 1; X unsigned seen: 1; X unsigned lit: 1; X}; Xtypedef struct rm PART; Xextern PART levl[80][22]; X X X X Xstruct mkroom { X char lx, hx, ly, hy, rtype, rlit, doorct, fdoor; X}; Xtypedef struct mkroom MKROOM; Xextern MKROOM rooms[15]; X X X X#define DOORMAX 100 Xstruct coord { X char x, y; X}; Xtypedef struct coord COORDINATES; Xextern COORDINATES doors[DOORMAX]; X X X Xstruct food { X char *foodnam, prob, delay; X int nutrition; X}; Xtypedef struct food *FOOD; Xextern struct food foods[]; X X X Xstruct armor { X char *armnam, prob, delay, a_ac, a_can; X}; Xtypedef struct armor *ARMOR; Xextern struct armor armors[]; X X X X X Xstruct weapon { X char *wepnam, prob, wsdam, wldam; X}; Xtypedef struct weapon *WEAPON; Xextern struct weapon weapons[]; X X X X Xstruct permonst { X char *mname, mlet, mhd, mmove, ac, damn, damd; X unsigned pxlth; X}; Xtypedef struct permonst *MONSTDATA; Xextern struct permonst mon[8][7]; X#define PM_MIMIC &mon[5][2] X#define PM_PIERC &mon[2][3] X#define PM_DEMON &mon[7][6] X#define PM_CHAM &mon[6][6] X X X X Xstruct obj { X struct obj *nobj; X char otyp; X int spe; X unsigned ox: 7; X unsigned oy: 5; X unsigned olet: 7; X unsigned quan: 5; X unsigned known: 1; X unsigned cursed: 1; X unsigned unpaid: 1; X}; Xtypedef struct obj *OBJECT; Xextern OBJECT fobj, invent, uwep, uarm, uarm2, uleft, uright; X X X Xstruct stole { X OBJECT sobj; X unsigned sgold; X}; Xtypedef struct stole *STOLE; X X Xstruct monst { X struct monst *nmon; X MONSTDATA data; X STOLE mstole; X char mx, my; X int mhp, orig_hp; X unsigned invis: 1; X unsigned cham: 1; X unsigned angry: 1; /* Michiel: only for shopkeeper */ X unsigned ale: 1; /* Michiel: is it an ale?? */ X unsigned mspeed: 2; X unsigned msleep: 1; X unsigned mfroz: 1; X unsigned mconf: 1; X unsigned mflee: 1; X unsigned mcan: 1; X unsigned mtame: 1; X unsigned wormno: 5; X unsigned mxlth; X char mextra[1]; X}; Xtypedef struct monst *MONSTER; Xextern MONSTER fmon, shopkeeper, vaultkeeper; Xextern struct permonst treasurer; X XMONSTER m_at (); X X X Xstruct wseg { X struct wseg *nseg; X char wx, wy; X}; X Xtypedef struct wseg *WORMSEGMENT; X X#define newseg() (alloc( sizeof(struct wseg) )->Wseg) X X Xstruct gen { X struct gen *ngen; X char gx, gy; X unsigned gflag; X}; Xtypedef struct gen *GOLD_TRAP; Xextern GOLD_TRAP fgold, ftrap; X XGOLD_TRAP g_at (); XOBJECT o_at (), getobj (); X X Xstruct flag { X unsigned topl: 1; X unsigned botl: 1; X /* faint:1, screen:1, */ X unsigned oneline: 1; X unsigned next: 1; X unsigned move: 1; X unsigned mv: 1; X unsigned run: 2; X unsigned dgold: 1; X unsigned dhp: 1; X unsigned dhpmax: 1; X unsigned dstr: 1; X unsigned dac: 1; X unsigned dulev: 1; X unsigned dexp: 1; X unsigned dhs: 1; X unsigned dscr: 1; X}; Xtypedef struct flag FLAG; Xextern FLAG flags; X Xstruct you { X char ux, uy, ustr, ustrmax, udaminc, uac; X int uhunger; X unsigned ufast: 7; X unsigned uconfused: 6; X unsigned uinvis: 6; X unsigned ulevel: 5; X unsigned utrap: 3; X unsigned upit: 1; X unsigned uinshop: 1; X unsigned uinzoo: 1; X unsigned uinyard: 1; X unsigned uinswamp: 1; X unsigned uinknox: 1; X unsigned umconf: 1; X unsigned uhcursed: 1; X unsigned ufireres: 1; X unsigned ucoldres: 1; X unsigned utel: 1; X unsigned upres: 1; X unsigned ustelth: 1; X unsigned uagmon: 1; X unsigned ufeed: 1; X unsigned usearch: 1; X unsigned ucinvis: 1; X unsigned uregen: 1; X unsigned ufloat: 1; X unsigned uswallow: 1; X unsigned uswldtim: 4; X unsigned ucham: 1; X unsigned uhs: 2; X unsigned ublind; X short uhp, uhpmax; X long ugold, uexp, urexp; X MONSTER ustuck; X}; Xtypedef struct you YOU; Xextern YOU u; X X X Xextern char *wepnam[], *pottyp[], *scrtyp[], *traps[], X *wantyp[], *ringtyp[], *potcol[], *scrnam[], X *wannam[], *rinnam[], wdam[], oiden[], X *potcall[], *scrcall[], *wandcall[], *ringcall[], X curx, cury, savx, X xdnstair, ydnstair, xupstair, yupstair, X seehx, seelx, seehy, seely, X *save_cm, *killer, dlevel, maxdlevel, X dx, dy, buf[], lock[], X genocided[60], oldux, olduy, wizard; X Xextern unsigned moves; X Xextern multi; X X#define newmonst(xl) (alloc( xl + sizeof(struct monst) )->Mtmp ) X#define newobj() (alloc( sizeof(struct obj) )->Otmp ) X#define newgen() (alloc( sizeof(struct gen) )->Gtmp ) X#define newstole() (alloc( sizeof(struct stole) )->Stmp ) X X X#define CHAR_NULL (char *)NULL X#define OBJ_NULL (struct obj *)NULL X#define TRAP_NULL (struct gen *)NULL X#define MON_NULL (struct monst *)NULL X#define STOLE_NULL (struct stole *)NULL X X#ifndef SHOW Xunion PTRS { X GOLD_TRAP Gtmp; X MONSTER Mtmp; X OBJECT Otmp; X STOLE Stmp; X WORMSEGMENT Wseg; X char *Val; X}; X Xextern union PTRS * alloc (); X#endif SHOW SHAR_EOF if test 6911 -ne "`wc -c 'hack.h'`" then echo shar: error transmitting "'hack.h'" '(should have been 6911 characters)' fi echo shar: extracting "'hack.invent.c'" '(5532 characters)' if test -f 'hack.invent.c' then echo shar: over-writing existing file "'hack.invent.c'" fi sed 's/^X//' << \SHAR_EOF > 'hack.invent.c' X/* X * Hack.invent.c X */ X X#include "hack.h" X X#define NOT_AT 0 X#define NO_OBJ 0 X Xextern WORMSEGMENT wsegs[32]; X Xextern OBJECT yourinvent0; X XOBJECT addinv (obj) Xregister OBJECT obj; X{ X register OBJECT otmp; X X for (otmp = invent; otmp; otmp = otmp -> nobj) { X if (otmp -> otyp == obj -> otyp && otmp -> olet == obj -> olet X && !obj -> unpaid && !otmp -> unpaid && X ((obj -> otyp < F_COOKIE && X obj -> olet == ')' && X obj -> quan + otmp -> quan < 32 && X obj -> spe == otmp -> spe) || X index ("%?!*", otmp -> olet))) { X otmp -> quan += obj -> quan; X ofree (obj); X return otmp; X } X if (!otmp -> nobj) { X otmp -> nobj = obj; X obj -> nobj = 0; X return obj; X } X } X invent = obj; X obj -> nobj = 0; X return obj; X} X Xuseup (obj) Xregister OBJECT obj; X{ X register OBJECT otmp; X X if (obj -> quan > 1) { X obj -> quan--; X return; X } X if (obj == invent) X invent = invent -> nobj; X else { X for (otmp = invent; otmp -> nobj != obj; X otmp = otmp -> nobj); X otmp -> nobj = obj -> nobj; X } X if (!onbill (obj)) X ofree (obj); X} X Xdelobj (obj) Xregister OBJECT obj; X{ X freeobj (obj); X ofree (obj); X} X Xofree (obj) Xregister OBJECT obj; X{ X if (obj > yourinvent0) X free (obj); X} X X/* Unlink obj from chain starting with fobj */ X Xfreeobj (obj) Xregister OBJECT obj; X{ X register OBJECT otmp; X X if (obj == fobj) X fobj = fobj -> nobj; X else { X for (otmp = fobj; otmp -> nobj != obj; otmp = otmp -> nobj) X if (!otmp) X panic (CORE, "Try to free non-existing object"); X otmp -> nobj = obj -> nobj; X } X} X Xdeltrap (trap) Xregister GOLD_TRAP trap; X{ X register GOLD_TRAP gtmp; X X if (trap == ftrap) X ftrap = ftrap -> ngen; X else { X for (gtmp = ftrap; gtmp -> ngen != trap; X gtmp = gtmp -> ngen); X gtmp -> ngen = trap -> ngen; X } X free (trap); X} X XMONSTER m_at (x, y) Xregister x, y; X{ X register MONSTER mtmp; X register WORMSEGMENT wtmp; X X for (mtmp = fmon; mtmp; mtmp = mtmp -> nmon) { X if (mtmp -> mx == x && mtmp -> my == y) X return (mtmp); X if (mtmp -> wormno) X for (wtmp = wsegs[mtmp -> wormno]; wtmp; X wtmp = wtmp -> nseg) X if (wtmp -> wx == x && wtmp -> wy == y) X return (mtmp); X } X return (NOT_AT); X} X XOBJECT o_at (x, y) Xregister x, y; X{ X register OBJECT otmp; X X for (otmp = fobj; otmp; otmp = otmp -> nobj) X if (otmp -> ox == x && otmp -> oy == y) X return (otmp); X return (NOT_AT); X} X XGOLD_TRAP g_at (x, y, ptr) Xregister x, y; Xregister GOLD_TRAP ptr; X{ X while (ptr) { X if (ptr -> gx == x && ptr -> gy == y) X return (ptr); X ptr = ptr -> ngen; X } X return (NOT_AT); X} X XOBJECT getobj (let, word) Xregister char *let, *word; X{ X register OBJECT otmp; X register char ilet, ilet1, ilet2; X char buffer[BUFSZ], allowall = 0; X register foo = 0, foo2; X X if (*let == '#') { X let++; X allowall++; X } X ilet = 'a'; X for (otmp = invent; otmp; otmp = otmp -> nobj) { X if (!let || index (let, otmp -> olet)) X buffer[foo++] = ilet; X if (ilet == 'z') X ilet = 'A'; X else X ilet++; X } X buffer[foo] = 0; X if (foo > 5) { /* Compactify string */ X foo = foo2 = 1; X ilet2 = buffer[0]; X ilet1 = buffer[1]; X while (ilet = buffer[++foo2] = buffer[++foo]) { X if (ilet == ilet1 + 1) { X if (ilet1 == ilet2 + 1) X buffer[foo2 - 1] = ilet1 = '-'; X else if (ilet2 == '-') { X buffer[--foo2] = ++ilet1; X continue; X } X } X ilet2 = ilet1; X ilet1 = ilet; X } X } X if (!foo && !allowall) { X pline ("You don't have anything to %s.", word); X return (NO_OBJ); X } X for (;;) { X pline ((foo) ? "What do you want to %s [%s or ?]? " : X "What do you want to %s? ", word, buffer); X flags.topl = 0; X flush (); X ilet = getchar (); X if (ilet == '\33' || ilet == ' ' || ilet == '\n') X if (strcmp (word, "identify")) X return (NO_OBJ); X else X continue;/* sukkel */ X if (ilet == '?') X doinv (foo ? let : 0, 0); X else { X if (ilet >= 'A' && ilet <= 'Z') X ilet += 26 - 'A'; X else X ilet -= 'a'; X for (otmp = invent; otmp && ilet; ilet--, X otmp = otmp -> nobj); X if (!otmp) { X pline ("You don't have that object."); X continue; X } X break; X } X } X if (!allowall && let && !index (let, otmp -> olet)) { X pline ("That is a silly thing to %s.", word); X return (NO_OBJ); X } X return (otmp); X} X Xprinv (obj) Xregister OBJECT obj; X{ X register OBJECT otmp; X register char ilet = 'a'; X X for (otmp = invent; otmp != obj; otmp = otmp -> nobj) X if (++ilet > 'z') X ilet = 'A'; X prname (obj, ilet, 1); X} X Xprname (obj, let, onelin) Xregister OBJECT obj; Xregister char let; X{ X char li[BUFSZ]; X X doname (obj, buf); X sprintf (li, "%c - %s.", let, buf); X if (onelin) X pline (li); X else X printf ("%s\n", li); X} X Xddoinv () { X nomove (); X if (!invent) X pline ("You are empty handed."); X else X doinv (0, 1); X} X X/* X * Page inventory done by Fred X * X */ X Xdoinv (str, opt) Xregister char *str; Xint opt; X{ X register OBJECT otmp; X register char ilet = 'a'; X register int count = 1; X int ct = 0; X X if (!flags.oneline) X for (otmp = invent; otmp; otmp = otmp -> nobj) X if (!str || index (str, otmp -> olet)) X ct++; X if (ct > 1) X cls (); X for (otmp = invent; otmp; otmp = otmp -> nobj) { X if (!str || index (str, otmp -> olet)) { X prname (otmp, ilet, ct <= 1); X count++; X } X if (++ilet > 'z') X ilet = 'A'; X if (!(count % 22) && otmp -> nobj) { X getret (); X cls (); /* M. F. Page listing */ X } X } X if (!str && opt) X doinvbill (); X if (ct > 1) { X getret (); X docrt (); X } X} SHAR_EOF if test 5532 -ne "`wc -c 'hack.invent.c'`" then echo shar: error transmitting "'hack.invent.c'" '(should have been 5532 characters)' fi echo shar: extracting "'hack.invinit.c'" '(649 characters)' if test -f 'hack.invinit.c' then echo shar: over-writing existing file "'hack.invinit.c'" fi sed 's/^X//' << \SHAR_EOF > 'hack.invinit.c' X/* X * Hack.invinit.c X */ X X#include "hack.h" X X/* X * struct obj { X * struct obj *nobj; X * char otyp, spe; X * ox, oy, olet, quan, known, cursed, unpaid X * }; X */ X Xstruct obj arrows0 = { X (struct obj *)0, X W_ARROW, 0, 0, 0, ')', 25, 1, 0, 0 /* 25 +0 arrows */ X}; X Xstruct obj bow0 = { X &arrows0, X W_BOW, 1, 0, 0, ')', 1, 1, 0, 0 /* +1 bow */ X}; X Xstruct obj mace0 = { X &bow0, X W_MACE, 1, 0, 0, ')', 1, 1, 0, 0 /* +1 mace */ X}; X Xstruct obj uarm0 = { X &mace0, X A_RING, 4, 0, 0, '[', 1, 1, 0, 0 /* +1 ring mail */ X}; X Xstruct obj food0 = { X &uarm0, X F_FOOD, 0, 0, 0, '%', 2, 1, 0, 0 /* 2 food rations */ X}; X Xstruct obj *yourinvent0 = &food0; SHAR_EOF if test 649 -ne "`wc -c 'hack.invinit.c'`" then echo shar: error transmitting "'hack.invinit.c'" '(should have been 649 characters)' fi echo shar: extracting "'hack.io.c'" '(1559 characters)' if test -f 'hack.io.c' then echo shar: over-writing existing file "'hack.io.c'" fi sed 's/^X//' << \SHAR_EOF > 'hack.io.c' X/* X * Hack.io.c X */ X X#include "hack.h" X#include X Xshort ospeed; /* Used by tputs */ X Xgetlin (str) Xregister char *str; X{ X register char *ostr = str; X X flags.topl = 0; X flush (); X for (;;) { X *str = getchar (); X if (*str == '\b') { X if (str != ostr) { X str--; X write (1, "\b \b", 3); X } X else X write (1, "\7", 1); X } X else if (*str == '\n') { X *str = 0; X return; X } X else if (*str >= ' ') { X write (1, str, 1); X str++; X } X } X} X Xgetret () { X printf ("\nHit space to continue: "); X flush (); X while (getchar () != ' '); X} X Xstruct termio ttyo; Xh_io_init() { X ioctl(1, TCGETA, &ttyo); X} X X X/* X * Put together cbreak-mode and echo --- Michiel X */ X X int speed_table[] = { 0, 50, 75, 110, 134, 150, 200, 300, 600, X 1200, 1800, 2400, 4800, 9600, 0, 0 }; X Xhackmode (x) Xregister x; X{ X struct termio ttyp; X X ioctl (1, TCGETA, &ttyp);/* Use of basic functions */ X ospeed = ttyp.c_cflag & 017; /* mask out other bits */ X ospeed = speed_table[ospeed]; X if (x) { X ttyp.c_lflag &= ~ (ECHO | ICANON); X ttyp.c_cc[4]=0; X ttyp.c_cc[5]=0; /* set min and time to 0 */ X } X else { X ttyp.c_lflag = ttyo.c_lflag; /* reset back to original */ X ttyp.c_cc[4]=ttyo.c_cc[4]; /* set EOF */ X ttyp.c_cc[5]=ttyo.c_cc[5]; /* set EOL */ X } X if (ioctl (1, TCSETA, &ttyp) < 0) { X printf ("ERROR: Cannot change tty"); X exit (1); X } X} X Xmore () { X printf (" --More--"); X flush (); X while (getchar () != ' '); X flags.topl = 0; X} X X#ifndef NORMAL_IO Xgetchar () { X char c; X X read (0, &c, 1); X return (c); X} X#endif NORMAL_IO SHAR_EOF if test 1559 -ne "`wc -c 'hack.io.c'`" then echo shar: error transmitting "'hack.io.c'" '(should have been 1559 characters)' fi echo shar: extracting "'hack.lev.c'" '(4721 characters)' if test -f 'hack.lev.c' then echo shar: over-writing existing file "'hack.lev.c'" fi sed 's/^X//' << \SHAR_EOF > 'hack.lev.c' X/* X * Hack.lev.c X */ X X#include "hack.h" X#include X X#define MAXLEVEL 40 X#define ERROR 1 X#define OK 0 X Xextern char *itoa (), nul[], upxstairs[MAXLEVEL], upystairs[MAXLEVEL]; X Xextern WORMSEGMENT wsegs[32], wheads[32]; Xextern unsigned wgrowtime[32]; Xextern struct permonst pm_ghost; X X#include "hack.savelev.c" X Xstruct permonst pm_ale = { X "giant eel", ';', 15, 6, -3, 3, 6, 0 X}; X Xgetlev (fd) { X register MONSTER mtmp; X register GOLD_TRAP gtmp; X register OBJECT otmp; X register WORMSEGMENT wtmp; X int tmp, xl; X unsigned tmoves, omoves; X STOLE stmp; X X if (fd < 0 || read (fd, levl, sizeof (levl)) != sizeof (levl)) X return ERROR; X fmon = 0; X fobj = 0; X fgold = 0; X ftrap = 0; X shopkeeper = 0; X vaultkeeper = 0; X mread (fd, &omoves, sizeof (unsigned)); X mread (fd, &xupstair, 1); X mread (fd, &yupstair, 1); X mread (fd, &xdnstair, 1); X mread (fd, &ydnstair, 1); X if (omoves) X tmoves = (moves > omoves) ? moves - omoves : 0; X for (;;) { X mread (fd, &xl, sizeof (int)); X if (xl == -1) X break; X mtmp = newmonst (xl); X mread (fd, mtmp, xl + sizeof (struct monst)); X X/* Michiel restore stolen objects */ X stmp = newstole (); X mread (fd, stmp, sizeof (struct stole)); X if (stmp -> sgold || stmp -> sobj) { X mtmp -> mstole = stmp; X mtmp -> mstole -> sobj = 0; X for (;;) { X otmp = newobj (); X mread (fd, otmp, sizeof (struct obj)); X if (!otmp -> olet) X break; X otmp -> nobj = mtmp -> mstole -> sobj; X mtmp -> mstole -> sobj = otmp; X } X ofree (otmp); X } X else X free (stmp); X/* Regenerate animals if you've been on another level */ X if (omoves) { X if (!index (genocided, mtmp -> data -> mlet)) { X if (index ("ViT", mtmp -> data -> mlet)) X mtmp -> mhp += mtmp -> mhp + tmoves; X else X mtmp -> mhp += tmoves / 20; X if (mtmp -> mhp > mtmp -> orig_hp) X mtmp -> mhp = mtmp -> orig_hp; X if (mtmp -> data -> mlet == '@') { X if (*mtmp -> data -> mname == 's') X shopkeeper = mtmp; X else if (*mtmp -> data -> mname == 'v') X vaultkeeper = mtmp; X } X mtmp -> nmon = fmon; X fmon = mtmp; X } X } X else { /* Convert code from MKLEV */ X if (mtmp -> mhp == 10) X mtmp -> data = &pm_ghost; X else if (mtmp -> ale) X mtmp -> data = &pm_ale; X else X mtmp -> data = &mon[mtmp -> mhp][mtmp -> orig_hp]; X if (mtmp -> data -> mlet == 'D') X mtmp -> mhp = 80; X else X mtmp -> mhp = mtmp -> data -> mhd ? X d (mtmp -> data -> mhd, 8) : rnd (4); X mtmp -> orig_hp = mtmp -> mhp; X mtmp -> cham = (mtmp -> data -> mlet == ':'); X mtmp -> invis = (mtmp -> data -> mlet == 'I'); X if (mtmp -> data -> mlet == 'w' && X getwn (mtmp)) X initworm (mtmp); X mtmp -> nmon = fmon; X fmon = mtmp; X } X } X for (;;) { X gtmp = newgen (); X mread (fd, gtmp, sizeof (struct gen)); X if (!gtmp -> gx) X break; X gtmp -> ngen = fgold; X fgold = gtmp; X } X for (;;) { X mread (fd, gtmp, sizeof (struct gen)); X if (!gtmp -> gx) X break; X gtmp -> ngen = ftrap; X ftrap = gtmp; X gtmp = newgen (); X } X free (gtmp); X for (;;) { X otmp = newobj (); X mread (fd, otmp, sizeof (struct obj)); X if (!otmp -> olet) X break; X otmp -> nobj = fobj; X fobj = otmp; X } X ofree (otmp); X mread (fd, rooms, sizeof (rooms)); X mread (fd, doors, sizeof (doors)); X if (!omoves) X return OK; /* From MKLEV */ X mread (fd, wsegs, sizeof (wsegs)); X for (tmp = 1; tmp < 32; tmp++) X if (wsegs[tmp]) { X wheads[tmp] = wsegs[tmp] = wtmp = newseg (); X for (;;) { X mread (fd, wtmp, sizeof (struct wseg)); X if (!wtmp -> nseg) X break; X wheads[tmp] -> nseg = wtmp = newseg (); X wheads[tmp] = wtmp; X } X } X mread (fd, wgrowtime, sizeof (wgrowtime)); X return OK; X} X Xmread (fd, buffer, len) Xregister fd, len; Xregister char *buffer; X{ X register rlen; X X if ((rlen = read (fd, buffer, len)) != len) X panic (CORE, "Read %d instead of %d bytes from file #%d\n", X rlen, len, fd); X} X Xmklev () { X register fd; X char type[2]; X X#ifndef DEBUG X if (getbones ()) { X sleep (2); X goto Z; X } X#endif DEBUG X if (flags.next) { X flags.next = 0; X type[0] = 'b'; X } X else if (dlevel < rn1 (3, MAXLEVEL - 3)) X type[0] = 'a'; X else { X type[0] = 'n'; X flags.next = 1; X } X type[1] = '\0'; X hackexec (0, "./mklev", lock, type, itoa (dlevel), genocided, X wizard ? "w" : "", NULL); X if ((fd = open (lock, 0)) < 0) { X pline ("Can't open %s! Second try.", lock); X flush (); X hackexec (0, "./mklev", lock, type, itoa (dlevel), genocided, X wizard ? "w" : "", NULL); X if ((fd = open (lock, 0)) < 0) X panic (NOCORE, "Mklev error no level"); X } X getlev (fd); X close (fd); XZ: X if (!upxstairs[dlevel] && !upystairs[dlevel]) { X upxstairs[dlevel] = xupstair; X upystairs[dlevel] = yupstair; X } X} SHAR_EOF if test 4721 -ne "`wc -c 'hack.lev.c'`" then echo shar: error transmitting "'hack.lev.c'" '(should have been 4721 characters)' fi echo shar: extracting "'hack.main.c'" '(5621 characters)' if test -f 'hack.main.c' then echo shar: over-writing existing file "'hack.main.c'" fi sed 's/^X//' << \SHAR_EOF > 'hack.main.c' X/* X * Hack.main.c X */ X X#include X#include "hack.h" X X#define exception( id ) ( id == uid ) X#define HUISJES 2201 X#define WILDE 2216 X Xextern char *hu_stat[4], *getenv (), *malloc (), *parse (); X Xint rfile; X XCOORDINATES doors[DOORMAX]; X XPART levl[80][22]; XMKROOM rooms[15]; XMONSTER fmon = 0; XGOLD_TRAP fgold = 0, ftrap = 0; XFLAG flags; XYOU u; XOBJECT fobj = 0, invent, uwep, uarm, Xuarm2 = 0, uright = 0, uleft = 0; X Xextern OBJECT yourinvent0; Xextern struct obj mace0, uarm0; X Xchar nul[20]; /* Contains zeros */ X/* Lock contains 'pid'.dlevel */ Xchar plname[10], lock[16], wizard, X curx, cury, savx, X xupstair, yupstair, xdnstair, ydnstair, X *save_cm = 0, *killer, *nomvmsg, dlevel = 0, X dx, dy, buf[BUFSZ], genocided[60], X SAVEFILE[37] = SAVEDIR; X Xunsigned moves = 1; X Xint multi = 0, done1 (), hangup (), hackpid; Xint uid; X Xmain (argc, argv) Xchar *argv[]; X{ X int fd; X char *getlogin(); X register char *yourname = getlogin (); X X uid = getuid (); X /* X * Check on UID's X */ X X/* if (kantoor () && !exception (HUISJES) && !exception (WILDE)) { X printf ("Sorry, You can't play hack now\n" ); X flush (); X exit (0); X } */ X X if (!access (LOCK, 0) && strcmp (WIZARD, yourname)) { X printf ("Sorry, I'm busy with debugging.\nTry again later.\n"); X flush (); X exit (0); X } X h_io_init(); /* grab copy of termio struct */ X strncpy (plname, yourname, sizeof (plname) - 1); X#ifdef WIZARD X while (argc > 1 && **++argv == '-') { X switch (argv[0][1]) { X case 'w': X if (!exception (HUISJES) && !exception (WILDE) && strcmp (yourname, WIZARD)) X printf ("Sorry\n"); X else { X strcpy (plname, "wizard"); X wizard++; X } X break; X default: X printf ("Unknown option: %s\n", *argv); X } X flush (); X } X#endif WIZARD X X if (chdir (PLAYGROUND) < 0) X panic (NOCORE, "Cannot chdir to %s!", PLAYGROUND); X if ((rfile = open (RECORD, 2)) < 0) X panic (NOCORE, "Can't open %s!", RECORD); X setuid (getuid ()); X umask (0); X srand (hackpid = getpid ()); X startup (); X signal (SIGHUP, hangup); X signal (SIGINT, done1); X hackmode (ON); X if (!wizard) { X cls (); X flush (); X } X strcat (SAVEFILE, plname); X fd = open (SAVEFILE, 0); X if (fd >= 0) { X if (dorecover (fd) < 0) X goto normalplay; X flags.move = 0; X } X else { Xnormalplay: X shuffle (); X invent = yourinvent0; X uwep = &mace0; X uarm = &uarm0; X u.uac = 6; /* 10 - uarm->spe */ X u.ulevel = 1; X u.uhunger = 900; X u.uhpmax = u.uhp = 12; X u.ustrmax = u.ustr = rn2 (20) ? 16 : rn1 (7, 14); X flags.move = 1; X dodown (); /* a3 */ X cls (); X setCon (SETC); X flags.botl = 1; X makedog (); X } X for (;;) { X if (flags.move) { X if (!u.ufast || moves % 2 == 0) { X if (fmon) X movemon (); X if (!rn2 (70)) { X makemon (0); X fmon -> mx = 0; X fmon -> my = 0; X rloc (fmon); X seeatl (fmon -> mx, fmon -> my, X fmon -> data -> mlet); X } X } X if (u.ufast && !--u.ufast) X pline ("You feel yourself slowing down"); X if (u.uconfused && !--u.uconfused) X pline ("You feel less confused now"); X if (u.ublind && !--u.ublind) { X pline ("You can see again"); X if (!u.uswallow) X setCon (SETC); X } X if (u.uinvis && !--u.uinvis) { X if (!u.uswallow) X on (u.ux, u.uy); X pline ("You are no longer invisible"); X } X ++moves; X if (u.uhp <= 0) { X pline ("You die..."); X more (); X done (DIED); X } X if (u.uhp < u.uhpmax) { X if (u.ulevel > 9) { X if (u.uregen || moves % 3 == 0) { X flags.dhp = 1; X u.uhp += X rnd (u.ulevel - 9); X if (u.uhp > u.uhpmax) X u.uhp = u.uhpmax; X } X } X else if (u.uregen || moves % X (22 - (u.ulevel << 1)) == 0) { X flags.dhp = 1; X u.uhp++; X } X } X if (u.utel && !rn2 (85)) X tele (); X if (u.usearch) X dosearch (); X gethungry (); X } X flags.move = 1; X if (flags.dscr && !flags.mv) X nscr (); X if (flags.botl) X bot (); X else if (flags.dgold) { X flags.dgold = 0; X curs (16, 24); X curx = 21; X printf ("%-5u", u.ugold); X } X if (flags.dhp) { X flags.dhp = 0; X curs (26, 24); X curx = 29; X printf ("%3d", u.uhp); X } X if (flags.dhpmax) { X flags.dhpmax = 0; X curs (30, 24); X printf ("%d)", u.uhpmax); X if (u.uhpmax < 100) X putchar (' '); X curx = (u.uhpmax < 10) ? 33 : 34; X } X if (flags.dac) { X flags.dac = 0; X curs (37, 24); X printf ("%-3d", u.uac); X curx = 40; X } X if (flags.dstr) { X flags.dstr = 0; X curs (46, 24); X prustr (); X curx = 51; X } X if (flags.dulev) { X flags.dulev = 0; X curs (57, 24); X printf ("%2d", u.ulevel); X curx = 59; X } X if (flags.dexp) { X flags.dexp = 0; X curs (60, 24); X if (u.ulevel < 14) X printf ("%-5u", u.uexp); X else X printf ("MAX++"); X curx = 65; X } X if (flags.dhs) { X flags.dhs = 0; X curs (71, 24); X printf (hu_stat[u.uhs]); X curx = 79; X } X if (multi < 0) { X if (!++multi) { X pline (nomvmsg ? nomvmsg : X "You can move again."); X nomvmsg = 0; X } X } X else { X if (multi) { X lookaround (); X if (!multi) { X flags.move = 0; X continue; X } X if (flags.mv) { X if (multi < 80 && !--multi) { X flags.mv = 0; X flags.run = 0; X } X domove (); X } X else { X --multi; X rhack (save_cm); X } X } X else X rhack (parse ()); X } X } X} X Xglo (n) Xregister n; /* Construct the string `hackpid.n' */ X{ X/* X register char *tf = lock; X X while( *tf && *tf != '.' ) X tf++; X *tf++ = '.'; X sprintf( tf, "%d", n ); X*/ X sprintf (lock, "%d.%d", hackpid, n); X} X Ximpossible () { X pline ("Program in disorder - perhaps you'd better Quit"); X} X SHAR_EOF if test 5621 -ne "`wc -c 'hack.main.c'`" then echo shar: error transmitting "'hack.main.c'" '(should have been 5621 characters)' fi echo shar: extracting "'hack.mkobj.c'" '(4439 characters)' if test -f 'hack.mkobj.c' then echo shar: over-writing existing file "'hack.mkobj.c'" fi sed 's/^X//' << \SHAR_EOF > 'hack.mkobj.c' X/* X * Hack.mkobj.c X */ X X#include "hack.h" X#include "hack.vars.h" X Xmkfood () { X register FOOD fp; X register i = rn2 (100); X X fp = &foods[0]; X while ((i -= fp -> prob) >= 0) X fp++; X return (fp - foods); X} X Xmkarm () { X register ARMOR ap; X register i = rn2 (100); X X ap = &armors[0]; X while ((i -= ap -> prob) >= 0) X ap++; X return (ap - armors); X} X Xmkwep () { X register WEAPON wp; X register i = rn2 (100); X X wp = &weapons[0]; X while ((i -= wp -> prob) >= 0) X wp++; X return (wp - weapons); X} X Xchar mkobjstr[] = "))[[!!!!????%%%%//=**"; X Xmkobj (let) Xregister let; X{ X register OBJECT otmp; X X otmp = newobj (); X otmp -> nobj = fobj; X fobj = otmp; X otmp -> known = 0; X otmp -> cursed = 0; X otmp -> spe = 0; X otmp -> unpaid = 0; X otmp -> quan = 1; X if (!let) X let = mkobjstr[rn2 (sizeof (mkobjstr) - 1)]; X otmp -> olet = let; X switch (let) { X X case ')': X otmp -> otyp = mkwep (); X if (otmp -> otyp <= W_AMMUNITION) X otmp -> quan = rn1 (6, 6); X if (!rn2 (11)) X otmp -> spe = rnd (3); X else if (!rn2 (10)) { X otmp -> cursed = 1; X otmp -> spe = -rnd (3); X } X break; X X case '*': X otmp -> otyp = rn2 (SIZE (potcol)); X otmp -> quan = rn2 (6) ? 1 : 2; X break; X X case '[': X otmp -> otyp = mkarm (); X if (!rn2 (8)) X otmp -> cursed = 1; X if (!rn2 (10)) X otmp -> spe = rnd (3); X else if (!rn2 (9)) { X otmp -> spe = -rnd (3); X otmp -> cursed = 1; X } X otmp -> spe += 10 - armors[otmp -> otyp].a_ac; X break; X X case '!': X otmp -> otyp = rn2 (SIZE (pottyp)); X break; X X case '?': X otmp -> otyp = rn2 (SIZE (scrtyp)); X break; X X case '%': X otmp -> otyp = mkfood (); X otmp -> quan = rn2 (6) ? 1 : 2; X break; X X case '/': X otmp -> otyp = rn2 (SIZE (wantyp)); X if (otmp -> otyp == Z_DEATH) X otmp -> otyp = rn2 (SIZE (wantyp)); X otmp -> spe = rn1 (5, (otmp -> otyp <= Z_CREATE_MON) ? X 11 : 4); X /* detection and light and create monster */ X break; X X case '=': X otmp -> otyp = rn2 (SIZE (ringtyp)); X if (otmp -> otyp >= R_GAIN_STR) { X if (!rn2 (3)) { X otmp -> spe = -rnd (2); X otmp -> cursed = 1; X break; X } X else X otmp -> spe = rnd (2); X } X else if (otmp -> otyp == R_TELE || X otmp -> otyp == R_AGGRAV_MON || X otmp -> otyp == R_HUNGER) X otmp -> cursed = 1; X break; X X default: X panic (CORE, "Impossible mkobj"); X } X} X Xshufl (base, num) Xregister char *base[]; Xregister num; X{ X char **tmp, *tmp1; X int curnum; X X for (curnum = num - 1; curnum > 0; curnum--) { X tmp = &base[rn2 (curnum)]; X tmp1 = *tmp; X *tmp = base[curnum]; X base[curnum] = tmp1; X } X} X Xshuffle () { X shufl (wannam, SIZE (wantyp)); X shufl (potcol, SIZE (potcol)); X shufl (rinnam, SIZE (ringtyp)); X shufl (scrnam, SIZE (scrtyp)); X} X Xsavenames (fd) Xregister fd; X{ X bwrite (fd, oiden, sizeof oiden); X bwrite (fd, potcol, sizeof potcol); X bwrite (fd, scrnam, sizeof scrnam); X bwrite (fd, wannam, sizeof wannam); X bwrite (fd, rinnam, sizeof rinnam); X} X Xrestnames (fd) Xregister fd; X{ X mread (fd, oiden, sizeof oiden); X mread (fd, potcol, sizeof potcol); X mread (fd, scrnam, sizeof scrnam); X mread (fd, wannam, sizeof wannam); X mread (fd, rinnam, sizeof rinnam); X} X X/* Restore the names we have given to things */ Xcallsrestore (fd) Xregister fd; X{ X restcalls (fd, potcall, SIZE (pottyp)); X restcalls (fd, wandcall, SIZE (wantyp)); X restcalls (fd, ringcall, SIZE (ringtyp)); X restcalls (fd, scrcall, SIZE (scrtyp)); X} X X/* Save things we have given names to */ Xcallssave (fd) Xregister fd; X{ X savecalls (fd, potcall, SIZE (pottyp)); X savecalls (fd, wandcall, SIZE (wantyp)); X savecalls (fd, ringcall, SIZE (ringtyp)); X savecalls (fd, scrcall, SIZE (scrtyp)); X} X Xsavecalls (fd, strings, max) Xchar *strings[]; Xregister int max, fd; X{ X register teller; X X for (teller = 0; teller < max; ++teller) { X if (strings[teller]) X bwrite (fd, strings[teller], X strlen (strings[teller]) + 1); X else X bwrite (fd, "\0", 1); X } X} X Xrestcalls (fd, strings, max) Xregister int fd, max; Xchar *strings[]; X{ X register teller; X char *str; X int cnt; X char buffer[BUFSZ]; X X str = NULL; X for (teller = 0; teller < max; ++teller) { X cnt = -1; X do { X ++cnt; X mread (fd, str, 1); X buffer[cnt] = *str; X } while (*str != '\0'); X if (cnt) { X strings[teller] = alloc (strlen (buffer) + 1) -> Val; X strcpy (strings[teller], buffer); X } X } X} SHAR_EOF if test 4439 -ne "`wc -c 'hack.mkobj.c'`" then echo shar: error transmitting "'hack.mkobj.c'" '(should have been 4439 characters)' fi echo shar: extracting "'hack.mon.c'" '(10311 characters)' if test -f 'hack.mon.c' then echo shar: over-writing existing file "'hack.mon.c'" fi sed 's/^X//' << \SHAR_EOF > 'hack.mon.c' X/* X * Hack.mon.c X */ X X/* Contains various monster routines */ X X#include "hack.h" X Xextern char WCLEV[], STOPGLOW[]; X Xdist (x, y) Xregister x, y; X{ X x -= u.ux; X y -= u.uy; X return (x * x + y * y); X} X Xr_free (x, y, mtmp) Xregister x, y; Xregister MONSTER mtmp; X{ X if (mtmp -> ale) X return (levl[x][y].typ == POOL); X else X return (levl[x][y].typ > SDOOR && X (x != u.ux || y != u.uy) && levl[x][y].typ < POOL); X /* DOOR,CORR,ROOM */ X} X X X/* Puts m next to u, or anywhere if there isn't room there */ Xmnexto (mtmp) XMONSTER mtmp; X{ X register x, y, z; X struct { X char zx, zy; X } foo[15], *tfoo; X int range; X X tfoo = foo; X range = 1; X do { /* Full kludge action */ X for (y = 0; y < 2; y++) X for (x = u.ux - range; x <= u.ux + range; x++) { X z = range; X if (!y) X z = -z; X if (test (x, z += u.uy)) { X tfoo -> zx = x; X tfoo++ -> zy = z; X if (tfoo == &foo[15]) X goto foofull; X } X } X for (x = 0; x < 2; x++) X for (y = u.uy + 1 - range; y < u.uy + range; X y++) { X z = range; X if (!x) X z = -z; X if (test (z += u.ux, y)) { X tfoo -> zx = z; X tfoo++ -> zy = y; X if (tfoo == &foo[15]) X goto foofull; X } X } X range++; X } while (tfoo == foo); Xfoofull: X tfoo = &foo[rn2 (tfoo - foo)]; X mtmp -> mx = tfoo -> zx; X mtmp -> my = tfoo -> zy; X pmon (mtmp); X if (mtmp -> data -> mlet == 'w') X initworm (mtmp); X} X Xrloc (mtmp) XMONSTER mtmp; X{ X register tx, ty; X register char ch = mtmp -> data -> mlet; X X if (ch == 'w' && mtmp -> mx) X return; /* Do not relocate worms */ X levlsym (mtmp -> mx, mtmp -> my, ch); X if (mtmp -> ale) { X do { X tx = rn1 (77, 2); X ty = rn2 (22); X /* until CORR,DORR,or ROOM; or... */ X } while (levl[tx][ty].typ != POOL || m_at (tx, ty) || X (tx == u.ux && ty == u.uy)); X } X else { X do { X tx = rn1 (77, 2); X ty = rn2 (22); X /* until CORR,DORR,or ROOM; or... */ X } while (levl[tx][ty].typ < DOOR || m_at (tx, ty) || X (tx == u.ux && ty == u.uy) X || levl[tx][ty].typ >= 7); X } X mtmp -> mx = tx; X mtmp -> my = ty; X pmon (mtmp); X if (ch == 'w') X initworm (mtmp); X} X Xtest (x, y) { X if (x <= 0 || x > 78 || y <= 0 || y > 20) X return 0; X if (m_at (x, y) || levl[x][y].typ < DOOR || levl[x][y].typ >= 7) X return 0; X return 1; X} X Xpoisoned (string, pname) Xregister char *string, *pname; X{ X pseebl ("%s was poisoned!", string); X if (u.upres) { X pline ("The poison doesn't seem to affect you."); X return; X } X X switch (rn2 (6)) { X case 0: X u.uhp = 0; X break; X case 1: X case 2: X case 3: X losestr (rn1 (3, 3)); X break; X case 4: X case 5: X losehp (rn1 (10, 6), pname); X return; X } X X if (u.uhp <= 0) X killer = pname; X} X Xsteal (mtmp) XMONSTER mtmp; X{ X register OBJECT otmp, ot1; X register tmp; X X for (otmp = invent, tmp = 0; otmp -> nobj; otmp = otmp -> nobj, tmp++); X X tmp = rn2 (tmp); X otmp = invent; X if (!tmp) X invent = invent -> nobj; X else { X for (; otmp && tmp; tmp--, otmp = otmp -> nobj); X ot1 = otmp -> nobj; X otmp -> nobj = ot1 -> nobj;/* rm obj from invent */ X otmp = ot1; X } X if (otmp == uarm || otmp == uarm2) { X u.uac += otmp -> spe; X if (otmp == uarm) X uarm = uarm2; X uarm2 = 0; X flags.dac = 1; X } X else if (otmp == uwep) X uwep = 0; X else if (otmp == uleft) { X uleft = 0; X doring (otmp, OFF); X } X else if (otmp == uright) { X uright = 0; X doring (otmp, OFF); X } X doname (otmp, buf); X pline ("She stole %s.", buf); X stlobj (mtmp, otmp); X} X Xstlobj (mtmp, otmp) Xregister MONSTER mtmp; Xregister OBJECT otmp; X{ X otmp -> nobj = 0; /* Michiel: dog and two objects? */ X if (mtmp -> mstole) { X otmp -> nobj = mtmp -> mstole -> sobj; X mtmp -> mstole -> sobj = otmp; X return; X } /* Michiel save stolen object */ X else { X mtmp -> mstole = newstole (); X mtmp -> mstole -> sobj = otmp; X mtmp -> mstole -> sgold = 0; X } X} X Xdelmon (mtmp) Xregister MONSTER mtmp; X{ X unstuck (mtmp); /* a3 */ X relmon (mtmp); X if (mtmp == shopkeeper) X shkdead (); X if (mtmp == vaultkeeper) { X mtmp -> data -> mmove = -1; X vaultkeeper = 0; X } X if (mtmp -> wormno) X wormdead (mtmp); X free (mtmp); X} X Xrelmon (mtmp) Xregister MONSTER mtmp; X{ X register MONSTER mtmp2; X X if (mtmp == fmon) X fmon = fmon -> nmon; X else { X for (mtmp2 = fmon; mtmp2 -> nmon != mtmp; mtmp2 = mtmp2 -> nmon); X mtmp2 -> nmon = mtmp -> nmon; X } X} X X/* Release the objects the killed animal has stolen */ Xrelobj (mtmp) Xregister MONSTER mtmp; X{ X register GOLD_TRAP gtmp; X register tmp = 0; X OBJECT otmp, otmp2; X X if (mtmp -> mstole) { /* Michiel drop stolen obj or gold */ X if (mtmp -> mstole -> sgold) X tmp = mtmp -> mstole -> sgold; X else { X otmp = mtmp -> mstole -> sobj; X do { X otmp -> ox = mtmp -> mx; X otmp -> oy = mtmp -> my; X otmp2 = otmp; X otmp = otmp -> nobj; X } while (otmp); X otmp2 -> nobj = fobj; X fobj = mtmp -> mstole -> sobj; X if (mtmp -> data -> mlet != 'd') X seeatl (otmp -> ox, otmp -> oy, otmp -> olet); X } X free (mtmp -> mstole); X mtmp -> mstole = NULL; X } X if (mtmp -> data -> mlet == 'L') { X gtmp = newgen (); X gtmp -> ngen = fgold; X gtmp -> gx = mtmp -> mx; X gtmp -> gy = mtmp -> my; X if (dlevel) X gtmp -> gflag = tmp + d (dlevel, 30); X else X gtmp -> gflag = tmp + d (maxdlevel, 30); X fgold = gtmp; X seeatl (mtmp -> mx, mtmp -> my, '$'); X } X} X X/* a3 */ Xunstuck (mtmp) Xregister MONSTER mtmp; X{ X if (mtmp == u.ustuck) { X if (u.uswallow) { X u.uswallow = 0; X u.uswldtim = 0; X docrt (); X setCon (SETC);/* Try a3 */ X } X u.ustuck = 0; X } X} X Xkilled (mtmp) Xregister MONSTER mtmp; X{ X register tmp; X X unstuck (mtmp); X levlsym (mtmp -> mx, mtmp -> my, mtmp -> data -> mlet); X if (mtmp -> cham) X mtmp -> data = (PM_CHAM); X pseebl ("You destroy %s!", mtmp -> data -> mname); X if (!u.ublind && u.umconf) { X pline (STOPGLOW); X u.umconf = 0; X } X tmp = mtmp -> data -> mhd; X tmp *= tmp; X ++tmp; X if (mtmp -> data -> ac < 3) X tmp += (7 - mtmp -> data -> ac) << 1; X if (index ("AcsSDXaeRTVWU&In:P", mtmp -> data -> mlet)) X tmp += mtmp -> data -> mhd << 1; X if (index ("DeV&P", mtmp -> data -> mlet)) X tmp += 7 * mtmp -> data -> mhd; X if (mtmp -> data -> mhd > 6) X tmp += 50; X if (mtmp -> ale) X tmp += 1000; X relobj (mtmp); X if ((index ("NTV&", mtmp -> data -> mlet) || !rn2 (5)) && !mtmp -> ale X && levl[mtmp -> mx][mtmp -> my].typ > SDOOR) { X /* Mimic in wall? */ X mkobj (0); X fobj -> ox = mtmp -> mx; X fobj -> oy = mtmp -> my; X if (!u.ublind) X atl (mtmp -> mx, mtmp -> my, fobj -> olet); X } X delmon (mtmp); X u.urexp += tmp << 2; X u.uexp += tmp; X flags.dexp = 1; X while (u.uexp >= 10L * pow (u.ulevel - 1)) { X pline (WCLEV, ++u.ulevel); X tmp = rnd (10); X if (tmp < 3) X tmp = rnd (10); X u.uhpmax += tmp; X u.uhp += tmp; X flags.dhp = 1; X flags.dhpmax = 1; X flags.dulev = 1; X } X} X X#define TBLIND 5 X#define NOTEST 6 X X/*VARARGS*/ Xpsee (mode, x, y, str, name, arg)/* Str bevat %s */ Xregister char *str, *name, *arg; X{ X char *a1, *a2; X X a1 = "the %s"; X a2 = "the %s"; X if (mode == TBLIND) { X if (u.ublind) X a1 = "it"; X } X else if (mode != NOTEST && !cansee (x, y)) X switch (mode) { X case IT1: X a1 = "it"; X break; X case THEIT2: X a2 = "it"; X break; X case 0: X return 0; X default: X pline ("Bad(%d) mode in psee", mode); X } X sprintf (buf, str, a1, a2); X if (*buf >= 'a' && *buf <= 'z') X *buf += 'A' - 'a'; X pline (buf, name, arg); X return 1; X} X X/*VARARGS*/ Xp2xthe (str, name, arg) Xregister char *str, *name, *arg; X{ X psee (NOTEST, 0, 0, str, name, arg); X} X Xpseebl (str, name) Xregister char *str, *name; X{ X psee (TBLIND, 0, 0, str, name, NULL); X} X Xrescham () { /* Force all chameleons to become normal */ X register MONSTER mtmp; X X for (mtmp = fmon; mtmp; mtmp = mtmp -> nmon) X if (mtmp -> cham) { X mtmp -> cham = 0; X if (u.uswallow && u.ustuck == mtmp) { X unstuck (mtmp); X mnexto (mtmp); X } X newcham (mtmp, PM_CHAM); X } X} X X/* Make a chameleon look like a new monster */ Xnewcham (mtmp, mdat) Xregister MONSTER mtmp; Xregister MONSTDATA mdat; X{ X register mhp, hpn, hpd; X X if (mdat == mtmp -> data) X return; /* Still the same monster */ X if (u.uswallow && mdat -> mlet == 'w') X return; X if (mtmp -> wormno) X wormdead (mtmp);/* Throw tail away */ X hpn = mtmp -> mhp; X hpd = mtmp -> data -> mhd << 3; X mtmp -> data = mdat; X mtmp -> invis = 0; X mtmp -> mtame = 0; X mhp = mdat -> mhd << 3; X/* New hp: same fraction of max as before */ X mtmp -> mhp = 2 + (hpn * mhp) / hpd; X hpn = mtmp -> orig_hp; X mtmp -> orig_hp = 2 + (hpn * mhp) / hpd; X if (mdat -> mlet == 'I') { X ++mtmp -> invis; X if (cansee (mtmp -> mx, mtmp -> my)) X prl (mtmp -> mx, mtmp -> my); X } X if (mdat -> mlet == 'w' && getwn (mtmp)) X initworm (mtmp); X if (u.uswallow && mtmp == u.ustuck && X !index (",'P", mdat -> mlet)) { X unstuck (mtmp); X mnexto (mtmp); X } X pmon (mtmp); X} X Xmakemon (ptr) Xregister MONSTDATA ptr; X{ X register MONSTER mtmp; X X if (!ptr) { X do X ptr = &mon[rn2 (dlevel / 3 + 1) % 8][rn2 (7)]; X while (index (genocided, ptr -> mlet)); X } X else { X if (index (genocided, ptr -> mlet)) { X if (!u.ublind) X p2xthe ("%s vanishes!", ptr -> mname); X return 1; X } X } X mtmp = newmonst (ptr -> pxlth); X mtmp -> nmon = fmon; X fmon = mtmp; X mtmp -> mstole = 0; X mtmp -> invis = 0; X mtmp -> cham = 0; X mtmp -> msleep = 0; X mtmp -> mfroz = 0; X mtmp -> mconf = 0; X mtmp -> mflee = 0; X mtmp -> mtame = 0; X mtmp -> mspeed = 0; X mtmp -> mcan = 0; X mtmp -> angry = 0; X mtmp -> mxlth = 0; X mtmp -> ale = 0; X mtmp -> data = ptr; X switch (ptr -> mlet) { X case 'I': X ++mtmp -> invis; X break; X case 'L': X mtmp -> msleep = u.uhcursed; X break; X case ':': X ++mtmp -> cham; X if (!u.ucham) X newcham (mtmp, &mon[rn1 (6, 2)][rn2 (7)]); X break; X case ';': X mtmp -> ale = 1; X break; X } X if (ptr -> mlet != 'w' || !getwn (mtmp)) X mtmp -> wormno = 0; X mtmp -> mhp = rnd (4); X if (ptr -> mhd) X mtmp -> mhp = d (ptr -> mhd, 8); X mtmp -> orig_hp = mtmp -> mhp; X return 0; X} X Xsomegold () { X return ((u.ugold < 100L) ? u.ugold : X (u.ugold > 10000L) ? rnd (10000) : rnd ((int) u.ugold)); X} X Xmkmonat (ptr, x, y) Xregister MONSTDATA ptr; Xregister x, y; X{ X if (makemon (ptr)) X return; X if (x == u.ux && y == u.uy) X mnexto (fmon); X else { X atl (x, y, ptr -> mlet); X fmon -> mx = x; X fmon -> my = y; X } X} SHAR_EOF if test 10311 -ne "`wc -c 'hack.mon.c'`" then echo shar: error transmitting "'hack.mon.c'" '(should have been 10311 characters)' fi echo shar: extracting "'hack.mon.do.c'" '(12240 characters)' if test -f 'hack.mon.do.c' then echo shar: over-writing existing file "'hack.mon.do.c'" fi sed 's/^X//' << \SHAR_EOF > 'hack.mon.do.c' X/* X * Hack.mon.do.c X */ X X/* Contains monster control routines */ X X#include "hack.h" X Xextern MONSTER bhit (); X Xmovemon () { X register MONSTER mtmp, mtmp2; X X for (mtmp = fmon; mtmp; mtmp = mtmp2) { X mtmp2 = mtmp -> nmon; X if (mtmp -> mspeed != MSLOW || moves % 2 == 0) X if (dochug (mtmp)) X continue;/* Monster died */ X if (mtmp -> mspeed == MFAST) X if (dochug (mtmp)) X continue; X X/* If we left the room: make monsters invis, even if they didn't move */ X X if (!cansee (mtmp -> mx, mtmp -> my)) X levlsym (mtmp -> mx, mtmp -> my, mtmp -> data -> mlet); X if (mtmp -> wormno && mtmp -> data -> mlet == 'w') X wormsee (mtmp -> wormno); X } X} X Xjustswld (mtmp) Xregister MONSTER mtmp; X{ X newsym (mtmp -> mx, mtmp -> my); X mtmp -> mx = u.ux; X mtmp -> my = u.uy; X u.ustuck = mtmp; X at (u.ux, u.uy, mtmp -> data -> mlet); X pseebl ("%s swallows you!", mtmp -> data -> mname); X more (); X u.uswallow = 1; X docrt (); X} X Xyouswld (mtmp, dam, die) Xregister MONSTER mtmp; Xregister dam, die; X{ X pseebl ("%s digests you!", killer = mtmp -> data -> mname); X if (dam > 0) { X u.uhp -= dam; X flags.dhp = 1; X } X if (u.uswldtim++ == die) { X pline ("It totally digests you!"); X u.uhp = 0; X } X} X Xx2hitu (mlev, x, name) Xregister mlev, x; Xregister char *name; /* a3 */ X{ X register i; X X for (i = 0; i < 2; i++) X hitu (mlev, (x < 0) ? d (2, x) : (x == 0) ? d (3, 4) : X rnd (x), name); X} X Xdochug (mtmp) Xregister MONSTER mtmp; X{ X register MONSTDATA mdat; X register tmp = 0, ctmp; X X if (mtmp -> mhp <= 0 && !mtmp -> mtame) X return 1; /* Killed by dog or ? */ X if (mtmp -> cham && !rn2 (6)) X newcham (mtmp, &mon[rn1 (6, 2)][rn2 (7)]); X mdat = mtmp -> data; X /* X if( mdat->mhd < 0 ) X panic( CORE, "Bad(%d)monster %c", mdat->mhd, X mdat->mlet ); X */ X if ((moves % 20 == 0 || index ("ViT", mdat -> mlet)) && X mtmp -> mhp < mtmp -> orig_hp) X mtmp -> mhp++; /* Regenerate monsters */ X if (mtmp -> mfroz) X return 0; /* Frozen monsters don't do anything */ X if (mtmp -> msleep) { X /* Wake up a monster, or get out of here */ X if (cansee (mtmp -> mx, mtmp -> my) && !u.ustelth && X (!rn2 (7) || u.uagmon)) X mtmp -> msleep = 0; X else X return 0; X } X X/* Confused monsters get unconfused with small probability */ X X if (mtmp -> mconf && !rn2 (50)) X mtmp -> mconf = 0; X if (mdat -> mmove >= rnd (12) && (mtmp -> mflee || mtmp -> mconf || X dist (mtmp -> mx, mtmp -> my) > 2 || mtmp -> mtame || X mtmp == shopkeeper) && (tmp = m_move (mtmp, 0)) && X mdat -> mmove <= 12) X return (tmp == 2); X /* Move monsters and exit if rate<=12 */ X if (tmp == 2) X return 1; /* Monster died moving */ X X if (!index ("Ea", mdat -> mlet) && dist (mtmp -> mx, mtmp -> my) < 3 X && !mtmp -> mtame && mtmp != shopkeeper && u.uhp > 0) { X nomul (tmp = 0); X if (u.uswallow) { X if (mtmp != u.ustuck) X if (mdat -> mmove - 12 > rnd (12)) X tmp = m_move (mtmp, 1); X } X else if (!index ("&DyF", mdat -> mlet)) { X if (mtmp -> ale && cansee (mtmp -> mx, mtmp -> my)) { X mtmp -> invis = 0; X pmon (mtmp); X } X tmp = hitu (mdat -> mhd, d (mdat -> damn, mdat -> damd), X mdat -> mname); X } X X/* Increase chance of hitting (no damage) for L and R */ X if (index ("LR", mdat -> mlet) && hitu (5, 0, mdat -> mname)) X tmp++; X X ctmp = (tmp && !mtmp -> mcan && (!uarm || X armors[uarm -> otyp].a_can < rnd (3))); X X switch (mdat -> mlet) { X X case ';': X if (mtmp -> mcan) X break; X if (!u.ustuck && !rn2 (20)) { X p2xthe ("%s swings itself around you!", X mdat -> mname); X u.ustuck = mtmp; X } X else if (u.ustuck == mtmp && ctmp) { X p2xthe ("%s drowns you...", mdat -> mname); X more (); X done (DROWNED); X } X break; X X case '&': X if (!mtmp -> mcan && !rn2 (15)) { X makemon (PM_DEMON); X mnexto (fmon); X } X else { X x2hitu (10, -6, mdat -> mname); X x2hitu (10, 3, mdat -> mname); X hitu (10, rn1 (4, 2), mdat -> mname); X } X break; X X case ',': X case '\'': X if (u.uswallow) X if (mdat -> mlet == ',') X youswld (mtmp, 4 + u.uac, 5); X else X youswld (mtmp, rnd (6), 7); X else if (tmp) X justswld (mtmp); X break; X X case 'A': X if (ctmp && rn2 (2)) { X pline ("You feel weaker!"); X losestr (1); X } X break; X X case 'C': X case 'Y': X hitu (4, rnd (6), mdat -> mname); X break; X X case 'c': X if (ctmp && !rn2 (5)) { X pline ("You get turned to stone!"); X u.uhp = 0; X } X break; X X case 'D': X if (rn2 (6) || mtmp -> mcan) { X hitu (10, d (3, 10), mdat -> mname); X x2hitu (10, 8, mdat -> mname); X break; X } X pseebl ("%s breathes fire!", mdat -> mname); X buzz (Z_FIRE, mtmp -> mx, mtmp -> my, X u.ux - mtmp -> mx, X u.uy - mtmp -> my); X break; X X case 'd': X hitu (6, d (2, 4), mdat -> mname); X break; X X case 'e': X hitu (10, d (3, 6), mdat -> mname); X break; X X case 'F': X if (mtmp -> mcan) X break; X pseebl ("%s explodes!", mdat -> mname); X if (u.ucoldres) X pline ("You don't seem affected by it."); X else { X if (17 - (u.ulevel >> 1) > rnd (20)) { X pline ("You get blasted!"); X tmp = 6; X } X else { X pline ("You duck the blast..."); X tmp = 3; X } X losehp (d (tmp, 6), mdat -> mname); X } X cmdel (mtmp); X return 1; X X case 'g': X if (!ctmp || multi < 0 || rn2 (6)) X break; X pseebl ("You are frozen by %ss juices", "cube'"); X nomul (-rnd (10)); X break; X X case 'h': X if (!ctmp || multi < 0 || rn2 (5)) X break; X pseebl ("You are put to sleep by %ss bite!", X "homunculus'"); X nomul (-rnd (10)); X break; X X case 'j': X tmp = hitu (4, rnd (3), mdat -> mname); X tmp &= hitu (4, rnd (3), mdat -> mname); X if (tmp) X x2hitu (4, 4, mdat -> mname); X break; X X case 'k': X if ((hitu (4, rnd (4), mdat -> mname) || !rn2 (3)) X && ctmp) X poisoned ("bee's sting", mdat -> mname); X break; X X case 'L': X if (ctmp && u.ugold && rn2 (2)) { X u.ugold -= (ctmp = somegold ()); X pline ("Your purse feels lighter."); X flags.dgold = 1; X X /* Michiel save stolen gold */ X if (mtmp -> mstole) X mtmp -> mstole -> sgold += ctmp; X else { X mtmp -> mstole = newstole (); X mtmp -> mstole -> sobj = 0; X mtmp -> mstole -> sgold = ctmp; X } X mtmp -> mflee = 1; X rloc (mtmp); X } X break; X X case 'N': X if (ctmp && invent && rn2 (2)) { X steal (mtmp); X rloc (mtmp); X mtmp -> mflee = 1; X } X break; X X case 'n': X x2hitu (11, -6, mdat -> mname); X break; X X case 'o': X hitu (5, rnd (6), mdat -> mname); X /* tmp= ?? */ X if (hitu (5, rnd (6), mdat -> mname) && ctmp && X !u.ustuck && rn2 (2)) { X u.ustuck = mtmp; X pseebl ("%s has grabbed you!", X mdat -> mname); X u.uhp -= d (2, 8); X break; X } X if (u.ustuck == mtmp) { X pline ("You are being crushed."); X u.uhp -= d (2, 8); X } X break; X X case 'P': X if (u.uswallow) X youswld (mtmp, d (2, 4), 12); X else if (ctmp && !rn2 (4)) X justswld (mtmp); X else X hitu (15, d (2, 4), mdat -> mname); X break; X X case 'Q': X x2hitu (3, 2, mdat -> mname); X break; X X case 'R': X if (ctmp && uarm && uarm -> otyp < A_STD_LEATHER X && uarm -> spe > -2) { X pline ("Your armor rusts!"); X --uarm -> spe; X u.uac++; X flags.dac = 1; X } X break; X X case 'S': X if (ctmp && !rn2 (8)) X poisoned ("snake's bite", mdat -> mname); X break; X X case 's': X if (tmp && !rn2 (8)) X poisoned ("scorpion's sting", X mdat -> mname); X x2hitu (5, 8, mdat -> mname); X break; X X case 'T': X x2hitu (6, 6, mdat -> mname); X break; X X case 'U': X x2hitu (9, 0, mdat -> mname);/* 0: d(3,4) */ X break; X X case 'v': X if (ctmp && !u.ustuck) X u.ustuck = mtmp; X break; X X case 'V': X if (tmp) X u.uhp -= 4; X if (rn2 (3)) X break; X V: X if (ctmp) {/* hit by V or W */ X if (u.ulevel > 1) X pline ("Goodbye level %d.", X u.ulevel--); X else X u.uhp = 0; X ctmp = rnd (10); X u.uhp -= ctmp; X u.uhpmax -= ctmp; X u.uexp = 10L * pow (u.ulevel - 1) - 1L; X flags.dhp = 1; X flags.dhpmax = 1; X flags.dulev = 1; X flags.dexp = 1; X } X break; X X case 'W': X if (rn2 (5)) X break; X goto V; X case 'w': X if (tmp) X wormhit (mtmp); X break; X case 'X': X for (tmp = 0; tmp < 3; tmp++) X hitu (8, rnd (3), mdat -> mname); X break; X X case 'y': X if (mtmp -> mcan) X break; X cmdel (mtmp); X if (!u.ublind) { X pline ("You are blinded by a blast of light!"); X u.ublind = d (4, 12); X unCoff (COFF, 0); X } X return 1; X } /* switch */ X X if (u.uhp <= 0) X killer = mdat -> mname; X } X else if (mtmp -> ale && cansee (mtmp -> mx, mtmp -> my)) { X mtmp -> invis = 1; X newsym (mtmp -> mx, mtmp -> my); X } X/* Extra movement for fast monsters */ X if (mdat -> mmove - 12 > rnd (12)) X tmp = m_move (mtmp, 1); X return (tmp == 2); X} X Xcmdel (mtmp) Xregister MONSTER mtmp; X{ X register char mx = mtmp -> mx, my = mtmp -> my; X X delmon (mtmp); X if (cansee (mx, my)) X newsym (mx, my); X} X Xinrange (mtmp) Xregister MONSTER mtmp; X{ X int zx, zy; X register char tx = u.ux - mtmp -> mx, ty = u.uy - mtmp -> my; X X/* This mess figures out if the person is within 8 */ X if ((!tx && abs (ty) < 8) || (!ty && abs (tx) < 8) || X (abs (tx) == abs (ty) && abs (tx) < 8)) { X if (tx == 0) X zx = 0; X else X zx = tx / abs (tx); X if (ty == 0) X zy = 0; X else X zy = ty / abs (ty); X/* If we don't save dx and dy a capital move may screw up: */ X tx = dx; X ty = dy; X if (bhit (zx, zy, 8) == mtmp) X buzz (Z_FIRE, mtmp -> mx, mtmp -> my, dx, dy); X dx = zx; X dy = zy; X } X} X Xm_move (mtmp, after) Xregister MONSTER mtmp; X{ X register MONSTER mtmp2; X register nix, niy, omx, omy, appr, nearer, cnt, zx, zy; X char ddx, ddy, mmoved = 0; X X/* My dog gets a special treatment */ X if (mtmp -> mtame) X return dog_move (mtmp, after); X X if (u.uswallow) X return (1); /* a3 */ X/* Likewise for shopkeeper */ X if (mtmp == shopkeeper) X return shk_move (); X if (mtmp == vaultkeeper && !mtmp -> angry) X return (0); X X if (mtmp -> data -> mlet == 't' && !rn2 (19)) { X if (rn2 (2)) { X ddx = mtmp -> mx; X ddy = mtmp -> my; X mnexto (mtmp);/* Doesn't change old position */ X levlsym (ddx, ddy, 't'); X } X else X rloc (mtmp);/* Rloc does */ X return 1; X } X if (!mtmp -> mcan) X switch (mtmp -> data -> mlet) { X case 'D': X inrange (mtmp); X break; X case 'U': X if (!rn2 (10) && !u.uconfused && X cansee (mtmp -> mx, mtmp -> my)) { X pline ("You are confused!"); X u.uconfused = d (3, 4); X } X if (!mtmp -> mflee && u.uswallow && X u.ustuck != mtmp) X return 1; X } X appr = 1; X if (mtmp -> mflee) X appr = -1; X if (mtmp -> mconf || u.uinvis || (index ("BI", mtmp -> data -> mlet) && X !rn2 (3))) X appr = 0; X omx = mtmp -> mx; X omy = mtmp -> my; X nix = omx; X niy = omy; X cnt = 0; X for (ddx = -1; ddx <= 1; ddx++) X for (ddy = -1; ddy <= 1; ddy++) X if (r_free (zx = omx + ddx, zy = omy + ddy, mtmp) X && (ddx || ddy) X && !(ddx && ddy && (levl[omx][omy].typ == DOOR || X levl[zx][zy].typ == DOOR))) { X if (!mtmp -> mconf && m_at (zx, zy)) X continue; X nearer = (dist (zx, zy) < dist (nix, niy)); X if ((appr > 0 && nearer) || (appr < 0 && X !nearer) || X (!mmoved && mtmp -> wormno) || X (!appr && !rn2 (++cnt))) { X nix = zx; X niy = zy; X mmoved++; X } X } X if (mmoved) { X if (mtmp -> mconf && (mtmp2 = m_at (nix, niy))) { X if (hitmm (mtmp, mtmp2) == 1 && rn2 (4) && X hitmm (mtmp2, mtmp) == 2) X return 2; X return 0; X } X if (!mtmp -> ale) { X mtmp -> mx = nix; X mtmp -> my = niy; X } X else if (levl[nix][niy].typ == POOL) { X mtmp -> mx = nix; X mtmp -> my = niy; X } X X if (mtmp -> wormno && mtmp -> data -> mlet == 'w') X worm_move (mtmp); X } X else { X if (!rn2 (10) && index ("tNL", mtmp -> data -> mlet)) { X rloc (mtmp); X return 0; X } X if (mtmp -> wormno) X worm_nomove (mtmp); X } X if (mmoved || !cansee (omx, omy)) X levlsym (omx, omy, mtmp -> data -> mlet); X pmon (mtmp); X return (mmoved); X} SHAR_EOF if test 12240 -ne "`wc -c 'hack.mon.do.c'`" then echo shar: error transmitting "'hack.mon.do.c'" '(should have been 12240 characters)' fi # End of shell archive exit 0 Brought to you by Super Global Mega Corp .com