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...."