gam@amdahl.UUCP (gam) (01/06/85)
I have gotten hack to compile successfully under Sys V Rel 2 and
the three shars following are the files with relevant changes.
Hack has not been played extensively here so I don't know how well
I have debugged it.
Among other things, I have used the System V 'drand48(3)' routines
for random number generation. Also some "linting" has been done.
If you have any problems, post them to net.sources.bugs.
------------------- close cover before striking match ------------------
: This is a shar archive. Extract with sh, not csh.
echo x - hack.do.c
sed -e 's/^X//' > hack.do.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include <stdio.h>
X#include <signal.h>
X#include "hack.h"
X#include "def.func_tab.h"
X
Xextern char *getenv(),*parse(),*getlogin(),*lowc(),*unctrl();
Xextern int float_down();
Xextern char *nomovemsg, *catmore;
Xextern struct obj *splitobj(), *addinv();
Xextern boolean hmon();
X
X/* Routines to do various user commands */
X
Xint done1();
X
Xdodrink() {
X register struct obj *otmp,*objs;
X register struct monst *mtmp;
X register int unkn = 0, nothing = 0;
X
X otmp = getobj("!", "drink");
X if(!otmp) return(0);
X switch(otmp->otyp){
X case POT_RESTORE_STRENGTH:
X unkn++;
X pline("Wow! This makes you feel great!");
X if(u.ustr < u.ustrmax) {
X u.ustr = u.ustrmax;
X flags.botl = 1;
X }
X break;
X case POT_BOOZE:
X unkn++;
X pline("Ooph! This tastes like liquid fire!");
X Confusion += d(3,8);
X /* the whiskey makes us feel better */
X if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey");
X if(!rn2(4)) {
X pline("You pass out.");
X multi = -rnd(15);
X nomovemsg = "You awake with a headache.";
X }
X break;
X case POT_INVISIBILITY:
X if(Invis)
X nothing++;
X else {
X if(!Blind)
X pline("Gee! All of a sudden, you can't see yourself.");
X else
X pline("You feel rather airy."), unkn++;
X newsym(u.ux,u.uy);
X }
X Invis += rn1(15,31);
X break;
X case POT_FRUIT_JUICE:
X pline("This tastes like fruit juice.");
X lesshungry(20);
X break;
X case POT_HEALING:
X pline("You begin to feel better.");
X flags.botl = 1;
X u.uhp += rnd(10);
X if(u.uhp > u.uhpmax)
X u.uhp = ++u.uhpmax;
X if(Blind) Blind = 1; /* see on next move */
X if(Sick) Sick = 0;
X break;
X case POT_PARALYSIS:
X pline("Your feet are frozen to the floor!");
X nomul(-(rn1(10,25)));
X break;
X case POT_MONSTER_DETECTION:
X if(!fmon) {
X strange_feeling(otmp);
X return(1);
X } else {
X cls();
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(mtmp->mx > 0)
X at(mtmp->mx,mtmp->my,mtmp->data->mlet);
X prme();
X pline("You sense the presence of monsters.");
X more();
X docrt();
X }
X break;
X case POT_OBJECT_DETECTION:
X if(!fobj) {
X strange_feeling(otmp);
X return(1);
X } else {
X for(objs = fobj; objs; objs = objs->nobj)
X if(objs->ox != u.ux || objs->oy != u.uy)
X goto outobjmap;
X pline("You sense the presence of objects close nearby.");
X break;
X outobjmap:
X cls();
X for(objs = fobj; objs; objs = objs->nobj)
X at(objs->ox,objs->oy,objs->olet);
X prme();
X pline("You sense the presence of objects.");
X more();
X docrt();
X }
X break;
X case POT_SICKNESS:
X pline("Yech! This stuff tastes like poison.");
X if(Poison_resistance)
X pline("(But in fact it was biologically contaminated orange juice.)");
X losestr(rn1(4,3));
X losehp(rnd(10), "poison potion");
X break;
X case POT_CONFUSION:
X if(!Confusion)
X pline("Huh, What? Where am I?");
X else
X nothing++;
X Confusion += rn1(7,16);
X break;
X case POT_GAIN_STRENGTH:
X pline("Wow do you feel strong!");
X if(u.ustr == 118) break;
X if(u.ustr > 17) u.ustr += rnd(118-u.ustr);
X else u.ustr++;
X if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
X flags.botl = 1;
X break;
X case POT_SPEED:
X if(Wounded_legs) {
X if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
X pline("Your legs feel somewhat better.");
X else
X pline("Your leg feels somewhat better.");
X Wounded_legs = 0;
X unkn++;
X break;
X }
X if(!(Fast & ~INTRINSIC))
X pline("You are suddenly moving much faster.");
X else
X pline("Your legs get new energy."), unkn++;
X Fast += rn1(10,100);
X break;
X case POT_BLINDNESS:
X if(!Blind)
X pline("A cloud of darkness falls upon you.");
X else
X nothing++;
X Blind += rn1(100,250);
X seeoff(0);
X break;
X case POT_GAIN_LEVEL:
X pluslvl();
X break;
X case POT_EXTRA_HEALING:
X pline("You feel much better.");
X flags.botl = 1;
X u.uhp += d(2,20)+1;
X if(u.uhp > u.uhpmax)
X u.uhp = (u.uhpmax += 2);
X if(Blind) Blind = 1;
X if(Sick) Sick = 0;
X break;
X case POT_LEVITATION:
X if(!Levitation)
X float_up();
X else
X nothing++;
X Levitation += rnd(100);
X u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
X break;
X default:
X pline("What a funny potion! (%d)", otmp->otyp);
X impossible();
X return(0);
X }
X if(nothing) {
X unkn++;
X pline("You have a peculiar feeling for a moment, then it passes.");
X }
X if(otmp->dknown && !objects[otmp->otyp].oc_name_known) {
X if(!unkn) {
X objects[otmp->otyp].oc_name_known = 1;
X u.urexp += 10;
X } else if(!objects[otmp->otyp].oc_uname)
X docall(otmp);
X }
X useup(otmp);
X return(1);
X}
X
Xpluslvl()
X{
X register num;
X
X pline("You feel more experienced.");
X num = rnd(10);
X u.uhpmax += num;
X u.uhp += num;
X u.uexp = (10*pow(u.ulevel-1))+1;
X pline("Welcome to level %d.", ++u.ulevel);
X flags.botl = 1;
X}
X
Xstrange_feeling(obj)
Xregister struct obj *obj;
X{
X pline("You have a strange feeling for a moment, then it passes.");
X if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname)
X docall(obj);
X useup(obj);
X}
X
Xdodrop() {
X register struct obj *obj;
X
X obj = getobj("0$#", "drop");
X if(!obj) return(0);
X if(obj->olet == '$') {
X if(obj->quan == 0)
X pline("You didn't drop any gold pieces.");
X else {
X mkgold((int) obj->quan, u.ux, u.uy);
X pline("You dropped %u gold piece%s.",
X obj->quan, plur(obj->quan));
X if(Invis) newsym(u.ux, u.uy);
X }
X free((char *) obj);
X return(1);
X }
X return(drop(obj));
X}
X
Xdrop(obj) register struct obj *obj; {
X if(obj->owornmask & (W_ARMOR | W_RING)){
X pline("You cannot drop something you are wearing.");
X return(0);
X }
X if(obj == uwep) {
X if(uwep->cursed) {
X pline("Your weapon is welded to your hand!");
X return(0);
X }
X setuwep((struct obj *) 0);
X }
X pline("You dropped %s.", doname(obj));
X dropx(obj);
X return(1);
X}
X
Xdropx(obj) register struct obj *obj; {
X if(obj->otyp == CRYSKNIFE)
X obj->otyp = WORM_TOOTH;
X freeinv(obj);
X obj->ox = u.ux;
X obj->oy = u.uy;
X obj->nobj = fobj;
X fobj = obj;
X if(Invis) newsym(u.ux,u.uy);
X subfrombill(obj);
X stackobj(obj);
X}
X
X/* drop several things */
Xdoddrop() {
X return(ggetobj("drop", drop, 0));
X}
X
Xrhack(cmd)
Xregister char *cmd;
X{
X register struct func_tab *tlist = list;
X boolean firsttime = FALSE;
X register res;
X
X if(!cmd) {
X firsttime = TRUE;
X flags.nopick = 0;
X cmd = parse();
X }
X if(!*cmd || *cmd == 0377)
X return; /* probably we just had an interrupt */
X if(movecm(cmd)) {
X walk:
X if(multi) flags.mv = 1;
X domove();
X return;
X }
X if(movecm(lowc(cmd))) {
X flags.run = 1;
X rush:
X if(firsttime){
X if(!multi) multi = COLNO;
X u.last_str_turn = 0;
X }
X flags.mv = 1;
X#ifdef QUEST
X if(flags.run >= 4) finddir();
X if(firsttime){
X u.ux0 = u.ux + u.dx;
X u.uy0 = u.uy + u.dy;
X }
X#endif QUEST
X domove();
X return;
X }
X if((*cmd == 'f' && movecm(cmd+1)) ||
X movecm(unctrl(cmd))) {
X flags.run = 2;
X goto rush;
X }
X if(*cmd == 'F' && movecm(lowc(cmd+1))) {
X flags.run = 3;
X goto rush;
X }
X if(*cmd == 'm' && movecm(cmd+1)) {
X flags.run = 0;
X flags.nopick = 1;
X goto walk;
X }
X if(*cmd == 'M' && movecm(lowc(cmd+1))) {
X flags.run = 1;
X flags.nopick = 1;
X goto rush;
X }
X#ifdef QUEST
X if(*cmd == cmd[1] && (*cmd == 'f' || *cmd == 'F')) {
X flags.run = 4;
X if(*cmd == 'F') flags.run += 2;
X if(cmd[2] == '-') flags.run += 1;
X goto rush;
X }
X#endif QUEST
X while(tlist->f_char) {
X if(*cmd == tlist->f_char){
X res = (*(tlist->f_funct))(0);
X if(!res) {
X flags.move = 0;
X multi = 0;
X }
X return;
X }
X tlist++;
X }
X pline("Unknown command '%s'",cmd);
X multi = flags.move = 0;
X}
X
Xdoredraw()
X{
X docrt();
X return(0);
X}
X
Xdohelp()
X{
X if(child(1)){
X execl(catmore,"more","help",(char *)0);
X exit(1);
X }
X return(0);
X}
X
X#ifdef SHELL
Xdosh(){
Xregister char *str;
X if(child(0)) {
X (void) chdir(getenv("HOME"));
X if(str = getenv("SHELL")) execl(str,str,(char *) 0);
X if(strcmp("player", getlogin()))
X execl("/bin/sh","sh",(char *) 0);
X pline("sh: cannot execute.");
X exit(1);
X }
X return(0);
X}
X#endif SHELL
X
X#ifdef BSD
X#include <sys/wait.h>
X#endif BSD
X
Xchild(wt) {
Xregister int f = fork();
X if(f == 0){ /* child */
X settty((char *) 0);
X (void) setuid(getuid());
X return(1);
X }
X if(f == -1) { /* cannot fork */
X pline("Fork failed. Try again.");
X return(0);
X }
X /* fork succeeded; wait for child to exit */
X (void) signal(SIGINT,SIG_IGN);
X (void) signal(SIGQUIT,SIG_IGN);
X#ifdef BSD
X (void) wait((union wait *) 0);
X#else
X (void) wait((int *) 0);
X#endif BSD
X setctty();
X (void) signal(SIGINT, (void (*)()) done1);
X#ifdef WIZARD
X if(wizard) (void) signal(SIGQUIT,SIG_DFL);
X#endif WIZARD
X if(wt) getret();
X docrt();
X return(0);
X}
X
Xdodown()
X{
X if(u.ux != xdnstair || u.uy != ydnstair) {
X pline("You can't go down here.");
X return(0);
X }
X if(u.ustuck) {
X pline("You are being held, and cannot go down.");
X return(1);
X }
X if(Levitation) {
X pline("You're floating high above the stairs.");
X return(0);
X }
X
X goto_level(dlevel+1, TRUE);
X return(1);
X}
X
Xdoup()
X{
X if(u.ux != xupstair || u.uy != yupstair) {
X pline("You can't go up here.");
X return(0);
X }
X if(u.ustuck) {
X pline("You are being held, and cannot go up.");
X return(1);
X }
X if(inv_weight() + 5 > 0) {
X pline("Your load is too heavy to climb the stairs.");
X return(1);
X }
X
X goto_level(dlevel-1, TRUE);
X return(1);
X}
X
Xgoto_level(newlevel, at_stairs)
Xregister int newlevel;
Xregister boolean at_stairs;
X{
X register fd;
X register boolean up = (newlevel < dlevel);
X
X if(newlevel <= 0) done("escaped"); /* in fact < 0 is impossible */
X if(newlevel == dlevel) return; /* this cannot happen either */
X
X glo(dlevel);
X fd = creat(lock,FMASK);
X if(fd < 0) {
X /*
X * This is not quite impossible: e.g., we may have
X * exceeded our quota. If that is the case then we
X * cannot leave this level, and cannot save either.
X */
X pline("A mysterious force prevents you from going %d.",
X up ? "up" : "down");
X return;
X }
X
X if(Punished) unplacebc();
X keepdogs();
X seeoff(1);
X flags.nscrinh = 1;
X u.ux = FAR; /* hack */
X (void) inshop(); /* probably was a trapdoor */
X
X savelev(fd);
X (void) close(fd);
X
X dlevel = newlevel;
X if(maxdlevel < dlevel)
X maxdlevel = dlevel;
X glo(dlevel);
X if((fd = open(lock,0)) < 0)
X mklev();
X else {
X (void) getlev(fd);
X (void) close(fd);
X }
X
X if(at_stairs) {
X if(up) {
X u.ux = xdnstair;
X u.uy = ydnstair;
X if(!u.ux) { /* entering a maze from below? */
X u.ux = xupstair; /* this will confuse the player! */
X u.uy = yupstair;
X }
X if(Punished){
X pline("With great effort you climb the stairs");
X placebc(1);
X }
X } else {
X u.ux = xupstair;
X u.uy = yupstair;
X if(inv_weight() + 5 > 0 || Punished){
X pline("You fall down the stairs.");
X losehp(rnd(3), "fall");
X if(Punished) {
X if(uwep != uball && rn2(3)){
X pline("... and are hit by the iron ball");
X losehp(rnd(20), "iron ball");
X }
X placebc(1);
X }
X selftouch("Falling, you");
X }
X }
X } else { /* trapdoor or level_tele */
X do {
X u.ux = rnd(COLNO-1);
X u.uy = rn2(ROWNO);
X } while(levl[u.ux][u.uy].typ != ROOM ||
X m_at(u.ux,u.uy));
X if(Punished){
X if(uwep != uball && !up /* %% */ && rn2(5)){
X pline("The iron ball falls on your head.");
X losehp(rnd(25), "iron ball");
X }
X placebc(1);
X }
X selftouch("Falling, you");
X }
X (void) inshop();
X#ifdef TRACK
X initrack();
X#endif TRACK
X
X losedogs();
X flags.nscrinh = 0;
X setsee();
X docrt();
X pickup();
X read_engr_at(u.ux,u.uy);
X}
X
Xdonull() {
X return(1); /* Do nothing, but let other things happen */
X}
X
Xstruct monst *bhit(), *boomhit();
Xdothrow()
X{
X register struct obj *obj;
X register struct monst *mon;
X register tmp;
X
X obj = getobj("#)", "throw"); /* it is also possible to throw food */
X /* (or jewels, or iron balls ... ) */
X if(!obj || !getdir())
X return(0);
X if(obj->owornmask & (W_ARMOR | W_RING)){
X pline("You can't throw something you are wearing");
X return(0);
X }
X if(obj == uwep){
X if(obj->cursed){
X pline("Your weapon is welded to your hand");
X return(1);
X }
X if(obj->quan > 1)
X setuwep(splitobj(obj, 1));
X else
X setuwep((struct obj *) 0);
X }
X else if(obj->quan > 1)
X (void) splitobj(obj, 1);
X freeinv(obj);
X if(u.uswallow) {
X mon = u.ustuck;
X bhitpos.x = mon->mx;
X bhitpos.y = mon->my;
X } else if(obj->otyp == BOOMERANG) {
X mon = boomhit(u.dx,u.dy);
X /* boomhit delivers -1 if the thing was caught */
X if((int) mon == -1) {
X (void) addinv(obj);
X return(1);
X }
X } else
X mon = bhit(u.dx,u.dy,
X (!Punished || obj != uball) ? 8 :
X !u.ustuck ? 5 : 1,
X obj->olet);
X if(mon) {
X /* awake monster if sleeping */
X wakeup(mon);
X
X if(obj->olet == WEAPON_SYM) {
X tmp = -1+u.ulevel+mon->data->ac+abon();
X if(obj->otyp < ROCK) {
X if(!uwep ||
X uwep->otyp != obj->otyp+(BOW-ARROW))
X tmp -= 4;
X else {
X tmp += uwep->spe;
X }
X } else
X if(obj->otyp == BOOMERANG) tmp += 4;
X tmp += obj->spe;
X if(u.uswallow || tmp >= rnd(20)) {
X if(hmon(mon,obj,1) == TRUE){
X /* mon still alive */
X#ifndef NOWORM
X cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp);
X#endif NOWORM
X } else mon = 0;
X /* weapons thrown disappear sometimes */
X if(obj->otyp < BOOMERANG && rn2(3)) {
X /* check bill; free */
X obfree(obj, (struct obj *) 0);
X return(1);
X }
X } else miss(objects[obj->otyp].oc_name, mon);
X } else if(obj->otyp == HEAVY_IRON_BALL) {
X tmp = -1+u.ulevel+mon->data->ac+abon();
X if(!Punished || obj != uball) tmp += 2;
X if(u.utrap) tmp -= 2;
X if(u.uswallow || tmp >= rnd(20)) {
X if(hmon(mon,obj,1) == FALSE)
X mon = 0; /* he died */
X } else miss("iron ball", mon);
X } else {
X if(cansee(bhitpos.x,bhitpos.y))
X pline("You miss %s.",monnam(mon));
X else pline("You miss it.");
X if(obj->olet == FOOD_SYM && mon->data->mlet == 'd')
X if(tamedog(mon,obj)) return(1);
X if(obj->olet == GEM_SYM && mon->data->mlet == 'u'){
X if(obj->dknown && objects[obj->otyp].oc_name_known){
X if(objects[obj->otyp].g_val > 0){
X u.uluck += 5;
X goto valuable;
X } else {
X pline("%s is not interested in your junk.",
X Monnam(mon));
X }
X } else { /* value unknown to @ */
X u.uluck++;
X valuable:
X pline("%s graciously accepts your gift.",
X Monnam(mon));
X mpickobj(mon, obj);
X rloc(mon);
X return(1);
X }
X }
X }
X }
X obj->ox = bhitpos.x;
X obj->oy = bhitpos.y;
X obj->nobj = fobj;
X fobj = obj;
X /* prevent him from throwing articles to the exit and escaping */
X /* subfrombill(obj); */
X stackobj(obj);
X if(Punished && obj == uball &&
X (bhitpos.x != u.ux || bhitpos.y != u.uy)){
X freeobj(uchain);
X unpobj(uchain);
X if(u.utrap){
X if(u.utraptype == TT_PIT)
X pline("The ball pulls you out of the pit!");
X else {
X register int side =
X rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
X pline("The ball pulls you out of the bear trap.");
X pline("Your %s leg is severely damaged.",
X (side == LEFT_SIDE) ? "left" : "right");
X Wounded_legs |= side + rnd(1000);
X losehp(2, "thrown ball");
X }
X u.utrap = 0;
X }
X unsee();
X uchain->nobj = fobj;
X fobj = uchain;
X u.ux = uchain->ox = bhitpos.x - u.dx;
X u.uy = uchain->oy = bhitpos.y - u.dy;
X setsee();
X (void) inshop();
X }
X if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
X return(1);
X}
X
Xgetdir()
X{
Xchar buf[2];
X pline("What direction?");
X buf[0] = readchar();
X buf[1] = 0;
X return(movecm(buf));
X}
X
X/* split obj so that it gets size num */
X/* remainder is put in the object structure delivered by this call */
Xstruct obj *
Xsplitobj(obj, num) register struct obj *obj; register int num; {
Xregister struct obj *otmp;
X otmp = newobj(0);
X *otmp = *obj; /* copies whole structure */
X otmp->o_id = flags.ident++;
X otmp->onamelth = 0;
X obj->quan = num;
X obj->owt = weight(obj);
X otmp->quan -= num;
X otmp->owt = weight(otmp); /* -= obj->owt ? */
X obj->nobj = otmp;
X if(obj->unpaid) splitbill(obj,otmp);
X return(otmp);
X}
X
Xchar *
Xlowc(str)
Xregister char *str;
X{
X static char buf[2];
X
X if(*str >= 'A' && *str <= 'Z') *buf = *str+'a'-'A';
X else *buf = *str;
X buf[1] = 0;
X return(buf);
X}
X
Xchar *
Xunctrl(str)
Xregister char *str;
X{
X static char buf[2];
X if(*str >= ('A' & 037) && *str <= ('Z' & 037))
X *buf = *str + 0140;
X else *buf = *str;
X buf[1] = 0;
X return(buf);
X}
!Funky!Stuff!
echo x - hack.h
sed -e 's/^X//' > hack.h << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include "mklev.h"
X#include "hack.onames.h"
X
X#define ON 1
X#define OFF 0
X
X#define index strchr
X
Xextern struct obj *invent, *uwep, *uarm, *uarm2, *uarmh, *uarms, *uarmg,
X *uleft, *uright, *fcobj;
Xextern struct obj *uchain; /* defined iff PUNISHED */
Xextern struct obj *uball; /* defined if PUNISHED */
Xstruct obj *o_at(), *getobj(), *sobj_at();
X
Xstruct flag {
X unsigned ident; /* social security number for each monster */
X unsigned topl:2; /* a top line (message) has been printed */
X /* 0: top line empty; 2: no --More-- reqd. */
X unsigned cbreak:1; /* in cbreak mode, rogue format */
X unsigned oneline:1; /* give inventories 1 line at a time */
X unsigned move:1;
X unsigned mv:1;
X unsigned run:3; /* 0: h (etc), 1: H (etc), 2: fh (etc) */
X /* 3: FH, 4: ff+, 5: ff-, 6: FF+, 7: FF- */
X unsigned nopick:1; /* do not pickup objects */
X unsigned echo:1; /* 1 to echo characters */
X unsigned botl:1; /* partially redo status line */
X unsigned botlx:1; /* print an entirely new bottom line */
X unsigned nscrinh:1; /* inhibit nscr() in pline(); */
X};
Xextern struct flag flags;
X
Xstruct prop {
X#define TIMEOUT 007777 /* mask */
X#define LEFT_RING W_RINGL /* 010000L */
X#define RIGHT_RING W_RINGR /* 020000L */
X#define INTRINSIC 040000L
X#define LEFT_SIDE LEFT_RING
X#define RIGHT_SIDE RIGHT_RING
X#define BOTH_SIDES (LEFT_SIDE | RIGHT_SIDE)
X long p_flgs;
X int (*p_tofn)(); /* called after timeout */
X};
X
Xstruct you {
X xchar ux, uy;
X schar dx, dy; /* direction of fast move */
X#ifdef QUEST
X schar di; /* direction of FF */
X xchar ux0, uy0; /* initial position FF */
X#endif QUEST
X xchar udisx, udisy; /* last display pos */
X char usym; /* usually '@' */
X schar uluck;
X int last_str_turn:3; /* 0: none, 1: half turn, 2: full turn */
X /* +: turn right, -: turn left */
X unsigned udispl:1; /* @ on display */
X unsigned ulevel:5;
X#ifdef QUEST
X unsigned uhorizon:7;
X#endif QUEST
X unsigned utrap:3; /* trap timeout */
X unsigned utraptype:1; /* defined if utrap nonzero */
X#define TT_BEARTRAP 0
X#define TT_PIT 1
X unsigned uinshop:1;
X
X
X/* perhaps these #define's should also be generated by makedefs */
X#define TELEPAT LAST_RING /* not a ring */
X#define Telepat u.uprops[TELEPAT].p_flgs
X#define FAST (LAST_RING+1) /* not a ring */
X#define Fast u.uprops[FAST].p_flgs
X#define CONFUSION (LAST_RING+2) /* not a ring */
X#define Confusion u.uprops[CONFUSION].p_flgs
X#define INVIS (LAST_RING+3) /* not a ring */
X#define Invis u.uprops[INVIS].p_flgs
X#define GLIB (LAST_RING+4) /* not a ring */
X#define Glib u.uprops[GLIB].p_flgs
X#define PUNISHED (LAST_RING+5) /* not a ring */
X#define Punished u.uprops[PUNISHED].p_flgs
X#define SICK (LAST_RING+6) /* not a ring */
X#define Sick u.uprops[SICK].p_flgs
X#define BLIND (LAST_RING+7) /* not a ring */
X#define Blind u.uprops[BLIND].p_flgs
X#define WOUNDED_LEGS (LAST_RING+8) /* not a ring */
X#define Wounded_legs u.uprops[WOUNDED_LEGS].p_flgs
X#define PROP(x) (x-RIN_ADORNMENT) /* convert ring to index in uprops */
X unsigned umconf:1;
X char *usick_cause;
X struct prop uprops[LAST_RING+9];
X
X unsigned uswallow:1; /* set if swallowed by a monster */
X unsigned uswldtim:4; /* time you have been swallowed */
X unsigned uhs:3; /* hunger state - see hack.eat.c */
X schar ustr,ustrmax;
X schar udaminc;
X schar uac;
X int uhp,uhpmax;
X long int ugold,ugold0,uexp,urexp;
X int uhunger; /* refd only in eat.c and shk.c */
X int uinvault;
X struct monst *ustuck;
X int nr_killed[CMNUM+2]; /* used for experience bookkeeping */
X};
X
Xextern struct you u;
X
Xextern char *traps[];
Xextern char *plur(), *monnam(), *Monnam(), *amonnam(), *Amonnam(),
X *doname(), *aobjnam();
Xextern char readchar();
Xextern char vowels[];
X
Xextern xchar curx,cury; /* cursor location on screen */
X
Xextern coord bhitpos; /* place where thrown weapon falls to the ground */
X
Xextern xchar seehx,seelx,seehy,seely; /* where to see*/
Xextern char *save_cm,*killer;
X
Xextern xchar dlevel, maxdlevel; /* dungeon level */
X
Xextern long moves;
X
Xextern int multi;
X
X
Xextern char lock[];
X
X
X#define DIST(x1,y1,x2,y2) (((x1)-(x2))*((x1)-(x2)) + ((y1)-(y2))*((y1)-(y2)))
X
X#define PL_CSIZ 20 /* sizeof pl_character */
X#define MAX_CARR_CAP 120 /* so that boulders can be heavier */
X#define FAR (COLNO+2) /* position outside screen */
X
Xextern void exit(),
X perror(),
X qsort(),
X free();
!Funky!Stuff!
echo x - hack.lev.c
sed -e 's/^X//' > hack.lev.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include "hack.h"
X#include <signal.h>
X#include <stdio.h>
Xextern struct monst *restmonchn();
Xextern struct obj *restobjchn();
Xextern struct obj *billobjs;
Xextern char *itoa();
X
Xextern char nul[];
X#ifndef NOWORM
X#include "def.wseg.h"
X
Xextern struct wseg *wsegs[32], *wheads[32];
Xextern long wgrowtime[32];
X#endif NOWORM
X
X#include "savelev.h"
X
Xgetlev(fd)
X{
X register struct gen *gtmp;
X#ifndef NOWORM
X register struct wseg *wtmp;
X#endif NOWORM
X register tmp;
X long omoves;
X
X if(fd<0 || read(fd, (char *) levl, sizeof(levl)) != sizeof(levl))
X return(1);
X fgold = 0;
X ftrap = 0;
X mread(fd, (char *)&omoves, sizeof(omoves)); /* 0 from MKLEV */
X mread(fd, (char *)&xupstair, sizeof(xupstair));
X mread(fd, (char *)&yupstair, sizeof(yupstair));
X mread(fd, (char *)&xdnstair, sizeof(xdnstair));
X mread(fd, (char *)&ydnstair, sizeof(ydnstair));
X
X fmon = restmonchn(fd);
X if(omoves) {
X /* regenerate animals while on another level */
X long tmoves = (moves > omoves) ? moves-omoves : 0;
X register struct monst *mtmp, *mtmp2;
X extern char genocided[];
X
X for(mtmp = fmon; mtmp; mtmp = mtmp2) {
X mtmp2 = mtmp->nmon;
X if(index(genocided, mtmp->data->mlet)) {
X mondead(mtmp);
X continue;
X }
X if(index("ViT", mtmp->data->mlet))
X mtmp->mhp += tmoves;
X else
X mtmp->mhp += tmoves/20;
X if(mtmp->mhp > mtmp->orig_hp)
X mtmp->mhp = mtmp->orig_hp;
X }
X }
X
X setshk();
X setgd();
X gtmp = newgen();
X mread(fd, (char *)gtmp, sizeof(struct gen));
X while(gtmp->gx) {
X gtmp->ngen = fgold;
X fgold = gtmp;
X gtmp = newgen();
X mread(fd, (char *)gtmp, sizeof(struct gen));
X }
X mread(fd, (char *)gtmp, sizeof(struct gen));
X while(gtmp->gx) {
X gtmp->ngen = ftrap;
X ftrap = gtmp;
X gtmp = newgen();
X mread(fd, (char *)gtmp, sizeof(struct gen));
X }
X free((char *) gtmp);
X fobj = restobjchn(fd);
X billobjs = restobjchn(fd);
X rest_engravings(fd);
X#ifndef QUEST
X mread(fd, (char *)rooms, sizeof(rooms));
X mread(fd, (char *)doors, sizeof(doors));
X#endif QUEST
X if(!omoves) return(0); /* from MKLEV */
X#ifndef NOWORM
X mread(fd, (char *)wsegs, sizeof(wsegs));
X for(tmp = 1; tmp < 32; tmp++) if(wsegs[tmp]){
X wheads[tmp] = wsegs[tmp] = wtmp = newseg();
X while(1) {
X mread(fd, (char *)wtmp, sizeof(struct wseg));
X if(!wtmp->nseg) break;
X wheads[tmp]->nseg = wtmp = newseg();
X wheads[tmp] = wtmp;
X }
X }
X mread(fd, (char *)wgrowtime, sizeof(wgrowtime));
X#endif NOWORM
X return(0);
X}
X
Xmread(fd, buf, len)
Xregister fd;
Xregister char *buf;
Xregister unsigned len;
X{
Xregister int rlen;
X rlen = read(fd, buf, len);
X if(rlen != len){
X pline("Read %d instead of %d bytes\n", rlen, len);
X panic("Cannot read %d bytes from file #%d\n", len, fd);
X }
X}
X
X#ifdef BSD
X#include <sys/wait.h>
X# define NZ(stat) (stat.w_status != 0) /* non-zero status */
X# define SIG(stat) (stat.w_termsig) /* terminated by signal */
X# define EXIT(stat) (stat.w_retcode) /* non-zero exit code */
X# define CDUMP(stat) (stat.w_coredump) /* dumped core */
X#else
X# define NZ(stat) (stat != 0)
X# define SIG(stat) ( (stat & 0xff00) ? 0 : (stat & 0x0f) )
X# define EXIT(stat) ( (stat & 0x00ff) ? 0 : ((stat >> 8) & 0x0f) )
X# define CDUMP(stat) (stat & 0200)
X#endif BSD
X
X
Xmklev()
X{
X register int fd;
X int fork_val;
X char type[2];
X#ifdef BSD
X union wait status;
X#else
X int status;
X#endif BSD
X extern char fut_geno[];
X
X if(getbones()) return;
X if(dlevel < rn1(3, 26)) type[0] = 'a'; /* normal level */
X else type[0] = 'b'; /* maze */
X type[1] = 0;
X fork_val = fork();
X switch(fork_val){
X case 0:
X (void) signal(SIGINT, SIG_IGN);
X (void) signal(SIGQUIT, SIG_IGN);
X execl("./mklev", "mklev", lock, type, itoa(dlevel), fut_geno,
X#ifdef WIZARD
X wizard ? "w" :
X#endif WIZARD
X "", (char *) 0);
X exit(2);
X case -1:
X settty("Cannot fork!\n");
X exit(1);
X default:
X (void) fflush(stdout); /* You fell into a trap ... */
X (void) wait(&status);
X }
X if(NZ(status)) {
X if(CDUMP(status)) {
X settty("Mklev dumped core. Exiting...\n");
X#ifdef DEBUG
Xfprintf(stderr, "signal was %d\n", SIG(status));
X#endif
X exit(1);
X }
X if(SIG(status)) {
X settty("Mklev killed by a signal. Exiting...\n");
X exit(1);
X }
X if(EXIT(status)) {
X if(EXIT(status) == 2) {
X settty("Cannot execl mklev.\n");
X exit(1);
X }
X pline("Mklev failed. Let's try again.");
X mklev();
X return;
X }
X }
X if((fd = open(lock, 0)) < 0) {
X pline("Can't open %s!", lock);
X mklev();
X return;
X }
X (void) getlev(fd);
X (void) close(fd);
X}
!Funky!Stuff!
exit
--
Gordon A. Moffett ...!{ihnp4,hplabs,sun}!amdahl!gam
"Her name was McGill, and she called herself Lil, but everyone knew
her as Nancy...."gam@amdahl.UUCP (gam) (01/06/85)
: This is a shar archive. Extract with sh, not csh.
echo x - hack.main.c
sed -e 's/^X//' > hack.main.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include <stdio.h>
X#include <signal.h>
X#include <errno.h>
X#include "hack.h"
X
Xextern char *getlogin();
Xextern char plname[PL_NSIZ], pl_character[PL_CSIZ];
Xextern char *getenv();
X
Xint (*afternmv)();
X
Xint done1();
Xvoid hangup();
X
Xchar safelock[] = "safelock";
Xxchar locknum; /* max num of players */
Xchar *catmore = "/usr/bin/pg -n -s -p '--More (page %d)--'";
Xchar SAVEF[PL_NSIZ + 5] = "save/";
Xchar perm[] = "perm";
Xchar *hname; /* name of the game (argv[0] of call) */
Xchar obuf[BUFSIZ]; /* BUFSIZ is defined in stdio.h */
X
Xextern char *nomovemsg;
Xextern long wailmsg;
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X int fd;
X#ifdef NEWS
X int nonews = 0;
X#endif NEWS
X char *dir;
X
X hname = argv[0];
X
X /*
X * See if we must change directory to the playground.
X * (Perhaps hack runs suid and playground is inaccessible
X * for the player.)
X * The environment variable HACKDIR is overridden by a
X * -d command line option.
X */
X dir = getenv("HACKDIR");
X if(argc > 1 && !strncmp(argv[1], "-d", 2)) {
X argc--;
X argv++;
X dir = argv[0]+2;
X if(*dir == '=' || *dir == ':') dir++;
X if(!*dir && argc > 1) {
X argc--;
X argv++;
X dir = argv[0];
X }
X if(!*dir)
X error("Flag -d must be followed by a directory name.");
X }
X
X /*
X * Now we know the directory containing 'record' and
X * may do a prscore().
X */
X if(argc > 1 && !strncmp(argv[1], "-s", 2)) {
X if(dir) chdirx(dir);
X prscore(argc, argv);
X exit(0);
X }
X
X /*
X * It seems he really wants to play. Find the creation date of
X * this game so as to avoid restoring outdated savefiles.
X */
X gethdate(hname);
X
X /*
X * We cannot do chdir earlier, otherwise gethdate will fail.
X */
X if(dir) chdirx(dir);
X
X /*
X * Who am i? Perhaps we should use $USER instead?
X */
X (void) strncpy(plname, getlogin(), sizeof(plname)-1);
X
X /*
X * Process options.
X */
X while(argc > 1 && argv[1][0] == '-'){
X argv++;
X argc--;
X switch(argv[0][1]){
X#ifdef WIZARD
X case 'w':
X if(!strcmp(getlogin(), WIZARD))
X wizard = TRUE;
X else printf("Sorry.\n");
X break;
X#endif WIZARD
X#ifdef NEWS
X case 'n':
X nonews++;
X break;
X#endif NEWS
X case 'u':
X if(argv[0][2])
X (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
X else if(argc > 1) {
X argc--;
X argv++;
X (void) strncpy(plname, argv[0], sizeof(plname)-1);
X } else
X printf("Player name expected after -u\n");
X break;
X default:
X printf("Unknown option: %s\n", *argv);
X }
X }
X
X if(argc > 1)
X locknum = atoi(argv[1]);
X if(argc > 2)
X catmore = argv[2];
X#ifdef WIZARD
X if(wizard) (void) strcpy(plname, "wizard"); else
X#endif WIZARD
X if(!*plname || !strncmp(plname, "player", 4)) askname();
X plnamesuffix(); /* strip suffix from name */
X
X setbuf(stdout,obuf);
X (void) setrand(0L);
X startup();
X cls();
X (void) signal(SIGHUP, hangup);
X#ifdef WIZARD
X if(!wizard) {
X#endif WIZARD
X (void) signal(SIGQUIT,SIG_IGN);
X (void) signal(SIGINT,SIG_IGN);
X if(locknum)
X lockcheck();
X else
X (void) strcpy(lock,plname);
X#ifdef WIZARD
X } else {
X register char *sfoo;
X (void) strcpy(lock,plname);
X if(sfoo = getenv("MAGIC"))
X while(*sfoo) {
X switch(*sfoo++) {
X case 'n': (void) setrand((long)*sfoo++);
X break;
X }
X }
X if(sfoo = getenv("GENOCIDED")){
X if(*sfoo == '!'){
X extern struct permonst mons[CMNUM+2];
X extern char genocided[], fut_geno[];
X register struct permonst *pm = mons;
X register char *gp = genocided;
X
X while(pm < mons+CMNUM+2){
X if(!index(sfoo, pm->mlet))
X *gp++ = pm->mlet;
X pm++;
X }
X *gp = 0;
X } else
X (void) strcpy(genocided, sfoo);
X (void) strcpy(fut_geno, genocided);
X }
X }
X#endif WIZARD
X u.uhp = 1; /* prevent RIP on early quits */
X u.ux = FAR; /* prevent nscr() */
X (void) strcat(SAVEF,plname);
X if((fd = open(SAVEF,0)) >= 0 &&
X (uptodate(fd) || unlink(SAVEF) == 666)) {
X (void) signal(SIGINT, (void (*)()) done1);
X puts("Restoring old save file...");
X (void) fflush(stdout);
X dorecover(fd);
X flags.move = 0;
X } else {
X#ifdef NEWS
X if(!nonews)
X if((fd = open(NEWS,0)) >= 0)
X outnews(fd);
X#endif NEWS
X flags.ident = 1;
X init_objects();
X u_init();
X (void) signal(SIGINT, (void (*)()) done1);
X glo(1);
X mklev();
X u.ux = xupstair;
X u.uy = yupstair;
X (void) inshop();
X setsee();
X flags.botlx = 1;
X makedog();
X seemons();
X docrt();
X pickup();
X read_engr_at(u.ux,u.uy); /* superfluous ? */
X flags.move = 1;
X flags.cbreak = ON;
X flags.echo = OFF;
X }
X setftty();
X#ifdef TRACK
X initrack();
X#endif TRACK
X for(;;) {
X if(flags.move) {
X#ifdef TRACK
X settrack();
X#endif TRACK
X if(moves%2 == 0 ||
X (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) {
X extern struct monst *makemon();
X movemon();
X if(!rn2(70))
X (void) makemon((struct permonst *)0, 0, 0);
X }
X if(Glib) glibr();
X timeout();
X ++moves;
X if(u.uhp < 1) {
X pline("You die...");
X done("died");
X }
X if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50){
X wailmsg = moves;
X if(u.uhp == 1)
X pline("You hear the wailing of the Banshee...");
X else
X pline("You hear the howling of the CwnAnnwn...");
X }
X if(u.uhp < u.uhpmax) {
X if(u.ulevel > 9) {
X if(Regeneration || !(moves%3)) {
X flags.botl = 1;
X u.uhp += rnd((int) u.ulevel-9);
X if(u.uhp > u.uhpmax)
X u.uhp = u.uhpmax;
X }
X } else if(Regeneration ||
X (!(moves%(22-u.ulevel*2)))) {
X flags.botl = 1;
X u.uhp++;
X }
X }
X if(Teleportation && !rn2(85)) tele();
X if(Searching && multi >= 0) (void) dosearch();
X gethungry();
X invault();
X }
X if(multi < 0) {
X if(!++multi){
X pline(nomovemsg ? nomovemsg :
X "You can move again.");
X nomovemsg = 0;
X if(afternmv) (*afternmv)();
X afternmv = 0;
X }
X }
X flags.move = 1;
X find_ac();
X#ifndef QUEST
X if(!flags.mv || Blind)
X#endif QUEST
X {
X seeobjs();
X seemons();
X nscr();
X }
X if(flags.botl || flags.botlx) bot();
X if(multi > 0) {
X#ifdef QUEST
X if(flags.run >= 4) finddir();
X#endif QUEST
X lookaround();
X if(!multi) { /* lookaround may clear multi */
X flags.move = 0;
X continue;
X }
X if(flags.mv) {
X if(multi<COLNO && !--multi)
X flags.mv = flags.run = 0;
X domove();
X } else {
X --multi;
X rhack(save_cm);
X }
X } else if(multi == 0)
X rhack((char *) 0);
X }
X}
X
Xlockcheck()
X{
X extern int errno;
X register int i, fd;
X
X /* we ignore QUIT and INT at this point */
X if (link(perm,safelock) == -1)
X error("Cannot link safelock. (Try again or rm safelock.)");
X
X for(i = 0; i < locknum; i++) {
X lock[0]= 'a' + i;
X if((fd = open(lock,0)) == -1) {
X if(errno == ENOENT) goto gotlock; /* no such file */
X (void) unlink(safelock);
X error("Cannot open %s", lock);
X }
X (void) close(fd);
X }
X (void) unlink(safelock);
X error("Too many hacks running now.");
Xgotlock:
X fd = creat(lock,FMASK);
X if(fd == -1) {
X error("cannot creat lock file.");
X } else {
X int pid;
X
X pid = getpid();
X if(write(fd, (char *) &pid, 2) != 2){
X error("cannot write lock");
X }
X if(close(fd) == -1){
X error("cannot close lock");
X }
X }
X if(unlink(safelock) == -1){
X error("Cannot unlink safelock");
X }
X}
X
X/*VARARGS1*/
Xerror(s,a1,a2,a3,a4) char *s,*a1,*a2,*a3,*a4; {
X printf("Error: ");
X printf(s,a1,a2,a3,a4);
X (void) putchar('\n');
X exit(1);
X}
X
Xglo(foo)
Xregister foo;
X{
X /* construct the string xlock.n */
X register char *tf;
X
X tf = lock;
X while(*tf && *tf!='.') tf++;
X (void) sprintf(tf, ".%d", foo);
X}
X
X/*
X * plname is filled either by an option (-u Player or -uPlayer) or
X * explicitly (-w implies wizard) or by askname.
X * It may still contain a suffix denoting pl_character.
X */
Xaskname(){
Xregister int c,ct;
X printf("\nWho are you? ");
X ct = 0;
X while((c = getchar()) != '\n'){
X if(c == EOF) error("End of input\n");
X if(c != '-')
X if(c < 'A' || (c > 'Z' && c < 'a') || c > 'z') c = '_';
X if(ct < sizeof(plname)-1) plname[ct++] = c;
X }
X plname[ct] = 0;
X if(ct == 0) askname();
X#ifdef QUEST
X else printf("Hello %s, welcome to quest!\n", plname);
X#else
X else printf("Hello %s, welcome to hack!\n", plname);
X#endif QUEST
X}
X
Ximpossible(){
X pline("Program in disorder - perhaps you'd better Quit");
X}
X
X#ifdef NEWS
Xint stopnews;
X
Xvoid
Xstopnws(){
X (void) signal(SIGINT, SIG_IGN);
X stopnews++;
X}
X
Xoutnews(fd) int fd; {
Xvoid (*prevsig)();
Xchar ch;
X prevsig = signal(SIGINT, stopnws);
X while(!stopnews && read(fd,&ch,1) == 1)
X (void) putchar(ch);
X (void) putchar('\n');
X (void) fflush(stdout);
X (void) close(fd);
X (void) signal(SIGINT, prevsig);
X /* See whether we will ask TSKCFW: he might have told us already */
X if(!stopnews && pl_character[0])
X getret();
X}
X#endif NEWS
X
Xchdirx(dir) char *dir; {
X if(chdir(dir) < 0) {
X perror(dir);
X error("Cannot chdir to %s.", dir);
X }
X}
!Funky!Stuff!
echo x - hack.pri.c
sed -e 's/^X//' > hack.pri.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include "hack.h"
X#include <stdio.h>
Xxchar scrlx, scrhx, scrly, scrhy; /* corners of new area on screen */
X
Xextern char *hu_stat[]; /* in eat.c */
X
Xswallowed()
X{
X char *ulook = "|@|";
X ulook[1] = u.usym;
X
X cls();
X curs(u.ux-1, u.uy+1);
X fputs("/-\\", stdout);
X curx = u.ux+2;
X curs(u.ux-1, u.uy+2);
X fputs(ulook, stdout);
X curx = u.ux+2;
X curs(u.ux-1, u.uy+3);
X fputs("\\-/", stdout);
X curx = u.ux+2;
X u.udispl = 1;
X u.udisx = u.ux;
X u.udisy = u.uy;
X}
X
X
X/*VARARGS1*/
Xboolean panicking;
X
Xpanic(str,a1,a2,a3,a4,a5,a6)
Xchar *str;
X{
X if(panicking++) exit(1); /* avoid loops */
X home();
X puts(" Suddenly, the dungeon collapses.");
X fputs(" ERROR: ",stdout);
X printf(str,a1,a2,a3,a4,a5,a6);
X if(fork())
X done("panic");
X else
X abort(); /* generate core dump */
X}
X
Xatl(x,y,ch)
Xregister x,y;
X{
X register struct rm *crm = &levl[x][y];
X
X if(x<0 || x>COLNO-1 || y<0 || y>ROWNO-1)
X panic("at(%d,%d,%c_%o_)",x,y,ch,ch);
X if(crm->seen && crm->scrsym == ch) return;
X crm->scrsym = ch;
X crm->new = 1;
X on_scr(x,y);
X}
X
Xon_scr(x,y)
Xregister x,y;
X{
X if(x<scrlx) scrlx = x;
X if(x>scrhx) scrhx = x;
X if(y<scrly) scrly = y;
X if(y>scrhy) scrhy = y;
X}
X
X/* call: (x,y) - display
X (-1,0) - close (leave last symbol)
X (-1,-1)- close (undo last symbol)
X (-1,let)-open: initialize symbol
X (-2,let)-change let
X*/
X
Xtmp_at(x,y) schar x,y; {
Xstatic schar prevx, prevy;
Xstatic char let;
X if((int)x == -2){ /* change let call */
X let = y;
X return;
X }
X if((int)x == -1 && (int)y >= 0){ /* open or close call */
X let = y;
X prevx = -1;
X return;
X }
X if(prevx >= 0 && cansee(prevx,prevy)) {
X delay();
X prl(prevx, prevy); /* in case there was a monster */
X at(prevx, prevy, levl[prevx][prevy].scrsym);
X }
X if(x >= 0){ /* normal call */
X if(cansee(x,y)) at(x,y,let);
X prevx = x;
X prevy = y;
X } else { /* close call */
X let = 0;
X prevx = -1;
X }
X}
X
X/* like the previous, but the symbols are first erased on completion */
XTmp_at(x,y) schar x,y; {
Xstatic char let;
Xstatic xchar cnt;
Xstatic coord tc[COLNO]; /* but watch reflecting beams! */
Xregister xx,yy;
X if((int)x == -1) {
X if(y > 0) { /* open call */
X let = y;
X cnt = 0;
X return;
X }
X /* close call (do not distinguish y==0 and y==-1) */
X while(cnt--) {
X xx = tc[cnt].x;
X yy = tc[cnt].y;
X prl(xx, yy);
X at(xx, yy, levl[xx][yy].scrsym);
X }
X cnt = let = 0; /* superfluous */
X return;
X }
X if((int)x == -2) { /* change let call */
X let = y;
X return;
X }
X /* normal call */
X if(cansee(x,y)) {
X if(cnt) delay();
X at(x,y,let);
X tc[cnt].x = x;
X tc[cnt].y = y;
X if(++cnt >= COLNO) panic("Tmp_at overflow?");
X levl[x][y].new = 0; /* prevent pline-nscr erasing --- */
X }
X}
X
Xat(x,y,ch)
Xregister xchar x,y;
Xchar ch;
X{
X#ifndef lint
X /* if xchar is unsigned, lint will complain about if(x < 0) */
X if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1)
X panic("At gets 0%o at %d %d(%d %d)",ch,x,y,u.ux,u.uy);
X#endif lint
X if(!ch) {
X home();
X printf("At gets null at %2d %2d.",x,y);
X curx = ROWNO+1;
X return;
X }
X y += 2;
X curs(x,y);
X (void) putchar(ch);
X curx++;
X}
X
Xprme(){
X if(!Invis) at(u.ux,u.uy,u.usym);
X}
X
Xdocrt()
X{
X register x,y;
X register struct rm *room;
X register struct monst *mtmp;
X
X if(u.uswallow) {
X swallowed();
X return;
X }
X cls();
X if(!Invis){
X levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym;
X levl[u.udisx][u.udisy].seen = 1;
X u.udispl = 1;
X } else u.udispl = 0;
X
X /* %% - is this really necessary? */
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(mtmp->mdispl && !(room = &levl[mtmp->mx][mtmp->my])->new &&
X !room->seen)
X mtmp->mdispl = 0;
X
X for(y = 0; y < ROWNO; y++)
X for(x = 0; x < COLNO; x++)
X if((room = &levl[x][y])->new) {
X room->new = 0;
X at(x,y,room->scrsym);
X } else if(room->seen) at(x,y,room->scrsym);
X scrlx = COLNO;
X scrly = ROWNO;
X scrhx = scrhy = 0;
X flags.botlx = 1;
X bot();
X}
X
Xdocorner(xmin,ymax) register xmin,ymax; {
X register x,y;
X register struct rm *room;
X if(u.uswallow) { /* Can be done more efficiently */
X swallowed();
X return;
X }
X for(y = 0; y < ymax; y++) {
X curs(xmin,y+2);
X cl_end();
X for(x = xmin; x < COLNO; x++) {
X if((room = &levl[x][y])->new) {
X room->new = 0;
X at(x,y,room->scrsym);
X } else if(room->seen) at(x,y,room->scrsym);
X }
X }
X}
X
Xpru()
X{
X if(u.udispl && (Invis || u.udisx != u.ux || u.udisy != u.uy))
X /* if(! levl[u.udisx][u.udisy].new) */
X if(!vism_at(u.udisx, u.udisy))
X newsym(u.udisx, u.udisy);
X if(Invis) {
X u.udispl = 0;
X prl(u.ux,u.uy);
X } else
X if(!u.udispl || u.udisx != u.ux || u.udisy != u.uy) {
X atl(u.ux, u.uy, u.usym);
X u.udispl = 1;
X u.udisx = u.ux;
X u.udisy = u.uy;
X }
X levl[u.ux][u.uy].seen = 1;
X}
X
X#ifndef NOWORM
X#include "def.wseg.h"
Xextern struct wseg *m_atseg;
X#endif NOWORM
X
X/* print a position that is visible for @ */
Xprl(x,y)
X{
X register struct rm *room;
X register struct monst *mtmp;
X register struct obj *otmp;
X
X if(x == u.ux && y == u.uy && !Invis) {
X pru();
X return;
X }
X room = &levl[x][y];
X if((!room->typ) || (room->typ<DOOR && levl[u.ux][u.uy].typ == CORR))
X return;
X if((mtmp = m_at(x,y)) && !mtmp->mhide &&
X (!mtmp->minvis || See_invisible)) {
X#ifndef NOWORM
X if(m_atseg)
X pwseg(m_atseg);
X else
X#endif NOWORM
X pmon(mtmp);
X }
X else if(otmp = o_at(x,y))
X atl(x,y,otmp->olet);
X else if(mtmp && (!mtmp->minvis || See_invisible)) {
X /* must be a hiding monster, but not hiding right now */
X /* assume for the moment that long worms do not hide */
X pmon(mtmp);
X }
X else if(g_at(x,y,fgold)) atl(x,y,'$');
X else if(!room->seen || room->scrsym == ' ') {
X room->new = room->seen = 1;
X newsym(x,y);
X on_scr(x,y);
X }
X room->seen = 1;
X}
X
Xchar
Xnews0(x,y)
Xregister xchar x,y;
X{
X register struct obj *otmp;
X register struct gen *gtmp;
X struct rm *room;
X register char tmp;
X
X room = &levl[x][y];
X if(!room->seen) tmp = ' ';
X else if(!Blind && (otmp = o_at(x,y))) tmp = otmp->olet;
X else if(!Blind && g_at(x,y,fgold)) tmp = '$';
X else if(x == xupstair && y == yupstair) tmp = '<';
X else if(x == xdnstair && y == ydnstair) tmp = '>';
X else if((gtmp = g_at(x,y,ftrap)) && (gtmp->gflag & SEEN)) tmp = '^';
X else switch(room->typ) {
X case SCORR:
X case SDOOR:
X tmp = room->scrsym; /* %% wrong after killing mimic ! */
X break;
X case HWALL:
X tmp = '-';
X break;
X case VWALL:
X tmp = '|';
X break;
X case LDOOR:
X case DOOR:
X tmp = '+';
X break;
X case CORR:
X tmp = CORR_SYM;
X break;
X case ROOM:
X if(room->lit || cansee(x,y) || Blind) tmp = '.';
X else tmp = ' ';
X break;
X default: tmp = ERRCHAR;
X }
X return(tmp);
X}
X
Xnewsym(x,y)
Xregister x,y;
X{
X atl(x,y,news0(x,y));
X}
X
X/* used with wand of digging: fill scrsym and force display */
Xmnewsym(x,y) register x,y; {
Xregister struct monst *mtmp = m_at(x,y);
X if(!mtmp || (mtmp->minvis && !See_invisible) ||
X (mtmp->mhide && o_at(x,y))){
X levl[x][y].scrsym = news0(x,y);
X levl[x][y].seen = 0;
X }
X}
X
Xnosee(x,y)
Xregister x,y;
X{
X register struct rm *room;
X
X room = &levl[x][y];
X if(room->scrsym == '.' && !room->lit && !Blind) {
X room->scrsym = ' ';
X room->new = 1;
X on_scr(x,y);
X }
X}
X
X#ifndef QUEST
Xprl1(x,y)
Xregister x,y;
X{
X if(u.dx) {
X if(u.dy) {
X prl(x-(2*u.dx),y);
X prl(x-u.dx,y);
X prl(x,y);
X prl(x,y-u.dy);
X prl(x,y-(2*u.dy));
X } else {
X prl(x,y-1);
X prl(x,y);
X prl(x,y+1);
X }
X } else {
X prl(x-1,y);
X prl(x,y);
X prl(x+1,y);
X }
X}
X
Xnose1(x,y)
Xregister x,y;
X{
X if(u.dx) {
X if(u.dy) {
X nosee(x,u.uy);
X nosee(x,u.uy-u.dy);
X nosee(x,y);
X nosee(u.ux-u.dx,y);
X nosee(u.ux,y);
X } else {
X nosee(x,y-1);
X nosee(x,y);
X nosee(x,y+1);
X }
X } else {
X nosee(x-1,y);
X nosee(x,y);
X nosee(x+1,y);
X }
X}
X#endif QUEST
X
Xvism_at(x,y) register x,y; {
Xregister struct monst *mtmp;
Xregister int csi = See_invisible;
X return((x == u.ux && y == u.uy && (!Invis || csi)) ? 1 :
X ((mtmp = m_at(x,y)) && (!mtmp->minvis || csi) &&
X (!mtmp->mhide || !o_at(mtmp->mx,mtmp->my)))
X ? cansee(x,y) : 0);
X}
X
X#ifdef NEWSCR
Xpobj(obj) register struct obj *obj; {
Xregister int show = (!obj->oinvis || See_invisible) &&
X cansee(obj->ox,obj->oy);
X if(obj->odispl){
X if(obj->odx != obj->ox || obj->ody != obj->oy || !show)
X if(!vism_at(obj->odx,obj->ody)){
X newsym(obj->odx, obj->ody);
X obj->odispl = 0;
X }
X }
X if(show && !vism_at(obj->ox,obj->oy)){
X atl(obj->ox,obj->oy,obj->olet);
X obj->odispl = 1;
X obj->odx = obj->ox;
X obj->ody = obj->oy;
X }
X}
X#endif NEWSCR
X
Xunpobj(obj) register struct obj *obj; {
X/* if(obj->odispl){
X if(!vism_at(obj->odx, obj->ody))
X newsym(obj->odx, obj->ody);
X obj->odispl = 0;
X }
X*/
X if(!vism_at(obj->ox,obj->oy))
X newsym(obj->ox,obj->oy);
X}
X
Xseeobjs(){
Xregister struct obj *obj, *obj2;
X for(obj = fobj; obj; obj = obj2) {
X obj2 = obj->nobj;
X if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
X && obj->age + 250 < moves)
X delobj(obj);
X }
X for(obj = invent; obj; obj = obj2) {
X obj2 = obj->nobj;
X if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
X && obj->age + 250 < moves)
X useup(obj);
X }
X}
X
Xseemons(){
Xregister struct monst *mtmp;
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
X pmon(mtmp);
X#ifndef NOWORM
X if(mtmp->wormno) wormsee(mtmp->wormno);
X#endif NOWORM
X }
X}
X
Xpmon(mon) register struct monst *mon; {
Xregister int show =
X ((!mon->minvis || See_invisible) &&
X (!mon->mhide || !o_at(mon->mx,mon->my)) &&
X cansee(mon->mx,mon->my))
X || (Blind && Telepat);
X if(mon->mdispl){
X if(mon->mdx != mon->mx || mon->mdy != mon->my || !show)
X unpmon(mon);
X }
X if(show && !mon->mdispl){
X atl(mon->mx,mon->my,
X mon->mimic ? mon->mimic : mon->data->mlet);
X mon->mdispl = 1;
X mon->mdx = mon->mx;
X mon->mdy = mon->my;
X }
X}
X
Xunpmon(mon) register struct monst *mon; {
X if(mon->mdispl){
X newsym(mon->mdx, mon->mdy);
X mon->mdispl = 0;
X }
X}
X
Xnscr()
X{
X register x,y;
X register struct rm *room;
X
X if(u.uswallow || u.ux == FAR || flags.nscrinh) return;
X pru();
X for(y = scrly; y <= scrhy; y++)
X for(x = scrlx; x <= scrhx; x++)
X if((room = &levl[x][y])->new) {
X room->new = 0;
X at(x,y,room->scrsym);
X }
X scrhx = scrhy = 0;
X scrlx = COLNO;
X scrly = ROWNO;
X}
X
Xchar oldbot[100], newbot[100]; /* 100 >= COLNO */
Xbot()
X{
Xregister char *ob = oldbot, *nb = newbot;
Xregister int i;
X if(flags.botlx) *ob = 0;
X flags.botl = flags.botlx = 0;
X (void) sprintf(newbot, "Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d Str ",
X dlevel, u.ugold, u.uhp, u.uhpmax, u.uac);
X if(u.ustr>18) {
X if(u.ustr>117) (void) strcat(newbot,"18/**");
X else (void) sprintf(newbot + strlen(newbot), "18/%02d",u.ustr-18);
X } else (void) sprintf(newbot + strlen(newbot), "%-2d ",u.ustr);
X (void) sprintf(newbot + strlen(newbot), " Exp %2d/%-5lu ", u.ulevel,u.uexp);
X (void) strcat(newbot, hu_stat[u.uhs]);
X for(i = 1; i<COLNO; i++) {
X if(*ob != *nb){
X curs(i,ROWNO+2);
X (void) putchar(*nb ? *nb : ' ');
X curx++;
X }
X if(*ob) ob++;
X if(*nb) nb++;
X }
X (void) strcpy(oldbot, newbot);
X}
X
X#ifdef WAN_PROBING
Xmstatusline(mtmp) register struct monst *mtmp; {
X pline("Status of %s: ", monnam(mtmp));
X pline("Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d Dam %d",
X mtmp->data->mlevel, mtmp->mgold, mtmp->mhp, mtmp->orig_hp,
X mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1));
X}
X#endif WAN_PROBING
X
Xcls(){
X if(flags.topl == 1)
X more();
X flags.topl = 0;
X
X clearscreen();
X
X flags.botlx = 1;
X}
!Funky!Stuff!
echo x - hack.sh
sed -e 's/^X//' > hack.sh << '!Funky!Stuff!'
X
XHACK=/usr/games/HACK
XHACKDIR=/usr/games/lib/hack/tmp
XMAXNROFPLAYERS=6
XMORE="/usr/bin/pg -f -n -s -p '--More (page %d)--'"
X
Xcd $HACKDIR
Xcase $1 in
X -s*)
X exec $HACK $@
X ;;
X *)
X# /bin/cat news
X exec $HACK $HACKDIR $MAXNROFPLAYERS $MORE
X ;;
Xesac
!Funky!Stuff!
echo x - hack.stat.c
sed -e 's/^X//' > hack.stat.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include "config.h"
X
Xextern char *index();
Xstruct stat buf,hbuf;
X
Xgethdate(name) char *name; {
Xregister char *np;
X if(stat(name, &hbuf))
X error("Cannot get status of %s.",
X (np = index(name, '/')) ? np+1 : name);
X}
X
Xuptodate(fd) {
X if(fstat(fd, &buf)) {
X pline("Cannot get status?");
X return(0);
X }
X if(buf.st_ctime < hbuf.st_ctime) {
X pline("Saved level is out of date.");
X return(0);
X }
X return(1);
X}
!Funky!Stuff!
exit
--
Gordon A. Moffett ...!{ihnp4,hplabs,sun}!amdahl!gam
"Her name was McGill, and she called herself Lil, but everyone knew
her as Nancy...."gam@amdahl.UUCP (gam) (01/06/85)
: This is a shar archive. Extract with sh, not csh.
echo x - hack.termcap.c
sed -e 's/^X//' > hack.termcap.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#define SINGLE
X#include <curses.h>
X#include <term.h>
X#include "config.h" /* for ROWNO and COLNO */
X
Xextern char *tparm();
Xextern char *getenv();
X
Xshort ospeed; /* terminal baudrate; used by tputs */
Xchar *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE;
Xchar PC = '\0';
X
Xstartup()
X{
X register char *tmp;
X char *pc;
X int tliberr;
X
X
X if(!(tmp = getenv("TERM")))
X error("Can't get TERM.");
X def_shell_mode();
X setupterm(tmp, 0, &tliberr);
X gettty(); /* sets ospeed */
X
X if(tliberr < 1)
X error("Unknown terminal type: %s.", tmp);
X if(pc = pad_char)
X PC = *pc;
X if(!(BC = cursor_left)){
X BC = "\b";
X }
X HO = cursor_home;
X if(columns < COLNO || lines < ROWNO+2)
X error("Screen must be at least %d by %d!",
X ROWNO+2, COLNO);
X if(!(CL = clear_screen) || !(CE = clr_eol) ||
X !(ND = cursor_right) ||
X !(UP = cursor_up) || over_strike)
X error("Hack needs clear_screen, clr_eol, cursor_up, cursor_right,\nand no over_strike.");
X if(!(CM = cursor_address))
X error("Use of hack on terminals without cursor_motion is unsupported...\n");
X XD = cursor_down;
X SO = enter_standout_mode;
X SE = exit_standout_mode;
X if(!SO || !SE) SO = SE = 0;
X}
X
X/* Cursor movements */
Xextern xchar curx, cury;
X
Xcurs(x,y)
Xregister int x,y; /* not xchar: perhaps xchar is unsigned and
X curx-x would be unsigned as well */
X{
X
X if (y == cury && x == curx) return;
X if(abs(cury-y)<= 3 && abs(curx-x)<= 3) {
X nocmov(x,y);
X } else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
X (void) putchar('\r');
X curx = 1;
X nocmov(x,y);
X } else if(!CM) {
X nocmov(x,y);
X } else
X cmov(x,y);
X}
X
Xcmov(x,y)
Xregister x,y;
X{
X if(!CM) error("Tries to cmov from %d %d to %d %d\n",curx,cury,x,y);
X xputs(tparm(CM,y-1,x-1));
X cury = y;
X curx = x;
X}
X
X
Xnocmov(x,y)
X{
X if (curx < x) { /* Go to the right. */
X while (curx < x) {
X xputs(ND);
X curx++;
X }
X } else if (curx > x) {
X while (curx > x) { /* Go to the left. */
X xputs(BC);
X curx--;
X }
X }
X if (cury > y) {
X if(UP) {
X while (cury > y) { /* Go up. */
X xputs(UP);
X cury--;
X }
X } else cmov(x,y);
X } else if (cury < y) {
X if(XD) {
X while(cury<y) {
X xputs(XD);
X cury++;
X }
X } else cmov(x,y);
X }
X}
X
Xxputs(s) char *s; {
X putp(s);
X}
X
Xcl_end() {
X xputs(CE);
X}
X
Xclearscreen() {
X xputs(CL);
X curx = cury = 1;
X}
X
Xhome()
X{
X if(HO) xputs(HO);
X else xputs(tparm(CM,0,0));
X curx = cury = 1;
X}
X
Xstandoutbeg()
X{
X if(SO) xputs(SO);
X}
X
Xstandoutend()
X{
X if(SE) xputs(SE);
X}
X
Xbacksp()
X{
X xputs(BC);
X curx--;
X}
X
Xbeep()
X{
X xputs(bell);
X}
X
Xdelay() {
X /* delay 40 ms - could also use a 'nap'-system call */
X delay_output(40);
X}
!Funky!Stuff!
echo x - hack.tty.c
sed -e 's/^X//' > hack.tty.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#define SINGLE
X#include <curses.h>
X#include <term.h>
X#undef move
X#include "hack.h"
X
Xextern short ospeed;
X
X
Xgettty(){
X def_prog_mode();
X ospeed = cur_term->Nttyb.c_cflag & CBAUD;
X/*
X if(ospeed <= B300) flags.oneline = 1;
X*/
X}
X
X/* reset terminal to original state */
Xsettty(s) char *s; {
X clearscreen();
X if(s) printf(s);
X (void) fflush(stdout);
X reset_shell_mode();
X}
X
Xsetctty()
X{
X reset_prog_mode();
X}
X
Xsetftty(){
Xregister int ef = (flags.echo == ON) ? ECHO : 0;
Xregister int cf = (flags.cbreak == ON) ? 0 : ICANON;
Xregister int change = 0;
X if((cur_term->Nttyb.c_lflag & ECHO) != ef){
X cur_term->Nttyb.c_lflag &= ~ECHO;
X cur_term->Nttyb.c_lflag |= ef;
X change++;
X }
X if((cur_term->Nttyb.c_lflag & ICANON) != cf){
X cur_term->Nttyb.c_lflag &= ~ICANON;
X cur_term->Nttyb.c_lflag |= cf;
X if (cur_term->Nttyb.c_lflag & ICANON) {
X cur_term->Nttyb.c_cc[VEOF] = cur_term->Ottyb.c_cc[VEOF];
X cur_term->Nttyb.c_cc[VEOL] = cur_term->Ottyb.c_cc[VEOL];
X } else {
X cur_term->Nttyb.c_cc[VTIME] = 1;
X cur_term->Nttyb.c_cc[VMIN] = 1;
X }
X change++;
X }
X if(change){
X setctty();
X }
X}
X
Xecho(n)
Xregister n;
X{
X
X if(n == ON)
X doecho();
X else
X donoecho();
X}
X
Xdoecho()
X{
X cur_term->Nttyb.c_lflag |= ECHO;
X setctty();
X}
X
Xdonoecho()
X{
X cur_term->Nttyb.c_lflag &= ~ECHO;
X setctty();
X}
X
Xgetlin(bufp)
Xregister char *bufp;
X{
X register char *obufp = bufp;
X register int c;
X
X flags.topl = 2; /* nonempty, no --More-- required */
X for(;;) {
X (void) fflush(stdout);
X if((c = getchar()) == EOF) {
X *bufp = 0;
X return;
X }
X if(c == '\b') {
X if(bufp != obufp) {
X bufp--;
X putstr("\b \b"); /* putsym converts \b */
X } else beep();
X } else if(c == '\n') {
X *bufp = 0;
X return;
X } else {
X *bufp = c;
X bufp[1] = 0;
X putstr(bufp);
X if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO)
X bufp++;
X }
X }
X}
X
Xgetret() {
X xgetret(TRUE);
X}
X
Xcgetret() {
X xgetret(FALSE);
X}
X
Xxgetret(spaceflag)
Xboolean spaceflag; /* TRUE if space (return) required */
X{
X printf("\nHit %s to continue: ",
X flags.cbreak ? "space" : "return");
X xwaitforspace(spaceflag);
X}
X
Xchar morc; /* tell the outside world what char he used */
X
Xxwaitforspace(spaceflag)
Xboolean spaceflag;
X{
Xregister int c;
X
X (void) fflush(stdout);
X morc = 0;
X
X while((c = getchar()) != '\n') {
X if(c == EOF) {
X settty("End of input?\n");
X exit(0);
X }
X if(flags.cbreak) {
X if(c == ' ') break;
X if(!spaceflag && letter(c)) {
X morc = c;
X break;
X }
X }
X }
X}
X
Xchar *
Xparse()
X{
X static char inline[COLNO];
X register foo;
X
X flags.move = 1;
X if(!Invis) curs(u.ux,u.uy+2); else home();
X (void) fflush(stdout);
X while((foo = getchar()) >= '0' && foo <= '9')
X multi += 10*multi+foo-'0';
X if(multi) {
X multi--;
X save_cm = inline;
X }
X inline[0] = foo;
X inline[1] = 0;
X if(foo == EOF) {
X settty("End of input?\n");
X exit(0);
X }
X if(foo == 'f' || foo == 'F'){
X inline[1] = getchar();
X#ifdef QUEST
X if(inline[1] == foo) inline[2] = getchar(); else
X#endif QUEST
X inline[2] = 0;
X }
X if(foo == 'm' || foo == 'M'){
X inline[1] = getchar();
X inline[2] = 0;
X }
X clrlin();
X return(inline);
X}
X
Xchar
Xreadchar() {
X register int sym;
X (void) fflush(stdout);
X if((sym = getchar()) == EOF) {
X settty("End of input?\n");
X exit(0);
X }
X if(flags.topl == 1) flags.topl = 2;
X return((char) sym);
X}
!Funky!Stuff!
echo x - mklev.c
sed -e 's/^X//' > mklev.c << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include <stdio.h>
X#include "mklev.h"
X#include "def.trap.h"
X
Xextern void exit(),
X free(),
X qsort();
X
Xextern char *getlogin();
Xextern struct monst *makemon();
X
Xchar *tfile,*tspe,**args;
Xchar nul[40];
X
X#include "savelev.h"
X
X#ifdef WIZARD
Xboolean wizard;
X#endif WIZARD
X
Xlong lrand48();
X
X#define somex() (int)((lrand48()%(croom->hx-croom->lx+1))+croom->lx)
X#define somey() (int)((lrand48()%(croom->hy-croom->ly+1))+croom->ly)
X
Xstruct rm levl[COLNO][ROWNO];
Xstruct monst *fmon;
Xstruct obj *fobj;
Xstruct gen *fgold, *ftrap;
X
Xchar *fut_geno; /* monsters that should not be created anymore */
X
Xstruct mkroom rooms[MAXNROFROOMS+1], *croom, *troom;
Xcoord doors[DOORMAX];
Xint doorindex = 0;
Xint comp();
X
Xxchar dlevel;
Xschar nxcor,xx,yy,dx,dy,tx,ty; /* for corridors and other things... */
Xboolean goldseen;
Xint nroom;
X
Xxchar xdnstair,xupstair,ydnstair,yupstair;
X
X
Xmain(argc,argv)
Xchar *argv[];
X{
X register unsigned tryct;
X
X if(argc < 6) panic("Too few arguments!!");
X args = argv;
X tfile = argv[1];
X tspe = argv[2];
X dlevel = atoi(argv[3]);
X if(dlevel < 1) panic("Bad level");
X fut_geno = argv[4];
X#ifdef WIZARD
X wizard = (argv[5][0] == 'w');
X#endif WIZARD
X (void) setrand(0L);
X init_objects();
X rooms[0].hx = -1; /* in case we are in a maze */
X
X /* a: normal; b: maze */
X if(*tspe == 'b') {
X makemaz();
X savelev();
X exit(0);
X }
X
X /* construct the rooms */
X while(nroom < (MAXNROFROOMS/3)) {
X croom = rooms;
X nroom = 0;
X (void) makerooms(0); /* not secret */
X }
X
X /* for each room: put things inside */
X for(croom = rooms; croom->hx > 0; croom++) {
X
X /* put a sleeping monster inside */
X if(!rn2(3)) (void)
X makemon((struct permonst *) 0, somex(), somey());
X
X /* put traps and mimics inside */
X goldseen = FALSE;
X while(!rn2(8-(dlevel/6))) mktrap(0,0);
X if(!goldseen && !rn2(3)) mkgold(0,somex(),somey());
X if(!rn2(3)) {
X mkobj_at(0, somex(), somey());
X tryct = 0;
X while(!rn2(5)) {
X if(++tryct > 100){
X printf("tryct overflow4\n");
X break;
X }
X mkobj_at(0, somex(), somey());
X }
X }
X }
X tryct = 0;
X do {
X if(++tryct > 1000) panic("Cannot make dnstairs\n");
X croom = &rooms[rn2(nroom)];
X xdnstair = somex();
X ydnstair = somey();
X } while((*tspe =='n' && (!(xdnstair%2) || !(ydnstair%2))) ||
X g_at(xdnstair,ydnstair,ftrap));
X levl[xdnstair][ydnstair].scrsym ='>';
X levl[xdnstair][ydnstair].typ = STAIRS;
X troom = croom;
X do {
X if(++tryct > 2000) panic("Cannot make upstairs\n");
X croom = &rooms[rn2(nroom)];
X xupstair = somex();
X yupstair = somey();
X } while(croom == troom || m_at(xupstair,yupstair) ||
X g_at(xupstair,yupstair,ftrap));
X levl[xupstair][yupstair].scrsym ='<';
X levl[xupstair][yupstair].typ = STAIRS;
X
X qsort((char *) rooms, (unsigned) nroom,
X sizeof(struct mkroom), comp);
X
X croom = rooms;
X troom = croom+1;
X nxcor = 0;
X mkpos();
X do makecor();
X while (croom->hx > 0 && troom->hx > 0);
X
X /* make a secret treasure vault, not connected to the rest */
X if(nroom < (2*MAXNROFROOMS/3)) if(!rn2(3)) {
X register int x,y;
X troom = croom = &rooms[nroom];
X if(makerooms(1)) { /* make secret room */
X troom->rtype = 6; /* treasure vault */
X for(x = troom->lx; x <= troom->hx; x++)
X for(y = troom->ly; y <= troom->hy; y++)
X mkgold(rnd(dlevel*100) + 50, x, y);
X }
X }
X
X#ifdef WIZARD
X if(wizard){
X if(rn2(3)) mkshop(); else mkzoo();
X } else
X#endif WIZARD
X if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 2) mkshop();
X else
X if(dlevel > 6 && (!rn2(7) || !strcmp("david", getlogin())))
X mkzoo();
X savelev();
X exit(0);
X}
X
Xmakerooms(secret) int secret; {
Xregister int lowx, lowy;
Xregister int tryct = 0;
X while(nroom < (MAXNROFROOMS/2) || secret)
X for(lowy = rn1(3,3); lowy < ROWNO-7; lowy += rn1(2,4)) {
X for(lowx = rn1(3,4); lowx < COLNO-10; lowx += rn1(2,7)) {
X if(tryct++ > 10000) return(0);
X if((lowy += (rn2(5)-2)) < 3) lowy = 3;
X else if(lowy > ROWNO-6) lowy = ROWNO-6;
X if(levl[lowx][lowy].typ) continue;
X if((secret && maker(lowx, 1, lowy, 1)) ||
X (!secret && maker(lowx,rn1(9,2),lowy,rn1(4,2))
X && nroom+2 > MAXNROFROOMS)) return(1);
X }
X }
X return(1);
X}
X
Xcomp(x,y)
Xregister struct mkroom *x,*y;
X{
X if(x->lx < y->lx) return(-1);
X return(x->lx > y->lx);
X}
X
Xcoord
Xfinddpos(xl,yl,xh,yh) {
Xcoord ff;
Xregister x,y;
X ff.x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
X ff.y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
X if(okdoor(ff.x, ff.y)) return(ff);
X if(xl < xh) for(x = xl; x <= xh; x++)
X if(okdoor(x, ff.y)){
X ff.x = x;
X return(ff);
X }
X if(yl < yh) for(y = yl; y <= yh; y++)
X if(okdoor(ff.x, y)){
X ff.y = y;
X return(ff);
X }
X return(ff);
X}
X
X/* when croom and troom exist, find position for a door in croom
X and direction for a corridor towards position [tx,ty] in the wall
X of troom */
Xmkpos()
X{
Xcoord cc,tt;
X if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
X if(troom->lx > croom->hx) {
X dx = 1;
X dy = 0;
X xx = croom->hx+1;
X tx = troom->lx-1;
X cc = finddpos(xx,croom->ly,xx,croom->hy);
X tt = finddpos(tx,troom->ly,tx,troom->hy);
X } else if(troom->hy < croom->ly) {
X dy = -1;
X dx = 0;
X yy = croom->ly-1;
X cc = finddpos(croom->lx,yy,croom->hx,yy);
X ty = troom->hy+1;
X tt = finddpos(troom->lx,ty,troom->hx,ty);
X } else if(troom->hx < croom->lx) {
X dx = -1;
X dy = 0;
X xx = croom->lx-1;
X tx = troom->hx+1;
X cc = finddpos(xx,croom->ly,xx,croom->hy);
X tt = finddpos(tx,troom->ly,tx,troom->hy);
X } else {
X dy = 1;
X dx = 0;
X yy = croom->hy+1;
X ty = troom->ly-1;
X cc = finddpos(croom->lx,yy,croom->hx,yy);
X tt = finddpos(troom->lx,ty,troom->hx,ty);
X }
X xx = cc.x;
X yy = cc.y;
X tx = tt.x;
X ty = tt.y;
X if(levl[xx+dx][yy+dy].typ) {
X if(nxcor) newloc();
X else {
X dodoor(xx,yy,croom);
X xx += dx;
X yy += dy;
X }
X return;
X }
X dodoor(xx,yy,croom);
X}
X
X/* if allowable, create a door at [x,y] */
Xokdoor(x,y)
Xregister x,y;
X{
X if(levl[x-1][y].typ == DOOR || levl[x+1][y].typ == DOOR ||
X levl[x][y+1].typ == DOOR || levl[x][y-1].typ == DOOR ||
X levl[x-1][y].typ == SDOOR || levl[x+1][y].typ == SDOOR ||
X levl[x][y-1].typ == SDOOR || levl[x][y+1].typ == SDOOR ||
X (levl[x][y].typ != HWALL && levl[x][y].typ != VWALL) ||
X doorindex >= DOORMAX)
X return(0);
X return(1);
X}
X
Xdodoor(x,y,aroom)
Xregister x,y;
Xregister struct mkroom *aroom;
X{
X register struct mkroom *broom;
X register tmp;
X if(doorindex >= DOORMAX) panic("DOORMAX exceeded?");
X if(!okdoor(x,y) && nxcor) return;
X if(!rn2(8)) levl[x][y].typ = SDOOR;
X else {
X levl[x][y].scrsym ='+';
X levl[x][y].typ = DOOR;
X }
X aroom->doorct++;
X broom = aroom+1;
X if(broom->hx < 0) tmp = doorindex; else
X for(tmp = doorindex; tmp > broom->fdoor; tmp--)
X doors[tmp] = doors[tmp-1];
X doorindex++;
X doors[tmp].x = x;
X doors[tmp].y = y;
X for( ; broom->hx >= 0; broom++) broom->fdoor++;
X}
X
Xnewloc()
X{
X register a,b;
X register int tryct = 0;
X
X ++croom;
X ++troom;
X if(nxcor || croom->hx < 0 || troom->hx < 0) {
X if(nxcor++ > rn1(nroom,4)) {
X croom = &rooms[nroom];
X return;
X }
X do {
X if(++tryct > 100){
X printf("tryct overflow5\n");
X croom = &rooms[nroom];
X return;
X }
X a = rn2(nroom);
X b = rn2(nroom);
X croom = &rooms[a];
X troom = &rooms[b];
X } while(croom == troom || (troom == croom+1 && !rn2(3)));
X }
X mkpos();
X}
X
X/* make a trap somewhere (in croom if mazeflag = 0) */
Xmktrap(num,mazeflag)
Xregister num,mazeflag;
X{
X register struct gen *gtmp;
X register int kind,nopierc,nomimic,fakedoor,fakegold,tryct = 0;
X register xchar mx,my;
X
X if(!num || num >= TRAPNUM) {
X nopierc = (dlevel < 4) ? 1 : 0;
X nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
X if(index(fut_geno, 'M')) nomimic = 1;
X kind = rn2(TRAPNUM - nopierc - nomimic);
X /* note: PIERC = 7, MIMIC = 8, TRAPNUM = 9 */
X } else kind = num;
X
X if(kind == MIMIC) {
X register struct monst *mtmp;
X
X fakedoor = (!rn2(3) && !mazeflag);
X fakegold = (!fakedoor && !rn2(2));
X if(fakegold) goldseen = TRUE;
X do {
X if(++tryct > 200) return;
X if(fakedoor) {
X /* note: fakedoor maybe on actual door */
X if(rn2(2)){
X if(rn2(2))
X mx = croom->hx+1;
X else mx = croom->lx-1;
X my = somey();
X } else {
X if(rn2(2))
X my = croom->hy+1;
X else my = croom->ly-1;
X mx = somex();
X }
X } else if(mazeflag) {
X extern coord mazexy();
X coord mm;
X mm = mazexy();
X mx = mm.x;
X my = mm.y;
X } else {
X mx = somex();
X my = somey();
X }
X } while(m_at(mx,my));
X if(mtmp = makemon(PM_MIMIC,mx,my))
X mtmp->mimic =
X fakegold ? '$' : fakedoor ? '+' :
X (mazeflag && rn2(2)) ? AMULET_SYM :
X "=/)%?![<>" [ rn2(9) ];
X return;
X }
X gtmp = newgen();
X gtmp->gflag = kind;
X do {
X if(++tryct > 200){
X printf("tryct overflow7\n");
X free((char *) gtmp);
X return;
X }
X if(mazeflag){
X extern coord mazexy();
X coord mm;
X mm = mazexy();
X gtmp->gx = mm.x;
X gtmp->gy = mm.y;
X } else {
X gtmp->gx = somex();
X gtmp->gy = somey();
X }
X } while(g_at(gtmp->gx, gtmp->gy, ftrap));
X gtmp->ngen = ftrap;
X ftrap = gtmp;
X if(mazeflag && !rn2(10) && gtmp->gflag < PIERC) gtmp->gflag |= SEEN;
X}
X
X/*VARARGS1*/
Xpanic(str,arg1,arg2,arg3)
Xchar *str,*arg1,*arg2,*arg3;
X{
X char bufr[BUFSZ];
X extern int sprintf();
X (void) sprintf(bufr,str,arg1,arg2,arg3);
X (void) write(1,"\nMKLEV ERROR: ",15);
X puts(bufr);
X (void) fflush(stdout);
X exit(1);
X}
X
Xmaker(lowx,ddx,lowy,ddy)
Xschar lowx,ddx,lowy,ddy;
X{
X register x, y, hix = lowx+ddx, hiy = lowy+ddy;
X
X if(nroom >= MAXNROFROOMS) return(0);
X if(hix > COLNO-5) hix = COLNO-5;
X if(hiy > ROWNO-4) hiy = ROWNO-4;
Xchk:
X if(hix <= lowx || hiy <= lowy) return(0);
X
X /* check area around room (and make room smaller if necessary) */
X for(x = lowx-4; x <= hix+4; x++)
X for(y = lowy-3; y <= hiy+3; y++)
X if(levl[x][y].typ) {
X if(rn2(3)) return(0);
X lowx = x+5;
X lowy = y+4;
X goto chk;
X }
X
X /* on low levels the room is lit (usually) */
X /* secret vaults are always lit */
X if((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1))
X for(x = lowx-1; x <= hix+1; x++)
X for(y = lowy-1; y <= hiy+1; y++)
X levl[x][y].lit = 1;
X croom->lx = lowx;
X croom->hx = hix;
X croom->ly = lowy;
X croom->hy = hiy;
X croom->rtype = croom->doorct = croom->fdoor = 0;
X for(x = lowx-1; x <= hix+1; x++)
X for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
X levl[x][y].scrsym = '-';
X levl[x][y].typ = HWALL;
X }
X for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
X for(y = lowy; y <= hiy; y++) {
X levl[x][y].scrsym = '|';
X levl[x][y].typ = VWALL;
X }
X for(x = lowx; x <= hix; x++)
X for(y = lowy; y <= hiy; y++) {
X levl[x][y].scrsym = '.';
X levl[x][y].typ = ROOM;
X }
X croom++;
X croom->hx = -1;
X nroom++;
X return(1);
X}
X
Xmakecor() {
X register nx, ny;
X register struct rm *crm;
X register dix, diy, secondtry = 0;
X
Xtryagain:
X nx = xx + dx;
X ny = yy + dy;
X
X if(nxcor && !rn2(35)) {
X newloc();
X return;
X }
X if(nx == COLNO-1 || nx == 0 || ny == 0 || ny == ROWNO-1) {
X if(nxcor) {
X newloc();
X return;
X } else {
X printf("something went wrong. we try again...\n");
X execl("./mklev",args[0],tfile,tspe,args[3],args[4],args[5],0);
X panic("cannot execute ./mklev\n");
X }
X }
X
X dix = abs(nx-tx);
X diy = abs(ny-ty);
X if(dy && dix > diy) {
X dy = 0;
X dx = (nx > tx) ? -1 : 1;
X } else if(dx && diy > dix) {
X dx = 0;
X dy = (ny > ty) ? -1 : 1;
X }
X
X crm = &levl[nx][ny];
X if(!(crm->typ)) {
X if(rn2(100)) {
X crm->typ = CORR;
X crm->scrsym = CORR_SYM;
X } else {
X crm->typ = SCORR;
X crm->scrsym = ' ';
X }
X xx = nx;
X yy = ny;
X if(nxcor && !rn2(50)) {
X mkobj_at(ROCK_SYM, nx, ny);
X }
X return;
X }
X if(crm->typ == CORR || crm->typ == SCORR) {
X xx = nx;
X yy = ny;
X return;
X }
X if(nx == tx && ny == ty) {
X dodoor(nx,ny,troom);
X newloc();
X return;
X }
X if(!secondtry++ && (nx != xx+dx || ny != yy+dy))
X goto tryagain;
X if(dx) {
X if(ty < ny) dy = -1;
X else dy = levl[nx+dx][ny-1].typ == ROOM?1:-1;
X dx = 0;
X } else {
X if(tx < nx) dx = -1;
X else dx = levl[nx-1][ny+dy].typ == ROOM?1:-1;
X dy = 0;
X }
X}
X
Xstruct monst *
Xm_at(x,y)
Xregister x,y;
X{
X register struct monst *mtmp;
X
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(mtmp->mx == x && mtmp->my == y) return(mtmp);
X return(0);
X}
X
Xstruct gen *
Xg_at(x,y,ptr)
Xregister x,y;
Xregister struct gen *ptr;
X{
X while(ptr) {
X if(ptr->gx == x && ptr->gy == y) return(ptr);
X ptr = ptr->ngen;
X }
X return(0);
X}
!Funky!Stuff!
echo x - mklev.h
sed -e 's/^X//' > mklev.h << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#include "config.h"
X
X#ifdef BSD
X#include <strings.h> /* declarations for strcat etc. */
X#else
X#include <string.h> /* idem on System V */
X#define index strchr
X#define rindex strrchr
X#endif BSD
X
X#include "def.objclass.h"
X
Xtypedef struct {
X xchar x,y;
X} coord;
X
X#include "def.monst.h" /* uses coord */
X#include "def.gen.h"
X#include "def.obj.h"
X
Xextern int sprintf();
X
X#define BUFSZ 256 /* for getlin buffers */
X#define PL_NSIZ 32 /* name of player, ghost, shopkeeper */
X
X#define HWALL 1 /* Level location types */
X#define VWALL 2
X#define SDOOR 3
X#define SCORR 4
X#define LDOOR 5
X#define DOOR 6 /* smallest accessible type */
X#define CORR 7
X#define ROOM 8
X#define STAIRS 9
X#ifdef QUEST
X#define CORR_SYM ':'
X#else
X#define CORR_SYM '#'
X#endif QUEST
X
X#define ERRCHAR '{'
X
X#define TRAPNUM 9
X
Xstruct rm {
X char scrsym;
X unsigned typ:5;
X unsigned new:1;
X unsigned seen:1;
X unsigned lit:1;
X};
Xextern struct rm levl[COLNO][ROWNO];
X
X#ifndef QUEST
Xstruct mkroom {
X xchar lx,hx,ly,hy;
X schar rtype,rlit,doorct,fdoor;
X};
X#define MAXNROFROOMS 15
Xextern struct mkroom rooms[MAXNROFROOMS+1];
X#define DOORMAX 100
Xextern coord doors[DOORMAX];
X#endif QUEST
X
X
X#include "def.permonst.h"
Xextern struct permonst mons[];
X#define PM_ACIDBLOB &mons[7]
X#define PM_PIERC &mons[17]
X#define PM_MIMIC &mons[37]
X#define PM_CHAM &mons[47]
X#define PM_DEMON &mons[54]
X#define PM_MINOTAUR &mons[55] /* last in mons array */
X#define PM_SHK &mons[56] /* very last */
X#define CMNUM 55 /* number of common monsters */
X
Xextern long *alloc();
X
Xextern xchar xdnstair, ydnstair, xupstair, yupstair; /* stairs up and down. */
X
Xextern xchar dlevel;
X#ifdef WIZARD
Xextern boolean wizard;
X#endif WIZARD
X#define newstring(x) (char *) alloc((unsigned)(x))
!Funky!Stuff!
echo x - rnd.c
sed -e 's/^X//' > rnd.c << '!Funky!Stuff!'
X#include <sys/types.h>
X#define RND(x) ((lrand48()>>3) % x)
Xlong lrand48();
X
Xsetrand(arg)
Xlong arg;
X{
X time_t time();
X void srand48();
X
X if (arg) {
X srand48(arg);
X } else {
X srand48(time(0));
X }
X}
X
Xrn1(x,y)
Xregister x,y;
X{
X return(RND(x)+y);
X}
X
Xrn2(x)
Xregister x;
X{
X return(RND(x));
X}
X
Xrnd(x)
Xregister x;
X{
X return(RND(x)+1);
X}
X
Xd(n,x)
Xregister n,x;
X{
X register tmp = n;
X
X while(n--) tmp += RND(x);
X return(tmp);
X}
!Funky!Stuff!
echo x - savelev.h
sed -e 's/^X//' > savelev.h << '!Funky!Stuff!'
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
X
X#ifdef MKLEV
X
Xsavelev(){
X int fd;
X
X#else
Xextern struct obj *billobjs;
X
Xsavelev(fd){
X#ifndef NOWORM
X register struct wseg *wtmp, *wtmp2;
X register tmp;
X#endif NOWORM
X
X#endif MKLEV
X
X#ifdef MKLEV
X if((fd = creat(tfile,FMASK)) < 0) panic("Cannot create %s\n", tfile);
X#else
X if(fd < 0) panic("Save on bad file!");
X#endif MKLEV
X bwrite(fd,(char *) levl,sizeof(levl));
X#ifdef MKLEV
X bwrite(fd,(char *) nul,sizeof(long));
X#else
X bwrite(fd,(char *) &moves,sizeof(long));
X#endif MKLEV
X bwrite(fd,(char *) &xupstair,sizeof(xupstair));
X bwrite(fd,(char *) &yupstair,sizeof(yupstair));
X bwrite(fd,(char *) &xdnstair,sizeof(xdnstair));
X bwrite(fd,(char *) &ydnstair,sizeof(ydnstair));
X savemonchn(fd, fmon);
X savegenchn(fd, fgold);
X savegenchn(fd, ftrap);
X saveobjchn(fd, fobj);
X#ifdef MKLEV
X saveobjchn(fd, (struct obj *) 0);
X bwrite(fd,(char *) nul, sizeof(unsigned));
X#else
X saveobjchn(fd, billobjs);
X billobjs = 0;
X save_engravings(fd);
X#endif MKLEV
X#ifndef QUEST
X bwrite(fd,(char *) rooms,sizeof(rooms));
X bwrite(fd,(char *) doors,sizeof(doors));
X#endif QUEST
X fgold = ftrap = 0;
X fmon = 0;
X fobj = 0;
X#ifndef MKLEV
X/*--------------------------------------------------------------------*/
X#ifndef NOWORM
X bwrite(fd,(char *) wsegs,sizeof(wsegs));
X for(tmp=1; tmp<32; tmp++){
X for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
X wtmp2 = wtmp->nseg;
X bwrite(fd,(char *) wtmp,sizeof(struct wseg));
X }
X wsegs[tmp] = 0;
X }
X bwrite(fd,(char *) wgrowtime,sizeof(wgrowtime));
X#endif NOWORM
X/*--------------------------------------------------------------------*/
X#endif MKLEV
X}
X
Xbwrite(fd,loc,num)
Xregister fd;
Xregister char *loc;
Xregister unsigned num;
X{
X if(write(fd, loc, num) != num)
X panic("cannot write %d bytes to file #%d",num,fd);
X}
X
Xsaveobjchn(fd,otmp)
Xregister fd;
Xregister struct obj *otmp;
X{
X register struct obj *otmp2;
X unsigned xl;
X int minusone = -1;
X
X while(otmp) {
X otmp2 = otmp->nobj;
X xl = otmp->onamelth;
X bwrite(fd, (char *) &xl, sizeof(int));
X bwrite(fd, (char *) otmp, xl + sizeof(struct obj));
X free((char *) otmp);
X otmp = otmp2;
X }
X bwrite(fd, (char *) &minusone, sizeof(int));
X}
X
Xsavemonchn(fd,mtmp)
Xregister fd;
Xregister struct monst *mtmp;
X{
X register struct monst *mtmp2;
X unsigned xl;
X int minusone = -1;
X struct permonst *monbegin = &mons[0];
X
X bwrite(fd, (char *) &monbegin, sizeof(monbegin));
X
X while(mtmp) {
X mtmp2 = mtmp->nmon;
X xl = mtmp->mxlth + mtmp->mnamelth;
X bwrite(fd, (char *) &xl, sizeof(int));
X bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
X if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
X free((char *) mtmp);
X mtmp = mtmp2;
X }
X bwrite(fd, (char *) &minusone, sizeof(int));
X}
X
Xsavegenchn(fd,gtmp)
Xregister fd;
Xregister struct gen *gtmp;
X{
X register struct gen *gtmp2;
X while(gtmp) {
X gtmp2 = gtmp->ngen;
X bwrite(fd, (char *) gtmp, sizeof(struct gen));
X free((char *) gtmp);
X gtmp = gtmp2;
X }
X bwrite(fd, nul, sizeof(struct gen));
X}
!Funky!Stuff!
exit
--
Gordon A. Moffett ...!{ihnp4,hplabs,sun}!amdahl!gam
"Her name was McGill, and she called herself Lil, but everyone knew
her as Nancy...."