games-request@tekred.TEK.COM (07/28/87)
Submitted by: mike@genat.UUCP (Mike Stephenson) Comp.sources.games: Volume 2, Issue 4 Archive-name: nethack/Part04 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 4 (of 16)." # Contents: invent.c mklev.c options.c # Wrapped by billr@tekred on Tue Jul 28 09:49:24 1987 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f invent.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"invent.c\" else echo shar: Extracting \"invent.c\" \(22500 characters\) sed "s/^X//" >invent.c <<'END_OF_invent.c' X/* SCCS Id: @(#)invent.c 1.3 87/07/14 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* invent.c - version 1.0.3 */ X X#include <stdio.h> X#include "hack.h" Xextern struct obj *splitobj(); Xextern struct obj zeroobj; Xextern char morc; Xextern char quitchars[]; Xstatic char *xprname(); X X#ifndef NOWORM X#include "wseg.h" Xextern struct wseg *wsegs[32]; X#endif X X#define NOINVSYM '#' X Xint lastinvnr = 51; /* 0 ... 51 */ X Xstatic Xassigninvlet(otmp) Xregister struct obj *otmp; X{ X boolean inuse[52]; X register int i; X register struct obj *obj; X X for(i = 0; i < 52; i++) inuse[i] = FALSE; X for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) { X i = obj->invlet; X if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else X if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE; X if(i == otmp->invlet) otmp->invlet = 0; X } X if((i = otmp->invlet) && X (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z'))) X return; X for(i = lastinvnr+1; i != lastinvnr; i++) { X if(i == 52) { i = -1; continue; } X if(!inuse[i]) break; X } X otmp->invlet = (inuse[i] ? NOINVSYM : X (i < 26) ? ('a'+i) : ('A'+i-26)); X lastinvnr = i; X} X Xstruct obj * Xaddinv(obj) Xregister struct obj *obj; X{ X register struct obj *otmp; X X /* merge or attach to end of chain */ X if(!invent) { X invent = obj; X otmp = 0; X } else X for(otmp = invent; /* otmp */; otmp = otmp->nobj) { X if(merged(otmp, obj, 0)) X return(otmp); X if(!otmp->nobj) { X otmp->nobj = obj; X break; X } X } X obj->nobj = 0; X X if(flags.invlet_constant) { X assigninvlet(obj); X /* X * The ordering of the chain is nowhere significant X * so in case you prefer some other order than the X * historical one, change the code below. X */ X if(otmp) { /* find proper place in chain */ X otmp->nobj = 0; X if((invent->invlet ^ 040) > (obj->invlet ^ 040)) { X obj->nobj = invent; X invent = obj; X } else X for(otmp = invent; ; otmp = otmp->nobj) { X if(!otmp->nobj || X (otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)){ X obj->nobj = otmp->nobj; X otmp->nobj = obj; X break; X } X } X } X } X X return(obj); X} X Xuseup(obj) Xregister struct obj *obj; X{ X if(obj->quan > 1){ X obj->quan--; X obj->owt = weight(obj); X } else { X setnotworn(obj); X freeinv(obj); X obfree(obj, (struct obj *) 0); X } X} X Xfreeinv(obj) Xregister struct obj *obj; X{ X register struct obj *otmp; X X if(obj == invent) X invent = invent->nobj; X else { X for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj) X if(!otmp->nobj) panic("freeinv"); X otmp->nobj = obj->nobj; X } X} X X/* destroy object in fobj chain (if unpaid, it remains on the bill) */ Xdelobj(obj) register struct obj *obj; { X freeobj(obj); X unpobj(obj); X obfree(obj, (struct obj *) 0); X} X X/* unlink obj from chain starting with fobj */ Xfreeobj(obj) register struct obj *obj; { X register struct obj *otmp; X X if(obj == fobj) fobj = fobj->nobj; X else { X for(otmp = fobj; otmp->nobj != obj; otmp = otmp->nobj) X if(!otmp) panic("error in freeobj"); X otmp->nobj = obj->nobj; X } X} X X/* Note: freegold throws away its argument! */ Xfreegold(gold) register struct gold *gold; { X register struct gold *gtmp; X X if(gold == fgold) fgold = gold->ngold; X else { X for(gtmp = fgold; gtmp->ngold != gold; gtmp = gtmp->ngold) X if(!gtmp) panic("error in freegold"); X gtmp->ngold = gold->ngold; X } X free((char *) gold); X} X Xdeltrap(trap) Xregister struct trap *trap; X{ X register struct trap *ttmp; X X if(trap == ftrap) X ftrap = ftrap->ntrap; X else { X for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ; X ttmp->ntrap = trap->ntrap; X } X free((char *) trap); X} X Xstruct wseg *m_atseg; X Xstruct monst * Xm_at(x,y) Xregister x,y; X{ X register struct monst *mtmp; X#ifndef NOWORM X register struct wseg *wtmp; X#endif X X m_atseg = 0; X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){ X if(mtmp->mx == x && mtmp->my == y) X return(mtmp); X#ifndef NOWORM X if(mtmp->wormno){ X for(wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg) X if(wtmp->wx == x && wtmp->wy == y){ X m_atseg = wtmp; X return(mtmp); X } X } X#endif X } X return(0); X} X Xstruct obj * Xo_at(x,y) Xregister x,y; X{ X register struct obj *otmp; X X for(otmp = fobj; otmp; otmp = otmp->nobj) X if(otmp->ox == x && otmp->oy == y) return(otmp); X return(0); X} X Xstruct obj * Xsobj_at(n,x,y) Xregister n,x,y; X{ X register struct obj *otmp; X X for(otmp = fobj; otmp; otmp = otmp->nobj) X if(otmp->ox == x && otmp->oy == y && otmp->otyp == n) X return(otmp); X return(0); X} X Xcarried(obj) register struct obj *obj; { Xregister struct obj *otmp; X for(otmp = invent; otmp; otmp = otmp->nobj) X if(otmp == obj) return(1); X return(0); X} X Xstruct obj * Xcarrying(type) Xregister int type; X{ X register struct obj *otmp; X X for(otmp = invent; otmp; otmp = otmp->nobj) X if(otmp->otyp == type) X return(otmp); X return((struct obj *) 0); X} X Xstruct obj * Xo_on(id, objchn) unsigned int id; register struct obj *objchn; { X while(objchn) { X if(objchn->o_id == id) return(objchn); X objchn = objchn->nobj; X } X return((struct obj *) 0); X} X Xstruct trap * Xt_at(x,y) Xregister x,y; X{ X register struct trap *trap = ftrap; X while(trap) { X if(trap->tx == x && trap->ty == y) return(trap); X trap = trap->ntrap; X } X return(0); X} X Xstruct gold * Xg_at(x,y) Xregister x,y; X{ X register struct gold *gold = fgold; X while(gold) { X if(gold->gx == x && gold->gy == y) return(gold); X gold = gold->ngold; X } X return(0); X} X X/* make dummy object structure containing gold - for temporary use only */ Xstruct obj * Xmkgoldobj(q) Xregister long q; X{ X register struct obj *otmp; X X otmp = newobj(0); X /* should set o_id etc. but otmp will be freed soon */ X otmp->olet = '$'; X u.ugold -= q; X OGOLD(otmp) = q; X flags.botl = 1; X return(otmp); X} X X/* X * getobj returns: X * struct obj *xxx: object to do something with. X * (struct obj *) 0 error return: no object. X * &zeroobj explicitly no object (as in w-). X */ Xstruct obj * Xgetobj(let,word) Xregister char *let,*word; X{ X register struct obj *otmp; X register char ilet,ilet1,ilet2; X char buf[BUFSZ]; X char lets[BUFSZ]; X register int foo = 0, foo2; X register char *bp = buf; X xchar allowcnt = 0; /* 0, 1 or 2 */ X boolean allowgold = FALSE; X boolean allowall = FALSE; X boolean allownone = FALSE; X xchar foox = 0; X long cnt; X X if(*let == '0') let++, allowcnt = 1; X if(*let == '$') let++, allowgold = TRUE; X if(*let == '#') let++, allowall = TRUE; X if(*let == '-') let++, allownone = TRUE; X if(allownone) *bp++ = '-'; X if(allowgold) *bp++ = '$'; X if(bp > buf && bp[-1] == '-') *bp++ = ' '; X X ilet = 'a'; X for(otmp = invent; otmp; otmp = otmp->nobj){ X if(!*let || index(let, otmp->olet)) { X bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet; X X /* ugly check: remove inappropriate things */ X if((!strcmp(word, "take off") && X !(otmp->owornmask & (W_ARMOR - W_ARM2))) X || (!strcmp(word, "wear") && X (otmp->owornmask & (W_ARMOR | W_RING))) X || (!strcmp(word, "wield") && X (otmp->owornmask & W_WEP)) X#ifdef MARKER X || (!strcmp(word, "write with") && X (otmp->olet == TOOL_SYM && otmp->otyp != MAGIC_MARKER)) X#endif X ) { X foo--; X foox++; X } X } X if(ilet == 'z') ilet = 'A'; else ilet++; X } X bp[foo] = 0; X if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0; X (void) strcpy(lets, bp); /* necessary since we destroy buf */ X if(foo > 5) { /* compactify string */ X foo = foo2 = 1; X ilet2 = bp[0]; X ilet1 = bp[1]; X while(ilet = bp[++foo2] = bp[++foo]){ X if(ilet == ilet1+1){ X if(ilet1 == ilet2+1) X bp[foo2 - 1] = ilet1 = '-'; X else if(ilet2 == '-') { X bp[--foo2] = ++ilet1; X continue; X } X } X ilet2 = ilet1; X ilet1 = ilet; X } X } X if(!foo && !allowall && !allowgold && !allownone) { X pline("You don't have anything %sto %s.", X foox ? "else " : "", word); X return(0); X } X for(;;) { X if(!buf[0]) X#ifdef REDO X if(!in_doagain) X#endif X pline("What do you want to %s [*]? ", word); X else X#ifdef REDO X if(!in_doagain) X#endif X pline("What do you want to %s [%s or ?*]? ", X word, buf); X X cnt = 0; X ilet = readchar(); X while(digit(ilet) && allowcnt) { X#ifdef REDO X if (ilet != '?' && ilet != '*') savech(ilet); X#endif X cnt = 10*cnt + (ilet - '0'); X allowcnt = 2; /* signal presence of cnt */ X ilet = readchar(); X } X if(digit(ilet)) { X pline("No count allowed with this command."); X continue; X } X if(index(quitchars,ilet)) X return((struct obj *)0); X if(ilet == '-') { X return(allownone ? &zeroobj : (struct obj *) 0); X } X if(ilet == '$') { X if(!allowgold){ X pline("You cannot %s gold.", word); X continue; X } X if(!(allowcnt == 2 && cnt < u.ugold)) X cnt = u.ugold; X return(mkgoldobj(cnt)); X } X if(ilet == '?') { X doinv(lets); X if(!(ilet = morc)) continue; X /* he typed a letter (not a space) to more() */ X } else if(ilet == '*') { X doinv((char *) 0); X if(!(ilet = morc)) continue; X /* ... */ X } X#ifdef REDO X if (ilet != '?' && ilet != '*') savech(ilet); X#endif X if(flags.invlet_constant) { X for(otmp = invent; otmp; otmp = otmp->nobj) X if(otmp->invlet == ilet) break; X } else { X if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1; X ilet -= 'a'; X for(otmp = invent; otmp && ilet; X ilet--, otmp = otmp->nobj) ; X } X if(!otmp) { X pline("You don't have that object."); X continue; X } X if(cnt < 0 || otmp->quan < cnt) { X pline("You don't have that many! [You have %u]" X , otmp->quan); X continue; X } X break; X } X if(!allowall && let && !index(let,otmp->olet)) { X pline("That is a silly thing to %s.",word); X return(0); X } X if(allowcnt == 2) { /* cnt given */ X if(cnt == 0) return(0); X if(cnt != otmp->quan) { X register struct obj *obj; X obj = splitobj(otmp, (int) cnt); X if(otmp == uwep) setuwep(obj); X } X } X return(otmp); X} X Xckunpaid(otmp) register struct obj *otmp; { X return( otmp->unpaid ); X} X X/* interactive version of getobj - used for Drop and Identify */ X/* return the number of times fn was called successfully */ Xggetobj(word, fn, max) Xchar *word; Xint (*fn)(), max; X{ Xchar buf[BUFSZ]; Xregister char *ip; Xregister char sym; Xregister int oletct = 0, iletct = 0; Xregister boolean allflag = FALSE; Xchar olets[20], ilets[20]; Xint (*ckfn)() = (int (*)()) 0; Xxchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */ X if(!invent && !allowgold){ X pline("You have nothing to %s.", word); X return(0); X } else { X register struct obj *otmp = invent; X register int uflg = 0; X X if(allowgold) ilets[iletct++] = '$'; X ilets[iletct] = 0; X while(otmp) { X if(!index(ilets, otmp->olet)){ X ilets[iletct++] = otmp->olet; X ilets[iletct] = 0; X } X if(otmp->unpaid) uflg = 1; X otmp = otmp->nobj; X } X ilets[iletct++] = ' '; X if(uflg) ilets[iletct++] = 'u'; X if(invent) ilets[iletct++] = 'a'; X ilets[iletct] = 0; X } X pline("What kinds of thing do you want to %s? [%s] ", X word, ilets); X getlin(buf); X if(buf[0] == '\033') { X clrlin(); X return(0); X } X ip = buf; X olets[0] = 0; X while(sym = *ip++){ X if(sym == ' ') continue; X if(sym == '$') { X if(allowgold == 1) X (*fn)(mkgoldobj(u.ugold)); X else if(!u.ugold) X pline("You have no gold."); X allowgold = 2; X } else X if(sym == 'a' || sym == 'A') allflag = TRUE; else X if(sym == 'u' || sym == 'U') ckfn = ckunpaid; else X#ifdef SPELLS X if(index("!%?[()=*/+\"0", sym)){ X#else X if(index("!%?[()=*/\"0", sym)){ X#endif X if(!index(olets, sym)){ X olets[oletct++] = sym; X olets[oletct] = 0; X } X } X else pline("You don't have any %c's.", sym); X } X if(allowgold == 2 && !oletct) X return(1); /* he dropped gold (or at least tried to) */ X else X return(askchain(invent, olets, allflag, fn, ckfn, max)); X} X X/* X * Walk through the chain starting at objchn and ask for all objects X * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL) X * whether the action in question (i.e., fn) has to be performed. X * If allflag then no questions are asked. Max gives the max nr of X * objects to be treated. Return the number of objects treated. X */ Xaskchain(objchn, olets, allflag, fn, ckfn, max) Xstruct obj *objchn; Xregister char *olets; Xint allflag; Xint (*fn)(), (*ckfn)(); Xint max; X{ Xregister struct obj *otmp, *otmp2; Xregister char sym, ilet; Xregister int cnt = 0; X#ifdef SORTING X /* changes so the askchain is interrogated in the order specified. X * For example, if a person specifies =/ then first all rings will be X * asked about followed by all wands -dgk X */ Xnextclass: X#endif X ilet = 'a'-1; X for(otmp = objchn; otmp; otmp = otmp2){ X if(ilet == 'z') ilet = 'A'; else ilet++; X otmp2 = otmp->nobj; X#ifdef SORTING X if (olets && *olets && otmp->olet != *olets) continue; X#else X if(olets && *olets && !index(olets, otmp->olet)) continue; X#endif X if(ckfn && !(*ckfn)(otmp)) continue; X if(!allflag) { X pline(xprname(otmp, ilet)); X addtopl(" [nyaq]? "); X sym = readchar(); X } X else sym = 'y'; X X switch(sym){ X case 'a': X allflag = 1; X case 'y': X cnt += (*fn)(otmp); X if(--max == 0) goto ret; X case 'n': X default: X break; X case 'q': X goto ret; X } X } X#ifdef SORTING X if (olets && *olets && *++olets) X goto nextclass; X#endif X pline(cnt ? "That was all." : "No applicable objects."); Xret: X return(cnt); X} X Xobj_to_let(obj) /* should of course only be called for things in invent */ Xregister struct obj *obj; X{ X register struct obj *otmp; X register char ilet; X X if(flags.invlet_constant) X return(obj->invlet); X ilet = 'a'; X for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj) X if(++ilet > 'z') ilet = 'A'; X return(otmp ? ilet : NOINVSYM); X} X Xprinv(obj) Xregister struct obj *obj; X{ X pline(xprname(obj, obj_to_let(obj))); X} X Xstatic char * Xxprname(obj,let) Xregister struct obj *obj; Xregister char let; X{ X static char li[BUFSZ]; X X (void) sprintf(li, "%c - %s.", X flags.invlet_constant ? obj->invlet : let, X doname(obj)); X return(li); X} X Xddoinv() X{ X doinv((char *) 0); X return(0); X} X X#ifdef SORTING X# ifdef SPELLS Xchar inv_order[] = "\")[%?+/=!(*0_`"; /* to be safe, include _ and ` */ X# else Xchar inv_order[] = "\")[%?/=!(*0_`"; X# endif Xextern char *let_to_name(); X#endif X X/* called with 0 or "": all objects in inventory */ X/* otherwise: all objects with (serial) letter in lets */ Xdoinv(lets) Xregister char *lets; X{ X register struct obj *otmp; X register char ilet; X int ct = 0; X char any[BUFSZ]; X#ifdef SORTING X char *invlet = inv_order; X int classcount = 0; X#endif /* SORTING /**/ X X morc = 0; /* just to be sure */ X X if(!invent){ X pline("Not carrying anything."); X return; X } X X cornline(0, (char *) 0); X#ifdef SORTING Xnextclass: X classcount = 0; X ilet = 'a'; X for(otmp = invent; otmp; otmp = otmp->nobj) { X if(flags.invlet_constant) ilet = otmp->invlet; X if(!lets || !*lets || index(lets, ilet)) { X if (!flags.sortpack || otmp->olet == *invlet) { X if (flags.sortpack && !classcount) { X cornline(1, let_to_name(*invlet)); X classcount++; X } X cornline(1, xprname(otmp, ilet)); X any[ct++] = ilet; X } X } X if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; X } X if (flags.sortpack && *++invlet) goto nextclass; X#else X ilet = 'a'; X for(otmp = invent; otmp; otmp = otmp->nobj) { X if(flags.invlet_constant) ilet = otmp->invlet; X if(!lets || !*lets || index(lets, ilet)) { X cornline(1, xprname(otmp, ilet)); X any[ct++] = ilet; X } X if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; X } X#endif /* SORTING /**/ X any[ct] = 0; X cornline(2, any); X} X Xdotypeinv () /* free after Robert Viduya */ X/* Changed to one type only, so he doesnt have to type cr */ X{ X char c, ilet; X char stuff[BUFSZ]; X register int stct; X register struct obj *otmp; X boolean billx = inshop() && doinvbill(0); X boolean unpd = FALSE; X X if (!invent && !u.ugold && !billx) { X pline ("You aren't carrying anything."); X return(0); X } X X stct = 0; X if(u.ugold) stuff[stct++] = '$'; X stuff[stct] = 0; X for(otmp = invent; otmp; otmp = otmp->nobj) { X if (!index (stuff, otmp->olet)) { X stuff[stct++] = otmp->olet; X stuff[stct] = 0; X } X if(otmp->unpaid) X unpd = TRUE; X } X if(unpd) stuff[stct++] = 'u'; X if(billx) stuff[stct++] = 'x'; X stuff[stct] = 0; X X if(stct > 1) { X#ifdef REDO X if (!in_doagain) X#endif X pline ("What type of object [%s] do you want an inventory of? ", X stuff); X c = readchar(); X#ifdef REDO X savech(c); X#endif X if(index(quitchars,c)) return(0); X } else X c = stuff[0]; X X if(c == '$') X return(doprgold()); X X if(c == 'x' || c == 'X') { X if(billx) X (void) doinvbill(1); X else X pline("No used-up objects on the shopping bill."); X return(0); X } X X if((c == 'u' || c == 'U') && !unpd) { X pline("You are not carrying any unpaid objects."); X return(0); X } X X stct = 0; X ilet = 'a'; X for (otmp = invent; otmp; otmp = otmp -> nobj) { X if(flags.invlet_constant) ilet = otmp->invlet; X if (c == otmp -> olet || (c == 'u' && otmp -> unpaid)) X stuff[stct++] = ilet; X if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; X } X stuff[stct] = '\0'; X if(stct == 0) X pline("You have no such objects."); X else X doinv (stuff); X X return(0); X} X X/* look at what is here */ Xdolook() { X register struct obj *otmp, *otmp0; X register struct gold *gold; X char *verb = Blind ? "feel" : "see"; X int ct = 0; X int fd = 0; X X#ifdef KAA X if(!Blind) read_engr_at(u.ux, u.uy); /* Eric Backus */ X#endif X if(!u.uswallow) { X otmp0 = o_at(u.ux, u.uy); X gold = g_at(u.ux, u.uy); X } else { X pline("You %s no objects here.", verb); X return(!!Blind); X } X X /* added by GAN 10/30/86 */ X#ifdef FOUNTAINS X if(IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { X fd++; X pline("There is a fountain here."); X } X#endif X#ifdef NEWCLASS X if(IS_THRONE(levl[u.ux][u.uy].typ)) { X fd++; X pline("There is an opulent throne here."); X } X#endif X if(u.ux == xupstair && u.uy == yupstair) { X fd++; X pline("There is a stairway up here."); X } X if(u.ux == xdnstair && u.uy == ydnstair) { X fd++; X cornline(1, "There is a stairway down here."); X } X if(Blind) { X pline("You try to feel what is lying here on the floor."); X if(Levitation) { X pline("But you can't reach it!"); X return(0); X } X } X X if(!otmp0 && !gold) { X if(Blind || !fd) X pline("You %s no objects here.", verb); X return(!!Blind); X } X X cornline(0, "Things that are here:"); X for(otmp = otmp0; otmp; otmp = otmp->nobj) { X if(otmp->ox == u.ux && otmp->oy == u.uy) { X ct++; X cornline(1, doname(otmp)); X if(Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) { X pline("Touching the dead cockatrice is a fatal mistake ..."); X pline("You die ..."); X killer = "dead cockatrice"; X done("died"); X } X } X } X X if(gold) { X char gbuf[30]; X X (void) sprintf(gbuf, "%ld gold piece%s", X gold->amount, plur(gold->amount)); X if(!ct++) X pline("You %s here %s.", verb, gbuf); X else X cornline(1, gbuf); X } X X if(ct == 1 && !gold) { X pline("You %s here %s.", verb, doname(otmp0)); X cornline(3, (char *) 0); X } X if(ct > 1) X cornline(2, (char *) 0); X return(!!Blind); X} X Xstackobj(obj) register struct obj *obj; { Xregister struct obj *otmp = fobj; X for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp != obj) X if(otmp->ox == obj->ox && otmp->oy == obj->oy && X merged(obj,otmp,1)) X return; X} X X/* merge obj with otmp and delete obj if types agree */ Xmerged(otmp,obj,lose) register struct obj *otmp, *obj; { X if(obj->otyp == otmp->otyp && X obj->unpaid == otmp->unpaid && X obj->spe == otmp->spe && X obj->dknown == otmp->dknown && X obj->cursed == otmp->cursed && X#ifdef SPELLS X (index("%*?!+", obj->olet) || X#else X (index("%*?!", obj->olet) || X#endif X (obj->known == otmp->known && X (obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) { X otmp->quan += obj->quan; X otmp->owt += obj->owt; X if(lose) freeobj(obj); X obfree(obj,otmp); /* free(obj), bill->otmp */ X return(1); X } else return(0); X} X X/* X * Gold is no longer displayed; in fact, when you have a lot of money, X * it may take a while before you have counted it all. X * [Bug: d$ and pickup still tell you how much it was.] X */ Xextern int (*occupation)(); Xextern char *occtxt; Xstatic long goldcounted; X Xcountgold(){ X if((goldcounted += 100*(u.ulevel + 1)) >= u.ugold) { X long eps = 0; X if(!rn2(2)) eps = rnd((int) (u.ugold/100 + 1)); X pline("You probably have about %ld gold pieces.", X u.ugold + eps); X return(0); /* done */ X } X return(1); /* continue */ X} X Xdoprgold(){ X if(!u.ugold) X pline("You do not carry any gold."); X else if(u.ugold <= 500) X pline("You are carrying %ld gold piece%s.", u.ugold, plur(u.ugold)); X else { X pline("You sit down in order to count your gold pieces."); X goldcounted = 500; X occupation = countgold; X occtxt = "counting your gold"; X } X return(1); X} X X/* --- end of gold counting section --- */ X Xdoprwep(){ X if(!uwep) pline("You are empty handed."); X else prinv(uwep); X return(0); X} X Xdoprarm(){ X if(!uarm && !uarmg && !uarms && !uarmh) X pline("You are not wearing any armor."); X else { X char lets[6]; X register int ct = 0; X X if(uarm) lets[ct++] = obj_to_let(uarm); X if(uarm2) lets[ct++] = obj_to_let(uarm2); X if(uarmh) lets[ct++] = obj_to_let(uarmh); X if(uarms) lets[ct++] = obj_to_let(uarms); X if(uarmg) lets[ct++] = obj_to_let(uarmg); X lets[ct] = 0; X doinv(lets); X } X return(0); X} X Xdoprring(){ X if(!uleft && !uright) X pline("You are not wearing any rings."); X else { X char lets[3]; X register int ct = 0; X X if(uleft) lets[ct++] = obj_to_let(uleft); X if(uright) lets[ct++] = obj_to_let(uright); X lets[ct] = 0; X doinv(lets); X } X return(0); X} X Xdigit(c) char c; { X return(c >= '0' && c <= '9'); X} X X/* X * useupf(obj) X * uses up an object that's on the floor X */ Xuseupf(obj) Xregister struct obj *obj; X{ X if(obj->quan > 1) { X obj->quan--; X obj->owt = weight(obj); X } else delobj(obj); X} X X#ifdef SORTING X/* X * Convert from a symbol to a string for printing object classes X * X * Names from objects.h X * char obj_symbols[] = { X * ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM, X * BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM, X * WAND_SYM, [SPBOOK_SYM], RING_SYM, GEM_SYM, 0 }; X */ X#define Sprintf (void) sprintf X Xextern char obj_symbols[]; Xstatic char *names[] = {"Illegal objects", "Amulets", "Comestibles", "Weapons", X "Tools", "Iron balls", "Chains", "Rocks", "Armor", X "Potions", "Scrolls", "Wands", X#ifdef SPELLS X "Spellbooks", X#endif X "Rings", "Gems"}; Xchar * Xlet_to_name(let) Xchar let; X{ X char *pos = index(obj_symbols, let); X extern char *HI, *HE; X /* buffer size is len(HI) + len(HE) + max(len(names[])) + 1 */ X static char buf[4 + 4 + 15 + 1]; X X if (pos == NULL) pos = obj_symbols; X Sprintf(buf, "%s%s%s", HI, names[pos - obj_symbols], HE); X return (buf); X} X#endif /* SORTING /**/ END_OF_invent.c if test 22500 -ne `wc -c <invent.c`; then echo shar: \"invent.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f mklev.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"mklev.c\" else echo shar: Extracting \"mklev.c\" \(19671 characters\) sed "s/^X//" >mklev.c <<'END_OF_mklev.c' X/* SCCS Id: @(#)mklev.c 1.3 87/07/14 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* mklev.c - version 1.0.3 */ X X#include "hack.h" X Xextern char *getlogin(), *getenv(); Xextern struct monst *makemon(); Xextern struct obj *mkobj_at(); Xextern struct trap *maketrap(); X X#define somex() ((rand()%(croom->hx-croom->lx+1))+croom->lx) X#define somey() ((rand()%(croom->hy-croom->ly+1))+croom->ly) X X#include "mkroom.h" X#define XLIM 4 /* define minimum required space around a room */ X#define YLIM 3 Xboolean secret; /* TRUE while making a vault: increase [XY]LIM */ Xstruct mkroom rooms[MAXNROFROOMS+1]; Xint smeq[MAXNROFROOMS+1]; Xcoord doors[DOORMAX]; Xint doorindex; Xstruct rm zerorm; Xint comp(); Xschar nxcor; Xboolean goldseen; Xint nroom; Xxchar xdnstair,xupstair,ydnstair,yupstair; X X/* Definitions used by makerooms() and addrs() */ X#define MAXRS 50 /* max lth of temp rectangle table - arbitrary */ Xstruct rectangle { X xchar rlx,rly,rhx,rhy; X} rs[MAXRS+1]; Xint rscnt,rsmax; /* 0..rscnt-1: currently under consideration */ X /* rscnt..rsmax: discarded */ X Xmakelevel() X{ X register struct mkroom *croom, *troom; X register unsigned tryct; X#ifndef REGBUG X register X#endif X int x,y; X X nroom = 0; X doorindex = 0; X rooms[0].hx = -1; /* in case we are in a maze */ X X for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) X levl[x][y] = zerorm; X X oinit(); /* assign level dependent obj probabilities */ X X if(dlevel >= rn1(3, 26)) { /* there might be several mazes */ X makemaz(); X return; X } X X /* construct the rooms */ X nroom = 0; X secret = FALSE; X (void) makerooms(); X X /* construct stairs (up and down in different rooms if possible) */ X croom = &rooms[rn2(nroom)]; X xdnstair = somex(); X ydnstair = somey(); X levl[xdnstair][ydnstair].scrsym ='>'; X levl[xdnstair][ydnstair].typ = STAIRS; X if(nroom > 1) { X troom = croom; X croom = &rooms[rn2(nroom-1)]; X if(croom >= troom) croom++; X } X xupstair = somex(); /* %% < and > might be in the same place */ X yupstair = somey(); X levl[xupstair][yupstair].scrsym ='<'; X levl[xupstair][yupstair].typ = STAIRS; X X /* for each room: put things inside */ X for(croom = rooms; croom->hx > 0; croom++) { X X /* put a sleeping monster inside */ X /* Note: monster may be on the stairs. This cannot be X avoided: maybe the player fell through a trapdoor X while a monster was on the stairs. Conclusion: X we have to check for monsters on the stairs anyway. */ 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,croom); X if(!goldseen && !rn2(3)) mkgold(0L,somex(),somey()); X#ifdef FOUNTAINS X if(!rn2(10)) mkfount(0,croom); X#endif X if(!rn2(3)) { X (void) 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 (void) mkobj_at(0, somex(), somey()); X } X } X } X X qsort((char *) rooms, nroom, sizeof(struct mkroom), comp); X makecorridors(); X make_niches(); X X /* make a secret treasure vault, not connected to the rest */ X if(nroom <= (2*MAXNROFROOMS/3)) if(rn2(3)) { X troom = &rooms[nroom]; X secret = TRUE; X if(makerooms()) { X troom->rtype = VAULT; /* treasure vault */ X for(x = troom->lx; x <= troom->hx; x++) X for(y = troom->ly; y <= troom->hy; y++) X mkgold((long)(rnd(dlevel*100) + 50), x, y); X if(!rn2(3)) X makevtele(); X } X } X X#ifdef WIZARD X if(wizard && getenv("SHOPTYPE")) mkshop(); else X#endif X if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3) mkshop(); X else X#ifdef NEWCLASS X if(dlevel > 4 && !rn2(6)) mkzoo(COURT); X#endif X if(dlevel > 6 && !rn2(7)) mkzoo(ZOO); X else X if(dlevel > 9 && !rn2(5)) mkzoo(BEEHIVE); X else X if(dlevel > 11 && !rn2(6)) mkzoo(MORGUE); X else X if(dlevel > 18 && !rn2(6)) mkswamp(); X} X Xmakerooms() { Xregister struct rectangle *rsp; Xregister int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy; Xint tryct = 0, xlim, ylim; X X /* init */ X xlim = XLIM + secret; X ylim = YLIM + secret; X if(nroom == 0) { X rsp = rs; X rsp->rlx = rsp->rly = 0; X rsp->rhx = COLNO-1; X rsp->rhy = ROWNO-1; X rsmax = 1; X } X rscnt = rsmax; X X /* make rooms until satisfied */ X while(rscnt > 0 && nroom < MAXNROFROOMS-1) { X if(!secret && nroom > (MAXNROFROOMS/3) && X !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom))) X return(0); X X /* pick a rectangle */ X rsp = &rs[rn2(rscnt)]; X hx = rsp->rhx; X hy = rsp->rhy; X lx = rsp->rlx; X ly = rsp->rly; X X /* find size of room */ X if(secret) X dx = dy = 1; X else { X dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8); X dy = 2 + rn2(4); X if(dx*dy > 50) X dy = 50/dx; X } X X /* look whether our room will fit */ X if(hx-lx < dx + dx/2 + 2*xlim || hy-ly < dy + dy/3 + 2*ylim) { X /* no, too small */ X /* maybe we throw this area out */ X if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) { X rscnt--; X rs[rsmax] = *rsp; X *rsp = rs[rscnt]; X rs[rscnt] = rs[rsmax]; X tryct = 0; X } else X tryct++; X continue; X } X X lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1); X lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1); X hix = lowx + dx; X hiy = lowy + dy; X X if(maker(lowx, dx, lowy, dy)) { X if(secret) return(1); X addrs(lowx-1, lowy-1, hix+1, hiy+1); X tryct = 0; X } else X if(tryct++ > 100) X break; X } X return(0); /* failed to make vault - very strange */ X} X Xaddrs(lowx,lowy,hix,hiy) Xregister int lowx,lowy,hix,hiy; X{ X register struct rectangle *rsp; X register int lx,ly,hx,hy,xlim,ylim; X boolean discarded; X X xlim = XLIM + secret; X ylim = YLIM + secret; X X /* walk down since rscnt and rsmax change */ X for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) { X X if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy || X (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy) X continue; X if((discarded = (rsp >= &rs[rscnt]))) { X *rsp = rs[--rsmax]; X } else { X rsmax--; X rscnt--; X *rsp = rs[rscnt]; X if(rscnt != rsmax) X rs[rscnt] = rs[rsmax]; X } X if(lowy - ly > 2*ylim + 4) X addrsx(lx,ly,hx,lowy-2,discarded); X if(lowx - lx > 2*xlim + 4) X addrsx(lx,ly,lowx-2,hy,discarded); X if(hy - hiy > 2*ylim + 4) X addrsx(lx,hiy+2,hx,hy,discarded); X if(hx - hix > 2*xlim + 4) X addrsx(hix+2,ly,hx,hy,discarded); X } X} X Xaddrsx(lx,ly,hx,hy,discarded) Xregister int lx,ly,hx,hy; Xboolean discarded; /* piece of a discarded area */ X{ X register struct rectangle *rsp; X X /* check inclusions */ X for(rsp = rs; rsp < &rs[rsmax]; rsp++) { X if(lx >= rsp->rlx && hx <= rsp->rhx && X ly >= rsp->rly && hy <= rsp->rhy) X return; X } X X /* make a new entry */ X if(rsmax >= MAXRS) { X#ifdef WIZARD X if(wizard) pline("MAXRS may be too small."); X#endif X return; X } X rsmax++; X if(!discarded) { X *rsp = rs[rscnt]; X rsp = &rs[rscnt]; X rscnt++; X } X rsp->rlx = lx; X rsp->rly = ly; X rsp->rhx = hx; X rsp->rhy = hy; 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) { X coord ff; X register x,y; X X x = (xl == xh) ? xl : (xl + rn2(xh-xl+1)); X y = (yl == yh) ? yl : (yl + rn2(yh-yl+1)); X if(okdoor(x, y)) X goto gotit; X X for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) X if(okdoor(x, y)) X goto gotit; X X for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) X if(levl[x][y].typ == DOOR || levl[x][y].typ == SDOOR) X goto gotit; X /* cannot find something reasonable -- strange */ X x = xl; X y = yh; Xgotit: X ff.x = x; X ff.y = y; X return(ff); X} X X/* see whether it is allowable to 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 if(doorindex >= DOORMAX) { X impossible("DOORMAX exceeded?"); X return; X } X if(!okdoor(x,y) && nxcor) X return; X dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR); X} X Xdosdoor(x,y,aroom,type) Xregister x,y; Xregister struct mkroom *aroom; Xregister type; X{ X register struct mkroom *broom; X register tmp; X X if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs with '+' as scrsym */ X type = DOOR; X levl[x][y].typ = type; X if(type == DOOR) X#ifdef DGK X levl[x][y].scrsym = symbol.door; X#else X levl[x][y].scrsym = '+'; X#endif /* DGK /**/ 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 X/* Only called from makerooms() */ Xmaker(lowx,ddx,lowy,ddy) Xschar lowx,ddx,lowy,ddy; X{ X register struct mkroom *croom; X register x, y, hix = lowx+ddx, hiy = lowy+ddy; X register xlim = XLIM + secret, ylim = YLIM + secret; X X if(nroom >= MAXNROFROOMS) return(0); X if(lowx < XLIM) lowx = XLIM; X if(lowy < YLIM) lowy = YLIM; X if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1; X if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1; 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 - xlim; x <= hix + xlim; x++) { X for(y = lowy - ylim; y <= hiy + ylim; y++) { X if(levl[x][y].typ) { X#ifdef WIZARD X if(wizard && !secret) X pline("Strange area [%d,%d] in maker().",x,y); X#endif X if(!rn2(3)) return(0); X if(x < lowx) X lowx = x+xlim+1; X else X hix = x-xlim-1; X if(y < lowy) X lowy = y+ylim+1; X else X hiy = y-ylim-1; X goto chk; X } X } X } X X croom = &rooms[nroom]; 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->rlit = 1; X } else X croom->rlit = 0; 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 X#ifdef DGK 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 = symbol.hwall; 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 = symbol.vwall; 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 = symbol.room; X levl[x][y].typ = ROOM; X } X levl[lowx-1][lowy-1].scrsym = symbol.tlcorn; X levl[hix+1][lowy-1].scrsym = symbol.trcorn; X levl[lowx-1][hiy+1].scrsym = symbol.blcorn; X levl[hix+1][hiy+1].scrsym = symbol.brcorn; X#else 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#endif /* DGK /**/ X X smeq[nroom] = nroom; X croom++; X croom->hx = -1; X nroom++; X return(1); X} X Xmakecorridors() { X register a,b; X X nxcor = 0; X for(a = 0; a < nroom-1; a++) X join(a, a+1); X for(a = 0; a < nroom-2; a++) X if(smeq[a] != smeq[a+2]) X join(a, a+2); X for(a = 0; a < nroom; a++) X for(b = 0; b < nroom; b++) X if(smeq[a] != smeq[b]) X join(a, b); X if(nroom > 2) X for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) { X a = rn2(nroom); X b = rn2(nroom-2); X if(b >= a) b += 2; X join(a, b); X } X} X Xjoin(a,b) Xregister a,b; X{ X coord cc,tt; X register tx, ty, xx, yy; X register struct rm *crm; X register struct mkroom *croom, *troom; X register dx, dy, dix, diy, cct; X X croom = &rooms[a]; X troom = &rooms[b]; X X /* find positions cc and tt for doors in croom and troom X and direction for a corridor between them */ X 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 - dx; X ty = tt.y - dy; X if(nxcor && levl[xx+dx][yy+dy].typ) X return; X dodoor(xx,yy,croom); X X cct = 0; X while(xx != tx || yy != ty) { X xx += dx; X yy += dy; X X /* loop: dig corridor at [xx,yy] and find new [xx,yy] */ X if(cct++ > 500 || (nxcor && !rn2(35))) X return; X X if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1) X return; /* impossible */ X X crm = &levl[xx][yy]; X if(!(crm->typ)) { X if(rn2(100)) { X crm->typ = CORR; X#ifdef DGK X crm->scrsym = symbol.corr; X#else X crm->scrsym = CORR_SYM; X#endif X if(nxcor && !rn2(50)) X (void) mkobj_at(ROCK_SYM, xx, yy); X } else { X crm->typ = SCORR; X crm->scrsym = ' '; X } X } else X if(crm->typ != CORR && crm->typ != SCORR) { X /* strange ... */ X return; X } X X /* find next corridor position */ X dix = abs(xx-tx); X diy = abs(yy-ty); X X /* do we have to change direction ? */ X if(dy && dix > diy) { X register ddx = (xx > tx) ? -1 : 1; X X crm = &levl[xx+ddx][yy]; X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { X dx = ddx; X dy = 0; X continue; X } X } else if(dx && diy > dix) { X register ddy = (yy > ty) ? -1 : 1; X X crm = &levl[xx][yy+ddy]; X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { X dy = ddy; X dx = 0; X continue; X } X } X X /* continue straight on? */ X crm = &levl[xx+dx][yy+dy]; X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) X continue; X X /* no, what must we do now?? */ X if(dx) { X dx = 0; X dy = (ty < yy) ? -1 : 1; X crm = &levl[xx+dx][yy+dy]; X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) X continue; X dy = -dy; X continue; X } else { X dy = 0; X dx = (tx < xx) ? -1 : 1; X crm = &levl[xx+dx][yy+dy]; X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) X continue; X dx = -dx; X continue; X } X } X X /* we succeeded in digging the corridor */ X dodoor(tt.x, tt.y, troom); X X if(smeq[a] < smeq[b]) X smeq[b] = smeq[a]; X else X smeq[a] = smeq[b]; X} X Xmake_niches() X{ X register int ct = rnd(nroom/2 + 1); X#ifdef NEWCLASS X boolean ltptr = TRUE, X vamp = TRUE; X X while(ct--) { X X if(dlevel > 15 && rn1(6,0) == 0 && ltptr) { X X ltptr = FALSE; X makeniche(LEVEL_TELEP); X } if (rn1(6,0) == 0) { X X vamp = FALSE; X makeniche(TRAPDOOR); X } else makeniche(NO_TRAP); X } X#else X while(ct--) makeniche(NO_TRAP); X#endif X} X Xmakevtele() X{ X makeniche(TELEP_TRAP); X} X X/* there should be one of these per trap */ Xchar *engravings[] = { "", "", "", "", "", X "ad ae?ar um", "?la? ?as ?er?", X "", "", "" X#ifdef NEWTRAPS X ,"", "" X#endif X#ifdef SPIDERS X ,"" X#endif X#ifdef NEWCLASS X , "", "ad ae?ar um" X#endif X#ifdef SPELLS X ,"" X#endif X }; X Xmakeniche(trap_type) Xint trap_type; X{ X register struct mkroom *aroom; X register struct rm *rm; X register int vct = 8; X coord dd; X register dy,xx,yy; X register struct trap *ttmp; X X if(doorindex < DOORMAX) X while(vct--) { X aroom = &rooms[rn2(nroom-1)]; X if(aroom->rtype != 0) continue; /* not an ordinary room */ X if(aroom->doorct == 1 && rn2(5)) continue; X if(rn2(2)) { X dy = 1; X dd = finddpos(aroom->lx,aroom->hy+1,aroom->hx,aroom->hy+1); X } else { X dy = -1; X dd = finddpos(aroom->lx,aroom->ly-1,aroom->hx,aroom->ly-1); X } X xx = dd.x; X yy = dd.y; X if((rm = &levl[xx][yy+dy])->typ) continue; X if(trap_type || !rn2(4)) { X X rm->typ = SCORR; X rm->scrsym = ' '; X if(trap_type) { X ttmp = maketrap(xx, yy+dy, trap_type); X ttmp->once = 1; X if (strlen(engravings[trap_type]) > 0) X make_engr_at(xx, yy-dy, engravings[trap_type]); X } X dosdoor(xx, yy, aroom, SDOOR); X } else { X rm->typ = CORR; X#ifdef DGK X rm->scrsym = symbol.corr; X#else X rm->scrsym = CORR_SYM; X#endif X if(rn2(7)) X dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR); X else { X mksobj_at(SCR_TELEPORTATION, xx, yy+dy); X if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy); X } X } X return; X } X} X X/* make a trap somewhere (in croom if mazeflag = 0) */ Xmktrap(num, mazeflag, croom) X#ifndef REGBUG Xregister X#endif X int num, mazeflag; X#ifndef REGBUG Xregister X#endif X struct mkroom *croom; X{ X#ifndef REGBUG X register X#endif X struct trap *ttmp; X#ifndef REGBUG X register X#endif X int kind,nopierc,nomimic,fakedoor,fakegold, X#ifdef NEWCLASS X nospikes, nolevltp, X#endif X tryct = 0; X xchar mx,my; X extern char fut_geno[]; X X if(!num || num >= TRAPNUM) { X nopierc = (dlevel < 4) ? 1 : 0; X#ifdef NEWCLASS X nolevltp = (dlevel < 5) ? 1 : 0; X nospikes = (dlevel < 6) ? 1 : 0; X#endif X nomimic = (dlevel < 9 || goldseen ) ? 1 : 0; X if(index(fut_geno, 'M')) nomimic = 1; X X do { X kind = rnd(TRAPNUM-1); X if((kind == PIERC && nopierc) || X (kind == MIMIC && nomimic) X#ifdef SPIDERS X || (kind == WEB) X#endif X#ifdef NEWCLASS X || (kind == SPIKED_PIT && nospikes) X || (kind == LEVEL_TELEP && nolevltp) X#endif X ) kind = NO_TRAP; X } while(kind == NO_TRAP); 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)) mx = croom->hx+1; X else mx = croom->lx-1; X my = somey(); X } else { X if(rn2(2)) 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) || levl[mx][my].typ == STAIRS); X if(mtmp = makemon(PM_MIMIC,mx,my)) { X mtmp->mimic = 1; X mtmp->mappearance = X#ifdef DGK X fakegold ? '$' : fakedoor ? symbol.door : X#else X fakegold ? '$' : fakedoor ? '+' : X#endif X (mazeflag && rn2(2)) ? AMULET_SYM : X#ifdef SPELLS X "=/)%?![<>+" [ rn2(10) ]; X#else X "=/)%?![<>" [ rn2(9) ]; X#endif X } X return; X } X X do { X if(++tryct > 200) X return; X 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(t_at(mx, my) || levl[mx][my].typ == STAIRS); X ttmp = maketrap(mx, my, kind); X if(mazeflag && !rn2(10) && ttmp->ttyp < PIERC) X ttmp->tseen = 1; X} X X#ifdef FOUNTAINS Xmkfount(mazeflag,croom) Xregister struct mkroom *croom; Xregister mazeflag; X{ X register xchar mx,my; X register int tryct = 0; X X do { X if(++tryct > 200) X return; X 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(t_at(mx, my) || levl[mx][my].typ == STAIRS X#ifdef NEWCLASS X || IS_THRONE(levl[mx][my].typ) X#endif X ); X X /* Put a fountain at mx, my */ X X levl[mx][my].typ = FOUNTAIN; X levl[mx][my].scrsym = FOUNTAIN_SYM; X X} X#endif /* FOUNTAINS /**/ X END_OF_mklev.c if test 19671 -ne `wc -c <mklev.c`; then echo shar: \"mklev.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f options.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"options.c\" else echo shar: Extracting \"options.c\" \(8991 characters\) sed "s/^X//" >options.c <<'END_OF_options.c' X/* SCCS Id: @(#)options.c 1.3 87/07/14 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* options.c - version 1.0.3 */ X X#include "config.h" X#include "hack.h" Xextern char *eos(); X#ifdef SORTING Xstatic boolean set_order; X#endif X Xinitoptions() X{ X register char *opts; X extern char *getenv(); X X flags.time = flags.nonews = flags.notombstone = flags.end_own = X flags.standout = flags.nonull = FALSE; X flags.no_rest_on_space = TRUE; X flags.invlet_constant = TRUE; X flags.end_top = 5; X flags.end_around = 4; X flags.female = FALSE; /* players are usually male */ X#ifdef SORTING X flags.sortpack = TRUE; X#endif X#ifdef SAFE_ATTACK X flags.confirm = TRUE; X#endif X#ifdef DGKMOD X flags.silent = flags.pickup = TRUE; X#endif X#ifdef DGK X flags.IBMBIOS = flags.DECRainbow = flags.rawio = FALSE; X read_config_file(); X#else X if(opts = getenv("HACKOPTIONS")) X parseoptions(opts,TRUE); X#endif X} X Xparseoptions(opts, from_env) Xregister char *opts; Xboolean from_env; X{ X register char *op,*op2; X unsigned num; X boolean negated; X X if(op = index(opts, ',')) { X *op++ = 0; X parseoptions(op, from_env); X } X if(op = index(opts, ' ')) { X op2 = op; X while(*op++) X if(*op != ' ') *op2++ = *op; X } X if(!*opts) return; X negated = FALSE; X while((*opts == '!') || !strncmp(opts, "no", 2)) { X if(*opts == '!') opts++; else opts += 2; X negated = !negated; X } X X#ifndef DGK X if(!strncmp(opts,"standout",4)) { X flags.standout = !negated; X return; X } X X if(!strncmp(opts,"null",4)) { X flags.nonull = negated; X return; X } X X if(!strncmp(opts,"tombstone",4)) { X flags.notombstone = negated; X return; X } X X if(!strncmp(opts,"news",4)) { X flags.nonews = negated; X return; X } X#endif X X#ifdef SAFE_ATTACK X if (!strncmp(opts, "conf", 4)) { X flags.confirm = !negated; X return; X } X X#endif X#ifdef DGKMOD X if (!strncmp(opts, "sile", 4)) { X flags.silent = !negated; X return; X } X X if (!strncmp(opts, "pick", 4)) { X flags.pickup = !negated; X return; X } X#endif X#ifdef DGK X if (!strncmp(opts, "IBMB", 4)) { X flags.IBMBIOS = !negated; X return; X } X X if (!strncmp(opts, "rawi", 4)) { X if (from_env) X flags.rawio = !negated; X else X pline("'rawio' only settable from %s.", configfile); X return; X } X X if (!strncmp(opts, "DECR", 4)) { X flags.DECRainbow = !negated; X return; X } X#endif X X#ifdef SORTING X if (!strncmp(opts, "sort", 4)) { X flags.sortpack = !negated; X return; X } X X /* X * the order to list the pack X */ X if (!strncmp(opts,"packorder",4)) { X register char *sp, *tmp; X extern char inv_order[]; X int tmpend; X X op = index(opts,':'); X if(!op) goto bad; X op++; /* skip : */ X X /* Missing characters in new order are filled in at the end X * from inv_order. X */ X for (sp = op; *sp; sp++) X if (!index(inv_order, *sp)) X goto bad; /* bad char in order */ X else if (index(sp + 1, *sp)) X goto bad; /* dup char in order */ X tmp = (char *) alloc(strlen(inv_order) + 1); X (void) strcpy(tmp, op); X for (sp = inv_order, tmpend = strlen(tmp); *sp; sp++) X if (!index(tmp, *sp)) { X tmp[tmpend++] = *sp; X tmp[tmpend] = 0; X } X (void) strcpy(inv_order, tmp); X free(tmp); X set_order = TRUE; X return; X } X#endif X X if(!strncmp(opts,"time",4)) { X flags.time = !negated; X flags.botl = 1; X return; X } X X if(!strncmp(opts,"restonspace",4)) { X flags.no_rest_on_space = negated; X return; X } X X#ifndef DGK X if(!strncmp(opts,"fixinv",4)) { X if(from_env) X flags.invlet_constant = !negated; X else X pline("The fixinvlet option must be in HACKOPTIONS."); X return; X } X#endif X X if(!strncmp(opts,"male",4)) { X#ifdef KAA X if(!from_env && flags.female != negated) X pline("That is not anatomically possible."); X else X#endif X flags.female = negated; X return; X } X if(!strncmp(opts,"female",6)) { X#ifdef KAA X if(!from_env && flags.female == negated) X pline("That is not anatomically possible."); X else X#endif X flags.female = !negated; X return; X } X X /* name:string */ X if(!strncmp(opts,"name",4)) { X extern char plname[PL_NSIZ]; X if(!from_env) { X#ifdef DGK X pline("'name' only settable from %s.", configfile); X#else X pline("The playername can be set only from HACKOPTIONS."); X#endif X return; X } X op = index(opts,':'); X if(!op) goto bad; X (void) strncpy(plname, op+1, sizeof(plname)-1); X return; X } X X /* endgame:5t[op] 5a[round] o[wn] */ X if(!strncmp(opts,"endgame",3)) { X op = index(opts,':'); X if(!op) goto bad; X op++; X while(*op) { X num = 1; X if(digit(*op)) { X num = atoi(op); X while(digit(*op)) op++; X } else X if(*op == '!') { X negated = !negated; X op++; X } X switch(*op) { X case 't': X flags.end_top = num; X break; X case 'a': X flags.end_around = num; X break; X case 'o': X flags.end_own = !negated; X break; X default: X goto bad; X } X while(letter(*++op)) ; X if(*op == '/') op++; X } X return; X } Xbad: X if(!from_env) { X if(!strncmp(opts, "help", 4)) { X pline("%s%s%s", X#ifdef DGK X X"To set options use OPTIONS=<options> in ", configfile, X" or give the command \"O\" followed by the line <options> while playing. ", X"Here <options> is a list of options separated by commas." ); X pline("%s%s", X"Boolean options are confirm, pickup, rawio, silent, sortpack, time, IBMBIOS,", X" and DECRainbow. These can be negated by prefixing them with '!' or \"no\"." ); X pline("%s%s%s", X"The compound options are name, as in OPTIONS=name:Merlin-W,", X#ifdef SORTING X" packorder, which lists the order that items should appear in your pack", X#ifdef SPELLS X" (the default is: packorder:\")[%?+/=!(*0 ), and endgame." ); X#else X" (the default is: packorder:\")[%?/=!(*0 ), and endgame." ); X#endif /* SPELLS /**/ X#else X"and engame.", ""); X#endif /* SORTING /**/ X pline("%s%s%s", X"Endgame is followed by a description of which parts of the scorelist ", X"you wish to see. You might for example say: ", X"\"endgame:own scores/5 top scores/4 around my score\"." ); X X#else X X"To set options use `HACKOPTIONS=\"<options>\"' in your environment, or ", X"give the command 'O' followed by the line `<options>' while playing. ", X"Here <options> is a list of <option>s separated by commas." ); X pline("%s%s%s", X"Simple (boolean) options are rest_on_space, news, time, ", X"null, tombstone, (fe)male. ", X"These can be negated by prefixing them with '!' or \"no\"." ); X pline("%s%s%s", X"The compound options are name, as in OPTIONS=name:Merlin-W,", X#ifdef SORTING X" packorder, which lists the order that items should appear in your pack", X#ifdef SPELLS X" (the default is: packorder:\")[%?+/=!(*0 ), and endgame." ); X#else X" (the default is: packorder:\")[%?/=!(*0 ), and endgame." ); X#endif /* SPELLS /**/ X#else X"and engame.", ""); X#endif /* SORTING /**/ X pline("%s%s%s", X"Endgame is followed by a description of what parts of the scorelist", X"you want to see. You might for example say: ", X"`endgame:own scores/5 top scores/4 around my score'." ); X X#endif /* DGK /**/ X return; X } X pline("Bad option: %s.", opts); X pline("Type `o help<cr>' for help."); X return; X } X#ifdef DGK X printf("Bad syntax in OPTIONS in %s.", configfile); X#else X puts("Bad syntax in HACKOPTIONS."); X puts("Use for example:"); X puts( X"HACKOPTIONS=\"!restonspace,notombstone,endgame:own/5 topscorers/4 around me\"" X ); X#endif X getret(); X} X Xdoset() X{ X char buf[BUFSZ]; X#ifdef SORTING X extern char inv_order[]; X#endif X X pline("What options do you want to set? "); X getlin(buf); X if(!buf[0] || buf[0] == '\033') { X#ifdef DGK X (void) strcpy(buf,"OPTIONS="); X#else X (void) strcpy(buf,"HACKOPTIONS="); X (void) strcat(buf, flags.female ? "female," : "male,"); X if(flags.standout) (void) strcat(buf,"standout,"); X if(flags.nonull) (void) strcat(buf,"nonull,"); X if(flags.nonews) (void) strcat(buf,"nonews,"); X if(flags.notombstone) (void) strcat(buf,"notombstone,"); X if(flags.no_rest_on_space) (void) strcat(buf,"!rest_on_space,"); X#endif X#ifdef SORTING X if (flags.sortpack) (void) strcat(buf,"sortpack,"); X if (set_order){ X (void) strcat(buf, "packorder: "); X (void) strcat(buf, inv_order); X (void) strcat(buf, ","); X } X#endif X#ifdef SAFE_ATTACK X if (flags.confirm) (void) strcat(buf,"confirm,"); X#endif X#ifdef DGKMOD X if (flags.pickup) (void) strcat(buf,"pickup,"); X if (flags.silent) (void) strcat(buf,"silent,"); X#endif X#ifdef DGK X if (flags.rawio) (void) strcat(buf,"rawio,"); X if (flags.IBMBIOS) (void) strcat(buf,"IBMBIOS,"); X if (flags.DECRainbow) (void) strcat(buf,"DECRainbow,"); X#endif X if(flags.time) (void) strcat(buf,"time,"); X if(flags.end_top != 5 || flags.end_around != 4 || flags.end_own){ X (void) sprintf(eos(buf), "endgame: %u topscores/%u around me", X flags.end_top, flags.end_around); X if(flags.end_own) (void) strcat(buf, "/own scores"); X } else { X register char *eop = eos(buf); X if(*--eop == ',') *eop = 0; X } X pline(buf); X } else X parseoptions(buf, FALSE); X X return(0); X} X X#ifdef DGKMOD Xdotogglepickup() { X flags.pickup = !flags.pickup; X pline("Pickup: %s.", flags.pickup ? "ON" : "OFF"); X return (0); X} X#endif END_OF_options.c if test 8991 -ne `wc -c <options.c`; then echo shar: \"options.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 4 \(of 16\). cp /dev/null ark4isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 16 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0