home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!zephyr.ens.tek.com!tekred!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v09i081: umoria3 - single player dungeon simulation (ver. 5.2), Part26/31
- Message-ID: <5616@tekred.CNA.TEK.COM>
- Date: 17 May 90 16:29:21 GMT
- Sender: news@tekred.CNA.TEK.COM
- Lines: 1970
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: wilson@ernie.Berkeley.EDU (Jim Wilson)
- Posting-number: Volume 9, Issue 81
- Archive-name: umoria3/Part26
- Supersedes: umoria2: Volume 5, Issue 32-37,41-52,87
-
-
-
- #! /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 26 (of 31)."
- # Contents: ibmpc/CONFIG.DOC ibmpc/ms_misc.c mac/dumpres/MakeFile.hqx
- # source/main.c util/showmon.c util/weapons/README
- # Wrapped by billr@saab on Wed May 16 11:54:43 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'ibmpc/CONFIG.DOC' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ibmpc/CONFIG.DOC'\"
- else
- echo shar: Extracting \"'ibmpc/CONFIG.DOC'\" \(10789 characters\)
- sed "s/^X//" >'ibmpc/CONFIG.DOC' <<'END_OF_FILE'
- X
- X The Dungeons of MORIA version 4.872
- X COPYRIGHT (c) Robert Alan Koeneke
- X
- X MSDOS port by D. G. Kneller
- X Nov 1, 1988
- X
- X
- X
- X
- X
- X
- XTable of contents
- X1. USAGE ............................................................. 1
- X2. REQUIREMENTS ...................................................... 1
- X3. INSTALLATION ...................................................... 1
- X3.1. Hard drive systems .............................................. 1
- X3.2. High-density floppy systems ..................................... 2
- X3.3. 2 - 360K floppy systems ......................................... 2
- X4. OPTIONS ........................................................... 2
- X4.1. SAVE ............................................................ 2
- X4.2. SCORE ........................................................... 3
- X4.3. KEYBOARD ........................................................ 3
- X4.4. GRAPHICS ........................................................ 3
- X4.5. RAWIO ........................................................... 3
- X4.6. IBMBIOS ......................................................... 3
- X4.7. ANSI ............................................................ 4
- X5. ENVIRONMENT VARIABLES ............................................. 5
- X6. BUGS .............................................................. 5
- X7. AUTHOR'S ADDRESS .................................................. 5
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X - i -
- X
- X
- X
- X
- XINTRODUCTION
- X
- XThis README file describes the requirements and setup necessary to get
- XMORIA running on your MSDOS computer. The actual game documentation is
- Xin MORIA.DOC. Some of the game documentation will be wrong if you
- Xchoose the Rogue-like command set.
- X
- X
- X1. USAGE
- X
- X Usage: moria [ -nors ] [ savefile ]
- X
- X Where: -n starts a new game, ignoring any existing save files.
- X -o selects the original (VMS) command set.
- X -r selects the Rogue-like command set.
- X -s prints the score file and exits.
- X
- X2. REQUIREMENTS
- X
- X 640K ram (really!)
- X DOS 2.x or higher
- X 2 - 360K floppy disk drives or 1 high density drive or 1 hard drive
- X A 24 (or 25) line by 80 column monitor. MORIA uses either BIOS calls
- X or ANSI for video output so should work properly on most monitors.
- X It must use ANSI to work on DEC Rainbows. It won't work in 43-line mode
- X of an EGA.
- X
- X
- X3. INSTALLATION
- X
- XMORIA is very easy to configure. The biggest problem is that there is
- Xnot enough room on a single 360K floppy disk to hold the DOS system
- Xfiles, MORIA.EXE (about 340K) and a MORIA save file (about 80K or so).
- XTo install MORIA, some files must be copied and 2 options in MORIA.CNF
- Xmust be set. Options and the MORIA.CNF are described more fully in the
- Xsection entitled OPTIONS. Here are a few methods of configuration.
- XThese methods are also described in the MORIA.CNF file.
- X
- X
- X3.1. Hard drive systems
- X
- XCreate a c:\games subdirectory on your hard disk and put c:\games on
- Xyour PATH (see the DOS manual if you need help with PATH). Copy
- XMORIA.EXE and MORIA.CNF to c:\games. Edit MORIA.CNF and put in the
- Xoptions:
- X
- X SAVE c:\games\moria.sav;n
- X SCORE c:\games\moria.scr
- X
- X
- X
- X
- X
- X
- X - 1 -
- X
- X3.2. High-density floppy systems
- X
- XThis is about as easy as for a hard disk. Format a diskette and put the
- XDOS system files on it (use FORMAT A:/S). Copy MORIA.EXE and MORIA.CNF
- Xto that diskette. Edit MORIA.CNF and put in the options:
- X
- X SAVE a:\moria.sav
- X SCORE a:\moria.scr
- X
- X
- X
- X3.3. 2 - 360K floppy systems
- X
- XYou will need to use 2 floppy diskettes. Format a diskette and put the
- XDOS system files on it (use FORMAT A:/S). Copy MORIA.CNF to this
- Xdiskette. This diskette will go in drive A when you want to play MORIA.
- XFormat a second diskette (no /S) and copy MORIA.EXE to it. This
- Xdiskette will go in drive B. Edit MORIA.CNF and put in the options:
- X
- X SAVE a:moria.sav
- X SCORE a:moria.scr
- X
- X
- XWhen you want to play MORIA, put both diskettes in and type "B:MORIA"
- X
- X
- X
- X4. OPTIONS
- X
- XWhen MORIA starts up it looks along your PATH for the file "MORIA.CNF".
- XMORIA.CNF contains configuration information for MORIA in the form of
- Xoptions. Options have a name and perhaps a value. If the option
- Xdoesn't have a value, simply mentioning its name selects that option.
- XHere are the options.
- X
- X4.1. SAVE
- X
- XThe SAVE option has 1 argument, the name of a file where saved games
- Xwill be stored. Normally, when you start MORIA by typing "MORIA file",
- XMORIA will try to use "file" as the name of a saved game. The SAVE
- Xoption allows you to give the name of the save file so you don't have to
- Xtype it in each time you save or restore a game. A sample SAVE option
- Xis:
- X
- X SAVE c:\games\moria.sav;n
- X
- X
- XThe ";n" is optional. If given it means that MORIA should never prompt
- Xyou for the name of the save file. If the SAVE option isn't given,
- XMORIA defaults to the file MORIA.SAV in the same directory as MORIA.CNF.
- XAlso, the SAVE option can be just ";n", which means use the default name
- Xwithout prompting.
- X
- X
- X
- X
- X
- X - 2 -
- X
- X4.2. SCORE
- X
- XThe SCORE option has 1 argument, the name of the file where the top
- Xscores are kept. A sample SCORE option is:
- X
- X SCORE c:\games\moria.scr
- X
- X
- XIf the SCORE option isn't given, MORIA defaults to the file MORIA.SCR in
- Xthe same directory as MORIA.CNF.
- X
- X
- X4.3. KEYBOARD
- X
- XMORIA can be played with either of 2 styles of commands. There is the
- Xoriginal VMS-style commands and a Rogue-style set of commands. The
- Xchoice of command set affects the keyboard letters used for doing the
- Xvarious game commands. The KEYBOARD value can be either "ROGUE" or
- X"VMS". The default is to use the original VMS-style commands.
- X
- X
- X4.4. GRAPHICS
- X
- XThe GRAPHICS option takes 2 arguments, the ASCII number for the
- Xcharacter to be used for displaying the walls and floors. For example,
- Xto use '#' for the walls and '.' for the floors, the GRAPHICS option
- Xwould be:
- X
- X GRAPHICS 35 46
- X
- X
- XIncidentally, these also are the default characters that are used if the
- XGRAPHICS option is not specified.
- X
- X
- X4.5. RAWIO
- X
- XNormally DOS does some extra work whenever a character is input from the
- Xkeyboard. One of the tasks is to interpret the special characters ^S
- X(control-S, which does a scroll lock) ^C (control-C, which acts like
- Xcontrol-Break) and ^P (control-P, which acts like control-PrtSc,
- Xtoggling output to your printer or giving an error message if you don't
- Xhave one). The RAWIO option will be used to tell DOS to not do this
- Xextra work by making the input (and output) operate in "raw" mode. This
- Xis good because ^P (a MORIA command) will now work. As well, screen
- Xoutput will be somewhat faster.
- X
- XURGENT! RAWIO will not work on Dec Rainbows and will probably lock up
- Xthe computer.
- X
- X
- X4.6. IBMBIOS
- X
- XIBMBIOS enables the use of a BIOS call to read input from the keyboard.
- X
- X
- X
- X - 3 -
- X
- XThe advantage of this is that the numeric keypad will then be useable as
- Xdirection keys for moving around. With this option the keypad keys map
- Xto the directions:
- X
- X 7 up & left 8 up 9 up & right
- X 4 left 5 nothing 6 right
- X 1 down & left 2 down 3 down & right
- X
- X And other keypad keys map to:
- X
- X - rest
- X + previous message
- X Ins inventory Del rest
- X
- X
- XIf you are using the Rogue-style command set, the shift key and NumLock
- Xkey modify these commands. With the shift key down, 7 will be "run up
- Xand left", 8 will be "run up", etc. The NumLock key is used as a toggle
- Xbetween moving and tunneling. With NumLock enabled, 7 will be "tunnel up
- Xand left", etc.
- X
- X
- X4.7. ANSI
- X
- XThe ANSI option tells MORIA to use ANSI sequences rather than using BIOS
- Xcalls for doing output. You must use the ANSI option if you are playing
- XMORIA on a DEC Rainbow. On IBM PCs, ATs and clones there should be no
- Xneed to use this option and you can safely ignore the rest of this
- Xsection.
- X
- XThe ANSI option takes three optional arguments: check_ansi, move_opt and
- Xuse_tgoto. If no arguments aren't given, they are assumed to be Y (yes),
- XY and N (no), respectively. The usage is
- X
- X ANSI [ check_ansi [ move_opt [ use_tgoto ] ] ]
- X
- XAn example is:
- X
- X ANSI Y N
- X
- Xcheck_ansi tells MORIA to check for ANSI.SYS when starting up. You may have
- Xto disable this check if MORIA insists you don't have ANSI installed, but you
- Xknow you do. move_opt tries to reduce the amount of output being sent to the
- Xscreen. use_tgoto tells MORIA to use the actual TERMCAP tgoto() routine. The
- Xdefault is to use a faster routine which only works for ANSI-like terminals.
- X
- XWhen the ANSI option is chosen, MORIA looks for ANSI control strings in
- Xa file called TERMCAP, first in the current directory, then in directory
- XETC. A sample TERMCAP file is supplied. Basically, this file maps
- Xbetween logical cursor operations (eg. "cursor up") to ANSI sequences
- X(eg ESC [ A). In the file, ESC (escape) is represented as \E. MORIA
- Xuses the following logical operations:
- X
- X
- X
- X
- X
- X - 4 -
- X
- X ce clear to end of line
- X cl clear screen
- X cm cursor motion (only if use_tgoto is chosen)
- X nd cursor forward (non-destructive space)
- X bc cursor back
- X up cursor up
- X xd cursor down
- X li number of lines on the screen
- X
- XMORIA can also use:
- X
- X ti terminal initialization string
- X te terminal end string
- X
- X
- X5. ENVIRONMENT VARIABLES
- X
- XMORIA uses the environment variable USER to determine your real name (as
- Xopposed to your role playing name in the game). The USER environment
- Xvariable can be set from DOS with:
- X
- X set USER = kneller
- X
- XIf the USER variable isn't set, MORIA just uses the name "player".
- X
- XIf the ANSI option is chosen, MORIA uses the variable TERM to determine
- Xthe terminal information to extract from the TERMCAP file. If the TERM
- Xvariable isn't set, MORIA assumes the value "ibmpc-mono".
- X
- X
- X
- X6. BUGS
- X
- XI have not played this game much so there may be bugs which I have not
- Xseen yet. Please report them to me so I can fix them.
- X
- X
- X7. AUTHOR'S ADDRESS
- X
- XIf you have any questions or bug reports please contact me at:
- X
- X D. G. Kneller
- X 1349 10th avenue
- X San Francisco, CA 94122
- X USA
- X
- X or by electronic mail at:
- X
- X ARPA: kneller@cgl.ucsf.edu
- X BITNET: kneller@ucsfcgl.bitnet
- X UUCP: ...ucbvax!ucsfcgl!kneller
- X
- X
- X
- X
- X
- X
- X - 5 -
- X
- END_OF_FILE
- if test 10789 -ne `wc -c <'ibmpc/CONFIG.DOC'`; then
- echo shar: \"'ibmpc/CONFIG.DOC'\" unpacked with wrong size!
- fi
- # end of 'ibmpc/CONFIG.DOC'
- fi
- if test -f 'ibmpc/ms_misc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ibmpc/ms_misc.c'\"
- else
- echo shar: Extracting \"'ibmpc/ms_misc.c'\" \(10270 characters\)
- sed "s/^X//" >'ibmpc/ms_misc.c' <<'END_OF_FILE'
- X/* ms_misc.c: MSDOS dependant code
- X
- X Copyright (c) 1989 James E. Wilson, Don Kneller
- X
- X This software may be copied and distributed for educational, research, and
- X not for profit purposes provided that this copyright and statement are
- X included in all such copies. */
- X
- X#ifdef MSDOS
- X#include <curses.h>
- X#ifdef ANSI
- X#include "ms_ansi.h"
- X#endif
- X#include <string.h>
- X#include <ctype.h>
- X#include <time.h>
- X#include <fcntl.h>
- X#include <stdio.h>
- X#include "config.h"
- X#include "constant.h"
- X#include "types.h"
- X#include "externs.h"
- X
- X#ifdef LINT_ARGS
- Xvoid exit(int);
- Xstatic unsigned int ioctl(int ,int ,unsigned int );
- Xstatic FILE *fopenp(char *, char *, char *);
- X#else
- Xvoid exit();
- Xstatic unsigned int ioctl();
- X#endif
- X
- X#define PATHLEN 80
- Xchar moriatop[PATHLEN];
- Xchar moriasav[PATHLEN];
- Xint saveprompt = TRUE;
- Xint ibmbios;
- Xstatic int rawio;
- Xint8u floorsym = '.';
- Xint8u wallsym = '#';
- X
- X/* UNIX compatability routines */
- Xvoid user_name(buf)
- Xchar *buf;
- X{
- X strcpy(buf, getlogin());
- X}
- X
- Xchar *
- Xgetlogin()
- X{
- X char *cp;
- X char *getenv();
- X
- X if ((cp = getenv("USER")) == NULL)
- X cp = "player";
- X return cp;
- X}
- X
- Xunsigned int
- Xsleep(secs)
- Xint secs;
- X{
- X time_t finish_time;
- X
- X finish_time = time((long *) NULL) + secs;
- X while (time((long *) NULL) < finish_time)
- X /* nothing */;
- X return 0;
- X}
- X
- Xvoid
- Xerror(fmt, a1, a2, a3, a4)
- Xchar *fmt;
- Xint a1, a2, a3, a4;
- X{
- X fprintf(stderr, "MORIA error: ");
- X fprintf(stderr, fmt, a1, a2, a3, a4);
- X (void) sleep(2);
- X exit(1);
- X}
- X
- Xvoid
- Xwarn(fmt, a1, a2, a3, a4)
- Xchar *fmt;
- Xint a1, a2, a3, a4;
- X{
- X fprintf(stderr, "MORIA warning: ");
- X fprintf(stderr, fmt, a1, a2, a3, a4);
- X (void) sleep(2);
- X}
- X
- X/* Search the path for a file of name "name". The directory is
- X * filled in with the directory part of the path.
- X */
- Xstatic FILE *
- Xfopenp(name, mode, directory)
- Xchar *name, *mode, directory[];
- X{
- X char *dp, *pathp, *getenv(), lastch;
- X FILE *fp;
- X
- X /* Try the default directory first. If the file can't be opened,
- X * start looking along the path.
- X */
- X if (fp = fopen(name, mode)) {
- X directory[0] = '\0';
- X return fp;
- X }
- X pathp = getenv("PATH");
- X while (pathp && *pathp) {
- X dp = directory;
- X while (*pathp && *pathp != ';')
- X lastch = *dp++ = *pathp++;
- X if (lastch != '\\' && lastch != '/' && lastch != ':')
- X *dp++ = '\\';
- X (void) strcpy(dp, name);
- X if (fp = fopen(directory, mode)) {
- X *dp = '\0';
- X return fp;
- X }
- X if (*pathp)
- X pathp++;
- X }
- X directory[0] = '\0';
- X return NULL;
- X}
- X
- X/* Read the configuration.
- X */
- Xvoid
- Xmsdos_init()
- X{
- X char buf[BUFSIZ], *bp, opt[PATHLEN];
- X int arg1, arg2, cnt;
- X FILE *fp;
- X
- X buf[0] = '\0';
- X bp = MORIA_CNF_NAME;
- X fp = fopenp(bp, "r", buf);
- X (void) strcpy(moriatop, buf);
- X (void) strcat(moriatop, MORIA_TOP_NAME);
- X (void) strcpy(moriasav, buf);
- X (void) strcat(moriasav, MORIA_SAV_NAME);
- X if (fp == NULL) {
- X warn("Can't find configuration file `%s'\n", bp);
- X return;
- X }
- X printf("Reading configuration from %s%s\n", buf, bp);
- X (void) sleep(1);
- X while (fgets(buf, sizeof buf, fp)) {
- X if (*buf == '#')
- X continue;
- X
- X cnt = sscanf(buf, "%s", opt);
- X if (cnt == 0 || opt[0] == '\0')
- X continue;
- X
- X /* Go through possible variables
- X */
- X if (strcmpi(opt, "GRAPHICS") == 0) {
- X cnt = sscanf(buf, "%*s%d%d\n", &arg1, &arg2);
- X if (cnt != 2)
- X warn("GRAPHICS did not contain 2 values\n");
- X else {
- X int i;
- X
- X wallsym = (int8u) arg1;
- X floorsym = (int8u) arg2;
- X
- X /* Adjust lists that depend on '#' and '.' */
- X object_list[OBJ_SECRET_DOOR].tchar = wallsym;
- X }
- X }
- X else if (strcmpi(opt, "SAVE") == 0) {
- X cnt = sscanf(buf, "%*s%s", opt);
- X if (cnt == 0)
- X warn("SAVE option requires a filename\n");
- X else {
- X if (bp = strchr(opt, ';')) {
- X *bp++ = '\0';
- X if (*bp == 'n' || *bp == 'N')
- X saveprompt = FALSE;
- X }
- X if (opt[0])
- X (void) strcpy(moriasav, opt);
- X }
- X }
- X else if (strcmpi(opt, "SCORE") == 0) {
- X cnt = sscanf(buf, "%*s%s", opt);
- X if (cnt == 0)
- X warn("SCORE option requires a filename\n");
- X else
- X (void) strcpy(moriatop, opt);
- X }
- X else if (strcmpi(opt, "KEYBOARD") == 0) {
- X cnt = sscanf(buf, "%*s%s", opt);
- X if (cnt == 0)
- X warn("KEYBOARD option requires a value\n");
- X else if (strcmpi(opt, "ROGUE") == 0)
- X rogue_like_commands = TRUE;
- X else if (strcmpi(opt, "VMS") == 0)
- X rogue_like_commands = FALSE;
- X }
- X else if (strcmpi(opt, "IBMBIOS") == 0)
- X ibmbios = TRUE;
- X else if (strcmpi(opt, "RAWIO") == 0)
- X rawio = TRUE;
- X#ifdef ANSI
- X /* Usage: ANSI [ check_ansi [ domoveopt [ tgoto ] ] ]
- X * where check_ansi and domoveopt are "Y"es unless explicitly
- X * set to "N"o. Tgoto is "N"o unless set to "Y"es.
- X */
- X else if (strcmpi(opt, "ANSI") == 0) {
- X cnt=sscanf(buf, "%*s%1s%1s%1s",&opt[0],&opt[1],&opt[2]);
- X ansi_prep(cnt < 1 || opt[0] == 'y' || opt[0] == 'Y',
- X cnt < 2 || opt[1] == 'y' || opt[1] == 'Y',
- X cnt >= 3 && (opt[2] == 'y' || opt[2] == 'Y'));
- X }
- X#endif
- X else
- X warn("Unknown configuration line: `%s'\n", buf);
- X }
- X fclose(fp);
- X
- X /* The only text file has been read. Switch to binary mode */
- X}
- X
- X#include <dos.h>
- X#define DEVICE 0x80
- X#define RAW 0x20
- X#define IOCTL 0x44
- X#define STDIN fileno(stdin)
- X#define STDOUT fileno(stdout)
- X#define GETBITS 0
- X#define SETBITS 1
- X
- Xstatic unsigned old_stdin, old_stdout, ioctl();
- X
- Xvoid
- Xmsdos_raw() {
- X if (!rawio)
- X return;
- X old_stdin = ioctl(STDIN, GETBITS, 0);
- X old_stdout = ioctl(STDOUT, GETBITS, 0);
- X if (old_stdin & DEVICE)
- X ioctl(STDIN, SETBITS, old_stdin | RAW);
- X if (old_stdout & DEVICE)
- X ioctl(STDOUT, SETBITS, old_stdout | RAW);
- X}
- X
- Xvoid
- Xmsdos_noraw() {
- X if (!rawio)
- X return;
- X if (old_stdin)
- X (void) ioctl(STDIN, SETBITS, old_stdin);
- X if (old_stdout)
- X (void) ioctl(STDOUT, SETBITS, old_stdout);
- X}
- X
- Xstatic unsigned int
- Xioctl(handle, mode, setvalue)
- Xunsigned int setvalue;
- X{
- X union REGS regs;
- X
- X regs.h.ah = IOCTL;
- X regs.h.al = (unsigned char) mode;
- X regs.x.bx = handle;
- X regs.h.dl = (unsigned char) setvalue;
- X regs.h.dh = 0; /* Zero out dh */
- X intdos(®s, ®s);
- X return (regs.x.dx);
- X}
- X
- X/* Normal characters are output when the shift key is not pushed.
- X * Shift characters are output when either shift key is pushed.
- X */
- X#define KEYPADHI 83
- X#define KEYPADLOW 71
- X#define ISKEYPAD(x) (KEYPADLOW <= (x) && (x) <= KEYPADHI)
- X#undef CTRL
- X#define CTRL(x) (x - '@')
- Xtypedef struct {
- X char normal, shift, numlock;
- X} KEY;
- Xstatic KEY roguekeypad[KEYPADHI - KEYPADLOW + 1] = {
- X {'y', 'Y', CTRL('Y')}, /* 7 */
- X {'k', 'K', CTRL('K')}, /* 8 */
- X {'u', 'U', CTRL('U')}, /* 9 */
- X {'.', '.', '.'}, /* - */
- X {'h', 'H', CTRL('H')}, /* 4 */
- X {'.', '.', '.'}, /* 5 */
- X {'l', 'L', CTRL('L')}, /* 6 */
- X {CTRL('P'), CTRL('P'), CTRL('P')}, /* + */
- X {'b', 'B', CTRL('B')}, /* 1 */
- X {'j', 'J', CTRL('J')}, /* 2 */
- X {'n', 'N', CTRL('N')}, /* 3 */
- X {'i', 'i', 'i'}, /* Ins */
- X {'.', '.', '.'} /* Del */
- X};
- Xstatic KEY originalkeypad[KEYPADHI - KEYPADLOW + 1] = {
- X {'7', '7', '7'}, /* 7 */
- X {'8', '8', '8'}, /* 8 */
- X {'9', '9', '9'}, /* 9 */
- X {'-', '-', '-'}, /* - */
- X {'4', '4', '4'}, /* 4 */
- X {'5', '5', '5'}, /* 5 - move */
- X {'6', '6', '6'}, /* 6 */
- X {CTRL('M'), CTRL('M'), CTRL('M')}, /* + */
- X {'1', '1', '1'}, /* 1 */
- X {'2', '2', '2'}, /* 2 */
- X {'3', '3', '3'}, /* 3 */
- X {'i', 'i', 'i'}, /* Ins */
- X {'.', '.', '.'} /* Del */
- X};
- X
- X/* bios_getch gets keys directly with a BIOS call.
- X */
- X#define SHIFT (0x1 | 0x2)
- X#define NUMLOCK 0x20
- X#define KEYBRD_BIOS 0x16
- X
- Xint
- Xbios_getch()
- X{
- X unsigned char scan, shift;
- X int ch;
- X KEY *kp;
- X union REGS regs;
- X
- X if (rogue_like_commands)
- X kp = roguekeypad;
- X else
- X kp = originalkeypad;
- X
- X /* Get scan code.
- X */
- X regs.h.ah = 0;
- X int86(KEYBRD_BIOS, ®s, ®s);
- X ch = regs.h.al;
- X scan = regs.h.ah;
- X
- X /* Get shift status.
- X */
- X regs.h.ah = 2;
- X int86(KEYBRD_BIOS, ®s, ®s);
- X shift = regs.h.al;
- X
- X /* If scan code is for the keypad, translate it.
- X */
- X if (ISKEYPAD(scan)) {
- X if (shift & NUMLOCK)
- X ch = kp[scan - KEYPADLOW].numlock;
- X else if (shift & SHIFT)
- X ch = kp[scan - KEYPADLOW].shift;
- X else
- X ch = kp[scan - KEYPADLOW].normal;
- X }
- X return ch;
- X}
- X
- Xint
- Xmsdos_getch()
- X{
- X int ch;
- X
- X if (ibmbios)
- X ch = bios_getch();
- X else {
- X ch = getch();
- X if (ch == 0)
- X ch = getch();
- X }
- X return ch;
- X}
- X
- X/* Hardcode the introductory message in */
- Xvoid
- Xmsdos_intro()
- X{
- X char buf[80];
- X
- X clear_screen(0, 0);
- X wmove(stdscr,0,0);
- X waddstr(stdscr," *********************");
- X wmove(stdscr,1,0);
- X sprintf(buf," ** Moria %d.%d **",
- X CUR_VERSION_MAJ, CUR_VERSION_MIN);
- X waddstr(stdscr,buf);
- X wmove(stdscr,2,0);
- X waddstr(stdscr," *********************");
- X wmove(stdscr,3,0);
- X waddstr(stdscr," COPYRIGHT (c) Robert Alan Koeneke");
- X wmove(stdscr,5,0);
- X waddstr(stdscr,"Programmers : Robert Alan Koeneke / University of Oklahoma");
- X wmove(stdscr,6,0);
- X waddstr(stdscr," Jimmey Wayne Todd / University of Oklahoma");
- X wmove(stdscr,8,0);
- X waddstr(stdscr,"UNIX Port : James E. Wilson / UC Berkeley");
- X wmove(stdscr,10,0);
- X waddstr(stdscr,"MSDOS Port : Don Kneller / 1349 - 10th ave");
- X wmove(stdscr,11,0);
- X waddstr(stdscr," / San Francisco, CA 94122");
- X wmove(stdscr,12,0);
- X waddstr(stdscr," / Dec 12, 1988");
- X pause_line(23);
- X}
- X
- X#ifdef PC_CURSES
- X/* Seems to be a bug in PCcurses whereby it won't really clear the screen
- X * if there are characters there it doesn't know about.
- X */
- X#define VIDEOINT 0x10
- Xvoid
- Xbios_clear()
- X{
- X union REGS regs;
- X unsigned char nocols, activepage;
- X
- X#ifdef ANSI
- X if (ansi)
- X return;
- X#endif
- X
- X /* get video attributes */
- X regs.h.ah = 15;
- X int86(VIDEOINT, ®s, ®s);
- X nocols = regs.h.ah;
- X activepage = regs.h.bh;
- X
- X /* Move to lower right corner */
- X regs.h.ah = 2;
- X regs.h.dh = (unsigned char) 24;
- X regs.h.dl = nocols - 1; /* lower right col */
- X regs.h.bh = activepage;
- X int86(VIDEOINT, ®s, ®s);
- X
- X /* get current attribute into bh */
- X regs.h.ah = 8;
- X regs.h.bh = activepage;
- X int86(VIDEOINT, ®s, ®s);
- X regs.h.bh = regs.h.ah;
- X
- X regs.h.cl = 0; /* upper left row */
- X regs.h.ch = 0; /* upper left col */
- X regs.h.dh = (unsigned char) 24; /* lower right row */
- X regs.h.dl = nocols - 1; /* lower right col */
- X regs.h.al = 0; /* clear window */
- X regs.h.ah = 7; /* scroll down */
- X int86(VIDEOINT, ®s, ®s);
- X}
- X#endif
- X
- X#endif
- END_OF_FILE
- if test 10270 -ne `wc -c <'ibmpc/ms_misc.c'`; then
- echo shar: \"'ibmpc/ms_misc.c'\" unpacked with wrong size!
- fi
- # end of 'ibmpc/ms_misc.c'
- fi
- if test -f 'mac/dumpres/MakeFile.hqx' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mac/dumpres/MakeFile.hqx'\"
- else
- echo shar: Extracting \"'mac/dumpres/MakeFile.hqx'\" \(1455 characters\)
- sed "s/^X//" >'mac/dumpres/MakeFile.hqx' <<'END_OF_FILE'
- X(This file must be converted with BinHex 4.0)
- X:$8eKDf9'D@aP,Q4eEA!!9%9B9%e38b!"!!!!!QS!!!&qfZp$6h"dD@pZFb!p)#e
- XYBQFJEfi06%p`G'P[ER-J23d04(9YF&*PFbj[)-3J4(9YF&*PFbjM$3P$)(Y$6h"
- XdD@pZFhdJ,@mJ4(9YF&*PFbj[)%4eEA"5CA-ZB`d04(9YF&*PFe4PFh3ZBbj[)-3
- XJ4(9YF&*PFe4PFh3ZB`d*3b"l3dp`G'P[ER0p)%4eEA"5CA08CA0d,Q-0#3e2BQT
- XPBh4c)$dJ4(9YF&*PFe4PFh3ZBbj[)%4eEA"5CA-ZE`d04(9YF&*PFe4PFh3Ja-3
- XJHdpLDQ9MG(0p$3P-D@jV)(Y-6h"dD@pZFhdJ,AFJ,@-J*de38b!R)#ed)%e38e3
- XJYJd*#AY2BQTPBh4cI5#f$3N*)RY-D@*bBA*TCA0p)R0dG@*c,QmJYJd*#5*l3da
- XTBR*KFQPPFhdL3e*eER4TE@8ZEb#f$3N*)RY-D@*bBA*TCA0p)NPZG'9bCQ&MC5j
- X[),B0#3NLHd0-D@*bBA*TCA0p)P0dC%0-D@)ZEb#f$3N*)RY$6'PLFQ&bD@9cI5*
- X$8d&148aTBLj[),B0#3NLHd0-D@*bBA*TCA0p)NeKG'JZEb#f$3N*)RY$6'PLFQ&
- XbD@9cI5*$5@jdCA*QB@0P,QmJYJd*#5*l6'PLFQ&bD@9cI5*8EfpX6'PLFbj[),B
- X0#3NYEb"%G@e`8Q9c9'9cG!d05@jcG'&XE#$%)%4eEA"5CA-ZD#"%G@e`8Q9c,Qm
- X0#84eF'aTBf&dC5!YH5"%G@e`8Q9c,QJJ)RY$5@jME(9NCA0p)Jd*4(9`E'PMBA4
- XP)#ej)%4eEA"5CA-ZEb!LHd0-D@*bBA*TCA0p)Je1TJ!!!3!!!!&-!!!!6!!!!$*
- X%G@e`8Q9c9'9cG#jYB@YP$5-J)#"8BA*RCA3k)#!J)!K0B@YP4QPXC@X#!!!!!!!
- X!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- X!!+)9Fa)!!!!!!!!"IQ&bBfJJ05`J-6Ni15!a-MSb-6Sd0!d04(9YF&*PFe4PFh3
- XZBbj[)-3J4(9YF&*PFe4PFh3ZE@&VC5"%G@e`8Q9c9'9cG#jM$3P$)%4eEA"5CA0
- X8CA0d,Q-04(9YF&*PFbjM,QmJa#"%G@e`8Q9c9'9cG#jYB@YP)%4eEA"5CA-ZB`d
- X!!!")!!P0EfjKBfm!JJ!$!!N!#Rrr!!i!#3!+Irm!K`#"!)*rr`!'!!3!2J!2!G-
- X#F`!q!!m"d`*cS$l[KJ!!!!!!!!!!!!!!!!%!!!!"!!!!!8`!!!"-!!!!-J!Y8%J
- X%DJ!!!"`!-J!!69"68J!!!!S$lIrr!!!!!!!ZIq3'X3:
- END_OF_FILE
- if test 1456 -ne `wc -c <'mac/dumpres/MakeFile.hqx'`; then
- echo shar: \"'mac/dumpres/MakeFile.hqx'\" unpacked with wrong size!
- fi
- # end of 'mac/dumpres/MakeFile.hqx'
- fi
- if test -f 'source/main.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'source/main.c'\"
- else
- echo shar: Extracting \"'source/main.c'\" \(11025 characters\)
- sed "s/^X//" >'source/main.c' <<'END_OF_FILE'
- X/* UNIX Moria Version 5.0
- X main.c: initialization, main() function and main loop
- X
- X Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
- X
- X This software may be copied and distributed for educational, research, and
- X not for profit purposes provided that this copyright and statement are
- X included in all such copies. */
- X
- X
- X/* Original copyright message follows. */
- X
- X/* Moria Version 4.8 COPYRIGHT (c) Robert Alan Koeneke */
- X/* */
- X/* I lovingly dedicate this game to hackers and adventurers */
- X/* everywhere... */
- X/* */
- X/* */
- X/* Designer and Programmer : Robert Alan Koeneke */
- X/* University of Oklahoma */
- X/* */
- X/* Assistant Programmers : Jimmey Wayne Todd */
- X/* University of Oklahoma */
- X/* */
- X/* Gary D. McAdoo */
- X/* University of Oklahoma */
- X/* */
- X/* UNIX Port : James E. Wilson */
- X/* UC Berkeley */
- X/* wilson@ernie.Berkeley.EDU */
- X/* ucbvax!ucbernie!wilson */
- X/* */
- X/* MSDOS Port : Don Kneller */
- X/* 1349 - 10th ave */
- X/* San Francisco, CA 94122 */
- X/* kneller@cgl.ucsf.EDU */
- X/* ...ucbvax!ucsfcgl!kneller */
- X/* kneller@ucsf-cgl.BITNET */
- X/* */
- X/* BRUCE Moria : Christopher Stuart */
- X/* Monash University */
- X/* Melbourne, Victoria, AUSTRALIA */
- X/* cjs@moncsbruce.oz */
- X/* */
- X/* Moria may be copied and modified freely as long as the above */
- X/* credits are retained. No one who-so-ever may sell or market */
- X/* this software in any form without the expressed written consent */
- X/* of the author Robert Alan Koeneke. */
- X/* */
- X
- X#include "config.h"
- X
- X/* include before constant, because param.h defines NULL incorrectly */
- X#ifndef USG
- X#include <sys/types.h>
- X#include <sys/param.h>
- X#endif
- X
- X#include "constant.h"
- X#include "types.h"
- X#include "externs.h"
- X
- X#ifdef USG
- X#ifndef ATARIST_MWC
- X#include <string.h>
- X#else
- X#include "string.h"
- X#endif
- X#else
- X#include <strings.h>
- X#endif
- X
- X#include <ctype.h>
- X
- X#ifdef Pyramid
- X#include <sys/time.h>
- X#else
- X#include <time.h>
- X#endif
- X
- X#ifndef MAC
- X#ifndef GEMDOS
- Xlong time();
- X#endif
- Xchar *getenv();
- X#endif
- X
- X#ifndef MAC
- X#ifdef USG
- X#ifndef MSDOS
- Xunsigned short getuid(), getgid();
- X#endif
- X#else
- X#ifndef SECURE
- X#ifdef BSD4_3
- Xuid_t getuid(), getgid();
- X#else /* other BSD versions */
- Xint getuid(), getgid();
- X#endif
- X#endif
- X#endif
- X#endif
- X
- X#ifndef VMS
- X#ifndef MAC
- X#if defined(ultrix) || defined(USG)
- Xvoid perror();
- X#endif
- X#endif
- X#endif
- X
- X#ifndef VMS
- X#ifndef MAC
- X#ifdef USG
- Xvoid exit();
- X#endif
- X#endif
- X#endif
- X
- X#ifdef ATARIST_MWC
- Xlong _stksize = 18000; /*(SAJ) for MWC */
- X#endif
- X
- X#if defined(LINT_ARGS)
- Xstatic void char_inven_init(void);
- Xstatic void init_m_level(void);
- Xstatic void init_t_level(void);
- X#if (COST_ADJ != 100)
- Xstatic void price_adjust(void);
- X#endif
- X#else
- Xstatic void char_inven_init();
- Xstatic void init_m_level();
- Xstatic void init_t_level();
- X#if (COST_ADJ != 100)
- Xstatic void price_adjust();
- X#endif
- X#endif
- X
- X/* Initialize, restore, and get the ball rolling. -RAK- */
- X#ifdef MAC
- X/* This is just a subroutine for the Mac version */
- X/* only options passed in are -orn */
- X/* save file name is never passed */
- Xint moria_main(argc, argv)
- Xint argc;
- Xchar *argv[];
- X#else
- Xint main(argc, argv)
- Xint argc;
- Xchar *argv[];
- X#endif
- X{
- X int32u seed;
- X int generate;
- X int result;
- X#ifndef MAC
- X char *p;
- X#endif
- X int new_game = FALSE;
- X int force_rogue_like = FALSE;
- X int force_keys_to;
- X char string[80];
- X
- X /* default command set defined in config.h file */
- X rogue_like_commands = ROGUE_LIKE;
- X
- X#ifdef SECURE
- X Authenticate();
- X#endif
- X
- X#ifdef MSDOS
- X msdos_init(); /* find out where everything is */
- X#endif
- X
- X /* call this routine to grab a file pointer to the highscore file */
- X /* and prepare things to relinquish setuid privileges */
- X init_scorefile();
- X
- X/* Call this routine to grab a file pointer to the log files and
- X start the backup process before relinquishing setuid privileges */
- X init_files();
- X
- X#ifndef SECURE
- X#if !defined(MSDOS) && !defined(ATARIST_MWC) && !defined(MAC)
- X if (0 != setuid(getuid()))
- X {
- X perror("Can't set permissions correctly! Setuid call failed.\n");
- X exit(0);
- X }
- X if (0 != setgid(getgid()))
- X {
- X perror("Can't set permissions correctly! Setgid call failed.\n");
- X exit(0);
- X }
- X#endif
- X#endif
- X
- X /* use curses */
- X init_curses();
- X
- X /* catch those nasty signals */
- X /* must come after init_curses as some of the signal handlers use curses */
- X init_signals();
- X
- X seed = 0; /* let wizard specify rng seed */
- X /* check for user interface option */
- X for (--argc, ++argv; argc > 0 && argv[0][0] == '-'; --argc, ++argv)
- X switch (argv[0][1])
- X {
- X case 'N':
- X case 'n': new_game = TRUE; break;
- X case 'O':
- X case 'o':
- X /* rogue_like_commands may be set in get_char(), so delay this
- X until after read savefile if any */
- X force_rogue_like = TRUE;
- X force_keys_to = FALSE;
- X break;
- X case 'R':
- X case 'r':
- X force_rogue_like = TRUE;
- X force_keys_to = TRUE;
- X break;
- X#ifndef MAC
- X case 'S':
- X case 's': display_scores(0, TRUE); exit_game();
- X case 'W':
- X case 'w':
- X to_be_wizard = TRUE;
- X
- X if (isdigit((int)argv[0][2]))
- X seed = atoi(&argv[0][2]);
- X break;
- X default: (void) printf("Usage: moria [-norsw] [savefile]\n");
- X exit_game();
- X#endif
- X }
- X
- X#ifndef MAC
- X /* Check operating hours */
- X /* If not wizard No_Control_Y */
- X read_times();
- X#endif
- X
- X /* Some necessary initializations */
- X /* all made into constants or initialized in variables.c */
- X
- X#if (COST_ADJ != 100)
- X price_adjust();
- X#endif
- X
- X /* Grab a random seed from the clock */
- X init_seeds(seed);
- X
- X /* Init monster and treasure levels for allocate */
- X init_m_level();
- X init_t_level();
- X
- X /* Init the store inventories */
- X store_init();
- X
- X#ifndef MAC
- X /* On Mac, if -n is passed, no savefile is used */
- X /* If -n is not passed, the calling routine will know savefile name,
- X hence, this code is not necessary */
- X
- X /* Auto-restart of saved file */
- X if (argv[0] != NULL)
- X (void) strcpy (savefile, argv[0]);
- X else if (p = getenv("MORIA_SAV"))
- X (void) strcpy(savefile, p);
- X else if (p = getenv("HOME"))
- X#ifdef ATARIST_MWC
- X (void) sprintf(savefile, "%s\\%s", p, MORIA_SAV);
- X#else
- X (void) sprintf(savefile, "%s/%s", p, MORIA_SAV);
- X#endif
- X else
- X (void) strcpy(savefile, MORIA_SAV);
- X#endif
- X
- X/* This restoration of a saved character may get ONLY the monster memory. In
- X this case, get_char returns false. It may also resurrect a dead character
- X (if you are the wizard). In this case, it returns true, but also sets the
- X parameter "generate" to true, as it does not recover any cave details. */
- X
- X result = get_char(&generate);
- X /* enter wizard mode before showing the character display, but must wait
- X until after get_char in case it was just a resurrection */
- X if (to_be_wizard)
- X if (!enter_wiz_mode())
- X exit_game();
- X
- X#ifdef MAC
- X if ((new_game == FALSE) && result)
- X#else
- X if ((new_game == FALSE) && !access(savefile, 0) && result)
- X#endif
- X {
- X change_name();
- X
- X /* could be restoring a dead character after a signal or HANGUP */
- X if (py.misc.chp < 0)
- X death = TRUE;
- X }
- X else
- X { /* Create character */
- X create_character();
- X char_inven_init();
- X py.flags.food = 7500;
- X py.flags.food_digested = 2;
- X if (class[py.misc.pclass].spell == MAGE)
- X { /* Magic realm */
- X clear_screen(); /* makes spell list easier to read */
- X calc_spells(A_INT);
- X calc_mana(A_INT);
- X }
- X else if (class[py.misc.pclass].spell == PRIEST)
- X { /* Clerical realm*/
- X calc_spells(A_WIS);
- X clear_screen(); /* force out the 'learn prayer' message */
- X calc_mana(A_WIS);
- X }
- X if (!_new_log())
- X {
- X (void) sprintf(string, "Can't get at log file \"%s\".", MORIA_LOG);
- X msg_print(string);
- X exit_game();
- X }
- X /* prevent ^c quit from entering score into scoreboard,
- X and prevent signal from creating panic save until this point,
- X all info needed for save file is now valid */
- X character_generated = 1;
- X generate = TRUE;
- X }
- X
- X if (force_rogue_like)
- X rogue_like_commands = force_keys_to;
- X
- X magic_init();
- X
- X /* Begin the game */
- X clear_screen();
- X prt_stat_block();
- X if (generate)
- X generate_cave();
- X
- X /* Loop till dead, or exit */
- X while(!death)
- X {
- X dungeon(); /* Dungeon logic */
- X
- X#ifndef MAC
- X /* check for eof here, see inkey() in io.c */
- X /* eof can occur if the process gets a HANGUP signal */
- X if (eof_flag)
- X {
- X (void) strcpy(died_from, "(end of input: saved)");
- X if (!save_char())
- X {
- X (void) strcpy(died_from, "unexpected eof");
- X }
- X /* should not reach here, by if we do, this guarantees exit */
- X death = TRUE;
- X }
- X#endif
- X
- X if (!death) generate_cave(); /* New level */
- X }
- X
- X exit_game(); /* Character gets buried. */
- X /* should never reach here, but just in case */
- X return (0);
- X}
- X
- X/* Init players with some belongings -RAK- */
- Xstatic void char_inven_init()
- X{
- X register int i, j;
- X inven_type inven_init;
- X
- X /* this is needed for bash to work right, it can't hurt anyway */
- X for (i = 0; i < INVEN_ARRAY_SIZE; i++)
- X invcopy(&inventory[i], OBJ_NOTHING);
- X
- X for (i = 0; i < 5; i++)
- X {
- X j = player_init[py.misc.pclass][i];
- X invcopy(&inven_init, j);
- X /* this makes it known2 and known1 */
- X store_bought(&inven_init);
- X /* must set this bit to display tohit/todam for stiletto */
- X if (inven_init.tval == TV_SWORD)
- X inven_init.ident |= ID_SHOW_HITDAM;
- X (void) inven_carry(&inven_init);
- X }
- X
- X /* wierd place for it, but why not? */
- X for (i = 0; i < 32; i++)
- X spell_order[i] = 99;
- X}
- X
- X
- X/* Initializes M_LEVEL array for use with PLACE_MONSTER -RAK- */
- Xstatic void init_m_level()
- X{
- X register int i, k;
- X
- X for (i = 0; i <= MAX_MONS_LEVEL; i++)
- X m_level[i] = 0;
- X
- X k = MAX_CREATURES - WIN_MON_TOT;
- X for (i = 0; i < k; i++)
- X m_level[c_list[i].level]++;
- X
- X for (i = 1; i <= MAX_MONS_LEVEL; i++)
- X m_level[i] += m_level[i-1];
- X}
- X
- X
- X/* Initializes T_LEVEL array for use with PLACE_OBJECT -RAK- */
- Xstatic void init_t_level()
- X{
- X register int i, l;
- X int tmp[MAX_OBJ_LEVEL+1];
- X
- X for (i = 0; i <= MAX_OBJ_LEVEL; i++)
- X t_level[i] = 0;
- X for (i = 0; i < MAX_DUNGEON_OBJ; i++)
- X t_level[object_list[i].level]++;
- X for (i = 1; i <= MAX_OBJ_LEVEL; i++)
- X t_level[i] += t_level[i-1];
- X
- X /* now produce an array with object indexes sorted by level, by using
- X the info in t_level, this is an O(n) sort! */
- X /* this is not a stable sort, but that does not matter */
- X for (i = 0; i <= MAX_OBJ_LEVEL; i++)
- X tmp[i] = 1;
- X for (i = 0; i < MAX_DUNGEON_OBJ; i++)
- X {
- X l = object_list[i].level;
- X sorted_objects[t_level[l] - tmp[l]] = i;
- X tmp[l]++;
- X }
- X}
- X
- X
- X#if (COST_ADJ != 100)
- X/* Adjust prices of objects -RAK- */
- Xstatic void price_adjust()
- X{
- X register int i;
- X
- X /* round half-way cases up */
- X for (i = 0; i < MAX_OBJECTS; i++)
- X object_list[i].cost = ((object_list[i].cost * COST_ADJ) + 50) / 100;
- X}
- X#endif
- END_OF_FILE
- if test 11025 -ne `wc -c <'source/main.c'`; then
- echo shar: \"'source/main.c'\" unpacked with wrong size!
- fi
- # end of 'source/main.c'
- fi
- if test -f 'util/showmon.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/showmon.c'\"
- else
- echo shar: Extracting \"'util/showmon.c'\" \(11631 characters\)
- sed "s/^X//" >'util/showmon.c' <<'END_OF_FILE'
- X/* this used to be in files.c, this is not a working program */
- X
- X/* move to cheat.c file */
- X/* Prints a listing of monsters -RAK- */
- Xprint_monsters()
- X{
- X register int i;
- X int j, xpos, attype, adesc, adice, asides, count;
- X register FILE *file1;
- X vtype out_val, filename1;
- X char *attstr;
- X register creature_type *c_ptr;
- X register char *string;
- X
- X prt("File name: ", 0, 0);
- X if (get_string(filename1, 0, 11, 64))
- X {
- X if (strlen(filename1) == 0)
- X (void) strcpy(filename1, "MORIAMON.DAT");
- X if ((file1 = fopen(filename1, "w")) != NULL)
- X {
- X prt("Writing Monster Dictionary...", 0, 0);
- X put_qio();
- X for (i = 0; i < MAX_CREATURES; i++)
- X {
- X c_ptr = &c_list[i];
- X /* Begin writing to file */
- X (void) fprintf(file1, "--------------------------------------------\n");
- X (void) fprintf(file1, "%3d %-31s (%c)\n", i, c_ptr->name, c_ptr->cchar);
- X (void) fprintf(file1, " Speed =%3d Level =%3d Exp =%6u\n",
- X c_ptr->speed-10, c_ptr->level, c_ptr->mexp);
- X (void) fprintf(file1, " AC =%3d Eye-sight =%3d HD =%6s\n",
- X c_ptr->ac, c_ptr->aaf, c_ptr->hd);
- X if (CM_WIN & c_ptr->cmove)
- X (void) fprintf(file1, " Creature is a ***Win Creature***\n");
- X if (CM_EATS_OTHER) & c_ptr->cmove)
- X (void) fprintf(file1, " Creature Eats/kills other creatures.\n");
- X if (CD_DRAGON & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature is a dragon.\n");
- X if (CD_ANIMAL & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature is an animal.\n");
- X if (CD_EVIL & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature is evil.\n");
- X if (CD_UNDEAD & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature is undead.\n");
- X if (CD_FROST & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature harmed by cold.\n");
- X if (CD_FIRE & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature harmed by fire.\n");
- X if (CD_POISON & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature harmed by poison.\n");
- X if (CD_ACID & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature harmed by acid.\n");
- X if (CD_LIGHT & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature harmed by blue light.\n");
- X if (CD_STONE & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature harmed by Stone-to-Mud.\n");
- X if (CD_NO_SLEEP & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature cannot be charmed or slept.\n");
- X if (CD_INFRA & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature seen with Infra-Vision.\n");
- X if (CD_MAX_HP & c_ptr->cdefense)
- X (void) fprintf(file1, " Creature has MAX hit points.\n");
- X if (CM_INVISIBLE & c_ptr->cmove)
- X (void) fprintf(file1, " Creature is invisible.\n");
- X if (CM_PICKS_UP & c_ptr->cmove)
- X (void) fprintf(file1, " Creature picks up objects.\n");
- X if (CM_MULTIPLY & c_ptr->cmove)
- X (void) fprintf(file1, " Creature multiplies.\n");
- X if (CM_CARRY_OBJ & c_ptr->cmove)
- X (void) fprintf(file1, " Carries object(s).\n");
- X if (CM_CARRY_GOLD & c_ptr->cmove)
- X (void) fprintf(file1, " Carries gold, gems, etc.\n");
- X if (CM_60_RANDOM & c_ptr->cmove)
- X (void) fprintf(file1, " Has object/gold 60%% of time.\n");
- X if (CM_90_RANDOM & c_ptr->cmove)
- X (void) fprintf(file1, " Has object/gold 90%% of time.\n");
- X if (CM_1D2_OBJ & c_ptr->cmove)
- X (void) fprintf(file1, " Has 1d2 object(s)/gold.\n");
- X if (CM_2D2_OBJ & c_ptr->cmove)
- X (void) fprintf(file1, " Has 2d2 object(s)/gold.\n");
- X if (CM_4D2_OBJ & c_ptr->cmove)
- X (void) fprintf(file1, " Has 4d2 object(s)/gold.\n");
- X /*
- X * Creature casts spells / Breathes Dragon
- X * breath.
- X */
- X if (c_ptr->spells != 0)
- X {
- X (void) fprintf(file1, " --Spells/Dragon Breath =\n");
- X (void) fprintf(file1, " Casts spells 1 out of %d turns.\n",
- X (int)(CS_FREQ & c_ptr->spells));
- X if (CS_TEL_SHORT & c_ptr->spells)
- X (void) fprintf(file1, " Can teleport short.\n");
- X if (CS_TEL_LONG & c_ptr->spells)
- X (void) fprintf(file1, " Can teleport long.\n");
- X if (CS_TEL_TO & c_ptr->spells)
- X (void) fprintf(file1, " Teleport player to itself.\n");
- X if (CS_LGHT_WND & c_ptr->spells)
- X (void) fprintf(file1, " Cause light wounds.\n");
- X if (CS_SER_WND & c_ptr->spells)
- X (void) fprintf(file1, " Cause serious wounds.\n");
- X if (CS_HOLD_PER & c_ptr->spells)
- X (void) fprintf(file1, " Hold person.\n");
- X if (CS_BLIND & c_ptr->spells)
- X (void) fprintf(file1, " Cause blindness.\n");
- X if (CS_CONFUSE & c_ptr->spells)
- X (void) fprintf(file1, " Cause confusion.\n");
- X if (CS_FEAR & c_ptr->spells)
- X (void) fprintf(file1, " Cause fear.\n");
- X if (CS_SUMMON_MON & c_ptr->spells)
- X (void) fprintf(file1, " Summon a monster.\n");
- X if (CS_SUMMON_UND & c_ptr->spells)
- X (void) fprintf(file1, " Summon an undead.\n");
- X if (CS_SLOW_PER & c_ptr->spells)
- X (void) fprintf(file1, " Slow person.\n");
- X if (CS_DRAIN_MANA & c_ptr->spells)
- X (void) fprintf(file1, " Drains mana for healing.\n");
- X if (0x00020000L & c_ptr->spells)
- X (void) fprintf(file1, " **Unknown spell value**\n");
- X if (0x00040000L & c_ptr->spells)
- X (void) fprintf(file1, " **Unknown spell value**\n");
- X if (CS_BR_LIGHT & c_ptr->spells)
- X (void) fprintf(file1, " Breathes Lightning Dragon Breath.\n");
- X if (CS_BR_GAS & c_ptr->spells)
- X (void) fprintf(file1, " Breathes Gas Dragon Breath.\n");
- X if (CS_BR_ACID & c_ptr->spells)
- X (void) fprintf(file1, " Breathes Acid Dragon Breath.\n");
- X if (CS_BR_FROST & c_ptr->spells)
- X (void) fprintf(file1, " Breathes Frost Dragon Breath.\n");
- X if (CS_BR_FIRE & c_ptr->spells)
- X (void) fprintf(file1, " Breathes Fire Dragon Breath.\n");
- X }
- X /* Movement for creature */
- X (void) fprintf(file1, " --Movement =\n");
- X if ((CM_ALL_MV_FLAGS & c_ptr->cmove) == 0)
- X (void) fprintf(file1, " Do not move.\n");
- X if (CM_ATTACK_ONLY & c_ptr->cmove)
- X (void) fprintf(file1, " Move only to attack.\n");
- X if (CM_MOVE_NORMAL & c_ptr->cmove)
- X (void) fprintf(file1, " Move and attack normally.\n");
- X if (CM_20_RANDOM & c_ptr->cmove)
- X (void) fprintf(file1, " 20%% random movement.\n");
- X if (CM_40_RANDOM & c_ptr->cmove)
- X (void) fprintf(file1, " 40%% random movement.\n");
- X if (CM_75_RANDOM & c_ptr->cmove)
- X (void) fprintf(file1, " 75%% random movement.\n");
- X if (CM_OPEN_DOOR & c_ptr->cmove)
- X (void) fprintf(file1, " Can open doors.\n");
- X if (CM_PHASE & c_ptr->cmove)
- X (void) fprintf(file1, " Can phase through walls.\n");
- X
- X (void) fprintf(file1, " --Creature attacks =\n");
- X attstr = c_ptr->damage;
- X count = 0;
- X while (*attstr != 0 && count < 4)
- X {
- X attype = monster_attacks[*attstr].attack_type;
- X adesc = monster_attacks[*attstr].attack_desc;
- X adice = monster_attacks[*attstr].attack_dice;
- X asides = monster_attacks[*attstr].attack_sides;
- X attstr++;
- X count++;
- X out_val[0] = '\0';
- X switch (adesc)
- X {
- X case 0:
- X (void) strcpy(out_val, " No hits for ");
- X break;
- X case 1:
- X (void) strcpy(out_val, " Hits for ");
- X break;
- X case 2:
- X (void) strcpy(out_val, " Bites for ");
- X break;
- X case 3:
- X (void) strcpy(out_val, " Claws for ");
- X break;
- X case 4:
- X (void) strcpy(out_val, " Stings for ");
- X break;
- X case 5:
- X (void) strcpy(out_val, " Touches for ");
- X break;
- X case 6:
- X (void) strcpy(out_val, " Kicks for ");
- X break;
- X case 7:
- X (void) strcpy(out_val, " Gazes for ");
- X break;
- X case 8:
- X (void) strcpy(out_val, " Breathes for ");
- X break;
- X case 9:
- X (void) strcpy(out_val, " Spits for ");
- X break;
- X case 10:
- X (void) strcpy(out_val, " Wails for ");
- X break;
- X case 11:
- X (void) strcpy(out_val, " Embraces for ");
- X break;
- X case 12:
- X (void) strcpy(out_val, " Crawls on you for ");
- X break;
- X case 13:
- X (void) strcpy(out_val, " Shoots spores for ");
- X break;
- X case 14:
- X (void) strcpy(out_val, " Begs for money for ");
- X break;
- X case 15:
- X (void) strcpy(out_val, " Slimes you for ");
- X break;
- X case 16:
- X (void) strcpy(out_val, " Crushes you for ");
- X break;
- X case 17:
- X (void) strcpy(out_val, " Tramples you for ");
- X break;
- X case 18:
- X (void) strcpy(out_val, " Drools on you for ");
- X break;
- X case 19:
- X (void) strcpy(out_val, " Insults you for ");
- X break;
- X case 99:
- X (void) strcpy(out_val, " Is repelled.");
- X break;
- X default:
- X (void) strcpy(out_val, " **Unknown value** ");
- X break;
- X }
- X switch (attype)
- X {
- X case 0:
- X (void) strcat(out_val, "no damage.");
- X break;
- X case 1:
- X (void) strcat(out_val, "normal damage.");
- X break;
- X case 2:
- X (void) strcat(out_val, "lowering strength.");
- X break;
- X case 3:
- X (void) strcat(out_val, "confusion.");
- X break;
- X case 4:
- X (void) strcat(out_val, "fear.");
- X break;
- X case 5:
- X (void) strcat(out_val, "fire damage.");
- X break;
- X case 6:
- X (void) strcat(out_val, "acid damage.");
- X break;
- X case 7:
- X (void) strcat(out_val, "cold damage.");
- X break;
- X case 8:
- X (void) strcat(out_val, "lightning damage.");
- X break;
- X case 9:
- X (void) strcat(out_val, "corrosion damage.");
- X break;
- X case 10:
- X (void) strcat(out_val, "blindness.");
- X break;
- X case 11:
- X (void) strcat(out_val, "paralyzation.");
- X break;
- X case 12:
- X (void) strcat(out_val, "stealing money.");
- X break;
- X case 13:
- X (void) strcat(out_val, "stealing object.");
- X break;
- X case 14:
- X (void) strcat(out_val, "poison damage.");
- X break;
- X case 15:
- X (void) strcat(out_val, "lose dexterity.");
- X break;
- X case 16:
- X (void) strcat(out_val, "lose constitution.");
- X break;
- X case 17:
- X (void) strcat(out_val, "lose intelligence.");
- X break;
- X case 18:
- X (void) strcat(out_val, "lose wisdom.");
- X break;
- X case 19:
- X (void) strcat(out_val, "lose experience.");
- X break;
- X case 20:
- X (void) strcat(out_val, "aggravates monsters.");
- X break;
- X case 21:
- X (void) strcat(out_val, "disenchants objects.");
- X break;
- X case 22:
- X (void) strcat(out_val, "eating food.");
- X break;
- X case 23:
- X (void) strcat(out_val, "eating light source.");
- X break;
- X case 24:
- X (void) strcat(out_val, "absorbing charges.");
- X break;
- X case 99:
- X (void) strcat(out_val, "blank message.");
- X break;
- X default:
- X (void) strcat(out_val, "**Unknown value**");
- X break;
- X }
- X (void) fprintf(file1, "%s (%dd%d)\n", out_val, adice,asides);
- X }
- X for (j = 0; j < 2; j++)
- X (void) fprintf(file1, "\n");
- X }
- X /* End writing to file */
- X (void) fclose(file1);
- X prt("Completed.", 0, 0);
- X }
- X }
- X}
- END_OF_FILE
- if test 11631 -ne `wc -c <'util/showmon.c'`; then
- echo shar: \"'util/showmon.c'\" unpacked with wrong size!
- fi
- # end of 'util/showmon.c'
- fi
- if test -f 'util/weapons/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/weapons/README'\"
- else
- echo shar: Extracting \"'util/weapons/README'\" \(10774 characters\)
- sed "s/^X//" >'util/weapons/README' <<'END_OF_FILE'
- X
- X>
- X> Here's a question for all of you who have had experiences with HA's. Is a
- X> dagger a better weapon than say, a war hammer or an axe? I've found a
- X> bodkin [+8,+8] and a war hammer [+7,+8], and found that the dagger sold
- X> for more in the stores. Why? Just because it is one up on To-Hit?? To me,
- X> it would seem like the war hammer is a way better weapon... Well, the
- X> difference between the prices is about 1000 gp.
- X>
- X
- X
- X
- Xok, here are some spoilers.
- X
- X
- X1) dont trust what the store will buy or sell things for as being a
- X good indicator of its true value. they basis it only on the base
- X value of a weapon, the to-hit and to-damage, and the special
- X abilities it has. these are _not_ always what makes a weapon
- X really good, and what might be good for one character may be bad
- X for another.
- X
- X2) when in doubt, keep the dagger. daggers are probably best for all
- X types of characters (mages, warriors etc) until you get your
- X strength and dexterity up real high.
- X
- X
- Xa detail explanation of how things work follows...
- X
- X
- Xthe amount of damage that a weapon will do is based on the following things:
- X
- X * the weight of the weapon. the lighter it is the more likely you
- X will get two hits in for each attack. on the other hand, the
- X heavier the weapon, the more likely you are to get a critical hit
- X (good, excellent, great hits).
- X
- X * the basic amount of damage the weapon does. most daggers do 1d4,
- X two handed swords (Zweihander) do 4d6.
- X
- X * your total to-hit. this includes the pluses that come with your
- X weapon, the minuses that your armor does, any rings of to-hit or
- X slaying, etc. the higher your total to-hit is, the more likely
- X you are to get a critical blow.
- X
- X * your total to-damage. like your total to-hit, this includes
- X everything. when you get a really good character, this will
- X usually dominate over the weapons basic damage.
- X
- X * your current strength. the stronger you are the easier it is for
- X you to get several hits per attack.
- X
- X * your current dexterity. the more dextrous you are the more hits
- X per attack you are capable of.
- X
- X * the level of your character. the more experience you have the
- X more likely you are to get a "good (x2)" or "excellent (x3)" hit.
- X
- X
- Xall of these things are mixed together in a rather complicated way. i
- Xhad to write a program that takes all of these factors into account
- Xand gives a true indication of which weapon is better. (i had two
- XHA's that i couldnt decide between. it turned out that depending on
- Xmy current strength and dex either one could be much better than the
- Xother. i ended up keeping both of them until both my str and dex were
- X18/100.)
- X
- X
- Xthe chance that you actually hit the monster is based on:
- X
- X * your "base to hit". this is based on what race your character is
- X and ranges from -10 for Halflings to 20 for Half-Trolls. it also
- X depends on what "class" your character is and these bonuses range
- X from 20 for mages to 70 for paladin's. (warriors arent much
- X behind with a bonus of 68). a human mage will have a "base to
- X hit" of 20, a half troll warrior will have a "base to hit" of 88.
- X
- X * your current level. the more experience you have, the more likely
- X you are to hit the monster. going up one level is equivalent to
- X enchanting your weapon's to-hit by one.
- X
- X * your total to-hit. the higher your total to-hit, the more likely
- X you are to hit the monster
- X
- X * the monsters ac (armor class). the higher the monster's ac, the
- X less likely you are to hit the monster. this varies a lot from
- X monster to monster. most worm masses, mushrooms, jellies and
- X stuff have ac's under 10. most of the ancient dragons have ac's
- X in the 80-100 range. the balrog has an ac of 125, the highest of
- X any monster. iron golems have an ac of 99, which can give you
- X some idea of how hard it would be to hit a ancient dragon without
- X taking too many risks. most of the other monsters seem to to be
- X in the 30-60 range.
- X
- X the formula for this is:
- X
- X val = bth + 3*level + 3*tohit
- X
- X if a random number between 1 and val is greater than the
- X monsters ac, then you hit, otherwise you miss.
- X
- X you will always hit one out of 20 times, even if your weapon is too
- X heavy for you to wield.
- X
- Xi dont have anything to calculate calculate your chances to hit
- Xmonsters because there are just too many different cases. a level 40
- Xhalf-troll warrior with a total to hit of 30 would have a two out of
- Xthree chance of hitting a AMHD. everyone else is going to going to be
- Xwell under 50-50.
- X
- X
- X
- XThe program "calc_hits" can help you figure out which weapon is better
- Xfor you now, and as your strength and dexterity goes up. it is based
- Xon the source code to moria so it should be basically correct.
- Xcalc_hits isnt a fancy program and it handles errors by stopping the
- Xprogram. it is designed to be used by the person who wrote it. :->
- X
- X
- Xprobably the best way to explain how to run the program is simply to
- Xgive you an example run comparing a bastard sword, a dagger (stiletto)
- Xand a two handed great flail. all of them will be (+3,+4) giving you
- Xa total to-hit of 2 and a total to-damage of 4.
- X
- Xthe results are given in a table form with the following field:
- X
- XMblow is the maximum number of blows you can get per attack. it is
- X based only on your dex.
- X
- XBlows is the number of plows you can get with your current strength
- X based on the Mblows, and strength/weight ratio.
- X
- Xwt ratio is your strength to weight of weapon ratio. a ratio above 10
- X doesnt do you any more good than a ratio of 10. if the ratio is
- X under 2, you can only get one blow no matter what your dex is.
- X
- Xdam is the amount of damage that you get, on the average if you hit
- X with every blow and dont get a critical hit.
- X
- Xw/ critical is the amount of damage you get on the average if you
- X include the possibilities of getting a critical hit. for low
- X level characters, this rarely makes a difference. for high
- X level characters, this can make a real difference.
- X
- X(wayne 6) % calc_hits
- XEnter level of your character: 12
- XEnter number of weapons: 3
- XEnter weight, weapon_dam, to_hit, to_dam for weapon #0: 140 3d4 2 4
- XEnter weight, weapon_dam, to_hit, to_dam for weapon #1: 12 1d4 2 4
- XEnter weight, weapon_dam, to_hit, to_dam for weapon #2: 280 3d6 2 4
- XEnter cstr, cdex: 11 14
- X| Weapon | Max blows | Blows | weight ratio | hp of dam | w/ critical |
- X| 0 | 2 | 1 | 0 | 11 | 12 |
- X| 1 | 2 | 2 | 9 | 13 | 13 |
- X| 2 | 0 | 0 | 0 | 0 | 0 |
- X
- XEnter cstr, cdex: 17 18
- X| Weapon | Max blows | Blows | weight ratio | hp of dam | w/ critical |
- X| 0 | 2 | 1 | 1 | 11 | 12 |
- X| 1 | 2 | 2 | 14 | 13 | 13 |
- X| 2 | 0 | 0 | 0 | 0 | 0 |
- X
- XEnter cstr, cdex: 18/20 18/10
- X| Weapon | Max blows | Blows | weight ratio | hp of dam | w/ critical |
- X| 0 | 3 | 2 | 2 | 23 | 25 |
- X| 1 | 3 | 3 | 31 | 19 | 19 |
- X| 2 | 3 | 1 | 1 | 14 | 17 |
- X
- XEnter cstr, cdex: 18/100 18/100
- X| Weapon | Max blows | Blows | weight ratio | hp of dam | w/ critical |
- X| 0 | 6 | 4 | 8 | 46 | 50 |
- X| 1 | 6 | 5 | 98 | 32 | 32 |
- X| 2 | 6 | 3 | 4 | 43 | 52 |
- X
- XEnter cstr, cdex:
- X(wayne 7) % exit
- X
- X
- X
- X
- X
- Xthere is a second program called "mk_all_weapon" that generates a list
- Xof how much damage all weapons will do given a certain character. it
- Xis useful for getting a feel of which weapons are good and why.
- X
- X
- Xfor low level characters, the following are the top 5 weapons:
- X
- Xcharacter level of 12
- Xtotal to-hit and to-damage of +7
- Xstrength of 11. these numbers wont change much until you get above 18
- Xdexterity of 17. these numbers will be the same unless your dex is
- X above 18/01 or below 10.
- X
- X Name | Mblow | Blows | wt ratio | dam | w/ critical |
- XDagger (Stiletto) | 2 | 2 | 9 | 19 | 19 |
- XDagger (Misercorde) | 2 | 2 | 7 | 19 | 19 |
- XDagger (Bodkin) | 2 | 2 | 5 | 19 | 19 |
- XMorningstar | 2 | 1 | 0 | 14 | 15 |
- XKatana | 2 | 1 | 0 | 14 | 15 |
- X
- Xthe bottom 5 for a low level character:
- X
- XFauchard | 0 | 0 | 0 | 0 | 0 |
- XExecutioner's Sword | 0 | 0 | 0 | 0 | 0 |
- XBeaked Axe | 0 | 0 | 0 | 0 | 0 |
- XBattle Axe (European) | 0 | 0 | 0 | 0 | 0 |
- XBattle Axe (Balestarius) | 0 | 0 | 0 | 0 | 0 |
- X
- X
- X
- Xfor high level characters, the following are the top 5 weapons:
- X
- Xcharacter level of 36
- Xtotal to-hit and to-damage of +20
- Xstrength of 18/100.
- Xdexterity of 18/100.
- X
- X Name | Mblow | Blows | wt ratio | dam | w/ critical |
- XKatana | 6 | 5 | 9 | 137 | 161 |
- XWar Hammer | 6 | 5 | 9 | 130 | 153 |
- XLucerne Hammer | 6 | 5 | 9 | 130 | 153 |
- XTwo Handed Sword (Claymore) | 6 | 4 | 5 | 122 | 151 |
- XTwo Handed Sword (No-Dachi) | 6 | 4 | 5 | 120 | 149 |
- X
- Xthe bottom 5
- X
- XTwo Handed Great Flail | 6 | 3 | 4 | 91 | 120 |
- XBall and Chain | 6 | 4 | 7 | 100 | 120 |
- XAwl-Pike | 6 | 4 | 7 | 98 | 118 |
- XLance | 6 | 3 | 3 | 87 | 117 |
- XFauchard | 6 | 4 | 6 | 84 | 102 |
- X
- X
- X
- Xthe katana tends to be at or near the top for all characters at all
- Xtimes. if you get even a poor katana (HA) or (DF), keep it and enchant
- Xit.
- X
- X
- Xone of the biggest mistakes people do is get rid of the weapon that
- Xthe start with and try to get a "bigger meaner" weapon. dont. just
- Xenchant your original weapon until you get something really good. i
- Xdont consider the (FT), (FB), (SD), (SE) and (SU) as "really good". i
- Xconsider the "(SM)" good, only if i dont already have something of see
- Xinvisible. (HA) and (DF)'s i keep if they are better than the ones i
- Xalready have.
- X
- X
- X-wayne
- END_OF_FILE
- if test 10774 -ne `wc -c <'util/weapons/README'`; then
- echo shar: \"'util/weapons/README'\" unpacked with wrong size!
- fi
- # end of 'util/weapons/README'
- fi
- echo shar: End of archive 26 \(of 31\).
- cp /dev/null ark26isdone
- 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 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 31 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
-