Hack sources for PDP11/44 and PDP11/45 (part 4 of 5)

2 views
Skip to first unread message

Michiel B. Huisjes

unread,
Feb 6, 1985, 1:52:11 AM2/6/85
to
#!/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 <signal.h>
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 <signal.h>
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 <signal.h>
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 <signal.h>
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 <signal.h>
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 <space> 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

Shelby Thornton

unread,
Feb 11, 1985, 8:58:45 PM2/11/85
to
It turns out that part 4 of 5 is incomplete (the tail got chopped off).
I hope that it was our machines fault, but either way, could someone
repost it?
Reply all
Reply to author
Forward
0 new messages