Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83 (MC830713); site ark.UUCP Path: utzoo!watmath!clyde!cbosgd!cbdkc1!desoto!packard!edsel!bentley!hoxna!houxm!whuxlm!harpo!decvax!genrad!panda!talcott!harvard!seismo!mcvax!vu44!botter!ark!huisjes From: huisjes@ark.UUCP (Michiel B. Huisjes) Newsgroups: net.sources Subject: Hack sources for PDP11/44 and PDP11/45 (part 4 of 5) Message-ID: <422@ark.UUCP> Date: Wed, 6-Feb-85 01:52:11 EST Article-I.D.: ark.422 Posted: Wed Feb 6 01:52:11 1985 Date-Received: Sat, 9-Feb-85 08:26:57 EST Reply-To: huisjes@ark.UUCP (Michiel Huisjes) Organization: VU Informatica, Amsterdam Lines: 2092 #!/bin/sh # # # # This is a shell archive. These archives are packed by the program # packmail(1). If you have the program unshar(1), I suggest you use it. # If you don't remove anything before the cut line and then feed to # sh(1) # # =====CUT HERE=======CUT HERE=======CUT HERE=======CUT HERE=======CUT HERE=== # echo 'Start of Hack, part 04 of 05:' echo 'x - data' sed 's/^X//' > data << '/' X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X! a potion X" The amulet of Frobozz X# a corridor X$ a pile, pot or chest of gold X% a piece of food X& a demon X' a lurker above X\ X) a weapon X* a gem X+ a door X, a trapper X- a wall X. the floor of a room X/ a wand X\ X\ X\ X\ X\ X\ X\ X\ X\ X\ X: a chameleon X; a giant ale X< the staircase to the previous level X= a ring X> the staircase to the next level X? a scroll X@ a human (or you) XA a giant ant XB a giant bat XC a centaur XD a dragon XE a floating eye XF a freezing sphere XG a gnome XH a hobgoblin XI an invisible stalker XJ a jackal XK a kobold XL a leprechaun XM a mimic XN a nymph XO an orc XP a purple worm XQ a quasit XR a rust monster XS a snake XT a troll XU an umber hulk XV a vampire XW a wraith XX a xorn XY a yeti XZ a zombie X[ a suit of armor X\ X\ X^ a trap X\ X\ Xa an acid blob Xb a giant beetle Xc a cockatrice Xd a dog Xe an ettin Xf a fog cloud Xg a gelatinous cube Xh a homunculus Xi an imp Xj a jaguar Xk a killer bee Xl a leocrotta Xm a minouter Xn a neo-otyugh Xo an owlbear Xp a piercer Xq a quivering blob Xr a giant rat Xs a giant scorpion Xt a teleporter Xu a ugod Xv a violet fungi Xw a long worm Xx a xerp Xy a yellow light Xz a zelomp X\ X| a wall X} a water filled area X~ a wormsegment X\ / echo 'x - hack.do.misc.c' sed 's/^X//' > hack.do.misc.c << '/' X/* X * Hack.do.misc.c X */ X X/* Routines to do various user commands */ X X#include X#include "hack.h" X#include "hack.do.vars.h" X /* (MT) has 'do' structures and lists */ X Xextern char *getenv (), UMISS[], WELDED[]; X X#define MAXLEVEL 40 X XOBJECT loseone (); X Xint done1 (); X Xchar upxstairs[MAXLEVEL], upystairs[MAXLEVEL]; X Xrhack (cmd) Xregister char *cmd; X{ X register FUNCTIONS * tlist = list; X X if (!cmd) { X pline ("Rhack: 0"); X impossible (); X return; X } X if (!*cmd || *cmd == -1) X return; /* Probably interrupt? */ X if (movecm (cmd)) { X if (multi) X flags.mv = 1; X domove (); X return; X } X if (movecm (lowc (cmd))) { X flags.run = 1; X multi = 80; X flags.mv = 1; X domove (); X return; X } X if (*cmd == 'f' && movecm (cmd + 1)) { X flags.run = 2; X multi = 80; X flags.mv = 1; X domove (); X return; X } X if (*cmd == 'F' && movecm (lowc (cmd + 1))) { X flags.run = 3; X multi = 80; X flags.mv = 1; X domove (); X return; X } X while (tlist -> f_char) { X if (*cmd == tlist -> f_char) { X (*(tlist -> f_funct)) (); X return; X } X tlist++; X } X pline ("Unknown command '%s'", cmd); X nomove (); X} X Xdoredraw () { X docrt (); X nomove (); X} X X/* X * VARIABELE ARGUMENTS, but if not given the last argument will always X * be a NULL. (Michiel) X */ X/*VARARGS*/ Xhackexec (num, file, arg1, arg2, arg3, arg4, arg5, arg6) Xregister int num; Xregister char *file, *arg1; Xchar *arg2, *arg3, *arg4, *arg5, *arg6; X{ X nomove (); X switch (fork ()) { X case -1: X pline ("Fork failed. Will try again."); X hackexec (num, file, arg1, arg2, arg3, arg4, X arg5, arg6); X break; X case 0: X if (num) { X signal (SIGINT, SIG_DFL); X setuid (getuid ()); X hackmode (OFF); X cls (); X flush (); X if (num == 2) X chdir (getenv ("HOME")); X } X else X signal (SIGINT, SIG_IGN); X execl (file, file, arg1, arg2, arg3, arg4, arg5, arg6); X panic (NOCORE, "%s: cannot execute.", file); X break; X default: X signal (SIGINT, SIG_IGN); X signal (SIGQUIT, SIG_IGN); X wait (0); X if (num) { X hackmode (ON); X docrt (); X } X signal (SIGINT, done1); X signal (SIGQUIT, SIG_DFL); X break; X } X} X Xdohelp () { X hackexec (1, MORE, HELP, NULL); X} X Xdosh () { X register char *str; X X if (str = getenv ("SHELL")) X hackexec (2, str, NULL); X else X hackexec (2, "/bin/sh", "-i", NULL); X} X Xdowield () { X register OBJECT wep; X X multi = 0; X if (!(wep = getobj (")", "wield"))) X flags.move = 0; X else if (uwep && uwep -> cursed) X pline (WELDED, weapons[uwep -> otyp].wepnam); X else { X uwep = wep; X if (uwep -> cursed) X pline ("The %s welds itself to your hand!", X weapons[uwep -> otyp].wepnam); X else X prinv (uwep); X } X} X Xddodown () { X dostairs ("down"); X} X Xddoup () { X dostairs ("up"); X} X Xdostairs (dir) Xregister char *dir; X{ X if (u.ustuck || X (*dir == 'd' && (u.ux != xdnstair || u.uy != ydnstair)) || X (*dir == 'u' && (u.ux != xupstair || u.uy != yupstair))) { X pline ("You can't go %s here", dir); X nomove (); X return; X } X keepdogs (1); X unCoff (COFF, 1); X dosavelev (); X if (*dir == 'd') X dodown (); X else X doup (); X losedogs (); X if (u.ucham) X rescham (); X setCon (CON); X if (u.uhcursed) X docurse (); X} X Xdosavelev () { X register fd; X X glo (dlevel); X fd = creat (lock, 0644); X savelev (fd); X close (fd); X} X Xextern int uid; X Xchecklev (dir) /* Michiel: Geen geknoei */ Xregister char *dir; X{ X if ((upxstairs[dlevel] != xupstair || X upystairs[dlevel] != yupstair) && !wizard) { X clearlocks (); X panic (NOCORE, "Way %s has been changed...", dir); X } X} X Xdodown () { X register fd; X X glo (++dlevel); X if ((fd = open (lock, 0)) < 0) X mklev (); X else { X if (maxdlevel < dlevel) X mklev ();/* Bad file */ X else X getlev (fd); X close (fd); X checklev ("down"); X } X if (maxdlevel < dlevel) X maxdlevel = dlevel;/* Trapdoor/stairs */ X u.ux = xupstair; X u.uy = yupstair; X inshop (); X} X Xdoup () { X register fd; X X if (dlevel == 1) X done (ESCAPED); X glo (--dlevel); X if ((fd = open (lock, 0)) < 0) X panic (CORE, "Cannot open %s\n", lock); X getlev (fd); X close (fd); X checklev ("up"); X u.ux = xdnstair; X u.uy = ydnstair; X} X Xm_call () { X register OBJECT obj; X X obj = getobj ("?!=/", "call"); X if (obj) X docall (obj); X flags.move = 0; X} X Xdocall (obj) Xregister OBJECT obj; X{ X register char *str, **str1; X X pline ("Call it:"); X getlin (buf); X flags.topl = 0; X if (!*buf) X return; X str = alloc (strlen (buf) + 1) -> Val; X strcpy (str, buf); X switch (obj -> olet) { X case '_': X free (str); X return; X case '?': X str1 = &scrcall[obj -> otyp]; X break; X case '!': X str1 = &potcall[obj -> otyp]; X break; X case '/': X str1 = &wandcall[obj -> otyp]; X break; X case '=': X str1 = &ringcall[obj -> otyp]; X break; X default: X pline ("What a weird(%c %d)thing to call", obj -> olet, obj -> otyp); X X } X if (*str1) X free (*str1); X *str1 = str; X} X Xdonull () { X} X XMONSTER bhit (); X Xdothrow () { X register OBJECT obj; X register MONSTER monst; X register tmp; X char x, y; X X obj = getobj ("#%)", "throw"); X /* One can also throw food */ X if (!obj || !getdir ()) { X nomove (); X return; /* Sets dx and dy to direction */ X } X if (obj == uarm || obj == uarm2 || obj == uleft || X obj == uright) { X pline ("You can't throw something you are wearing"); X return; X } X if (obj == uwep && uwepcursed ()) X return; X monst = bhit (dx, dy, 8); X x = dx; X y = dy; X obj = loseone (obj); /* Separate one out from list */ X if (monst) { X if (obj -> olet == ')') { X tmp = u.ulevel - 1 + monst -> data -> ac + abon (); X if (obj -> otyp <= W_AMMUNITION) { X if (!uwep || uwep -> otyp != obj -> otyp + X 11) X tmp -= 4; X else { X if (uwep -> cursed) X tmp -= uwep -> spe; X else X tmp += uwep -> spe; X } X } X else { X if (obj -> cursed) X tmp -= obj -> spe; X else X tmp += obj -> spe; X } X if (tmp >= rnd (20)) { X if (hmon (monst, obj)) { X hit (weapons[obj -> otyp].wepnam, X monst); X cutworm (monst, x, y, obj -> otyp); X } X else X monst = 0; X if (obj -> otyp <= W_AMMUNITION && X rn2 (2)) { X freeobj (obj); X if (!onbill (obj)) X ofree (obj); X return; X } X } X else X miss (weapons[obj -> otyp].wepnam, monst); X } X else { X psee (IT1, x, y, UMISS, monst -> data -> mname, NULL); X if (obj -> olet == '%' && monst -> data -> mlet == 'd') X if (tamedog (monst, obj)) X return; X } X/* Awake monster if sleeping */ X if (monst) { X monst -> msleep = 0; X if (monst == shopkeeper) X setangry (); X } X } X obj -> ox = x; X obj -> oy = y; X if (obj -> unpaid && inshproom (x, y)) X subfrombill (obj); X if (!m_at (x, y)) X newsym (x, y); X} X X/* Create a new object (at fobj) of multiplicity 1 X remove obj from invent if necessary */ XOBJECT loseone (obj) Xregister OBJECT obj; X{ X register OBJECT otmp; X X if (!index ("/=", obj -> olet) && obj -> quan > 1) { X obj -> quan--; X otmp = newobj (); X *otmp = *obj; X otmp -> quan = 1; X otmp -> unpaid = 0;/* Obj is still on the bill */ X otmp -> nobj = fobj; X fobj = otmp; X } X else { 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 obj -> nobj = fobj; X fobj = obj; X } X return (fobj); X} X Xgetdir () { X pline ("What direction?"); X flush (); X *buf = getchar (); X flags.topl = 0; X return (movecm (buf)); X} X Xdocurse () { X register MONSTER mtmp; X X for (mtmp = fmon; mtmp; mtmp = mtmp -> nmon) { X mtmp -> msleep = 0; X mtmp -> mtame = 0; X } X if (shopkeeper) X shopkeeper -> angry = 1; X if (vaultkeeper) X vaultkeeper -> angry = 1; X} / echo 'x - hack.end.c' sed 's/^X//' > hack.end.c << '/' X/* X * Hack.end.c X */ X X#include "hack.h" X#include X X#define MAXLEVEL 40 X Xextern char plname[], *itoa (), *setan (); X Xextern int billct, rfile; X Xchar maxdlevel = 0, *strcat (); X Xchar *statxx[] = { X "choked", X "died", X "starved", X "drowned", X "quit", X "escaped" X}; X Xdone1 () { X register char c; X X nomove (); X signal (SIGINT, done1); X pline ("Really quit?"); X flush (); X if ((c = getchar ()) == 'y') X done (QUIT); X else if (c == 'S') X hangup (); X} X Xdone (status) Xregister int status; X{ X if (wizard && status != QUIT && status != ESCAPED) { X u.ustr = (u.ustrmax += 2); X u.uhp = (u.uhpmax += 10); X u.uac--; X if (uwep) X uwep -> spe++; X pline ("For some reason you are still alive."); X nomove (); X flags.botl = 1; X return; X } X if (status == QUIT && u.uhp <= 0) X status = DIED; X if (billct) X paybill (); X clearlocks (); X if (status < QUIT) { /* Not when quit or escaped */ X#ifndef DEBUG X savebones (); X#endif DEBUG X outrip (); X } X hackmode (OFF); X cls (); X printf ("Goodbye %s...\n\n", plname); X u.urexp += u.ugold; X if (status == DIED) { X strcpy (killer, setan (killer)); X u.urexp -= u.ugold / 10; X } X else X killer = statxx[status]; X if (status == ESCAPED) { X OBJECT otmp; X X u.urexp += 150; X for (otmp = invent; otmp; otmp = otmp -> nobj) { X if (otmp -> olet == '*') X u.urexp += otmp -> quan * 10 * rnd (250); X else if (otmp -> olet == '"') X u.urexp += 25000; X } X printf ("You escaped from the dungeon"); X } X else X printf ("You %s on dungeon level %d,", statxx[status], X dlevel); X printf (" with %U points\n", u.urexp); X printf ("and %U pieces of gold, after %u moves.\n", X u.ugold, moves); X printf ("You were level %d with a maximum of %d hit points when you %s.\n\n", u.ulevel, u.uhpmax, statxx[status]); X topten (); X flush (); X exit (0); X} X X#define NAMESIZE 8 X#define DEATHSIZE 40 X#define TOPPRINT 15 /* Aantal scores dat wordt afgedrukt */ X#define TOPLIST 25 /* Length of 'top ten' list */ X Xtopten () { X int tmp; X struct recitem { X long points; X int level, maxlvl, hp, maxhp; X char str[NAMESIZE + 1], death[DEATHSIZE + 1]; X } rec[TOPLIST + 1], *t1; X register flg; X X for (t1 = rec; t1 < &rec[TOPLIST]; t1++) X if (read (rfile, t1, sizeof (struct recitem)) <= 0) X t1 -> points = 0; X flg = 0; X if (u.urexp > rec[TOPLIST - 1].points && !wizard) { X signal (SIGINT, SIG_IGN); X if (u.urexp > rec[TOPPRINT - 1].points) X printf ("You made the top %d list!\n", TOPPRINT); X if (lseek (rfile, 0L, 0) < 0) X panic (CORE, "Cannot lseek on record file"); X X/* Stick in new entry. NB: we save the last few X entries that disappeared from the list */ X X for (tmp = TOPLIST - 2; tmp >= 0 && rec[tmp].points < X u.urexp; tmp--) X rec[tmp + 1] = rec[tmp]; X tmp++; /* Point to right place */ X rec[tmp].points = u.urexp; X rec[tmp].level = dlevel; X rec[tmp].maxlvl = maxdlevel; X rec[tmp].hp = u.uhp; X rec[tmp].maxhp = u.uhpmax; X strncpy (rec[tmp].str, plname, NAMESIZE); X rec[tmp].str[NAMESIZE] = 0; X strncpy (rec[tmp].death, killer, DEATHSIZE); X rec[tmp].death[DEATHSIZE] = 0; X flg++; X } X printf ("Number Points Name\n"); X for (t1 = rec, tmp = 1; t1 < &rec[TOPLIST]; tmp++, t1++) { X char killed = 0; X X if (flg && t1 -> points) X write (rfile, t1, sizeof (struct recitem)); X if (t1 >= &rec[TOPPRINT] || t1 -> points == 0) X continue; X printf ("%2d %6D %8s ", tmp, t1 -> points, X t1 -> str); X if (*t1 -> death == 'e') X printf ("escaped the dungeon [max level %d]", t1 -> maxlvl); X else { X switch (t1 -> death[1]) { X case 'u': X printf ("quit"); X break; X case 'h': X printf ("choked on his food"); X break; X case 't': X printf ("starved"); X break; X case 'r': X printf ("drowned"); X break; X default: X printf ("was killed"); X killed++; X } X printf (" on%s level %d", X killed ? "" : " dungeon", t1 -> level); X if (t1 -> maxlvl != t1 -> level) X printf (" [%d]", t1 -> maxlvl); X } X if (killed) X printf (" by %s", t1 -> death); X putchar ('.'); X if (t1 -> maxhp) X printf (" Hp: %s [%d]", (t1 -> hp > 0) ? X itoa (t1 -> hp) : "-", t1 -> maxhp); X putchar ('\n'); X } X close (rfile); X} X Xchar * X itoa (a) Xregister int a; X{ X static char buffer[8]; X X sprintf (buffer, "%d", a); X return (buffer); X} X Xclearlocks () { X register x; X X signal (SIGINT, SIG_IGN); X for (x = 1; x <= MAXLEVEL; x++) { X glo (x); X if (unlink (lock)) X break; X } X#ifdef DEBUG X glo (0); X unlink (lock); X#endif DEBUG X} X Xhangup () { X save (); X clearlocks (); X exit (1); X} / echo 'x - hack.invent.c' sed 's/^X//' > 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} / echo 'x - hack.lev.c' sed 's/^X//' > 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} / echo 'x - hack.main.c' sed 's/^X//' > 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 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 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} / echo 'x - hack.mkobj.c' sed 's/^X//' > 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} / echo 'x - hack.save.c' sed 's/^X//' > hack.save.c << '/' X/* X * Hack.save.c X */ X X/* X * The old version of save () didn't work at all. Many things are changed, X * but some things are not implemented yet, like saving in a shop, or saving X * while swallowed or stuck X */ X X#include "hack.h" X#include "hack.dog.h" X#include X X#define MAXLEVEL 40 X Xextern char SAVEFILE[], nul[], upxstairs[MAXLEVEL], X upystairs[MAXLEVEL], shlevel, vaultflag[MAXLEVEL]; Xextern long robbed; Xextern unsigned starved; Xextern COORDINATES shk, shd; Xextern MONSTER shopkeeper; Xextern MONSTER mydogs; X Xsave () { X register fd, ofd, tmp; X register OBJECT otmp, otmp2; X MONSTER mtmp; X int version = VERSION; X X nomove (); X if (shopkeeper && inshproom (u.ux, u.uy)) { X pline ("You are not allowed to save in a shop. (Continue or Quit)"); X return; X } X else if (u.ustuck || u.uswallow) { X pline ("Not implemented when you're stuck or swallowed. (Continue or Quit)"); X return; X } X if ((fd = creat (SAVEFILE, 0644)) < 0) { X pline ("Cannot creat save file. (Continue or Quit)"); X return; X } X signal (SIGINT, SIG_IGN); X signal (SIGQUIT, SIG_IGN); X X bwrite (fd, &version, sizeof (version)); X keepdogs (0); X savelev (fd); X for (otmp = invent; otmp; otmp = otmp2) { X bwrite (fd, otmp, sizeof (struct obj)); X if (otmp == uarm) X bwrite (fd, "a", 1); X else if (otmp == uarm2) X bwrite (fd, "b", 1); X else if (otmp == uwep) X bwrite (fd, "w", 1); X else if (otmp == uleft) X bwrite (fd, "l", 1); X else if (otmp == uright) X bwrite (fd, "r", 1); X else X bwrite (fd, "n", 1); X otmp2 = otmp -> nobj; X ofree (otmp); X } X bwrite (fd, nul, sizeof (struct obj)); X bwrite (fd, &flags, sizeof (struct flag)); X bwrite (fd, &dlevel, sizeof dlevel); X bwrite (fd, &moves, sizeof moves); X bwrite (fd, &u, sizeof (struct you)); X bwrite (fd, genocided, sizeof genocided); X bwrite (fd, upxstairs, sizeof upxstairs); X bwrite (fd, upystairs, sizeof upystairs); X bwrite (fd, vaultflag, sizeof vaultflag); X X savenames (fd); X X/* SHOP part */ X bwrite (fd, &shd, sizeof (struct coord)); X bwrite (fd, &shk, sizeof (struct coord)); X bwrite (fd, &shlevel, sizeof shlevel); X bwrite (fd, &robbed, sizeof robbed); X X/* Various globals */ X bwrite (fd, &starved, sizeof starved); X bwrite (fd, &seehx, sizeof seehx); X bwrite (fd, &seelx, sizeof seelx); X bwrite (fd, &seehy, sizeof seehy); X bwrite (fd, &seely, sizeof seely); X bwrite (fd, &dx, sizeof dx); X bwrite (fd, &dy, sizeof dy); X bwrite (fd, &maxdlevel, sizeof maxdlevel); X X/* And the dog(s) if any */ X for (mtmp = mydogs; mtmp; mtmp = mtmp -> nmon) X bwrite (fd, mtmp, sizeof (struct monst) + X sizeof (struct edog)); X bwrite (fd, nul, sizeof (struct monst) + sizeof (struct edog)); X X callssave (fd); X X cls (); X printf ("Saving level "); X flush (); X for (tmp = 1;; tmp++) { X glo (tmp); X if ((ofd = open (lock, 0)) < 0) X break; X getlev (ofd); X close (ofd); X savelev (fd); X printf ("%2d - %s", tmp, X (tmp % 10) ? "" : "\n "); X flush (); X unlink (lock); X } X X close (fd); X (*index (lock, '.')) = '\0';/* Remove main lock */ X unlink (lock); X printf ("\n\nSee you around...\n"); X flush (); X hackmode (OFF); X exit (0); X} X Xdorecover (fd) Xregister fd; X{ X register nfd, tmp; X register OBJECT otmp, olast; X MONSTER mtmp; X int version; X X cls (); X printf ("Starting up a suspended game....\n"); X flush (); X mread (fd, &version, sizeof (version)); X if (version != VERSION) { X printf ("Sorry, you're savefile is out of date.\n"); X printf ("I will have to remove it.\n"); X printf ("Type to continue."); X close (fd); X unlink (SAVEFILE); X flush (); X while (getchar () != ' '); X return - 1; X } X X getlev (fd); X X invent = otmp = newobj (); X while (1) { X mread (fd, otmp, sizeof (struct obj)); X if (!otmp -> olet) { X if (otmp == invent) X invent = 0; X else X olast -> nobj = 0; X ofree (otmp); X break; X } X olast = otmp; X olast -> nobj = otmp = newobj (); X mread (fd, buf, 1); X switch (*buf) { X case 'w': X uwep = olast; X break; X case 'r': X uright = olast; X break; X case 'l': X uleft = olast; X break; X case 'a': X uarm = olast; X break; X case 'b': X uarm2 = olast; X case 'n': X break; X default: X panic (CORE, "Error reading save file"); X } X } X mread (fd, &flags, sizeof (struct flag)); X mread (fd, &dlevel, sizeof dlevel); X mread (fd, &moves, sizeof moves); X mread (fd, &u, sizeof (struct you)); X mread (fd, genocided, sizeof genocided); X mread (fd, upxstairs, sizeof upxstairs); X mread (fd, upystairs, sizeof upystairs); X mread (fd, vaultflag, sizeof vaultflag); X X restnames (fd); X X/* Restore shop part */ X mread (fd, &shd, sizeof (struct coord)); X mread (fd, &shk, sizeof (shk)); X mread (fd, &shlevel, sizeof shlevel); X mread (fd, &robbed, sizeof robbed); X X/* Restore various globals */ X mread (fd, &starved, sizeof starved); X mread (fd, &seehx, sizeof seehx); X mread (fd, &seelx, sizeof seelx); X mread (fd, &seehy, sizeof seehy); X mread (fd, &seely, sizeof seely); X mread (fd, &dx, sizeof dx); X mread (fd, &dy, sizeof dy); X mread (fd, &maxdlevel, sizeof maxdlevel); X X/* Let's try the dog again */ X while (1) { X mtmp = newmonst (sizeof (struct edog)); X mread (fd, mtmp, sizeof (struct monst) + X sizeof (struct edog)); X if (mtmp -> data == 0) X break; X else { X mtmp -> nmon = mydogs; X mydogs = mtmp; X } X } X free (mtmp); X X callsrestore (fd); X X printf ("Restoring level "); X flush (); X for (tmp = 1;; tmp++) { X if (getlev (fd)) X break; X glo (tmp); X if ((nfd = creat (lock, 0644)) < 0) X panic (CORE, "Cannot open temp file %s!\n", X lock); X savelev (nfd); X printf ("%2d - %s", tmp, X (tmp % 10) ? "" : "\n "); X flush (); X close (nfd); X } X X lseek (fd, (long) (sizeof (version)), 0); X getlev (fd); X close (fd); X losedogs (); X unlink (SAVEFILE); X docrt (); X return 1; X} / echo 'Part 04 of Hack complete.' exit -- Michiel Huisjes. {seismo|decvax|philabs}!mcvax!vu44!ark!huisjes Brought to you by Super Global Mega Corp .com