home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!news.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v16i088: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part80/108
- Message-ID: <4451@master.CNA.TEK.COM>
- Date: 5 Feb 93 19:21:16 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 2102
- Approved: billr@saab.CNA.TEK.COM
- Xref: uunet comp.sources.games:1639
-
- Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
- Posting-number: Volume 16, Issue 88
- Archive-name: nethack31/Part80
- Supersedes: nethack3p9: Volume 10, Issue 46-102
- Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
-
-
-
- #! /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 80 (of 108)."
- # Contents: src/options.c src/pickup.c
- # Wrapped by billr@saab on Wed Jan 27 16:09:18 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/options.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/options.c'\"
- else
- echo shar: Extracting \"'src/options.c'\" \(26644 characters\)
- sed "s/^X//" >'src/options.c' <<'END_OF_FILE'
- X/* SCCS Id: @(#)options.c 3.1 92/11/14 */
- X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- X/* NetHack may be freely redistributed. See license for details. */
- X
- X#include "hack.h"
- X#include "termcap.h"
- X#include <ctype.h>
- X
- X/*
- X * NOTE: If you add (or delete) an option, please update the short
- X * options help (option_help()), the long options help (dat/opthelp),
- X * and the current options setting display function (doset()).
- X */
- X
- X#if defined(TOS) && defined(TEXTCOLOR)
- Xextern boolean colors_changed; /* in tos.c */
- X#endif
- X
- Xextern const char *roles[]; /* from u_init.c */
- Xextern char inv_order[]; /* from invent.c */
- X
- Xstatic boolean initial, from_file;
- Xstatic boolean NEARDATA set_order;
- X
- Xstatic void FDECL(nmcpy, (char *, const char *, int));
- Xstatic void FDECL(escapes, (const char *, char *));
- Xstatic void FDECL(rejectoption, (const char *));
- Xstatic void FDECL(badoption, (const char *));
- Xstatic char *FDECL(string_for_env_opt, (const char *, char *));
- Xstatic int FDECL(change_inv_order, (char *, int));
- Xstatic void FDECL(oc_to_str, (char *, char *));
- X
- Xstatic struct Bool_Opt
- X{
- X const char *name;
- X boolean *addr, initvalue;
- X} boolopt[] = {
- X#if defined(MICRO) && !defined(AMIGA)
- X {"BIOS", &flags.BIOS, FALSE},
- X#endif
- X#ifdef INSURANCE
- X {"checkpoint", &flags.ins_chkpt, TRUE},
- X#endif
- X#ifdef TEXTCOLOR
- X# ifdef MICRO
- X {"color", &flags.use_color, TRUE},
- X# else /* systems that support multiple terminals, many monochrome */
- X {"color", &flags.use_color, FALSE},
- X# endif
- X#endif
- X {"confirm",&flags.confirm, TRUE},
- X#ifdef TERMLIB
- X {"DECgraphics", &flags.DECgraphics, FALSE},
- X#endif
- X {"disclose", &flags.end_disclose, TRUE},
- X {"female", &flags.female, FALSE},
- X {"fixinv", &flags.invlet_constant, TRUE},
- X#ifdef AMIFLUSH
- X {"flush", &flags.amiflush, FALSE},
- X#endif
- X {"help", &flags.help, TRUE},
- X#ifdef TEXTCOLOR
- X {"hilite_pet", &flags.hilite_pet, FALSE},
- X#endif
- X#ifdef ASCIIGRAPH
- X {"IBMgraphics", &flags.IBMgraphics, FALSE},
- X#endif
- X {"ignintr", &flags.ignintr, FALSE},
- X#ifdef MAC_GRAPHICS_ENV
- X {"large_font", &flags.large_font, FALSE},
- X#endif
- X {"legacy",&flags.legacy, TRUE},
- X {"lit_corridor", &flags.lit_corridor, FALSE},
- X#ifdef MAC_GRAPHICS_ENV
- X {"MACgraphics", &flags.MACgraphics, TRUE},
- X#endif
- X#ifdef NEWS
- X {"news", &flags.news, TRUE},
- X#endif
- X {"null", &flags.null, TRUE},
- X {"number_pad", &flags.num_pad, FALSE},
- X {"pickup", &flags.pickup, TRUE},
- X#ifdef MAC
- X {"popup_dialog", &flags.popup_dialog, FALSE},
- X#endif
- X#if defined(MICRO) && !defined(AMIGA)
- X {"rawio", &flags.rawio, FALSE},
- X#endif
- X {"rest_on_space", &flags.rest_on_space, FALSE},
- X {"safepet", &flags.safe_dog, TRUE},
- X#ifdef EXP_ON_BOTL
- X {"showexp", &flags.showexp, FALSE},
- X#endif
- X#ifdef SCORE_ON_BOTL
- X {"showscore", &flags.showscore, FALSE},
- X#endif
- X {"silent", &flags.silent, TRUE},
- X {"sortpack", &flags.sortpack, TRUE},
- X {"sound", &flags.soundok, TRUE},
- X {"standout", &flags.standout, FALSE},
- X {"time", &flags.time, FALSE},
- X {"tombstone",&flags.tombstone, TRUE},
- X {"verbose", &flags.verbose, TRUE},
- X {NULL, (boolean *)0, FALSE}
- X};
- X
- Xstatic boolean need_redraw; /* for doset() */
- X
- Xvoid
- Xinitoptions()
- X{
- X register char *opts;
- X int i;
- X
- X for (i = 0; boolopt[i].name; i++) {
- X if (boolopt[i].addr)
- X *(boolopt[i].addr) = boolopt[i].initvalue;
- X }
- X flags.end_own = FALSE;
- X flags.end_top = 3;
- X flags.end_around = 2;
- X flags.msg_history = 20;
- X
- X /* Set the default monster and object class symbols. Don't use */
- X /* memcpy() --- sizeof char != sizeof uchar on some machines. */
- X for (i = 0; i < MAXOCLASSES; i++)
- X oc_syms[i] = (uchar) def_oc_syms[i];
- X for (i = 0; i < MAXMCLASSES; i++)
- X monsyms[i] = (uchar) def_monsyms[i];
- X
- X switch_graphics(ASCII_GRAPHICS); /* set default characters */
- X#ifdef UNIX
- X /*
- X * Set defaults for some options depending on what we can
- X * detect about the environment's capabilities.
- X * This has to be done after the global initialization above
- X * and before reading user-specific initialization via
- X * config file/environment variable below.
- X */
- X /* this detects the IBM-compatible console on most 386 boxes */
- X if (!strncmp(getenv("TERM"), "AT", 2)) {
- X switch_graphics(IBM_GRAPHICS);
- X# ifdef TEXTCOLOR
- X flags.use_color = TRUE;
- X# endif
- X }
- X#endif /* UNIX */
- X#if defined(UNIX) || defined(VMS)
- X /* detect whether a "vt" terminal can handle alternate charsets */
- X if (!strncmpi(getenv("TERM"), "vt", 2) && (AS && AE) &&
- X !strcmp(AS, "\016") && !strcmp(AE, "\017")) {
- X switch_graphics(DEC_GRAPHICS);
- X }
- X#endif /* UNIX || VMS */
- X
- X#ifdef MAC_GRAPHICS_ENV
- X switch_graphics(MAC_GRAPHICS);
- X#endif /* MAC_GRAPHICS_ENV */
- X
- X#ifdef TUTTI_FRUTTI
- X /* since this is done before init_objects(), do partial init here */
- X objects[SLIME_MOLD].oc_name_idx = SLIME_MOLD;
- X nmcpy(pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ);
- X#endif
- X opts = getenv("NETHACKOPTIONS");
- X if (!opts) opts = getenv("HACKOPTIONS");
- X if (opts)
- X if (*opts == '/' || *opts == '\\' || *opts == '@') {
- X if (*opts == '@') opts++; /* @filename */
- X /* looks like a filename */
- X read_config_file(opts);
- X } else {
- X read_config_file(NULL);
- X parseoptions(opts, TRUE, FALSE);
- X }
- X else
- X read_config_file(NULL);
- X#ifdef AMIGA
- X ami_wbench_init(); /* must be here or can't set fruit */
- X#endif
- X#ifdef TUTTI_FRUTTI
- X (void)fruitadd(pl_fruit);
- X /* Remove "slime mold" from list of object names; this will */
- X /* prevent it from being wished unless it's actually present */
- X /* as a named (or default) fruit. Wishing for "fruit" will */
- X /* result in the player's preferred fruit [better than "\033"]. */
- X obj_descr[SLIME_MOLD].oc_name = "fruit";
- X#endif
- X if(flags.female) { /* should have been set in NETHACKOPTIONS */
- X roles[2] = "Cavewoman";
- X roles[6] = "Priestess";
- X }
- X}
- X
- Xstatic void
- Xnmcpy(dest, src, maxlen)
- X char *dest;
- X const char *src;
- X int maxlen;
- X{
- X int count;
- X
- X for(count = 1; count < maxlen; count++) {
- X if(*src == ',' || *src == '\0') break; /*exit on \0 terminator*/
- X *dest++ = *src++;
- X }
- X *dest = 0;
- X}
- X
- X/*
- X * escapes: escape expansion for showsyms. C-style escapes understood include
- X * \n, \b, \t, \r, \xnnn (hex), \onnn (octal), \nnn (decimal). The ^-prefix
- X * for control characters is also understood, and \[mM] followed by any of the
- X * previous forms or by a character has the effect of 'meta'-ing the value (so
- X * that the alternate character set will be enabled).
- X */
- Xstatic void
- Xescapes(cp, tp)
- Xconst char *cp;
- Xchar *tp;
- X{
- X while (*cp)
- X {
- X int cval = 0, meta = 0;
- X
- X if (*cp == '\\' && index("mM", cp[1])) {
- X meta = 1;
- X cp += 2;
- X }
- X if (*cp == '\\' && index("0123456789xXoO", cp[1]))
- X {
- X const char *dp, *hex = "00112233445566778899aAbBcCdDeEfF";
- X int dcount = 0;
- X
- X cp++;
- X if (*cp == 'x' || *cp == 'X')
- X for (++cp; (dp = index(hex, *cp)) && (dcount++ < 2); cp++)
- X cval = (cval * 16) + (dp - hex) / 2;
- X else if (*cp == 'o' || *cp == 'O')
- X for (++cp; (index("01234567",*cp)) && (dcount++ < 3); cp++)
- X cval = (cval * 8) + (*cp - '0');
- X else
- X for (; (index("0123456789",*cp)) && (dcount++ < 3); cp++)
- X cval = (cval * 10) + (*cp - '0');
- X }
- X else if (*cp == '\\') /* C-style character escapes */
- X {
- X switch (*++cp)
- X {
- X case '\\': cval = '\\'; break;
- X case 'n': cval = '\n'; break;
- X case 't': cval = '\t'; break;
- X case 'b': cval = '\b'; break;
- X case 'r': cval = '\r'; break;
- X default: cval = *cp;
- X }
- X cp++;
- X }
- X else if (*cp == '^') /* expand control-character syntax */
- X {
- X cval = (*++cp & 0x1f);
- X cp++;
- X }
- X else
- X cval = *cp++;
- X if (meta)
- X cval |= 0x80;
- X *tp++ = cval;
- X }
- X *tp = '\0';
- X}
- X
- Xstatic void
- Xrejectoption(optname)
- Xconst char *optname;
- X{
- X#ifdef MICRO
- X# ifdef AMIGA
- X if(FromWBench){
- X pline("\"%s\" settable only from %s or in icon.",
- X optname, configfile);
- X } else
- X# endif
- X pline("\"%s\" settable only from %s.", optname, configfile);
- X#else
- X pline("%s can be set only from NETHACKOPTIONS or %s.", optname,
- X configfile);
- X#endif
- X}
- X
- Xstatic void
- Xbadoption(opts)
- Xconst char *opts;
- X{
- X if(!initial) {
- X if(!strncmp(opts, "h", 1) || !strncmp(opts, "?", 1))
- X option_help();
- X else
- X pline("Unknown option: %s. Enter \"?g\" for help.", opts);
- X return;
- X }
- X# ifdef AMIGA
- X if(ami_wbench_badopt(opts)) {
- X# endif
- X if(from_file)
- X raw_printf("Bad syntax in OPTIONS in %s: %s.", configfile, opts);
- X else
- X raw_printf("Bad syntax in NETHACKOPTIONS: %s.", opts);
- X# ifdef AMIGA
- X }
- X# endif
- X wait_synch();
- X}
- X
- Xstatic char *
- Xstring_for_env_opt(optname, opts)
- Xconst char *optname;
- Xchar *opts;
- X{
- X register char *colon;
- X
- X if(!initial) {
- X rejectoption(optname);
- X return NULL;
- X }
- X colon = index(opts,':');
- X if(!colon) {
- X badoption(opts);
- X return NULL;
- X }
- X return ++colon;
- X}
- X
- X/*
- X * Change the inventory order, using the given string as the new order.
- X * Missing characters in the new order are filled in at the end from
- X * the current inv_order.
- X *
- X * This routine always returns 1 unless the parameter 'fail' is true
- X * and there is a duplicate or bad char in the string.
- X */
- Xstatic int
- Xchange_inv_order(op, fail)
- X char *op;
- X int fail; /* If TRUE, return 0 if any duplicates or bad chars. */
- X{
- X int oc_sym, num;
- X char *sp, *tmp, buf[BUFSZ];
- X
- X for (sp = op; *sp; sp++) {
- X oc_sym = def_char_to_objclass(*sp);
- X
- X /* Remove bad or duplicate entries. */
- X if (oc_sym == MAXOCLASSES ||
- X (!index(inv_order, oc_sym)) || (index(sp+1, *sp))) {
- X
- X if (fail) return 0;
- X for(tmp = sp; *tmp; tmp++)
- X tmp[0] = tmp[1];
- X sp--;
- X } else
- X *sp = (char) oc_sym;
- X }
- X Strcpy(buf, op);
- X for (sp = inv_order, num = strlen(buf); *sp; sp++)
- X if (!index(buf, *sp))
- X buf[num++] = *sp;
- X
- X buf[num] = 0;
- X Strcpy(inv_order, buf);
- X return 1;
- X}
- X
- Xvoid
- Xparseoptions(opts, tinitial, tfrom_file)
- Xregister char *opts;
- Xboolean tinitial, tfrom_file;
- X{
- X register char *op;
- X unsigned num;
- X boolean negated;
- X int i;
- X
- X initial = tinitial;
- X from_file = tfrom_file;
- X if ((op = index(opts, ',')) != 0) {
- X *op++ = 0;
- X parseoptions(op, initial, from_file);
- X }
- X
- X /* strip leading and trailing white space */
- X while (isspace(*opts)) opts++;
- X op = eos(opts);
- X while (--op >= opts && isspace(*op)) *op = '\0';
- X
- X if(!*opts) return;
- X negated = FALSE;
- X while((*opts == '!') || !strncmpi(opts, "no", 2)) {
- X if(*opts == '!') opts++; else opts += 2;
- X negated = !negated;
- X }
- X
- X#if defined(MICRO) && !defined(AMIGA)
- X /* included for compatibility with old NetHack.cnf files */
- X if (!strncmp(opts, "IBM_", 4)) {
- X flags.BIOS = !negated;
- X return;
- X }
- X
- X /* put here cause it has to come from the config file */
- X if (!strncmpi(opts, "raw", 3)) {
- X if (initial)
- X flags.rawio = !negated;
- X else
- X rejectoption("rawio");
- X return;
- X }
- X#endif /* MICRO */
- X
- X#if defined(TOS) && defined(TEXTCOLOR)
- X if (!strncmpi(opts, "col", 3)) {
- X flags.use_color = !negated;
- X if (flags.BIOS && !initial) {
- X if (colors_changed)
- X restore_colors();
- X else
- X set_colors();
- X }
- X }
- X#endif
- X /* other special-case boolean options */
- X#ifdef TERMLIB
- X if (!strncmpi(opts, "DEC", 3)) {
- X#ifdef REINCARNATION
- X if (!initial && Is_rogue_level(&u.uz))
- X assign_rogue_graphics(FALSE);
- X#endif
- X flags.DECgraphics = !negated;
- X need_redraw = TRUE;
- X switch_graphics(flags.DECgraphics ?
- X DEC_GRAPHICS : ASCII_GRAPHICS);
- X#ifdef REINCARNATION
- X if (!initial && Is_rogue_level(&u.uz))
- X assign_rogue_graphics(TRUE);
- X#endif
- X return;
- X }
- X#endif /* TERMLIB */
- X#ifdef ASCIIGRAPH
- X if (!strncmpi(opts, "IBMg", 4)) {
- X#ifdef REINCARNATION
- X if (!initial && Is_rogue_level(&u.uz))
- X assign_rogue_graphics(FALSE);
- X#endif
- X flags.IBMgraphics = !negated;
- X need_redraw = TRUE;
- X switch_graphics(flags.IBMgraphics ?
- X IBM_GRAPHICS : ASCII_GRAPHICS);
- X#ifdef REINCARNATION
- X if (!initial && Is_rogue_level(&u.uz))
- X assign_rogue_graphics(TRUE);
- X#endif
- X return;
- X }
- X#endif /* ASCIIGRAPH */
- X#ifdef MAC_GRAPHICS_ENV
- X if (!strncmpi(opts, "MACg", 4)) {
- X#ifdef REINCARNATION
- X if (!initial && Is_rogue_level(&u.uz))
- X assign_rogue_graphics(FALSE);
- X#endif
- X flags.MACgraphics = !negated;
- X need_redraw = TRUE;
- X switch_graphics(flags.MACgraphics ?
- X MAC_GRAPHICS : ASCII_GRAPHICS);
- X#ifdef REINCARNATION
- X if (!initial && Is_rogue_level(&u.uz))
- X assign_rogue_graphics(TRUE);
- X#endif
- X return;
- X }
- X#endif /* MAC_GRAPHICS_ENV */
- X
- X /* common boolean options */
- X
- X if (!strncmpi(opts, "fem", 3)) {
- X if(!initial && flags.female == negated)
- X pline("That is not anatomically possible.");
- X else
- X flags.female = !negated;
- X return;
- X }
- X
- X if (!strncmpi(opts, "fix", 3)) {
- X flags.invlet_constant = !negated;
- X if (!initial && flags.invlet_constant) reassign();
- X return;
- X }
- X
- X if (!strncmpi(opts, "male", 4)) {
- X if(!initial && flags.female != negated)
- X pline("That is not anatomically possible.");
- X else
- X flags.female = negated;
- X return;
- X }
- X
- X if (!strncmpi(opts, "num", 3)) {
- X flags.num_pad = !negated;
- X if (!initial) number_pad(flags.num_pad ? 1 : 0);
- X return;
- X }
- X#ifdef EXP_ON_BOTL
- X if (!strncmpi(opts, "showexp", 7)) {
- X flags.showexp = !negated;
- X flags.botl = 1;
- X return;
- X }
- X#endif
- X#ifdef SCORE_ON_BOTL
- X if (!strncmpi(opts, "showscore", 9)) {
- X flags.showscore = !negated;
- X flags.botl = 1;
- X return;
- X }
- X#endif
- X if (!strncmpi(opts, "time", 4)) {
- X flags.time = !negated;
- X flags.botl = 1;
- X return;
- X }
- X
- X if (!strncmpi(opts, "legacy", 6)) {
- X if(!initial) rejectoption("legacy");
- X else flags.legacy = !negated;
- X return;
- X }
- X
- X /* compound options */
- X
- X if (!strncmpi(opts, "pet", 3)) {
- X if ((op = string_for_env_opt("pettype", opts)) != 0)
- X switch (*op) {
- X case 'd': /* dog */
- X case 'D':
- X preferred_pet = 'd';
- X break;
- X case 'c': /* cat */
- X case 'C':
- X case 'f': /* feline */
- X case 'F':
- X preferred_pet = 'c';
- X break;
- X default:
- X pline("Unrecognized pettype '%s'", op);
- X break;
- X }
- X return;
- X }
- X
- X if (!strncmpi(opts, "cat", 3)) {
- X if ((op = string_for_env_opt("catname", opts)) != 0)
- X nmcpy(catname, op, 62);
- X return;
- X }
- X
- X if (!strncmpi(opts, "dog", 3)) {
- X if ((op = string_for_env_opt("dogname", opts)) != 0)
- X nmcpy(dogname, op, 62);
- X return;
- X }
- X
- X if (!strncmpi(opts, "msg", 3)) {
- X if ((op = string_for_env_opt("msghistory", opts)) != 0) {
- X flags.msg_history = atoi(op);
- X }
- X return;
- X }
- X#ifdef TUTTI_FRUTTI
- X if (!strncmpi(opts, "fr", 2)) {
- X op = index(opts, ':');
- X if (!op) {
- X badoption(opts);
- X return;
- X }
- X op++;
- X if (!initial) {
- X struct fruit *f;
- X int numfruits = 0;
- X
- X for(f=ffruit; f; f=f->nextf) {
- X if (!strcmp(op, f->fname)) goto goodfruit;
- X numfruits++;
- X }
- X if (numfruits >= 100) {
- X pline("Doing that so many times isn't very fruitful.");
- X return;
- X }
- X }
- Xgoodfruit:
- X nmcpy(pl_fruit, op, PL_FSIZ);
- X if (!*pl_fruit)
- X nmcpy(pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ);
- X if (!initial)
- X (void)fruitadd(pl_fruit);
- X /* If initial, then initoptions is allowed to do it instead
- X * of here (initoptions always has to do it even if there's
- X * no fruit option at all. Also, we don't want people
- X * setting multiple fruits in their options.)
- X */
- X return;
- X }
- X#endif
- X /* graphics:string */
- X if (!strncmpi(opts, "gr", 2)) {
- X uchar translate[MAXPCHARS+1];
- X int lth;
- X
- X if (!(opts = string_for_env_opt("graphics", opts)))
- X return;
- X escapes(opts, opts);
- X
- X lth = strlen(opts);
- X if (lth > MAXPCHARS) lth = MAXPCHARS;
- X /* match the form obtained from PC configuration files */
- X for (i = 0; i < lth; i++)
- X translate[i] = (uchar) opts[i];
- X assign_graphics(translate, lth);
- X return;
- X }
- X
- X /* objects:string */
- X if (!strncmpi(opts, "objects", 7)) {
- X int k, length;
- X
- X if (!(opts = string_for_env_opt("objects", opts)))
- X return;
- X escapes(opts, opts);
- X
- X /*
- X * Override the default object class symbols. The first
- X * object in the object class is the "random object". I
- X * don't want to use 0 as an object class, so the "random
- X * object" is basically a place holder.
- X *
- X * The object class symbols have already been initialized in
- X * initoptions().
- X */
- X length = strlen(opts);
- X if (length >= MAXOCLASSES)
- X length = MAXOCLASSES-1; /* don't count RANDOM_OBJECT */
- X
- X for (k = 0; k < length; k++)
- X oc_syms[k+1] = (uchar) opts[k];
- X return;
- X }
- X
- X /* monsters:string */
- X if (!strncmpi(opts, "monsters", 8)) {
- X int k, length;
- X
- X if (!(opts = string_for_env_opt("monsters", opts)))
- X return;
- X escapes(opts, opts);
- X
- X /* Override default mon class symbols set in initoptions(). */
- X length = strlen(opts);
- X if (length >= MAXMCLASSES)
- X length = MAXMCLASSES-1; /* mon class 0 unused */
- X
- X for (k = 0; k < length; k++)
- X monsyms[k+1] = (uchar) opts[k];
- X return;
- X }
- X
- X /* name:string */
- X if (!strncmpi(opts, "name", 4)) {
- X if ((op = string_for_env_opt("name", opts)) != 0)
- X nmcpy(plname, op, (int)sizeof(plname)-1);
- X return;
- X }
- X
- X /* the order to list the pack */
- X if (!strncmpi(opts, "pack", 4)) {
- X op = index(opts,':');
- X if(!op) {
- X badoption(opts);
- X return;
- X }
- X op++; /* skip : */
- X
- X if (!change_inv_order(op, 1))
- X set_order = TRUE;
- X else
- X badoption(opts);
- X return;
- X }
- X
- X /* scores:5t[op] 5a[round] o[wn] */
- X if (!strncmpi(opts, "scores", 6)) {
- X op = index(opts,':');
- X if(!op) {
- X badoption(opts);
- X return;
- X }
- X op++;
- X while(*op) {
- X num = 1;
- X if(digit(*op)) {
- X num = atoi(op);
- X while(digit(*op)) op++;
- X } else if(*op == '!') {
- X negated = !negated;
- X op++;
- X }
- X while(*op == ' ') op++;
- X
- X switch(*op) {
- X case 't':
- X case 'T':
- X flags.end_top = num;
- X break;
- X case 'a':
- X case 'A':
- X flags.end_around = num;
- X break;
- X case 'o':
- X case 'O':
- X flags.end_own = !negated;
- X break;
- X default:
- X badoption(opts);
- X return;
- X }
- X while(letter(*++op) || *op == ' ') ;
- X if(*op == '/') op++;
- X }
- X return;
- X }
- X if (!strncmpi(opts, "win", 3)) {
- X if ((op = string_for_env_opt("windowtype", opts)) != 0) {
- X char buf[16];
- X nmcpy(buf, op, 15);
- X choose_windows(buf);
- X }
- X return;
- X }
- X
- X /* OK, if we still haven't recognized the option, check the boolean
- X * options list
- X */
- X for (i = 0; boolopt[i].name; i++) {
- X if (boolopt[i].addr && !strncmpi(boolopt[i].name, opts, 3)) {
- X *(boolopt[i].addr) = !negated;
- X#ifdef TEXTCOLOR
- X if((boolopt[i].addr) == &flags.use_color)
- X need_redraw = TRUE;
- X
- X if((boolopt[i].addr) == &flags.hilite_pet)
- X need_redraw = TRUE;
- X#endif
- X if (!initial && boolopt[i].addr==&flags.lit_corridor) {
- X /*
- X * All corridor squares seen via night vision or
- X * candles & lamps change. Update them by calling
- X * newsym() on them. Don't do this if we are
- X * initializing the options --- the vision system
- X * isn't set up yet.
- X */
- X vision_recalc(2); /* shut down vision */
- X vision_full_recalc = 1; /* delayed recalc */
- X }
- X return;
- X }
- X }
- X
- X /* out of valid options */
- X badoption(opts);
- X}
- X
- X/*
- X * Convert the given string of object classes to a string of default object
- X * symbols.
- X */
- Xstatic void
- Xoc_to_str(src,dest)
- X char *src, *dest;
- X{
- X int i;
- X
- X while ((i = (int) *src++) != 0) {
- X if (i < 0 || i >= MAXOCLASSES)
- X impossible("oc_to_str: illegal object class %d", i);
- X else
- X *dest++ = def_oc_syms[i];
- X }
- X *dest = '\0';
- X}
- X
- X#ifdef MICRO
- X# define OPTIONS_HEADING "OPTIONS"
- X#else
- X# define OPTIONS_HEADING "NETHACKOPTIONS"
- X#endif
- X
- Xint
- Xdoset()
- X{
- X char buf[BUFSZ], pack_order[MAXOCLASSES+1], on_off;
- X const char *opt_name;
- X int i;
- X winid tmpwin;
- X
- X switch (yn_function("Show the current settings [c], or set options [s]?",
- X "csq", 'q')) {
- X default:
- X case 'q':
- X clear_nhwindow(WIN_MESSAGE);
- X return 0;
- X case 'c':
- X tmpwin = create_nhwindow(NHW_MENU);
- X putstr(tmpwin, 0, OPTIONS_HEADING);
- X putstr(tmpwin, 0, "");
- X /* print the booleans */
- X for (i = 0; boolopt[i].name; i++) {
- X if (!boolopt[i].addr) continue;
- X opt_name = boolopt[i].name;
- X if (*(boolopt[i].addr)) {
- X on_off = ' '; /* on */
- X } else {
- X if (!strcmp(opt_name, "female"))
- X opt_name = "male", on_off = ' ';
- X else
- X on_off = '!'; /* off */
- X }
- X Sprintf(buf, "%c%s", on_off, opt_name);
- X putstr(tmpwin, 0, buf);
- X }
- X /* print the compounds */
- X Sprintf(buf, " catname: %s",
- X (catname[0] != 0) ? catname : "(null)");
- X putstr(tmpwin, 0, buf);
- X Sprintf(buf, " dogname: %s",
- X (dogname[0] != 0) ? dogname : "(null)");
- X putstr(tmpwin, 0, buf);
- X#ifdef TUTTI_FRUTTI
- X Sprintf(buf, " fruit: %s", pl_fruit);
- X putstr(tmpwin, 0, buf);
- X#endif
- X Sprintf(buf, " msghistory: %u", flags.msg_history);
- X putstr(tmpwin, 0, buf);
- X Sprintf(buf, " name: %s", plname);
- X putstr(tmpwin, 0, buf);
- X oc_to_str(inv_order, pack_order);
- X Sprintf(buf, " packorder: %s", pack_order);
- X putstr(tmpwin, 0, buf);
- X Sprintf(buf, " pettype: %s", preferred_pet == 'c' ? "cat" :
- X preferred_pet == 'd' ? "dog" : "random");
- X putstr(tmpwin, 0, buf);
- X Sprintf(buf, " scores: %utop/%uaround%s",
- X flags.end_top, flags.end_around,
- X (flags.end_own ? "/own" : ""));
- X putstr(tmpwin, 0, buf);
- X Sprintf(buf, " windowtype: %s", windowprocs.name);
- X putstr(tmpwin, 0, buf);
- X display_nhwindow(tmpwin, TRUE);
- X destroy_nhwindow(tmpwin);
- X break;
- X case 's':
- X clear_nhwindow(WIN_MESSAGE);
- X getlin("What options do you want to set?", buf);
- X clear_nhwindow(WIN_MESSAGE);
- X if(buf[0] == '\033') return 0;
- X need_redraw = FALSE;
- X parseoptions(buf, FALSE, FALSE);
- X if(need_redraw)
- X (void) doredraw();
- X break;
- X }
- X
- X return 0;
- X}
- X
- Xint
- Xdotogglepickup() {
- X flags.pickup = !flags.pickup;
- X pline("Pickup: %s.", flags.pickup ? "ON" : "OFF");
- X return 0;
- X}
- X
- X/* data for option_help() */
- Xstatic const char *opt_intro[] = {
- X "",
- X " NetHack Options Help:",
- X "",
- X#define CONFIG_SLOT 3 /* fill in next value at run-time */
- X NULL,
- X#ifndef MICRO
- X "or use `NETHACKOPTIONS=\"<options>\"' in your environment;",
- X# ifdef VMS
- X "-- for example, $ DEFINE NETHACKOPTIONS \"nopickup,fruit:kumquat\"",
- X# endif
- X#endif
- X "or press \"O\" while playing, and type your <options> at the prompt.",
- X "In either case, <options> is a list of options separated by commas.",
- X "",
- X "Boolean options (which can be negated by prefixing them with '!' or \"no\"):",
- X NULL
- X};
- Xstatic const char *opt_compound[] = {
- X "Compound options:",
- X "`catname' - the name of your (first) cat (e.g., catname:Tabby),",
- X "`dogname' - the name of your (first) dog (e.g., dogname:Fang),",
- X#ifdef TUTTI_FRUTTI
- X "`fruit' - the name of a fruit you enjoy eating,",
- X# define FRUIT_OFFSET 1
- X#else
- X# define FRUIT_OFFSET 0
- X#endif
- X "`graphics' - defines the symbols to use in drawing the dungeon map,",
- X "`monsters' - defines the symbols to use for monsters,",
- X "`msghistory'- number of top line messages to save,",
- X "`name' - your character's name (e.g., name:Merlin-W),",
- X "`objects' - defines the symbols to use for objects,",
- X "`packorder' - the inventory order of the items in your pack",
- X#define PCKORD_SLOT 9+FRUIT_OFFSET
- X NULL,
- X "`pettype' - your preferred initial pet type,",
- X "`scores' - the parts of the score list you wish to see,",
- X "`windowtype'- windowing system to use.",
- X "",
- X "Some of the options can be set only before the game is started. You will",
- X "be so informed, if you attempt to set them while in the game.",
- X NULL
- X};
- X
- Xvoid
- Xoption_help()
- X{
- X char buf[BUFSZ], pack_order[MAXOCLASSES+1];
- X register int i;
- X winid datawin;
- X
- X datawin = create_nhwindow(NHW_TEXT);
- X#ifdef AMIGA
- X if(FromWBench){
- X Sprintf(buf,"Set options as OPTIONS= in %s or in icon;",configfile);
- X } else
- X#endif
- X Sprintf(buf, "Set options as OPTIONS=<options> in %s;", configfile);
- X opt_intro[CONFIG_SLOT] = (const char *) buf;
- X for (i = 0; opt_intro[i]; i++)
- X putstr(datawin, 0, opt_intro[i]);
- X
- X /* Boolean options */
- X for (i = 0; boolopt[i].name; i++) {
- X if (boolopt[i].addr)
- X next_opt(datawin, boolopt[i].name);
- X }
- X next_opt(datawin, "");
- X
- X /* Compound options */
- X oc_to_str(inv_order, pack_order);
- X Sprintf(buf, " (currently, packorder:%s ),", pack_order);
- X#if 0
- X assert( opt_compound[PCKORD_SLOT] == NULL );
- X#endif
- X opt_compound[PCKORD_SLOT] = (const char *) buf;
- X for (i = 0; opt_compound[i]; i++)
- X putstr(datawin, 0, opt_compound[i]);
- X
- X display_nhwindow(datawin, FALSE);
- X destroy_nhwindow(datawin);
- X return;
- X}
- X
- X/*
- X * prints the next boolean option, on the same line if possible, on a new
- X * line if not. End with next_opt("").
- X */
- Xvoid
- Xnext_opt(datawin, str)
- Xwinid datawin;
- Xconst char *str;
- X{
- X static char buf[121];
- X int i;
- X char *s;
- X
- X if (!*str) {
- X for (s = buf; *s; s++); /* find end of string */
- X if (s > &buf[1] && s[-2] == ',')
- X s[-2] = 0; /* strip last ", " */
- X i = 121;
- X }
- X else
- X i = strlen(buf) + strlen(str) + 2;
- X
- X if (i > COLNO - 2) { /* rule of thumb */
- X putstr(datawin, 0, buf);
- X buf[0] = 0;
- X }
- X if (*str) {
- X Strcat(buf, str);
- X Strcat(buf, ", ");
- X }
- X else
- X putstr(datawin, 0, str);
- X return;
- X}
- X
- X#ifdef TUTTI_FRUTTI
- X/* Returns the fid of the fruit type; if that type already exists, it
- X * returns the fid of that one; if it does not exist, it adds a new fruit
- X * type to the chain and returns the new one.
- X */
- Xint
- Xfruitadd(str)
- Xchar *str;
- X{
- X register int i,j;
- X register struct fruit *f;
- X#ifdef GCC_WARN
- X struct fruit *lastf = (struct fruit *)0;
- X#else
- X struct fruit *lastf;
- X#endif
- X int highest_fruit_id = 0;
- X char buf[PL_FSIZ];
- X boolean user_specified = (str == pl_fruit);
- X /* if not user-specified, then it's a fruit name for a fruit on
- X * a bones level...
- X */
- X
- X /* Note: every fruit has an id (spe for fruit objects) of at least
- X * 1; 0 is an error.
- X */
- X if (user_specified) {
- X /* disallow naming after other foods (since it'd be impossible
- X * to tell the difference)
- X */
- X
- X boolean found = FALSE;
- X
- X for(i = bases[j=letindex(FOOD_CLASS)]; i < bases[j+1]; i++) {
- X if (!strcmp(OBJ_NAME(objects[i]), pl_fruit)) {
- X found = TRUE;
- X break;
- X }
- X }
- X if (found ||
- X (!strncmp(str, "tin of ", 7) && name_to_mon(str+7) > -1) ||
- X !strcmp(str, "empty tin") ||
- X !strcmp(str, "tin of spinach") ||
- X ((!strncmp(eos(str)-6," corpse",7) ||
- X !strncmp(eos(str)-3, " egg",4))
- X && name_to_mon(str) > -1))
- X {
- X Strcpy(buf, pl_fruit);
- X Strcpy(pl_fruit, "candied ");
- X nmcpy(pl_fruit+8, buf, PL_FSIZ-8);
- X }
- X }
- X for(f=ffruit; f; f = f->nextf) {
- X lastf = f;
- X if(f->fid > highest_fruit_id) highest_fruit_id = f->fid;
- X if(!strncmp(str, f->fname, PL_FSIZ))
- X goto nonew;
- X }
- X /* if adding another fruit would overflow spe, use a random
- X fruit instead... we've got a lot to choose from. */
- X if (highest_fruit_id >= 127) return rnd(127);
- X highest_fruit_id++;
- X f = newfruit();
- X if (ffruit) lastf->nextf = f;
- X else ffruit = f;
- X Strcpy(f->fname, str);
- X f->fid = highest_fruit_id;
- X f->nextf = 0;
- Xnonew:
- X if (user_specified) current_fruit = highest_fruit_id;
- X return f->fid;
- X}
- X#endif
- X
- X/*options.c*/
- END_OF_FILE
- if test 26644 -ne `wc -c <'src/options.c'`; then
- echo shar: \"'src/options.c'\" unpacked with wrong size!
- fi
- # end of 'src/options.c'
- fi
- if test -f 'src/pickup.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/pickup.c'\"
- else
- echo shar: Extracting \"'src/pickup.c'\" \(26706 characters\)
- sed "s/^X//" >'src/pickup.c' <<'END_OF_FILE'
- X/* SCCS Id: @(#)pickup.c 3.1 93/01/04 */
- X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- X/* NetHack may be freely redistributed. See license for details. */
- X
- X/*
- X * Contains code for picking objects up, and container use.
- X */
- X
- X#include "hack.h"
- X
- Xstatic void FDECL(unsplitobj, (struct obj *,struct obj *,long));
- Xstatic void FDECL(simple_look, (struct obj *,BOOLEAN_P));
- Xstatic boolean FDECL(query_classes, (char *,boolean *,boolean *,
- X const char *,struct obj *,BOOLEAN_P,BOOLEAN_P));
- Xstatic boolean FDECL(pickup_object, (struct obj *,struct obj *));
- Xstatic boolean FDECL(mbag_explodes, (struct obj *,int));
- XSTATIC_PTR int FDECL(in_container,(struct obj *));
- XSTATIC_PTR int FDECL(ck_bag,(struct obj *));
- XSTATIC_PTR int FDECL(out_container,(struct obj *));
- X
- X/*
- X * How much the weight of the given container will change when the given
- X * object is removed from it. This calculation must match the one used
- X * by weight() in mkobj.c.
- X */
- X#define DELTA_CWT(cont,obj) \
- X ((cont)->cursed ? (obj)->owt * 2 : \
- X 1 + ((obj)->owt / ((cont)->blessed ? 4 : 2)))
- X
- Xstatic const char moderateloadmsg[] = "You have a little trouble lifting";
- Xstatic const char nearloadmsg[] = "You have much trouble lifting";
- X
- Xstatic void
- Xunsplitobj(obj_block, obj_chip, resplit)
- Xregister struct obj *obj_block, *obj_chip;
- Xlong resplit; /* non-zero => shift the quantities */
- X{
- X if (obj_block->nobj != obj_chip) {
- X impossible("can't unsplit objects");
- X } else if (resplit) { /* 1st object should be reduced to 'resplit' */
- X obj_chip->quan += (obj_block->quan - resplit);
- X obj_block->quan = resplit;
- X obj_block->owt = weight(obj_block);
- X obj_chip->owt = weight(obj_chip);
- X } else { /* 2nd obj should be merged back into 1st, then destroyed */
- X obj_block->nobj = obj_chip->nobj;
- X obj_block->nexthere = obj_chip->nexthere;
- X obj_block->quan += obj_chip->quan;
- X obj_block->owt = weight(obj_block);
- X /* no need to worry about 'unsplitbill'; unsplit only occurs
- X when unable to pick something up, hence we're not dealing
- X with billable objects here (I hope!)
- X */
- X dealloc_obj(obj_chip);
- X }
- X}
- X
- X/* much simpler version of the look-here code; used by query_classes() */
- Xstatic void
- Xsimple_look(otmp, here)
- Xstruct obj *otmp; /* list of objects */
- Xboolean here; /* flag for type of obj list linkage */
- X{
- X /* Neither of the first two cases is expected to happen, since
- X * we're only called after multiple classes of objects have been
- X * detected, hence multiple objects must be present.
- X */
- X if (!otmp) {
- X impossible("simple_look(NULL)");
- X } else if (!(here ? otmp->nexthere : otmp->nobj)) {
- X pline("%s", doname(otmp));
- X } else {
- X winid tmpwin = create_nhwindow(NHW_MENU);
- X putstr(tmpwin, 0, "");
- X do {
- X putstr(tmpwin, 0, doname(otmp));
- X otmp = here ? otmp->nexthere : otmp->nobj;
- X } while (otmp);
- X display_nhwindow(tmpwin, TRUE);
- X destroy_nhwindow(tmpwin);
- X }
- X}
- X
- Xint
- Xcollect_obj_classes(ilets, otmp, here, incl_gold)
- Xchar ilets[];
- Xregister struct obj *otmp;
- Xboolean here, incl_gold;
- X{
- X register int iletct = 0;
- X register char c, last_c = '\0';
- X
- X if (incl_gold)
- X ilets[iletct++] = def_oc_syms[GOLD_CLASS];
- X ilets[iletct] = '\0'; /* terminate ilets so that index() will work */
- X while (otmp) {
- X c = def_oc_syms[(int)otmp->oclass];
- X if (c != last_c && !index(ilets, (last_c = c)))
- X ilets[iletct++] = c, ilets[iletct] = '\0';
- X otmp = here ? otmp->nexthere : otmp->nobj;
- X }
- X
- X return iletct;
- X}
- X
- Xstatic boolean
- Xquery_classes(olets, one_at_a_time, everything, action, objs, here, incl_gold)
- Xchar olets[];
- Xboolean *one_at_a_time, *everything;
- Xconst char *action;
- Xstruct obj *objs;
- Xboolean here, incl_gold;
- X{
- X char ilets[20], inbuf[BUFSZ];
- X int iletct, oletct;
- X char qbuf[QBUFSZ];
- X
- X olets[oletct = 0] = '\0';
- X *one_at_a_time = *everything = FALSE;
- X iletct = collect_obj_classes(ilets, objs, here, incl_gold);
- X if (iletct == 0) {
- X return FALSE;
- X } else if (iletct == 1) {
- X olets[0] = def_char_to_objclass(ilets[0]);
- X olets[1] = '\0';
- X } else { /* more than one choice available */
- X const char *where = 0;
- X register char sym, oc_of_sym, *p;
- X /* additional choices */
- X ilets[iletct++] = ' ';
- X ilets[iletct++] = 'a';
- X ilets[iletct++] = 'A';
- X ilets[iletct++] = (objs == invent ? 'i' : ':');
- X ilets[iletct] = '\0';
- Xask_again:
- X olets[oletct = 0] = '\0';
- X *one_at_a_time = *everything = FALSE;
- X Sprintf(qbuf,"What kinds of thing do you want to %s? [%s]",
- X action, ilets);
- X getlin(qbuf,inbuf);
- X if (*inbuf == '\033') {
- X clear_nhwindow(WIN_MESSAGE);
- X return FALSE;
- X }
- X for (p = inbuf; (sym = *p++); ) {
- X /* new A function (selective all) added by GAN 01/09/87 */
- X if (sym == ' ') continue;
- X else if (sym == 'A') *one_at_a_time = TRUE;
- X else if (sym == 'a') *everything = TRUE;
- X else if (sym == ':') {
- X simple_look(objs, here); /* dumb if objs==invent */
- X goto ask_again;
- X } else if (sym == 'i') {
- X (void) display_inventory(NULL, FALSE);
- X goto ask_again;
- X } else {
- X oc_of_sym = def_char_to_objclass(sym);
- X if (index(ilets,sym)) {
- X olets[oletct++] = oc_of_sym;
- X olets[oletct] = '\0';
- X } else {
- X if (!where)
- X where = !strcmp(action,"pick up") ? "here" :
- X !strcmp(action,"take out") ?
- X "inside" : "";
- X if (*where)
- X pline("There are no %c's %s.", sym, where);
- X else
- X You("have no %c's.", sym);
- X }
- X }
- X }
- X if (!oletct && !*everything) *one_at_a_time = TRUE;
- X }
- X return TRUE;
- X}
- X
- Xvoid
- Xpickup(all)
- Xint all; /* all >= 0 => yes/no; < 0 => -count */
- X{
- X register struct obj *obj;
- X struct obj *obj2, *objx;
- X boolean all_of_a_type = FALSE, selective = FALSE;
- X char olets[20];
- X long count;
- X
- X count = (all < 0) ? (-1L * all) : 0L;
- X if (count) all = 0;
- X
- X if(Levitation && !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) {
- X if ((multi && !flags.run) || (all && !flags.pickup))
- X read_engr_at(u.ux,u.uy);
- X return;
- X }
- X
- X /* multi && !flags.run means they are in the middle of some other
- X * action, or possibly paralyzed, sleeping, etc.... and they just
- X * teleported onto the object. They shouldn't pick it up.
- X */
- X if ((multi && !flags.run) || (all && !flags.pickup)) {
- X int ct = 0;
- X
- X for (obj = level.objects[u.ux][u.uy]; obj;
- X obj = obj->nexthere)
- X if(obj != uchain)
- X ct++;
- X
- X /* If there are objects here, take a look.
- X */
- X if (ct) {
- X if (flags.run)
- X nomul(0);
- X flush_screen(1);
- X if (ct < 5)
- X (void) dolook();
- X else {
- X read_engr_at(u.ux,u.uy);
- X pline("There are several objects here.");
- X }
- X } else read_engr_at(u.ux,u.uy);
- X return;
- X }
- X
- X /* check for more than one object */
- X if(!all) {
- X register int ct = 0;
- X
- X for(obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere)
- X ct++;
- X if(ct < 2)
- X all++;
- X else {
- X pline("There are several objects here.");
- X count = 0;
- X }
- X }
- X
- X#ifdef POLYSELF
- X if (nolimbs(uasmon)) {
- X You("cannot pick things up without limbs.");
- X return;
- X }
- X#endif
- X
- X /* added by GAN 10/24/86 to allow selective picking up */
- X if (!all) {
- X if (!query_classes(olets, &selective, &all_of_a_type,
- X "pick up", level.objects[u.ux][u.uy], TRUE, FALSE))
- X return;
- X }
- X if(all_of_a_type && !olets[0]) all = TRUE;
- X
- X for(obj = level.objects[u.ux][u.uy]; obj; obj = obj2) {
- X obj2 = obj->nexthere; /* perhaps obj will be picked up */
- X objx = 0;
- X if(flags.run) nomul(0);
- X
- X if(!all) {
- X if(!selective && !index(olets,obj->oclass)) continue;
- X
- X if (!all_of_a_type) {
- X char qbuf[QBUFSZ];
- X Sprintf(qbuf,"Pick up %s?", doname(obj));
- X switch ((obj->quan < 2L) ? ynaq(qbuf) : ynNaq(qbuf)) {
- X case 'q': return;
- X case 'n': continue;
- X case 'a':
- X all_of_a_type = TRUE;
- X if (selective) {
- X selective = FALSE;
- X olets[0] = obj->oclass;
- X olets[1] = '\0';
- X }
- X break;
- X case '#': /* count was entered */
- X if (!yn_number) continue; /* 0 count => No */
- X else count = yn_number;
- X /* fall thru :-} */
- X default: /* 'y' */
- X break;
- X }
- X }
- X }
- X
- X if (count) {
- X /* Pickup a specific number of items; split the object
- X unless count corresponds to full quantity. 1 special
- X case: cursed loadstones will remain as merged unit.
- X */
- X if (count < obj->quan &&
- X (!obj->cursed || obj->otyp != LOADSTONE)) {
- X objx = splitobj(obj, count);
- X if (!objx || objx->nexthere != obj2)
- X impossible("bad object split in pickup");
- X }
- X count = 0; /* reset */
- X }
- X if (pickup_object(obj, objx)) break;
- X }
- X
- X /*
- X * Re-map what is at the hero's location after the pickup so the
- X * map is correct.
- X */
- X newsym(u.ux,u.uy);
- X}
- X
- X/*
- X * Pick up an object from the ground or out of a container and add it to
- X * the inventory. Returns true if pickup() should break out of its loop.
- X */
- Xstatic boolean
- Xpickup_object(obj, objx)
- Xstruct obj *obj, *objx;
- X{
- X int wt, nearload;
- X long pickquan;
- X
- X if (obj == uchain) { /* do not pick up attached chain */
- X return FALSE;
- X } else if (obj->oartifact && !touch_artifact(obj,&youmonst)) {
- X return FALSE;
- X } else if (obj->otyp == GOLD_PIECE) {
- X /*
- X * Special consideration for gold pieces...
- X */
- X long iw = (long)max_capacity() - ((u.ugold + 50L) / 100L);
- X long gold_capacity = ((-iw) * 100L) - 50L + 99L - u.ugold;
- X
- X if (gold_capacity <= 0L) {
- X if (objx) unsplitobj(obj, objx, 0L);
- X pline("There %s %ld gold piece%s here, but you cannot carry any more.",
- X (obj->quan == 1L) ? "is" : "are",
- X obj->quan, plur(obj->quan));
- X return FALSE;
- X } else if (gold_capacity < obj->quan) {
- X if (objx) unsplitobj(obj, objx, 0L);
- X You("can only carry %s of the %ld gold pieces lying here.",
- X gold_capacity == 1L ? "one" : "some", obj->quan);
- X pline("%s %ld gold piece%s.",
- X nearloadmsg, gold_capacity, plur(gold_capacity));
- X u.ugold += gold_capacity;
- X obj->quan -= gold_capacity;
- X costly_gold(obj->ox, obj->oy, gold_capacity);
- X } else {
- X u.ugold += obj->quan;
- X if ((nearload = near_capacity()) != 0)
- X pline("%s %ld gold piece%s.",
- X nearload < MOD_ENCUMBER ?
- X moderateloadmsg : nearloadmsg,
- X obj->quan, plur(obj->quan));
- X else
- X prinv(NULL, obj, 0L);
- X costly_gold(obj->ox, obj->oy, obj->quan);
- X delobj(obj);
- X }
- X flags.botl = 1;
- X if (flags.run) nomul(0);
- X return FALSE;
- X } else if (obj->otyp == CORPSE) {
- X
- X if (obj->corpsenm == PM_COCKATRICE && !uarmg
- X#ifdef POLYSELF
- X && !resists_ston(uasmon)
- X#endif
- X ) {
- X#ifdef POLYSELF
- X if (poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))
- X display_nhwindow(WIN_MESSAGE, FALSE);
- X else
- X#endif
- X {
- X pline("Touching the cockatrice corpse is a fatal mistake.");
- X You("turn to stone.");
- X You("die...");
- X killer_format = KILLED_BY_AN;
- X killer = "cockatrice corpse";
- X done(STONING);
- X }
- X } else if (is_rider(&mons[obj->corpsenm])) {
- X pline("At your touch, the corpse suddenly moves...");
- X revive_corpse(obj, 1, FALSE);
- X exercise(A_WIS, FALSE);
- X return FALSE;
- X }
- X
- X } else if (obj->otyp == SCR_SCARE_MONSTER) {
- X if (obj->blessed) obj->blessed = 0;
- X else if (!obj->spe && !obj->cursed) obj->spe = 1;
- X else {
- X pline("The scroll%s turn%s to dust as you pick %s up.",
- X plur(obj->quan), (obj->quan == 1L) ? "s" : "",
- X (obj->quan == 1L) ? "it" : "them");
- X if (!(objects[SCR_SCARE_MONSTER].oc_name_known) &&
- X !(objects[SCR_SCARE_MONSTER].oc_uname))
- X docall(obj);
- X useupf(obj);
- X return FALSE;
- X }
- X }
- X
- X wt = max_capacity() + (int)obj->owt;
- X if (obj->otyp == LOADSTONE)
- X goto lift_some; /* pick it up even if too heavy */
- X#ifdef POLYSELF
- X if (obj->otyp == BOULDER && throws_rocks(uasmon)) {
- X goto lift_some;
- X }
- X#endif
- X if (wt > 0) {
- X if (obj->quan > 1L) {
- X /* see how many we can lift */
- X long qq, savequan = obj->quan;
- X int iw = max_capacity();
- X /* This is correct only because containers */
- X /* don't merge. -dean */
- X for (qq = 1; qq < savequan; qq++) {
- X obj->quan = qq;
- X if (iw + weight(obj) > 0)
- X break;
- X }
- X obj->quan = savequan;
- X qq--;
- X /* we can carry qq of them */
- X if (qq) {
- X if (objx) { /* temporarily unsplit */
- X savequan = obj->quan;
- X obj->quan += objx->quan;
- X }
- X You("can only carry %s of the %s lying here.",
- X (qq == 1L) ? "one" : "some", doname(obj));
- X if (objx) { /* re-do the prior split */
- X obj->quan = savequan;
- X unsplitobj(obj, objx, qq);
- X } else { /* split into two groups */
- X objx = splitobj(obj, qq);
- X if (objx->otyp == SCR_SCARE_MONSTER) objx->spe = 0;
- X }
- X goto lift_some;
- X }
- X }
- X if (objx) unsplitobj(obj, objx, 0L);
- X pline("There %s %s here, but %s.",
- X (obj->quan == 1L) ? "is" : "are", doname(obj),
- X !invent ? (obj->quan == 1L ?
- X "it is too heavy for you to lift" :
- X "they are too heavy for you to lift") :
- X "you cannot carry any more");
- X if (obj->otyp == SCR_SCARE_MONSTER) obj->spe = 0;
- X return TRUE;
- X }
- X
- Xlift_some:
- X if (inv_cnt() >= 52) {
- X if (objx) unsplitobj(obj, objx, 0L);
- X Your("knapsack cannot accommodate any more items.");
- X if (obj->otyp == SCR_SCARE_MONSTER) obj->spe = 0;
- X return TRUE;
- X }
- X
- X pickquan = obj->quan; /* save number picked up */
- X obj = pick_obj(obj);
- X
- X if (!Blind) obj->dknown = 1;
- X if (uwep && uwep == obj) mrg_to_wielded = TRUE;
- X nearload = near_capacity();
- X prinv(nearload > SLT_ENCUMBER ? nearloadmsg :
- X nearload > UNENCUMBERED ? moderateloadmsg : NULL,
- X obj, pickquan);
- X mrg_to_wielded = FALSE;
- X return FALSE;
- X}
- X
- X/* Gold never reaches this routine. */
- Xstruct obj *
- Xpick_obj(otmp)
- Xregister struct obj *otmp;
- X{
- X freeobj(otmp);
- X if (*u.ushops && costly_spot(u.ux, u.uy) &&
- X otmp != uball) /* don't charge for this - kd, 1/17/90 */
- X /* sets obj->unpaid if necessary */
- X addtobill(otmp, TRUE, FALSE, FALSE);
- X if(Invisible) newsym(u.ux,u.uy);
- X return(addinv(otmp)); /* might merge it with other objects */
- X}
- X
- X/*
- X * prints a message if encumbrance changed since the last check and
- X * returns the new encumbrance value (from near_capacity()).
- X */
- Xint
- Xencumber_msg()
- X{
- X static int oldcap = UNENCUMBERED;
- X int newcap = near_capacity();
- X
- X if(oldcap < newcap) {
- X switch(newcap) {
- X case 1: Your("movements are slowed slightly because of your load.");
- X break;
- X case 2: You("rebalance your load. Movement is difficult.");
- X break;
- X case 3: You("stagger under your heavy load. Movement is very hard.");
- X break;
- X default: You("can barely move a handspan with this load!");
- X break;
- X }
- X flags.botl = 1;
- X } else if(oldcap > newcap) {
- X switch(newcap) {
- X case 0: Your("movements are now unencumbered.");
- X break;
- X case 1: Your("movements are only slowed slightly by your load.");
- X break;
- X case 2: You("rebalance your load. Movement is still difficult.");
- X break;
- X case 3: You("stagger under your load. Movement is still very hard.");
- X break;
- X }
- X flags.botl = 1;
- X }
- X
- X oldcap = newcap;
- X return (newcap);
- X}
- X
- Xint
- Xdoloot() /* loot a container on the floor. */
- X{
- X register struct obj *cobj, *nobj;
- X register int c;
- X int timepassed = 0;
- X
- X if (Levitation && !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) {
- X You("cannot reach the floor.");
- X return(0);
- X }
- X if(is_pool(u.ux, u.uy)) {
- X You("cannot loot things that are deep in the water.");
- X return(0);
- X }
- X
- X#ifdef POLYSELF
- X if(nolimbs(uasmon)) {
- X You("cannot loot things without limbs.");
- X return(0);
- X }
- X#endif
- X
- X for(cobj = level.objects[u.ux][u.uy]; cobj; cobj = nobj) {
- X nobj = cobj->nexthere;
- X
- X if(Is_container(cobj)) {
- X char qbuf[QBUFSZ];
- X
- X Sprintf(qbuf, "There is %s here, loot it?", doname(cobj));
- X c = ynq(qbuf);
- X if(c == 'q') return (timepassed);
- X if(c == 'n') continue;
- X
- X if(cobj->olocked) {
- X pline("Hmmm, it seems to be locked.");
- X continue;
- X }
- X if(cobj->otyp == BAG_OF_TRICKS) {
- X You("carefully open the bag...");
- X pline("It develops a huge set of teeth and bites you!");
- X c = rnd(10);
- X if(Half_physical_damage) c = (c+1) / 2;
- X losehp(c, "carnivorous bag", KILLED_BY_AN);
- X makeknown(BAG_OF_TRICKS);
- X timepassed = 1;
- X continue;
- X }
- X
- X You("carefully open %s...", the(xname(cobj)));
- X if (cobj->otrapped && chest_trap(cobj, FINGER, FALSE)) {
- X timepassed = 1;
- X continue; /* explosion destroyed cobj */
- X }
- X if(multi < 0) return (1); /* a paralysis trap */
- X
- X timepassed |= use_container(cobj, 0);
- X }
- X }
- X return (timepassed);
- X}
- X
- X/*
- X * Decide whether an object being placed into a magic bag will cause
- X * it to explode. If the object is a bag itself, check recursively.
- X */
- Xstatic boolean
- Xmbag_explodes(obj, depthin)
- X struct obj *obj;
- X int depthin;
- X{
- X /* odds: 1/1, 2/2, 3/4, 4/8, 5/16, 6/32, 7/64, 8/128, 9/128, 10/128,... */
- X if ((Is_mbag(obj) || (obj->otyp == WAN_CANCELLATION && obj->spe > 0)) &&
- X (rn2(1 << (depthin > 7 ? 7 : depthin)) <= depthin))
- X return TRUE;
- X else if (Is_container(obj)) {
- X struct obj *otmp;
- X
- X for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
- X if (mbag_explodes(otmp, depthin+1)) return TRUE;
- X }
- X return FALSE;
- X}
- X
- X/* A variable set in use_container(), to be used by the callback routines */
- X/* chk_bg(), in_container(), and out_container() from askchain(). */
- Xstatic struct obj NEARDATA *current_container;
- X#define Icebox (current_container->otyp == ICE_BOX)
- X
- XSTATIC_PTR int
- Xin_container(obj)
- Xregister struct obj *obj;
- X{
- X register struct obj *gold;
- X boolean is_gold = (obj->otyp == GOLD_PIECE);
- X boolean floor_container = !carried(current_container);
- X char buf[BUFSZ];
- X
- X if (!current_container) {
- X impossible("<in> no current_container?");
- X return 0;
- X } else if (obj == uball || obj == uchain) {
- X You("must be kidding.");
- X return 0;
- X } else if (obj == current_container) {
- X pline("That would be an interesting topological exercise.");
- X return 0;
- X } else if (obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)) {
- X Norep("You cannot %s something you are wearing.",
- X Icebox ? "refrigerate" : "stash");
- X return 0;
- X } else if ((obj->otyp == LOADSTONE) && obj->cursed) {
- X obj->bknown = 1;
- X pline("The stone%s won't leave your person.", plur(obj->quan));
- X return 0;
- X } else if (obj->otyp == AMULET_OF_YENDOR ||
- X obj->otyp == CANDELABRUM_OF_INVOCATION ||
- X obj->otyp == BELL_OF_OPENING ||
- X obj->otyp == SPE_BOOK_OF_THE_DEAD) {
- X /* Prohibit Amulets in containers; if you allow it, monsters can't
- X * steal them. It also becomes a pain to check to see if someone
- X * has the Amulet. Ditto for the Candelabrum, the Bell and the Book.
- X */
- X pline("%s cannot be confined in such trappings.", The(xname(obj)));
- X return 0;
- X }
- X#ifdef WALKIES
- X else if (obj->otyp == LEASH && obj->leashmon != 0) {
- X pline("%s is attached to your pet.", The(xname(obj)));
- X return 0;
- X }
- X#endif
- X else if (obj == uwep) {
- X if (welded(obj)) {
- X weldmsg(obj, FALSE);
- X return 0;
- X }
- X setuwep((struct obj *) 0);
- X if (uwep) return 0; /* unwielded, died, rewielded */
- X }
- X
- X /* boxes can't fit into any container */
- X if (obj->otyp == ICE_BOX || Is_box(obj)) {
- X /*
- X * xname() uses a static result array. Save obj's name
- X * before current_container's name is computed. Don't
- X * use the result of strcpy() within You() --- the order
- X * of evaluation of the parameters is undefined.
- X */
- X Strcpy(buf, the(xname(obj)));
- X You("cannot fit %s into %s.", buf,
- X the(xname(current_container)));
- X return 0;
- X }
- X
- X freeinv(obj);
- X
- X if (is_gold) { /* look for other gold within the container */
- X for (gold = current_container->cobj; gold; gold = gold->nobj)
- X if (gold->otyp == GOLD_PIECE) break;
- X } else
- X gold = 0;
- X
- X if (gold) {
- X gold->quan += obj->quan;
- X } else {
- X obj->nobj = current_container->cobj;
- X current_container->cobj = obj;
- X }
- X
- X current_container->owt = weight(current_container);
- X
- X Strcpy(buf, the(xname(current_container)));
- X You("put %s into %s.", doname(obj), buf);
- X
- X if (floor_container && costly_spot(u.ux, u.uy)) {
- X sellobj_state(TRUE);
- X sellobj(obj, u.ux, u.uy);
- X sellobj_state(FALSE);
- X }
- X (void) snuff_candle(obj); /* must follow the "put" msg */
- X if (Icebox && obj->otyp != OIL_LAMP && obj->otyp != BRASS_LANTERN
- X && !Is_candle(obj))
- X obj->age = monstermoves - obj->age; /* actual age */
- X
- X else if (Is_mbag(current_container) && mbag_explodes(obj, 0)) {
- X You("are blasted by a magical explosion!");
- X
- X /* the !floor_container case is taken care of */
- X if(*u.ushops && costly_spot(u.ux, u.uy) && floor_container) {
- X register struct monst *shkp;
- X
- X if ((shkp = shop_keeper(*u.ushops)) != 0)
- X (void)stolen_value(current_container, u.ux, u.uy,
- X (boolean)shkp->mpeaceful, FALSE);
- X }
- X delete_contents(current_container);
- X if (!floor_container)
- X useup(current_container);
- X else if (obj_here(current_container, u.ux, u.uy))
- X useupf(current_container);
- X else
- X panic("in_container: bag not found.");
- X
- X losehp(d(6,6),"magical explosion", KILLED_BY_AN);
- X current_container = 0; /* baggone = TRUE; */
- X }
- X
- X if (is_gold) {
- X if (gold) dealloc_obj(obj);
- X bot(); /* update character's gold piece count immediately */
- X }
- X
- X return(current_container ? 1 : -1);
- X}
- X
- XSTATIC_PTR int
- Xck_bag(obj)
- Xstruct obj *obj;
- X{
- X return current_container && obj != current_container;
- X}
- X
- XSTATIC_PTR int
- Xout_container(obj)
- Xregister struct obj *obj;
- X{
- X register struct obj *otmp, *ootmp;
- X boolean is_gold = (obj->otyp == GOLD_PIECE);
- X int loadlev;
- X long quan;
- X
- X if (!current_container) {
- X impossible("<out> no current_container?");
- X return -1;
- X } else if (is_gold) {
- X obj->owt = weight(obj);
- X } else if (inv_cnt() >= 52) {
- X You("have no room to hold anything else.");
- X return -1; /* skips gold too; oh well */
- X }
- X
- X if(obj->oartifact && !touch_artifact(obj,&youmonst)) return 0;
- X
- X if(obj->otyp != LOADSTONE && max_capacity() + (int)obj->owt -
- X (carried(current_container) ?
- X (current_container->otyp == BAG_OF_HOLDING ?
- X (int)DELTA_CWT(current_container,obj) : (int)obj->owt) : 0) > 0) {
- X char buf[BUFSZ];
- X
- X Strcpy(buf, doname(obj));
- X pline("There %s %s in %s, but %s.",
- X obj->quan==1 ? "is" : "are",
- X buf, the(xname(current_container)),
- X invent ? "you cannot carry any more"
- X : "it is too heavy for you to carry");
- X /* "too heavy for you to lift" is not right if you're carrying
- X the container... */
- X return(0);
- X }
- X /* Remove the object from the list. */
- X if (obj == current_container->cobj)
- X current_container->cobj = obj->nobj;
- X else {
- X for(otmp = current_container->cobj; otmp->nobj != obj;
- X otmp = otmp->nobj)
- X if(!otmp->nobj) panic("out_container");
- X otmp->nobj = obj->nobj;
- X }
- X
- X current_container->owt = weight(current_container);
- X
- X if (Icebox && obj->otyp != OIL_LAMP && obj->otyp != BRASS_LANTERN
- X && !Is_candle(obj))
- X obj->age = monstermoves - obj->age;
- X /* simulated point of time */
- X
- X if(!obj->unpaid && !carried(current_container) &&
- X costly_spot(current_container->ox, current_container->oy)) {
- X
- X addtobill(obj, FALSE, FALSE, FALSE);
- X }
- X
- X quan = obj->quan;
- X ootmp = addinv(obj);
- X loadlev = near_capacity();
- X prinv(loadlev ?
- X (loadlev < MOD_ENCUMBER ?
- X "You have a little trouble removing" :
- X "You have much trouble removing") : NULL,
- X ootmp, quan);
- X
- X if (is_gold) {
- X dealloc_obj(obj);
- X bot(); /* update character's gold piece count immediately */
- X }
- X return 1;
- X}
- X
- X/* for getobj: allow counts, allow all types, expect food */
- Xstatic const char NEARDATA frozen_food[] =
- X { ALLOW_COUNT, ALL_CLASSES, FOOD_CLASS, 0 };
- X
- Xint
- Xuse_container(obj, held)
- Xregister struct obj *obj;
- Xregister int held;
- X{
- X register int cnt = 0;
- X register struct obj *curr, *prev, *otmp;
- X boolean one_by_one, allflag;
- X char select[MAXOCLASSES+1];
- X char qbuf[QBUFSZ];
- X int used = 0, lcnt = 0;
- X long loss = 0L;
- X register struct monst *shkp;
- X
- X current_container = obj; /* for use by in/out_container */
- X if (current_container->olocked) {
- X pline("%s seems to be locked.", The(xname(current_container)));
- X if (held) You("must put it down to unlock.");
- X return 0;
- X }
- X /* Count the number of contained objects. Sometimes toss objects if */
- X /* a cursed magic bag. */
- X for(curr = obj->cobj, prev = (struct obj *) 0; curr;
- X prev = curr, curr = otmp) {
- X otmp = curr->nobj;
- X if (Is_mbag(obj) && obj->cursed && !rn2(13)) {
- X if (curr->known)
- X pline("%s to have vanished!", The(aobjnam(curr,"seem")));
- X else
- X You("%s %s disappear.", Blind ? "notice" : "see",
- X doname(curr));
- X if (prev)
- X prev->nobj = otmp;
- X else
- X obj->cobj = otmp;
- X
- X if(*u.ushops && (shkp = shop_keeper(*u.ushops))) {
- X if(held) {
- X if(curr->unpaid)
- X loss += stolen_value(curr, u.ux, u.uy,
- X (boolean)shkp->mpeaceful, TRUE);
- X lcnt++;
- X } else if(costly_spot(u.ux, u.uy)) {
- X loss += stolen_value(curr, u.ux, u.uy,
- X (boolean)shkp->mpeaceful, TRUE);
- X lcnt++;
- X }
- X }
- X /* obfree() will free all contained objects */
- X obfree(curr, (struct obj *) 0);
- X } else
- X cnt++;
- X }
- X
- X if (cnt && loss)
- X You("owe %ld zorkmids for lost item%s.",
- X loss, lcnt > 1 ? "s" : "");
- X
- X current_container->owt = weight(current_container);
- X
- X if(!cnt)
- X pline("%s %s is empty.", (held) ? "Your" : "The", xname(obj));
- X else {
- X Sprintf(qbuf, "Do you want to take something out of %s?",
- X the(xname(obj)));
- Xask_again:
- X switch (yn_function(qbuf, ":ynq", 'n')) {
- X case ':':
- X container_contents(current_container, FALSE, FALSE);
- X goto ask_again;
- X case 'y':
- X if (query_classes(select, &one_by_one, &allflag, "take out",
- X current_container->cobj, FALSE, FALSE)) {
- X if (askchain((struct obj **)¤t_container->cobj,
- X (one_by_one ? (char *)0 : select), allflag,
- X out_container, (int (*)())0, 0, "nodot"))
- X used = 1;
- X }
- X /*FALLTHRU*/
- X case 'n':
- X break;
- X case 'q':
- X default:
- X return 0;
- X }
- X }
- X
- X if (!invent && (u.ugold == 0 || Icebox)) return used;
- X if (yn_function("Do you wish to put something in?", ynqchars, 'n')
- X != 'y') return used;
- X if (Icebox && current_container->dknown) {
- X otmp = getobj(frozen_food, "put in");
- X if(!otmp || !in_container(otmp))
- X flags.move = multi = 0;
- X } else {
- X if (query_classes(select, &one_by_one, &allflag, "put in",
- X invent, FALSE, (u.ugold != 0L))) {
- X struct obj *u_gold = (struct obj *)0;
- X if (u.ugold && (one_by_one || (allflag && !*select)
- X || index(select, GOLD_CLASS))) {
- X /* make gold object & insert at head of inventory */
- X u_gold = mkgoldobj(u.ugold); /*(removes gold too)*/
- X u.ugold = u_gold->quan; /* put the gold back */
- X u_gold->nobj = invent;
- X invent = u_gold;
- X }
- X used = (askchain((struct obj **)&invent,
- X (one_by_one ? (char *)0 : select), allflag,
- X in_container, ck_bag, 0, "nodot") > 0);
- X if (u_gold && invent && invent->otyp == GOLD_PIECE) {
- X /* didn't stash [all of] it */
- X u_gold = invent;
- X invent = u_gold->nobj;
- X dealloc_obj(u_gold);
- X }
- X }
- X }
- X
- X return used;
- X}
- X
- X/*pickup.c*/
- END_OF_FILE
- if test 26706 -ne `wc -c <'src/pickup.c'`; then
- echo shar: \"'src/pickup.c'\" unpacked with wrong size!
- fi
- # end of 'src/pickup.c'
- fi
- echo shar: End of archive 80 \(of 108\).
- cp /dev/null ark80isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
- 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
- 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
- 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
- 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
- 101 102 103 104 105 106 107 108 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 108 archives.
- echo "Now execute 'rebuild.sh'"
- rm -f ark10[0-8]isdone 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
-