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: v16i069: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part61/108
- Message-ID: <4372@master.CNA.TEK.COM>
- Date: 1 Feb 93 19:49:45 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 2382
- Approved: billr@saab.CNA.TEK.COM
- Xref: uunet comp.sources.games:1619
-
- Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
- Posting-number: Volume 16, Issue 69
- Archive-name: nethack31/Part61
- 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 61 (of 108)."
- # Contents: src/files.c src/zap.c2
- # Wrapped by billr@saab on Wed Jan 27 16:09:10 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/files.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/files.c'\"
- else
- echo shar: Extracting \"'src/files.c'\" \(21581 characters\)
- sed "s/^X//" >'src/files.c' <<'END_OF_FILE'
- X/* SCCS Id: @(#)files.c 3.1 92/12/07 */
- X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- X/* NetHack may be freely redistributed. See license for details. */
- X
- X#include "hack.h"
- X
- X#include <ctype.h>
- X
- X#if !defined(MAC) && !defined(O_WRONLY) && !defined(AZTEC_C)
- X#include <fcntl.h>
- X#endif
- X#if defined(UNIX) || defined(VMS)
- X#include <errno.h>
- X# ifndef SKIP_ERRNO
- Xextern int errno;
- X# endif
- X#include <signal.h>
- X#endif
- X
- X#if defined(MSDOS) || defined(OS2) || defined(TOS)
- X# ifndef GNUDOS
- X#include <sys\stat.h>
- X# else
- X#include <sys/stat.h>
- X# endif
- X#endif
- X#ifndef O_BINARY /* used for micros, no-op for others */
- X# define O_BINARY 0
- X#endif
- X
- X#ifdef MFLOPPY
- Xchar bones[FILENAME]; /* pathname of bones files */
- Xchar lock[FILENAME]; /* pathname of level files */
- X#else
- Xstatic char bones[] = "bonesnn.xxxx";
- X# ifdef VMS
- Xchar lock[PL_NSIZ+17] = "1lock"; /* long enough for _uid+name+.99;1 */
- X# else
- Xchar lock[PL_NSIZ+14] = "1lock"; /* long enough for uid+name+.99 */
- X# endif
- X#endif
- X
- X#ifdef MAC
- X#include <files.h>
- XMacDirs theDirs ;
- X#endif
- X
- X#ifdef UNIX
- X#define SAVESIZE (PL_NSIZ + 13) /* save/99999player.e */
- X#else
- X# ifdef VMS
- X#define SAVESIZE (PL_NSIZ + 22) /* [.save]<uid>player.e;1 */
- X# else
- X#define SAVESIZE FILENAME /* from macconf.h or pcconf.h */
- X# endif
- X#endif
- X
- Xchar SAVEF[SAVESIZE]; /* holds relative path of save file from playground */
- X#ifdef MICRO
- Xchar SAVEP[SAVESIZE]; /* holds path of directory for save file */
- X#endif
- X#ifdef AMIGA
- Xextern char PATH[]; /* see sys/amiga/amidos.c */
- X#endif
- X
- Xstatic char * FDECL(set_bonesfile_name, (char *,d_level*));
- X
- X/* fopen a file, with OS-dependent bells and whistles */
- XFILE *
- Xfopen_datafile(filename, mode)
- Xconst char *filename, *mode;
- X{
- X FILE *fp;
- X#ifdef AMIGA
- X fp = fopenp(filename, mode);
- X#else
- X# ifdef VMS /* essential to have punctuation, to avoid logical names */
- X char tmp[BUFSIZ];
- X
- X if (!index(filename, '.') && !index(filename, ';'))
- X filename = strcat(strcpy(tmp, filename), ";0");
- X fp = fopen(filename, mode, "mbc=16");
- X# else
- X fp = fopen(filename, mode);
- X# endif
- X#endif
- X return fp;
- X}
- X
- X
- X/* ---------- BEGIN LEVEL FILE HANDLING ----------- */
- X
- X#ifdef MFLOPPY
- X/* Set names for bones[] and lock[] */
- Xvoid
- Xset_lock_and_bones()
- X{
- X if (!ramdisk) {
- X Strcpy(levels, permbones);
- X Strcpy(bones, permbones);
- X }
- X append_slash(permbones);
- X append_slash(levels);
- X append_slash(bones);
- X Strcat(bones, "bonesnn.*");
- X Strcpy(lock, levels);
- X Strcat(lock, alllevels);
- X return;
- X}
- X#endif /* MFLOPPY */
- X
- X
- X/* Construct a file name for a level-type file, which is of the form
- X * something.level (with any old level stripped off).
- X * This assumes there is space on the end of 'file' to append
- X * a two digit number. This is true for 'level'
- X * but be careful if you use it for other things -dgk
- X */
- Xvoid
- Xset_levelfile_name(file, lev)
- Xchar *file;
- Xint lev;
- X{
- X char *tf;
- X
- X tf = rindex(file, '.');
- X if (!tf) tf = eos(file);
- X Sprintf(tf, ".%d", lev);
- X#ifdef VMS
- X Strcat(tf, ";1");
- X#endif
- X return;
- X}
- X
- Xint
- Xcreate_levelfile(lev)
- Xint lev;
- X{
- X int fd;
- X
- X set_levelfile_name(lock, lev);
- X
- X#if defined(MICRO)
- X /* Use O_TRUNC to force the file to be shortened if it already
- X * exists and is currently longer.
- X */
- X fd = open(lock, O_WRONLY |O_CREAT | O_TRUNC | O_BINARY, FCMASK);
- X#else
- X#ifdef MAC
- X fd = maccreat ( lock , LEVL_TYPE ) ;
- X#else /* MAC */
- X fd = creat(lock, FCMASK);
- X#endif /* MAC */
- X#endif /* MICRO */
- X
- X return fd;
- X}
- X
- X
- Xint
- Xopen_levelfile(lev)
- Xint lev;
- X{
- X int fd;
- X
- X set_levelfile_name(lock, lev);
- X#ifdef MFLOPPY
- X /* If not currently accessible, swap it in. */
- X if (fileinfo[lev].where != ACTIVE)
- X swapin_file(lev);
- X#endif
- X# ifdef MAC
- X fd = macopen ( lock , O_RDONLY | O_BINARY , LEVL_TYPE ) ;
- X# else /* MAC */
- X fd = open(lock, O_RDONLY | O_BINARY, 0);
- X# endif /* MAC */
- X return fd;
- X}
- X
- X
- Xvoid
- Xdelete_levelfile(lev)
- Xint lev;
- X{
- X set_levelfile_name(lock, lev);
- X (void) unlink(lock);
- X}
- X
- X
- Xvoid
- Xclearlocks()
- X{
- X#ifdef MFLOPPY
- X eraseall(levels, alllevels);
- X# ifndef AMIGA
- X if (ramdisk)
- X eraseall(permbones, alllevels);
- X# endif
- X#else
- X register int x;
- X
- X# if defined(UNIX) || defined(VMS)
- X (void) signal(SIGHUP, SIG_IGN);
- X# endif
- X for (x = maxledgerno(); x >= 0; x--)
- X delete_levelfile(x); /* not all levels need be present */
- X#endif
- X}
- X
- X/* ---------- END LEVEL FILE HANDLING ----------- */
- X
- X
- X/* ---------- BEGIN BONES FILE HANDLING ----------- */
- X
- Xstatic char *
- Xset_bonesfile_name(file, lev)
- Xchar *file;
- Xd_level *lev;
- X{
- X char *dptr = rindex(file, '.');
- X s_level *sptr;
- X
- X if (!dptr) dptr = eos(file);
- X *(dptr-2) = dungeons[lev->dnum].boneid;
- X#ifdef MULDGN
- X *(dptr-1) = In_quest(lev) ? pl_character[0] : '0';
- X#else
- X *(dptr-1) = '0';
- X#endif
- X if ((sptr = Is_special(lev)) != 0)
- X Sprintf(dptr, ".%c", sptr->boneid);
- X else
- X Sprintf(dptr, ".%d", lev->dlevel);
- X#ifdef VMS
- X Strcat(dptr, ";1");
- X#endif
- X return(dptr-2);
- X}
- X
- Xint
- Xcreate_bonesfile(lev, bonesid)
- Xd_level *lev;
- Xchar **bonesid;
- X{
- X int fd;
- X
- X *bonesid = set_bonesfile_name(bones, lev);
- X
- X#ifdef MICRO
- X /* Use O_TRUNC to force the file to be shortened if it already
- X * exists and is currently longer.
- X */
- X fd = open(bones, O_WRONLY |O_CREAT | O_TRUNC | O_BINARY, FCMASK);
- X#else
- X# ifdef MAC
- X fd = maccreat ( bones , BONE_TYPE ) ;
- X# else /* MAC */
- X fd = creat(bones, FCMASK);
- X# endif /* MAC */
- X# if defined(VMS) && !defined(SECURE)
- X /*
- X Re-protect bones file with world:read+write+execute+delete access.
- X umask() doesn't seem very reliable; also, vaxcrtl won't let us set
- X delete access without write access, which is what's really wanted.
- X Can't simply create it with the desired protection because creat
- X ANDs the mask with the user's default protection, which usually
- X denies some or all access to world.
- X */
- X (void) chmod(bones, FCMASK | 007); /* allow other users full access */
- X# endif /* VMS && !SECURE */
- X#endif /* MICRO */
- X
- X return fd;
- X}
- X
- X
- Xint
- Xopen_bonesfile(lev, bonesid)
- Xd_level *lev;
- Xchar **bonesid;
- X{
- X int fd;
- X
- X *bonesid = set_bonesfile_name(bones, lev);
- X uncompress(bones); /* no effect if nonexistent */
- X#ifdef MAC
- X fd = macopen ( bones , O_RDONLY | O_BINARY , BONE_TYPE ) ;
- X#else
- X fd = open(bones, O_RDONLY | O_BINARY, 0);
- X#endif
- X return fd;
- X}
- X
- X
- Xint
- Xdelete_bonesfile(lev)
- Xd_level *lev;
- X{
- X (void) set_bonesfile_name(bones, lev);
- X return !(unlink(bones) < 0);
- X}
- X
- X
- X/* assume we're compressing the recently read or created bonesfile, so the
- X * file name is already set properly */
- Xvoid
- Xcompress_bonesfile()
- X{
- X compress(bones);
- X}
- X
- X/* ---------- END BONES FILE HANDLING ----------- */
- X
- X
- X/* ---------- BEGIN SAVE FILE HANDLING ----------- */
- X
- X/* set savefile name in OS-dependent manner from pre-existing plname,
- X * avoiding troublesome characters */
- Xvoid
- Xset_savefile_name()
- X{
- X#ifdef VMS
- X Sprintf(SAVEF, "[.save]%d%s", getuid(), plname);
- X regularize(SAVEF+7);
- X Strcat(SAVEF, ";1");
- X#else
- X# ifdef MICRO
- X Strcpy(SAVEF, SAVEP);
- X {
- X int i = strlen(SAVEP);
- X# ifdef AMIGA
- X /* plname has to share space with SAVEP and ".sav" */
- X (void)strncat(SAVEF, plname, FILENAME - i - 4);
- X# else
- X (void)strncat(SAVEF, plname, 8);
- X# endif
- X regularize(SAVEF+i);
- X }
- X Strcat(SAVEF, ".sav");
- X# else
- X Sprintf(SAVEF, "save/%d%s", (int)getuid(), plname);
- X regularize(SAVEF+5); /* avoid . or / in name */
- X# endif
- X#endif
- X}
- X
- X#ifdef INSURANCE
- Xvoid
- Xsave_savefile_name(fd)
- Xint fd;
- X{
- X (void) write(fd, (genericptr_t) SAVEF, sizeof(SAVEF));
- X}
- X#endif
- X
- X
- X#if defined(WIZARD) && !defined(MICRO)
- X/* change pre-existing savefile name to indicate an error savefile */
- Xvoid
- Xset_error_savefile()
- X{
- X# ifdef VMS
- X {
- X char *semi_colon = rindex(SAVEF, ';');
- X if (semi_colon) *semi_colon = '\0';
- X }
- X Strcat(SAVEF, ".e;1");
- X# else
- X#ifdef MAC
- X Strcat(SAVEF, "-e");
- X#else
- X Strcat(SAVEF, ".e");
- X#endif
- X# endif
- X}
- X#endif
- X
- X
- X/* create save file, overwriting one if it already exists */
- Xint
- Xcreate_savefile()
- X{
- X int fd;
- X# ifdef AMIGA
- X fd = ami_wbench_getsave(O_WRONLY | O_CREAT | O_TRUNC);
- X# else
- X# ifdef MICRO
- X fd = open(SAVEF, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK);
- X# else
- X# ifdef MAC
- X fd = creat(SAVEF, SAVE_TYPE);
- X# else /* MAC */
- X fd = creat(SAVEF, FCMASK);
- X# endif /* MAC */
- X# if defined(VMS) && !defined(SECURE)
- X /*
- X Make sure the save file is owned by the current process. That's
- X the default for non-privileged users, but for priv'd users the
- X file will be owned by the directory's owner instead of the user.
- X */
- X# ifdef getuid /*(see vmsunix.c)*/
- X# undef getuid
- X# endif
- X (void) chown(SAVEF, getuid(), getgid());
- X# endif /* VMS && !SECURE */
- X# endif
- X# endif
- X
- X return fd;
- X}
- X
- X
- X/* open savefile for reading */
- Xint
- Xopen_savefile()
- X{
- X int fd;
- X
- X#ifdef AMIGA
- X fd = ami_wbench_getsave(O_RDONLY);
- X#else
- X# ifdef MAC
- X fd = macopen ( SAVEF , O_RDONLY , SAVE_TYPE ) ;
- X# else /* MAC */
- X fd = open(SAVEF, O_RDONLY, 0);
- X# endif /* MAC */
- X#endif /* AMIGA */
- X return fd;
- X}
- X
- X
- X/* delete savefile */
- Xint
- Xdelete_savefile()
- X{
- X#ifdef AMIGA
- X ami_wbench_unlink(SAVEF);
- X#endif
- X (void) unlink(SAVEF);
- X return 0; /* for xxxmain.c test */
- X}
- X
- X
- X/* ---------- END SAVE FILE HANDLING ----------- */
- X
- X
- X/* ---------- BEGIN FILE COMPRESSION HANDLING ----------- */
- X
- X/* compress file */
- Xvoid
- Xcompress(filename)
- Xconst char *filename;
- X{
- X#ifdef COMPRESS
- X char cmd[80];
- X
- X Strcpy(cmd, COMPRESS);
- X Strcat(cmd, " ");
- X# ifdef COMPRESS_OPTIONS
- X Strcat(cmd, COMPRESS_OPTIONS);
- X Strcat(cmd, " ");
- X# endif
- X Strcat(cmd,filename);
- X (void) system(cmd);
- X#endif
- X}
- X
- X
- X/* uncompress file if it exists */
- Xvoid
- Xuncompress(filename)
- Xconst char *filename;
- X{
- X#ifdef COMPRESS
- X char cmd[80], cfn[80];
- X int fd;
- X
- X Strcpy(cfn,filename);
- X Strcat(cfn,".Z");
- X if((fd = open(cfn,O_RDONLY)) >= 0) {
- X (void) close(fd);
- X Strcpy(cmd, COMPRESS);
- X Strcat(cmd, " -d "); /* uncompress */
- X# ifdef COMPRESS_OPTIONS
- X Strcat(cmd, COMPRESS_OPTIONS);
- X Strcat(cmd, " ");
- X# endif
- X Strcat(cmd,cfn);
- X (void) system(cmd);
- X }
- X#endif
- X}
- X
- X/* ---------- END FILE COMPRESSION HANDLING ----------- */
- X
- X
- X/* ---------- BEGIN FILE LOCKING HANDLING ----------- */
- X
- X#ifdef NO_FILE_LINKS /* implies UNIX */
- Xstatic int lockfd; /* for lock_file() to pass to unlock_file() */
- X#endif
- X
- X#if defined(UNIX) || defined(VMS)
- X#define HUP if(!done_hup)
- X
- Xstatic char *
- Xmake_lockname(filename)
- Xconst char *filename;
- X{
- X static char lockname[BUFSZ];
- X
- X# ifdef NO_FILE_LINKS
- X Strcpy(lockname, LOCKDIR);
- X Strcat(lockname, "/");
- X Strcat(lockname, filename);
- X# else
- X Strcpy(lockname, filename);
- X# endif
- X# ifdef VMS
- X {
- X char *semi_colon = rindex(lockname, ';');
- X if (semi_colon) *semi_colon = '\0';
- X }
- X Strcat(lockname, ".lock;1");
- X# else
- X Strcat(lockname, "_lock");
- X# endif
- X return lockname;
- X}
- X#endif /* UNIX || VMS */
- X
- X
- X/* lock a file */
- Xboolean
- Xlock_file(filename, retryct)
- Xconst char *filename;
- Xint retryct;
- X{
- X#if defined(UNIX) || defined(VMS)
- X char *lockname;
- X
- X lockname = make_lockname(filename);
- X
- X# ifdef NO_FILE_LINKS
- X while ((lockfd = open(lockname, O_RDWR|O_CREAT|O_EXCL, 0666)) == -1) {
- X# else
- X while (link(filename, lockname) == -1) {
- X# endif
- X register int errnosv = errno;
- X
- X switch (errnosv) { /* George Barbanis */
- X case ENOENT:
- X HUP raw_printf("Can't find file %s to lock!", filename);
- X return FALSE;
- X case EACCES:
- X HUP raw_printf("No write permission to lock %s!",
- X filename);
- X return FALSE;
- X case EEXIST:
- X break; /* retry checks below */
- X default:
- X HUP perror(lockname);
- X HUP raw_printf(
- X "Cannot lock %s for unknown reason (%d).",
- X filename, errnosv);
- X return FALSE;
- X }
- X
- X if (!retryct--) {
- X HUP (void) raw_print("I give up. Sorry.");
- X HUP raw_printf("Perhaps there is an old %s around?",
- X lockname);
- X return FALSE;
- X }
- X
- X HUP raw_printf("Waiting for access to %s. (%d retries left).",
- X filename, retryct);
- X# if defined(SYSV) || defined(ULTRIX) || defined(VMS)
- X (void)
- X# endif
- X sleep(1);
- X }
- X#endif /* UNIX || VMS */
- X return TRUE;
- X}
- X
- X
- X#ifdef VMS /* for unlock_file, use the unlink() routine in vmsunix.c */
- X# ifdef unlink
- X# undef unlink
- X# endif
- X# define unlink(foo) vms_unlink(foo)
- X#endif
- X
- X/* unlock file, which must be currently locked by lock_file */
- Xvoid
- Xunlock_file(filename)
- Xconst char *filename;
- X{
- X#if defined(UNIX) || defined(VMS)
- X char *lockname;
- X
- X lockname = make_lockname(filename);
- X
- X if (unlink(lockname) < 0)
- X HUP raw_printf("Can't unlink %s.", lockname);
- X# ifdef NO_FILE_LINKS
- X (void) close(lockfd);
- X# endif
- X
- X#endif /* UNIX || VMS */
- X}
- X
- X/* ---------- END FILE LOCKING HANDLING ----------- */
- X
- X
- X/* ---------- BEGIN CONFIG FILE HANDLING ----------- */
- X
- Xconst char *configfile =
- X#ifdef UNIX
- X ".nethackrc";
- X#else
- X#ifdef MAC
- X "NetHack defaults";
- X#else
- X "NetHack.cnf";
- X#endif
- X#endif
- X
- Xstatic FILE *FDECL(fopen_config_file, (const char *));
- Xstatic int FDECL(get_uchars, (FILE *, char *, char *, uchar *, int, const char *));
- Xint FDECL(parse_config_line, (FILE *, char *, char *, char *));
- X
- X#ifndef MFLOPPY
- X#define fopenp fopen
- X#endif
- X
- Xstatic FILE *
- Xfopen_config_file(filename)
- Xconst char *filename;
- X{
- X FILE *fp;
- X#if defined(UNIX) || defined(VMS)
- X char tmp_config[BUFSZ];
- X#endif
- X
- X /* "filename" is an environment variable, so it should hang around */
- X if (filename && ((fp = fopenp(filename, "r")) != (FILE *)0)) {
- X configfile = filename;
- X return(fp);
- X }
- X
- X#if defined(MICRO) || defined(MAC)
- X if ((fp = fopenp(configfile, "r")) != (FILE *)0)
- X return(fp);
- X#else
- X# ifdef VMS
- X if ((fp = fopenp("nethackini", "r")) != (FILE *)0) {
- X configfile = "nethackini";
- X return(fp);
- X }
- X if ((fp = fopenp("sys$login:nethack.ini", "r")) != (FILE *)0) {
- X configfile = "nethack.ini";
- X return(fp);
- X }
- X Sprintf(tmp_config, "%s%s", getenv("HOME"), "NetHack.cnf");
- X if ((fp = fopenp(tmp_config, "r")) != (FILE *)0)
- X return(fp);
- X# else /* should be only UNIX left */
- X Sprintf(tmp_config, "%s/%s", getenv("HOME"), ".nethackrc");
- X if ((fp = fopenp(tmp_config, "r")) != (FILE *)0)
- X return(fp);
- X# endif
- X#endif
- X return (FILE *)0;
- X
- X}
- X
- X
- X/*
- X * Retrieve a list of integers from a file into a uchar array.
- X *
- X * NOTE: This routine is unable to read a value of 0.
- X */
- Xstatic int
- Xget_uchars(fp, buf, bufp, list, size, name)
- X FILE *fp; /* input file pointer */
- X char *buf; /* read buffer, must be of size BUFSZ */
- X char *bufp; /* current pointer */
- X uchar *list; /* return list */
- X int size; /* return list size */
- X const char *name; /* name of option for error message */
- X{
- X unsigned int num = 0;
- X int count = 0;
- X
- X while (1) {
- X switch(*bufp) {
- X case ' ': case '\0':
- X case '\t': case '\n':
- X if (num) {
- X list[count++] = num;
- X num = 0;
- X }
- X if (count == size || !*bufp) return count;
- X bufp++;
- X break;
- X
- X case '0': case '1': case '2': case '3':
- X case '4': case '5': case '6': case '7':
- X case '8': case '9':
- X num = num*10 + (*bufp-'0');
- X bufp++;
- X break;
- X
- X case '\\':
- X if (fp == (FILE *)0)
- X goto gi_error;
- X do {
- X if (!fgets(buf, BUFSZ, fp)) goto gi_error;
- X } while (buf[0] == '#');
- X bufp = buf;
- X break;
- X
- X default:
- Xgi_error:
- X raw_printf("Syntax error in %s", name);
- X wait_synch();
- X return count;
- X }
- X }
- X /*NOTREACHED*/
- X}
- X
- X/*ARGSUSED*/
- Xint
- Xparse_config_line(fp, buf, tmp_ramdisk, tmp_levels)
- XFILE *fp;
- Xchar *buf;
- Xchar *tmp_ramdisk;
- Xchar *tmp_levels;
- X{
- X char *bufp, *altp;
- X
- X if (*buf == '#')
- X return 1;
- X
- X /* remove trailing whitespace */
- X bufp = eos(buf);
- X while (--bufp > buf && isspace(*bufp))
- X continue;
- X
- X if (bufp <= buf)
- X return 1; /* skip all-blank lines */
- X else
- X *(bufp + 1) = '\0'; /* terminate line */
- X
- X /* find the '=' or ':' */
- X bufp = index(buf, '=');
- X altp = index(buf, ':');
- X if (!bufp || (altp && altp < bufp)) bufp = altp;
- X if (!bufp) return 0;
- X
- X /* skip whitespace between '=' and value */
- X do { ++bufp; } while (isspace(*bufp));
- X
- X /* Go through possible variables */
- X if (!strncmpi(buf, "OPTIONS", 4)) {
- X parseoptions(bufp, TRUE, TRUE);
- X if (plname[0]) /* If a name was given */
- X plnamesuffix(); /* set the character class */
- X#ifdef MICRO
- X } else if (!strncmpi(buf, "HACKDIR", 4)) {
- X (void) strncpy(hackdir, bufp, PATHLEN);
- X# ifdef MFLOPPY
- X } else if (!strncmpi(buf, "RAMDISK", 3)) {
- X /* The following ifdef is NOT in the wrong
- X * place. For now, we accept and silently
- X * ignore RAMDISK */
- X# ifndef AMIGA
- X (void) strncpy(tmp_ramdisk, bufp, PATHLEN);
- X# endif
- X# endif
- X } else if (!strncmpi(buf, "LEVELS", 4)) {
- X (void) strncpy(tmp_levels, bufp, PATHLEN);
- X
- X } else if (!strncmpi(buf, "SAVE", 4)) {
- X char *ptr;
- X if (ptr = index(bufp, ';')) {
- X *ptr = '\0';
- X# ifdef MFLOPPY
- X if (*(ptr+1) == 'n' || *(ptr+1) == 'N') {
- X extern int saveprompt;
- X saveprompt = FALSE;
- X }
- X# endif
- X }
- X (void) strncpy(SAVEP, bufp, PATHLEN);
- X append_slash(SAVEP);
- X#endif /* MICRO */
- X } else if(!strncmpi(buf, "CHARACTER", 4)) {
- X (void) strncpy(pl_character, bufp, PL_CSIZ);
- X } else if(!strncmpi(buf, "DOGNAME", 3)) {
- X (void) strncpy(dogname, bufp, 62);
- X } else if(!strncmpi(buf, "CATNAME", 3)) {
- X (void) strncpy(catname, bufp, 62);
- X } else if(!strncmpi(buf, "NAME", 4)) {
- X (void) strncpy(plname, bufp, PL_NSIZ);
- X plnamesuffix();
- X } else if (!strncmpi(buf, "GRAPHICS", 4)) {
- X uchar translate[MAXPCHARS];
- X int len;
- X
- X len = get_uchars(fp, buf, bufp, translate,
- X MAXPCHARS, "GRAPHICS");
- X assign_graphics(translate, len);
- X } else if (!strncmpi(buf, "OBJECTS", 3)) {
- X /* oc_syms[0] is the RANDOM object, unused */
- X (void) get_uchars(fp, buf, bufp, &(oc_syms[1]),
- X MAXOCLASSES-1, "OBJECTS");
- X } else if (!strncmpi(buf, "MONSTERS", 3)) {
- X /* monsyms[0] is unused */
- X (void) get_uchars(fp, buf, bufp, &(monsyms[1]),
- X MAXMCLASSES-1, "MONSTERS");
- X#ifdef AMIGA
- X } else if (!strncmpi(buf, "PATH", 4)) {
- X (void) strncpy(PATH, bufp, PATHLEN);
- X } else if (!strncmpi(buf, "PENS", 3)) {
- X int i;
- X char *t;
- X extern unsigned short amii_curmap[];
- X for (i = 0, t = strtok(bufp, ",");
- X t && i < 8;
- X t = strtok(NULL, ","), ++i) {
- X sscanf(t, "%hx", &amii_curmap[i]);
- X }
- X amii_setpens();
- X#endif
- X } else
- X return 0;
- X return 1;
- X}
- X
- Xvoid
- Xread_config_file(filename)
- Xconst char *filename;
- X{
- X#define tmp_levels (char *)0
- X#define tmp_ramdisk (char *)0
- X
- X#ifdef MICRO
- X#undef tmp_levels
- X char tmp_levels[PATHLEN];
- X# ifdef MFLOPPY
- X# ifndef AMIGA
- X#undef tmp_ramdisk
- X char tmp_ramdisk[PATHLEN];
- X# endif
- X# endif
- X#endif
- X char buf[BUFSZ];
- X FILE *fp;
- X
- X#if defined(MAC)
- X {
- X long nul = 0L ;
- X Str255 volName ;
- X /*
- X * We should try and get this data from a rsrc, in the profile file
- X * the user double-clicked... This data should be saved with the
- X * save file in the resource fork, AND be saveable in "stationery"
- X */
- X GetVol ( volName , & theDirs . dataRefNum ) ;
- X GetWDInfo ( theDirs . dataRefNum , & theDirs . dataRefNum , & theDirs .
- X dataDirID , & nul ) ;
- X if ( volName [ 0 ] > 31 ) volName [ 0 ] = 31 ;
- X for ( nul = 1 ; nul <= volName [ 0 ] ; nul ++ ) {
- X if ( volName [ nul ] == ':' ) {
- X volName [ nul ] = 0 ;
- X volName [ 0 ] = nul - 1 ;
- X break ;
- X }
- X }
- X BlockMove ( volName , theDirs . dataName , 32L ) ;
- X }
- X#endif /* MAC */
- X
- X if (!(fp = fopen_config_file(filename))) return;
- X
- X#ifdef MICRO
- X# ifdef MFLOPPY
- X# ifndef AMIGA
- X tmp_ramdisk[0] = 0;
- X# endif
- X# endif
- X tmp_levels[0] = 0;
- X#endif
- X
- X while (fgets(buf, BUFSZ, fp)) {
- X if (!parse_config_line(fp, buf, tmp_ramdisk, tmp_levels)) {
- X raw_printf("Bad option line: \"%s\"", buf);
- X wait_synch();
- X }
- X }
- X (void) fclose(fp);
- X
- X#ifdef MICRO
- X# ifdef MFLOPPY
- X Strcpy(permbones, tmp_levels);
- X# ifndef AMIGA
- X if (tmp_ramdisk[0]) {
- X Strcpy(levels, tmp_ramdisk);
- X if (strcmp(permbones, levels)) /* if not identical */
- X ramdisk = TRUE;
- X } else
- X# endif /* AMIGA */
- X Strcpy(levels, tmp_levels);
- X
- X Strcpy(bones, levels);
- X# endif /* MFLOPPY */
- X#endif /* MICRO */
- X return;
- X}
- X
- X/* ---------- END CONFIG FILE HANDLING ----------- */
- X
- X/* ---------- BEGIN SCOREBOARD CREATION ----------- */
- X
- X/* verify that we can write to the scoreboard file; if not, try to create one */
- Xvoid
- Xcheck_recordfile(dir)
- Xconst char *dir;
- X{
- X#if defined(UNIX) || defined(VMS)
- X int fd = open(RECORD, O_RDWR, 0);
- X
- X if (fd >= 0) {
- X# ifdef VMS /* must be stream-lf to use UPDATE_RECORD_IN_PLACE */
- X if (!file_is_stmlf(fd)) {
- X raw_printf( /* note: assume VMS dir has trailing punct */
- X "Warning: scoreboard file %s%s is not in stream_lf format",
- X (dir ? dir : "[]"), RECORD);
- X wait_synch();
- X }
- X# endif
- X (void) close(fd); /* RECORD is accessible */
- X } else if ((fd = open(RECORD, O_CREAT|O_RDWR, FCMASK)) >= 0) {
- X (void) close(fd); /* RECORD newly created */
- X# if defined(VMS) && !defined(SECURE)
- X /* Re-protect RECORD with world:read+write+execute+delete access. */
- X (void) chmod(RECORD, FCMASK | 007); /* allow everyone full access */
- X# endif /* VMS && !SECURE */
- X } else {
- X raw_printf("Warning: cannot write scoreboard file %s/%s",
- X (dir ? dir : "."), RECORD);
- X wait_synch();
- X }
- X#endif /* !UNIX && !VMS */
- X
- X#ifdef MICRO
- X int fd;
- X char tmp[PATHLEN];
- X
- X# ifdef OS2_CODEVIEW /* explicit path on opening for OS/2 */
- X Strcpy(tmp, dir);
- X append_slash(tmp);
- X Strcat(tmp, RECORD);
- X# else
- X Strcpy(tmp, RECORD);
- X# endif
- X
- X if ((fd = open(tmp, O_RDWR)) < 0) {
- X /* try to create empty record */
- X# ifdef AZTEC_C
- X /* Aztec doesn't use the third argument */
- X if ((fd = open(tmp, O_CREAT|O_RDWR)) < 0) {
- X# else
- X if ((fd = open(tmp, O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) < 0) {
- X# endif
- X raw_printf("Warning: cannot write record %s", tmp);
- X wait_synch();
- X } else
- X (void) close(fd);
- X } else /* open succeeded */
- X (void) close(fd);
- X#else /* MICRO */
- X
- X# ifdef MAC
- X int fd = macopen ( RECORD , O_RDWR | O_CREAT , TEXT_TYPE ) ;
- X
- X if ( fd < 0 ) {
- X raw_printf ( "Warning: cannot write %s" , RECORD ) ;
- X } else {
- X close ( fd ) ;
- X }
- X# endif /* MAC */
- X
- X#endif /* MICRO */
- X}
- X
- X/* ---------- END SCOREBOARD CREATION ----------- */
- X
- X
- X/*files.c*/
- END_OF_FILE
- if test 21581 -ne `wc -c <'src/files.c'`; then
- echo shar: \"'src/files.c'\" unpacked with wrong size!
- fi
- # end of 'src/files.c'
- fi
- if test -f 'src/zap.c2' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/zap.c2'\"
- else
- echo shar: Extracting \"'src/zap.c2'\" \(32988 characters\)
- sed "s/^X//" >'src/zap.c2' <<'END_OF_FILE'
- Xconst char *
- Xexclam(force)
- Xregister int force;
- X{
- X /* force == 0 occurs e.g. with sleep ray */
- X /* note that large force is usual with wands so that !! would
- X require information about hand/weapon/wand */
- X return (const char *)((force < 0) ? "?" : (force <= 4) ? "." : "!");
- X}
- X
- Xvoid
- Xhit(str,mtmp,force)
- Xregister const char *str;
- Xregister struct monst *mtmp;
- Xregister const char *force; /* usually either "." or "!" */
- X{
- X if(!cansee(bhitpos.x,bhitpos.y) || !flags.verbose)
- X pline("%s hits it.", The(str));
- X else pline("%s hits %s%s", The(str), mon_nam(mtmp), force);
- X}
- X
- Xvoid
- Xmiss(str,mtmp)
- Xregister const char *str;
- Xregister struct monst *mtmp;
- X{
- X pline("%s misses %s.", The(str),
- X (cansee(bhitpos.x,bhitpos.y) && flags.verbose) ?
- X mon_nam(mtmp) : "it");
- X}
- X
- X/*
- X * Called for the following distance effects:
- X * when a weapon is thrown (weapon == THROWN_WEAPON)
- X * when an object is kicked (KICKED_WEAPON)
- X * when an IMMEDIATE wand is zapped (ZAPPED_WAND)
- X * when a light beam is flashed (FLASHED_LIGHT)
- X * for some invisible effect on a monster (INVIS_BEAM)
- X * A thrown/kicked object falls down at the end of its range or when a monster
- X * is hit. The variable 'bhitpos' is set to the final position of the weapon
- X * thrown/zapped. The ray of a wand may affect (by calling a provided
- X * function) several objects and monsters on its path. The return value
- X * is the monster hit (weapon != ZAPPED_WAND), or a null monster pointer.
- X *
- X * Check !u.uswallow before calling bhit().
- X */
- Xstruct monst *
- Xbhit(ddx,ddy,range,weapon,fhitm,fhito,obj)
- Xregister int ddx,ddy,range; /* direction and range */
- Xint weapon; /* see values in hack.h */
- X /* fns called when mon/obj hit */
- Xint FDECL((*fhitm), (MONST_P, OBJ_P)),
- X FDECL((*fhito), (OBJ_P, OBJ_P));
- Xstruct obj *obj; /* object tossed/used */
- X{
- X register struct monst *mtmp;
- X register uchar typ;
- X register boolean shopdoor = FALSE;
- X
- X if (weapon == KICKED_WEAPON) {
- X /* object starts one square in front of player */
- X bhitpos.x = u.ux + ddx;
- X bhitpos.y = u.uy + ddy;
- X range--;
- X } else {
- X bhitpos.x = u.ux;
- X bhitpos.y = u.uy;
- X }
- X
- X if (weapon == FLASHED_LIGHT) {
- X tmp_at(DISP_BEAM, cmap_to_glyph(S_flashbeam));
- X } else if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM)
- X tmp_at(DISP_FLASH, obj_to_glyph(obj));
- X while(range-- > 0) {
- X int x,y;
- X
- X bhitpos.x += ddx;
- X bhitpos.y += ddy;
- X x = bhitpos.x; y = bhitpos.y;
- X
- X if(!isok(x, y)) {
- X bhitpos.x -= ddx;
- X bhitpos.y -= ddy;
- X break;
- X }
- X if(obj->otyp == PICK_AXE && inside_shop(x, y) &&
- X shkcatch(obj, x, y)) {
- X tmp_at(DISP_END, 0);
- X return(m_at(x, y));
- X }
- X
- X typ = levl[bhitpos.x][bhitpos.y].typ;
- X
- X if (weapon == ZAPPED_WAND && find_drawbridge(&x,&y))
- X switch (obj->otyp) {
- X case WAN_OPENING:
- X case SPE_KNOCK:
- X if (is_db_wall(bhitpos.x, bhitpos.y)) {
- X if (cansee(x,y) || cansee(bhitpos.x,bhitpos.y))
- X makeknown(obj->otyp);
- X open_drawbridge(x,y);
- X }
- X break;
- X case WAN_LOCKING:
- X case SPE_WIZARD_LOCK:
- X if ((cansee(x,y) || cansee(bhitpos.x, bhitpos.y))
- X && levl[x][y].typ == DRAWBRIDGE_DOWN)
- X makeknown(obj->otyp);
- X close_drawbridge(x,y);
- X break;
- X case WAN_STRIKING:
- X case SPE_FORCE_BOLT:
- X if (typ != DRAWBRIDGE_UP)
- X destroy_drawbridge(x,y);
- X makeknown(obj->otyp);
- X break;
- X }
- X
- X if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) {
- X if(weapon != ZAPPED_WAND) {
- X if(weapon != INVIS_BEAM) tmp_at(DISP_END, 0);
- X return(mtmp);
- X }
- X (*fhitm)(mtmp, obj);
- X range -= 3;
- X }
- X if(fhito) {
- X if(bhitpile(obj,fhito,bhitpos.x,bhitpos.y))
- X range--;
- X } else if(weapon == KICKED_WEAPON &&
- X ((obj->otyp == GOLD_PIECE &&
- X OBJ_AT(bhitpos.x, bhitpos.y)) ||
- X down_gate(bhitpos.x, bhitpos.y) != -1)) {
- X tmp_at(DISP_END, 0);
- X return (struct monst *)0;
- X }
- X if(weapon == ZAPPED_WAND && (IS_DOOR(typ) || typ == SDOOR)) {
- X switch (obj->otyp) {
- X case WAN_OPENING:
- X case WAN_LOCKING:
- X case WAN_STRIKING:
- X case SPE_KNOCK:
- X case SPE_WIZARD_LOCK:
- X case SPE_FORCE_BOLT:
- X if (doorlock(obj, bhitpos.x, bhitpos.y)) {
- X if (cansee(bhitpos.x, bhitpos.y) ||
- X (obj->otyp == WAN_STRIKING))
- X makeknown(obj->otyp);
- X if (levl[bhitpos.x][bhitpos.y].doormask == D_BROKEN
- X && *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE)) {
- X shopdoor = TRUE;
- X }
- X }
- X break;
- X }
- X }
- X if(!ZAP_POS(typ) || closed_door(bhitpos.x, bhitpos.y)) {
- X bhitpos.x -= ddx;
- X bhitpos.y -= ddy;
- X break;
- X }
- X if(weapon != ZAPPED_WAND && weapon != INVIS_BEAM) {
- X tmp_at(bhitpos.x, bhitpos.y);
- X delay_output();
- X /* kicked objects fall in pools */
- X if((weapon == KICKED_WEAPON) &&
- X is_pool(bhitpos.x, bhitpos.y))
- X break;
- X#ifdef SINKS
- X if(IS_SINK(typ) && weapon != FLASHED_LIGHT)
- X break; /* physical objects fall onto sink */
- X#endif
- X }
- X }
- X
- X if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM) tmp_at(DISP_END, 0);
- X
- X if(shopdoor)
- X pay_for_damage("destroy");
- X
- X return (struct monst *)0;
- X}
- X
- Xstruct monst *
- Xboomhit(dx, dy)
- Xint dx, dy;
- X{
- X register int i, ct;
- X int boom = S_boomleft; /* showsym[] index */
- X struct monst *mtmp;
- X
- X bhitpos.x = u.ux;
- X bhitpos.y = u.uy;
- X
- X for(i=0; i<8; i++) if(xdir[i] == dx && ydir[i] == dy) break;
- X tmp_at(DISP_FLASH, cmap_to_glyph(boom));
- X for(ct=0; ct<10; ct++) {
- X if(i == 8) i = 0;
- X boom = (boom == S_boomleft) ? S_boomright : S_boomleft;
- X tmp_at(DISP_CHANGE, cmap_to_glyph(boom));/* change glyph */
- X dx = xdir[i];
- X dy = ydir[i];
- X bhitpos.x += dx;
- X bhitpos.y += dy;
- X if(MON_AT(bhitpos.x, bhitpos.y)) {
- X mtmp = m_at(bhitpos.x,bhitpos.y);
- X m_respond(mtmp);
- X tmp_at(DISP_END, 0);
- X return(mtmp);
- X }
- X if(!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ) ||
- X closed_door(bhitpos.x, bhitpos.y)) {
- X bhitpos.x -= dx;
- X bhitpos.y -= dy;
- X break;
- X }
- X if(bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */
- X if(Fumbling || rn2(20) >= ACURR(A_DEX)) {
- X /* we hit ourselves */
- X (void) thitu(10, rnd(10), (struct obj *)0,
- X "boomerang");
- X break;
- X } else { /* we catch it */
- X tmp_at(DISP_END, 0);
- X pline("Skillfully, you catch the boomerang.");
- X return(&youmonst);
- X }
- X }
- X tmp_at(bhitpos.x, bhitpos.y);
- X delay_output();
- X if(ct % 5 != 0) i++;
- X#ifdef SINKS
- X if(IS_SINK(levl[bhitpos.x][bhitpos.y].typ))
- X break; /* boomerang falls on sink */
- X#endif
- X }
- X tmp_at(DISP_END, 0); /* do not leave last symbol */
- X return (struct monst *)0;
- X}
- X
- Xstatic int
- Xzhit(mon, type, nd) /* returns damage to mon */
- Xregister struct monst *mon;
- Xregister int type, nd;
- X{
- X register int tmp = 0;
- X register int abstype = abs(type) % 10;
- X
- X switch(abstype) {
- X case ZT_MAGIC_MISSILE:
- X tmp = d(nd,6);
- X break;
- X case ZT_FIRE:
- X if(resists_fire(mon->data)) {
- X shieldeff(mon->mx, mon->my);
- X break;
- X }
- X tmp = d(nd,6);
- X if(resists_cold(mon->data)) tmp += 7;
- X break;
- X case ZT_COLD:
- X if(resists_cold(mon->data)) {
- X shieldeff(mon->mx, mon->my);
- X break;
- X }
- X tmp = d(nd,6);
- X if(resists_fire(mon->data)) tmp += d(nd, 3);
- X break;
- X case ZT_SLEEP:
- X tmp = 0;
- X if(resists_sleep(mon->data) ||
- X resist(mon, (type == ZT_WAND(ZT_SLEEP)) ?
- X WAND_CLASS : '\0', 0, NOTELL))
- X shieldeff(mon->mx, mon->my);
- X else if (mon->mcanmove) {
- X int tmp2 = d(nd,25);
- X mon->mcanmove = 0;
- X if ((unsigned)mon->mfrozen + tmp2 > 127)
- X mon->mfrozen = 127;
- X else mon->mfrozen += tmp2;
- X }
- X break;
- X case ZT_DEATH: /* death/disintegration */
- X if(abs(type) != ZT_BREATH(ZT_DEATH)) { /* death */
- X if(mon->data == &mons[PM_DEATH]) {
- X mon->mhpmax += mon->mhpmax/2;
- X mon->mhp = mon->mhpmax;
- X tmp = 0;
- X break;
- X }
- X if(is_undead(mon->data)) {
- X shieldeff(mon->mx, mon->my);
- X break;
- X }
- X type = -1; /* so they don't get saving throws */
- X } else {
- X if (resists_disint(mon->data)) {
- X shieldeff(mon->mx, mon->my);
- X break;
- X } else {
- X tmp = MAGIC_COOKIE;
- X break;
- X }
- X }
- X tmp = mon->mhp+1;
- X break;
- X case ZT_LIGHTNING:
- X if(resists_elec(mon->data)) {
- X shieldeff(mon->mx, mon->my);
- X break;
- X }
- X tmp = d(nd,6);
- X if (haseyes(mon->data)) {
- X register unsigned rnd_tmp = rnd(50);
- X mon->mcansee = 0;
- X if((mon->mblinded + rnd_tmp) > 127)
- X mon->mblinded = 127;
- X else mon->mblinded += rnd_tmp;
- X }
- X break;
- X case ZT_POISON_GAS:
- X if(resists_poison(mon->data)) {
- X shieldeff(mon->mx, mon->my);
- X break;
- X }
- X tmp = d(nd,6);
- X break;
- X case ZT_ACID:
- X if(resists_acid(mon->data)) {
- X shieldeff(mon->mx, mon->my);
- X break;
- X }
- X tmp = d(nd,6);
- X break;
- X }
- X#ifdef MULDGN
- X if(pl_character[0] == 'K' && type >= 10 && type <= 19 &&
- X u.uhave.questart) tmp *= 2;
- X#endif
- X if (type >= 0)
- X if (resist(mon, (type < ZT_SPELL(0)) ? WAND_CLASS : '\0',
- X 0, NOTELL)) tmp /= 2;
- X mon->mhp -= tmp;
- X return(tmp);
- X}
- X
- X/*
- X * burn scrolls and spell books on floor at position x,y
- X * return the number of scrolls and spell books burned
- X */
- Xstatic int
- Xburn_floor_paper(x, y)
- Xint x, y;
- X{
- X register struct obj *obj, *obj2;
- X register int cnt = 0;
- X register long i, scrquan;
- X
- X for(obj = level.objects[x][y]; obj; obj = obj2) {
- X obj2 = obj->nexthere;
- X /* Bug fix - KAA */
- X if(obj->oclass == SCROLL_CLASS
- X || obj->oclass == SPBOOK_CLASS) {
- X if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
- X continue;
- X scrquan = obj->quan;
- X for(i = 1; i <= scrquan ; i++)
- X if(!rn2(3)) {
- X cnt++;
- X /* not useupf(), which charges */
- X if (obj->quan > 1L) obj->quan--;
- X else delobj(obj);
- X }
- X }
- X }
- X return(cnt);
- X}
- X
- X/* type == 0 to 9 : you shooting a wand */
- X/* type == 10 to 19 : you casting a spell */
- X/* type == 20 to 29 : you breathing as a monster */
- X/* type == -10 to -19 : monster casting spell */
- X/* type == -20 to -29 : monster breathing at you */
- X/* type == -30 to -39 : monster shooting a wand (MUSE only) */
- X/* called with dx = dy = 0 with vertical bolts */
- Xvoid
- Xbuzz(type,nd,sx,sy,dx,dy)
- Xregister int type, nd;
- Xregister xchar sx,sy;
- Xregister int dx,dy;
- X{
- X int range, abstype = abs(type) % 10;
- X struct rm *lev;
- X register xchar lsx, lsy;
- X struct monst *mon;
- X boolean bodyhit = FALSE, shopdamage = FALSE;
- X#ifdef MUSE
- X register const char *fltxt = fl[(type <= -30) ? abstype : abs(type)];
- X#else
- X register const char *fltxt = fl[abs(type)];
- X#endif
- X if(u.uswallow) {
- X register int tmp;
- X
- X if(type < 0) return;
- X tmp = zhit(u.ustuck, type, nd);
- X if(!u.ustuck) u.uswallow = 0;
- X else pline("%s rips into %s%s",
- X The(fltxt), mon_nam(u.ustuck), exclam(tmp));
- X /* Using disintegration from the inside only makes a hole... */
- X if (tmp == MAGIC_COOKIE)
- X u.ustuck->mhp = 0;
- X if (u.ustuck->mhp < 1)
- X killed(u.ustuck);
- X return;
- X }
- X if(type < 0) newsym(u.ux,u.uy);
- X range = rn1(7,7);
- X if(dx == 0 && dy == 0) range = 1;
- X tmp_at(DISP_BEAM, zapdir_to_glyph(dx, dy, abstype));
- X while(range-- > 0) {
- X lsx = sx; sx += dx;
- X lsy = sy; sy += dy;
- X if(isok(sx,sy) && (lev = &levl[sx][sy])->typ) {
- X if(cansee(sx,sy)) {
- X if(ZAP_POS(lev->typ) || cansee(lsx,lsy))
- X tmp_at(sx,sy);
- X delay_output(); /* wait a little */
- X }
- X } else
- X goto make_bounce;
- X
- X if (type != ZT_SPELL(ZT_FIRE))
- X /* Fireballs only damage when they explode */
- X range += zap_over_floor(sx, sy, type, &shopdamage);
- X if ((mon = m_at(sx, sy)) != 0) {
- X if (type == ZT_SPELL(ZT_FIRE)) break;
- X if (type >= 0) mon->data->mflags3 &= ~M3_WAITMASK;
- X if (rnd(20) < 18 + find_mac(mon)) {
- X#ifdef MUSE
- X struct obj *oshld = which_armor(mon, W_ARMS);
- X
- X if (oshld && oshld->otyp == SHIELD_OF_REFLECTION) {
- X if(cansee(mon->mx,mon->my)) {
- X hit(fltxt, mon, exclam(0));
- X pline("But it reflects from %s shield!",
- X s_suffix(mon_nam(mon)));
- X makeknown(SHIELD_OF_REFLECTION);
- X shieldeff(sx, sy);
- X }
- X
- X dx = -dx;
- X dy = -dy;
- X } else
- X#endif
- X {
- X register int tmp = zhit(mon, type, nd);
- X
- X if (is_rider(mon->data) && type == ZT_BREATH(ZT_DEATH)) {
- X if(cansee(mon->mx, mon->my)) {
- X hit(fltxt, mon, exclam(tmp));
- X pline("%s disintegrates.", Monnam(mon));
- X if(Blind)
- X You("sense the fragments of %s body reassembling!",
- X s_suffix(mon_nam(mon)));
- X else
- X pline("%s body fragments reassemble before your %s!",
- X s_suffix(Monnam(mon)),
- X makeplural(body_part(EYE)));
- X pline("%s resurrects!", Monnam(mon));
- X }
- X mon->mhp = mon->mhpmax;
- X break; /* Out of while loop */
- X }
- X if(mon->data == &mons[PM_DEATH] &&
- X abs(type)%10 == ZT_DEATH) {
- X if(cansee(mon->mx,mon->my)) {
- X hit(fltxt, mon, exclam(tmp));
- X pline("Death absorbs the deadly %s!",
- X type == ZT_BREATH(ZT_DEATH) ?
- X "blast" : "ray");
- X pline("It seems even stronger than before.");
- X }
- X break; /* Out of while loop */
- X }
- X if (tmp == MAGIC_COOKIE) { /* disintegration */
- X struct obj *otmp, *otmp2;
- X pline("%s is disintegrated!", Monnam(mon));
- X mon->mgold = 0;
- X otmp = mon->minvent;
- X while(otmp) {
- X#ifdef MULDGN
- X if (is_quest_artifact(otmp))
- X otmp = otmp->nobj;
- X else {
- X#endif
- X otmp2 = otmp;
- X if (otmp == mon->minvent)
- X mon->minvent = otmp->nobj;
- X otmp = otmp->nobj;
- X obfree(otmp2, (struct obj *)0);
- X#ifdef MULDGN
- X }
- X#endif
- X }
- X if (type < 0)
- X monkilled(mon, (char *)0, AD_RBRE);
- X else
- X xkilled(mon, 2);
- X } else if(mon->mhp < 1) {
- X if(type < 0)
- X monkilled(mon, fltxt, AD_RBRE);
- X else
- X killed(mon);
- X } else
- X hit(fltxt, mon, exclam(tmp));
- X }
- X range -= 2;
- X } else
- X miss(fltxt,mon);
- X } else if(sx == u.ux && sy == u.uy) {
- X nomul(0);
- X if(rnd(20) < 18+u.uac) {
- X register int dam = 0;
- X range -= 2;
- X pline("%s hits you!", The(fltxt));
- X if (Reflecting) {
- X if (!Blind) {
- X if(Reflecting & WORN_AMUL)
- X makeknown(AMULET_OF_REFLECTION);
- X else
- X makeknown(SHIELD_OF_REFLECTION);
- X pline("But it reflects from your %s!",
- X (Reflecting & W_AMUL) ? "amulet" : "shield");
- X } else
- X pline("For some reason you are not affected.");
- X dx = -dx;
- X dy = -dy;
- X shieldeff(sx, sy);
- X }
- X else switch(abstype) {
- X case ZT_MAGIC_MISSILE:
- X if(Antimagic) {
- X shieldeff(sx, sy);
- X pline("The missiles bounce off!");
- X } else {
- X dam = d(nd,6);
- X exercise(A_STR, FALSE);
- X }
- X break;
- X case ZT_FIRE:
- X if(Fire_resistance) {
- X shieldeff(sx, sy);
- X You("don't feel hot!");
- X#ifdef POLYSELF
- X ugolemeffects(AD_FIRE, d(nd, 6));
- X#endif
- X } else dam = d(nd, 6);
- X while (1) {
- X switch(rn2(5)) {
- X case 0:
- X if (!rust_dmg(uarmh, "leather helmet", 0, FALSE))
- X continue;
- X break;
- X case 1:
- X bodyhit = TRUE;
- X if (uarmc) break;
- X if (uarm)
- X (void)(rust_dmg(uarm, xname(uarm), 0, FALSE));
- X break;
- X case 2:
- X if (!rust_dmg(uarms, "wooden shield", 0, FALSE))
- X continue;
- X break;
- X case 3:
- X if (!rust_dmg(uarmg, "gloves", 0, FALSE)) continue;
- X break;
- X case 4:
- X if (!rust_dmg(uarmf, "boots", 0, FALSE)) continue;
- X break;
- X }
- X break; /* Out of while loop */
- X }
- X if(!rn2(3) && bodyhit)
- X destroy_item(POTION_CLASS, AD_FIRE);
- X if(!rn2(3) && bodyhit)
- X destroy_item(SCROLL_CLASS, AD_FIRE);
- X if(!rn2(5) && bodyhit)
- X destroy_item(SPBOOK_CLASS, AD_FIRE);
- X break;
- X case ZT_COLD:
- X if(Cold_resistance) {
- X shieldeff(sx, sy);
- X You("don't feel cold.");
- X#ifdef POLYSELF
- X ugolemeffects(AD_COLD, d(nd, 6));
- X#endif
- X } else
- X dam = d(nd, 6);
- X if(!rn2(3))
- X destroy_item(POTION_CLASS, AD_COLD);
- X break;
- X case ZT_SLEEP:
- X if(Sleep_resistance) {
- X shieldeff(u.ux, u.uy);
- X You("don't feel sleepy.");
- X } else {
- X /* have to do this _before_ we reset multi */
- X stop_occupation();
- X nomul(-d(nd,25)); /* sleep ray */
- X u.usleep = 1;
- X nomovemsg = "You wake up.";
- X }
- X break;
- X case ZT_DEATH:
- X if(abs(type) == ZT_BREATH(ZT_DEATH)) {
- X if (Disint_resistance) {
- X You("are not disintegrated.");
- X break;
- X } else if(uarms) {
- X (void) destroy_arm(uarms);
- X break;
- X } else if (uarm) {
- X (void) destroy_arm(uarm);
- X break;
- X }
- X }
- X#ifdef POLYSELF
- X else if(is_undead(uasmon)) {
- X shieldeff(sx, sy);
- X You("seem unaffected.");
- X break;
- X }
- X#endif
- X else if(Antimagic) {
- X shieldeff(sx, sy);
- X You("aren't affected.");
- X } else
- X u.uhp = -1;
- X break;
- X case ZT_LIGHTNING:
- X if (Shock_resistance) {
- X shieldeff(sx, sy);
- X You("aren't affected.");
- X#ifdef POLYSELF
- X ugolemeffects(AD_ELEC, d(nd, 6));
- X#endif
- X } else {
- X dam = d(nd, 6);
- X exercise(A_CON, FALSE);
- X }
- X if(!rn2(3))
- X destroy_item(WAND_CLASS, AD_ELEC);
- X if(!rn2(3))
- X destroy_item(RING_CLASS, AD_ELEC);
- X break;
- X case ZT_POISON_GAS:
- X poisoned("blast", A_DEX, "poisoned blast", 15);
- X break;
- X case ZT_ACID:
- X#ifdef POLYSELF
- X if (resists_acid(uasmon))
- X dam = 0;
- X else
- X#endif
- X {
- X pline("The acid burns!");
- X dam = d(nd,6);
- X exercise(A_STR, FALSE);
- X }
- X if(!rn2(6)) erode_weapon(TRUE);
- X if(!rn2(6)) erode_armor(TRUE);
- X break;
- X }
- X if(Half_spell_damage && dam &&
- X type < 0 && (type > -20 || type < -29)) /* !Breath */
- X dam = (dam+1) / 2;
- X losehp(dam, fltxt, KILLED_BY_AN);
- X } else pline("%s whizzes by you!", The(fltxt));
- X if (abstype == ZT_LIGHTNING && !Blind) {
- X You("are blinded by the flash!");
- X make_blinded((long)d(nd,50),FALSE);
- X }
- X stop_occupation();
- X nomul(0);
- X }
- X if(!ZAP_POS(lev->typ) || (closed_door(sx, sy) && (range >= 0))) {
- X int bounce;
- X uchar rmn;
- X
- X make_bounce:
- X if (type == ZT_SPELL(ZT_FIRE)) {
- X sx = lsx;
- X sy = lsy;
- X break; /* fireballs explode before the wall */
- X }
- X bounce = 0;
- X range--;
- X if(range && cansee(lsx,lsy))
- X pline("%s bounces!", The(fltxt));
- X if(!dx || !dy || !rn2(20)) {
- X dx = -dx;
- X dy = -dy;
- X } else {
- X if(isok(sx,lsy) && ZAP_POS(rmn = levl[sx][lsy].typ) &&
- X (IS_ROOM(rmn) || (isok(sx+dx,lsy) &&
- X ZAP_POS(levl[sx+dx][lsy].typ))))
- X bounce = 1;
- X if(isok(lsx,sy) && ZAP_POS(rmn = levl[lsx][sy].typ) &&
- X (IS_ROOM(rmn) || (isok(lsx,sy+dy) &&
- X ZAP_POS(levl[lsx][sy+dy].typ))))
- X if(!bounce || rn2(2))
- X bounce = 2;
- X
- X switch(bounce) {
- X case 0: dx = -dx; /* fall into... */
- X case 1: dy = -dy; break;
- X case 2: dx = -dx; break;
- X }
- X tmp_at(DISP_CHANGE, zapdir_to_glyph(dx,dy,abstype));
- X }
- X }
- X }
- X tmp_at(DISP_END,0);
- X if (type == ZT_SPELL(ZT_FIRE))
- X explode(sx, sy, type, d(12,6), 0);
- X if (shopdamage)
- X pay_for_damage(abstype == ZT_FIRE ? "burn away" :
- X abstype == ZT_COLD ? "shatter" :
- X abstype == ZT_DEATH ? "disintegrate" : "destroy");
- X}
- X
- X/* Burn floor scrolls, evaporate pools, etc... in a single square. Used
- X * both for normal bolts of fire, cold, etc... and for fireballs.
- X * Sets shopdamage to TRUE if a shop door is destroyed, and returns the
- X * amount by which range is reduced (the latter is just ignored by fireballs)
- X */
- Xint
- Xzap_over_floor(x, y, type, shopdamage)
- Xxchar x, y;
- Xint type;
- Xboolean *shopdamage;
- X{
- X struct monst *mon;
- X int abstype = abs(type) % 10;
- X struct rm *lev = &levl[x][y];
- X int rangemod = 0;
- X
- X if(abstype == ZT_FIRE) {
- X if(is_ice(x, y)) {
- X if (lev->typ == DRAWBRIDGE_UP)
- X lev->drawbridgemask &= ~DB_ICE; /* revert to DB_MOAT */
- X else { /* lev->typ == ICE */
- X#ifdef STUPID
- X if (lev->icedpool == ICED_POOL) lev->typ = POOL;
- X else lev->typ = MOAT;
- X#else
- X lev->typ = (lev->icedpool == ICED_POOL ? POOL : MOAT);
- X#endif
- X lev->icedpool = 0;
- X }
- X newsym(x,y);
- X Norep("The ice crackles and melts.");
- X if (x == u.ux && y == u.uy)
- X spoteffects(); /* possibly drown */
- X } else if(is_pool(x,y)) {
- X const char *msgtxt = "You hear a hissing sound.";
- X if(lev->typ != POOL) { /* MOAT or DRAWBRIDGE_UP */
- X if (cansee(x,y)) msgtxt = "Some water evaporates.";
- X } else {
- X register struct trap *ttmp;
- X
- X rangemod -= 3;
- X lev->typ = ROOM;
- X ttmp = maketrap(x, y, PIT);
- X ttmp->tseen = 1;
- X if (cansee(x,y)) msgtxt = "The water evaporates.";
- X }
- X Norep(msgtxt);
- X if (lev->typ == ROOM) newsym(x,y);
- X }
- X }
- X else if(abstype == ZT_COLD && (is_pool(x,y) || is_lava(x,y))) {
- X boolean lava = is_lava(x,y);
- X boolean moat = (!lava && (lev->typ != POOL) &&
- X (lev->typ != WATER) &&
- X !Is_medusa_level(&u.uz) &&
- X !Is_waterlevel(&u.uz));
- X
- X if (lev->typ == WATER) {
- X /* For now, don't let WATER freeze. */
- X if (cansee(x,y))
- X pline("The water freezes for a moment.");
- X else
- X You("hear a soft crackling sound");
- X rangemod -= 1000; /* stop */
- X } else {
- X rangemod -= 3;
- X if (lev->typ == DRAWBRIDGE_UP) {
- X lev->drawbridgemask |= (lava ? DB_FLOOR : DB_ICE);
- X } else {
- X if (!lava)
- X lev->icedpool =
- X (lev->typ == POOL ? ICED_POOL : ICED_MOAT);
- X lev->typ = (lava ? ROOM : ICE);
- X }
- X /*
- X * Not perfect: There could be stuff on the bottom. If
- X * we leave it here, it'll pop to the surface which is
- X * strange, so just destroy all the objects at this location.
- X * A better solution requires major changes (as usual).
- X */
- X if(OBJ_AT(x,y))
- X delallobj(x,y);
- X if(cansee(x,y)) {
- X if(moat)
- X Norep("The moat is bridged with ice!");
- X else if(lava)
- X Norep("The lava cools and solidifies.");
- X else
- X Norep("The water freezes.");
- X newsym(x,y);
- X } else if(flags.soundok && !lava)
- X You("hear a crackling sound.");
- X if(x == u.ux && y == u.uy &&
- X u.utrap && u.utraptype == TT_LAVA) {
- X#ifdef POLYSELF
- X if (passes_walls(uasmon))
- X You("pass through the now-solid rock.");
- X else {
- X#endif
- X u.utrap = rn1(50,20);
- X u.utraptype = TT_INFLOOR;
- X You("are firmly stuck in the cooling rock.");
- X#ifdef POLYSELF
- X }
- X#endif
- X }
- X }
- X }
- X if(closed_door(x, y)) {
- X rangemod = -1000;
- X switch(abstype) {
- X case ZT_FIRE:
- X if(type >= 0 && *in_rooms(x, y, SHOPBASE)) {
- X add_damage(x, y, 400L);
- X *shopdamage = TRUE;
- X }
- X lev->doormask = D_NODOOR;
- X unblock_point(x,y); /* vision */
- X if(cansee(x,y)) {
- X pline("The door is consumed in flames!");
- X newsym(x,y);
- X }
- X else You("smell smoke.");
- X break;
- X case ZT_COLD:
- X if(type >= 0 && *in_rooms(x, y, SHOPBASE)) {
- X add_damage(x, y, 400L);
- X *shopdamage = TRUE;
- X }
- X lev->doormask = D_NODOOR;
- X unblock_point(x,y); /* vision */
- X if(cansee(x,y)) {
- X pline("The door freezes and shatters!");
- X newsym(x,y);
- X }
- X else You("feel cold.");
- X break;
- X case ZT_DEATH:
- X /* death spells/wands don't disintegrate */
- X if(abs(type) != ZT_BREATH(ZT_DEATH))
- X goto def_case;
- X if(type >= 0 && *in_rooms(x, y, SHOPBASE)) {
- X add_damage(x, y, 400L);
- X *shopdamage = TRUE;
- X }
- X lev->doormask = D_NODOOR;
- X unblock_point(x,y); /* vision */
- X if(cansee(x,y)) {
- X pline("The door disintegrates!");
- X newsym(x,y);
- X }
- X else if(flags.soundok)
- X You("hear a crashing sound.");
- X break;
- X case ZT_LIGHTNING:
- X if(type >= 0 && *in_rooms(x, y, SHOPBASE)) {
- X add_damage(x, y, 400L);
- X *shopdamage = TRUE;
- X }
- X lev->doormask = D_BROKEN;
- X unblock_point(x,y); /* vision */
- X if(cansee(x,y)) {
- X pline("The door splinters!");
- X newsym(x,y);
- X }
- X else if(flags.soundok)
- X You("hear a crackling sound.");
- X break;
- X default:
- X def_case:
- X if(cansee(x,y)) {
- X pline("The door absorbs %s %s!",
- X (type < 0) ? "the" : "your",
- X abs(type) < ZT_SPELL(0) ? "bolt" :
- X abs(type) < ZT_BREATH(0) ? "spell" :
- X "blast");
- X } else You("feel vibrations.");
- X break;
- X }
- X }
- X if(OBJ_AT(x, y) && abstype == ZT_FIRE)
- X if(burn_floor_paper(x,y) && cansee(x,y)) {
- X newsym(x,y);
- X if(!Blind)
- X You("see a puff of smoke.");
- X }
- X if ((mon = m_at(x,y)) != 0) {
- X /* Cannot use wakeup() which also angers the monster */
- X mon->msleep = 0;
- X if(mon->m_ap_type) seemimic(mon);
- X if(type >= 0) {
- X setmangry(mon);
- X if(mon->ispriest && *in_rooms(mon->mx, mon->my, TEMPLE))
- X ghod_hitsu(mon);
- X if(mon->isshk && !*u.ushops)
- X hot_pursuit(mon);
- X }
- X }
- X return rangemod;
- X}
- X
- Xvoid
- Xrloco(obj)
- Xregister struct obj *obj;
- X{
- X register xchar tx, ty, otx, oty;
- X
- X otx = obj->ox;
- X oty = obj->oy;
- X do {
- X tx = rn1(COLNO-3,2);
- X ty = rn2(ROWNO);
- X } while(!goodpos(tx,ty,(struct monst *)0, (struct permonst *)0));
- X freeobj(obj);
- X if (flooreffects(obj, tx, ty, "fall"))
- X return;
- X if(costly_spot(otx, oty) && (!costly_spot(tx, ty) ||
- X !index(in_rooms(tx, ty, 0),
- X *in_rooms(otx, oty, 0)))) {
- X if(costly_spot(u.ux, u.uy) &&
- X index(u.urooms, *in_rooms(otx, oty, 0)))
- X addtobill(obj, FALSE, FALSE, FALSE);
- X else (void)stolen_value(obj, otx, oty, FALSE, FALSE);
- X }
- X obj->nobj = fobj;
- X fobj = obj;
- X place_object(obj, tx, ty);
- X newsym(otx, oty);
- X newsym(tx,ty);
- X}
- X
- Xvoid
- Xfracture_rock(obj) /* fractured by pick-axe or wand of striking */
- Xregister struct obj *obj; /* no texts here! */
- X{
- X obj->otyp = ROCK;
- X obj->quan = (long) rn1(60, 7);
- X obj->owt = weight(obj);
- X obj->oclass = GEM_CLASS;
- X obj->known = FALSE;
- X obj->onamelth = 0; /* no names */
- X if(!does_block(obj->ox,obj->oy,&levl[obj->ox][obj->oy]))
- X unblock_point(obj->ox,obj->oy);
- X if(cansee(obj->ox,obj->oy))
- X newsym(obj->ox,obj->oy);
- X}
- X
- Xboolean
- Xbreak_statue(obj)
- Xregister struct obj *obj;
- X{
- X struct trap *trap;
- X struct obj *item, *nitem;
- X
- X if((trap = t_at(obj->ox,obj->oy)) && trap->ttyp == STATUE_TRAP)
- X if(makemon(&mons[obj->corpsenm], obj->ox, obj->oy)) {
- X pline("Instead of shattering, the statue suddenly comes alive!");
- X delobj(obj);
- X deltrap(trap);
- X return FALSE;
- X }
- X for(item = obj->cobj; item; item = nitem) {
- X nitem = item->nobj;
- X item->nobj = fobj;
- X fobj = item;
- X place_object(item, obj->ox, obj->oy);
- X }
- X obj->cobj = (struct obj *)0;
- X fracture_rock(obj);
- X return TRUE;
- X}
- X
- Xconst char *destroy_strings[] = {
- X "freezes and shatters", "freeze and shatter", "shattered potion",
- X "boils and explodes", "boil and explode", "boiling potion",
- X "catches fire and burns", "catch fire and burn", "burning scroll",
- X "catches fire and burns", "catch fire and burn", "burning book",
- X "turns to dust and vanishes", "turn to dust and vanish", "",
- X "breaks apart and explodes", "break apart and explode", "exploding wand"
- X};
- X
- Xvoid
- Xdestroy_item(osym, dmgtyp)
- Xregister int osym, dmgtyp;
- X{
- X register struct obj *obj, *obj2;
- X register int dmg, xresist, skip;
- X register long i, cnt, quan;
- X register int dindx;
- X const char *mult;
- X
- X for(obj = invent; obj; obj = obj2) {
- X
- X obj2 = obj->nobj;
- X if(obj->oclass != osym) continue; /* test only objs of type osym */
- X if(obj->oartifact) continue; /* don't destroy artifacts */
- X xresist = skip = 0;
- X#ifdef GCC_WARN
- X dmg = dindx = 0;
- X quan = 0L;
- X#endif
- X switch(dmgtyp) {
- X case AD_COLD:
- X if(osym == POTION_CLASS) {
- X quan = obj->quan;
- X dindx = 0;
- X dmg = rnd(4);
- X } else skip++;
- X break;
- X case AD_FIRE:
- X xresist = (Fire_resistance && obj->oclass != POTION_CLASS);
- X
- X if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
- X skip++;
- X if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
- X skip++;
- X if (!Blind)
- X pline("%s glows a strange %s, but remains intact.",
- X The(xname(obj)),
- X Hallucination ? hcolor() : "dark red");
- X }
- X quan = obj->quan;
- X switch(osym) {
- X case POTION_CLASS:
- X dindx = 1;
- X dmg = rnd(6);
- X break;
- X case SCROLL_CLASS:
- X dindx = 2;
- X dmg = 1;
- X break;
- X case SPBOOK_CLASS:
- X dindx = 3;
- X dmg = 1;
- X break;
- X default:
- X skip++;
- X break;
- X }
- X break;
- X case AD_ELEC:
- X xresist = (Shock_resistance && obj->oclass != RING_CLASS);
- X quan = obj->quan;
- X switch(osym) {
- X case RING_CLASS:
- X if(obj->otyp == RIN_SHOCK_RESISTANCE)
- X { skip++; break; }
- X dindx = 4;
- X dmg = 0;
- X break;
- X case WAND_CLASS:
- X if(obj->otyp == WAN_LIGHTNING) { skip++; break; }
- X dindx = 5;
- X dmg = rnd(10);
- X break;
- X default:
- X skip++;
- X break;
- X }
- X break;
- X default:
- X skip++;
- X break;
- X }
- X if(!skip) {
- X for(i = cnt = 0L; i < quan; i++)
- X if(!rn2(3)) cnt++;
- X
- X if(!cnt) continue;
- X if(cnt == quan) mult = "Your";
- X else mult = (cnt == 1L) ? "One of your" : "Some of your";
- X pline("%s %s %s!", mult, xname(obj),
- X (cnt > 1L) ? destroy_strings[dindx*3 + 1]
- X : destroy_strings[dindx*3]);
- X if(osym == POTION_CLASS && dmgtyp != AD_COLD)
- X potionbreathe(obj);
- X for(i = 0; i < cnt; i++) {
- X if (obj->owornmask) {
- X if (obj->owornmask & W_RING) /* ring being worn */
- X Ring_gone(obj);
- X else
- X setnotworn(obj);
- X }
- X useup(obj);
- X }
- X if(dmg) {
- X if(xresist) You("aren't hurt!");
- X else {
- X losehp(dmg, (cnt==1L) ? destroy_strings[dindx*3 + 2] :
- X (const char *)makeplural(destroy_strings[dindx*3 + 2]),
- X (cnt==1L) ? KILLED_BY_AN : KILLED_BY);
- X exercise(A_STR, FALSE);
- X }
- X }
- X }
- X }
- X return;
- X}
- X
- Xint
- Xdestroy_mitem(mtmp, osym, dmgtyp)
- Xregister struct monst *mtmp;
- Xregister int osym, dmgtyp;
- X{
- X register struct obj *obj, *obj2;
- X register int skip, tmp = 0;
- X register long i, cnt, quan;
- X register int dindx;
- X boolean vis=canseemon(mtmp);
- X
- X for(obj = mtmp->minvent; obj; obj = obj2) {
- X
- X obj2 = obj->nobj;
- X if(obj->oclass != osym) continue; /* test only objs of type osym */
- X skip = 0;
- X#ifdef GCC_WARN
- X quan = 0L;
- X dindx = 0;
- X#endif
- X switch(dmgtyp) {
- X case AD_COLD:
- X if(osym == POTION_CLASS) {
- X quan = obj->quan;
- X dindx = 0;
- X tmp++;
- X } else skip++;
- X break;
- X case AD_FIRE:
- X if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
- X skip++;
- X if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
- X skip++;
- X if (vis)
- X pline("%s glows a strange %s, but remains intact.",
- X The(distant_name(obj, xname)),
- X Hallucination ? hcolor() : "dark red");
- X }
- X quan = obj->quan;
- X switch(osym) {
- X case POTION_CLASS:
- X dindx = 1;
- X tmp++;
- X break;
- X case SCROLL_CLASS:
- X dindx = 2;
- X tmp++;
- X break;
- X case SPBOOK_CLASS:
- X dindx = 3;
- X tmp++;
- X break;
- X default:
- X skip++;
- X break;
- X }
- X break;
- X case AD_ELEC:
- X quan = obj->quan;
- X switch(osym) {
- X case RING_CLASS:
- X if(obj->otyp == RIN_SHOCK_RESISTANCE)
- X { skip++; break; }
- X dindx = 4;
- X break;
- X case WAND_CLASS:
- X if(obj->otyp == WAN_LIGHTNING) { skip++; break; }
- X dindx = 5;
- X tmp++;
- X break;
- X default:
- X skip++;
- X break;
- X }
- X break;
- X default:
- X skip++;
- X break;
- X }
- X if(!skip) {
- X for(i = cnt = 0L; i < quan; i++)
- X if(!rn2(3)) cnt++;
- X
- X if(!cnt) continue;
- X if (vis) pline("%s %s %s!",
- X s_suffix(Monnam(mtmp)), xname(obj),
- X (cnt > 1L) ? destroy_strings[dindx*3 + 1]
- X : destroy_strings[dindx*3]);
- X for(i = 0; i < cnt; i++) m_useup(mtmp, obj);
- X }
- X }
- X return(tmp);
- X}
- X
- X/*ARGSUSED*/
- Xint
- Xresist(mtmp, class, damage, tell)
- Xregister struct monst *mtmp;
- Xregister char class;
- Xregister int damage, tell;
- X{
- X register int resisted;
- X register int lev;
- X
- X switch(class) {
- X
- X case WAND_CLASS:
- X lev = 8;
- X break;
- X
- X case SCROLL_CLASS:
- X lev = 6;
- X break;
- X
- X case POTION_CLASS:
- X lev = 5;
- X break;
- X
- X default: lev = u.ulevel;
- X break;
- X }
- X
- X resisted = (rn2(100) - (unsigned)mtmp->m_lev + lev) < mtmp->data->mr;
- X if(resisted) {
- X
- X if(tell) {
- X shieldeff(mtmp->mx, mtmp->my);
- X pline("%s resists!", Monnam(mtmp));
- X }
- X mtmp->mhp -= damage/2;
- X } else mtmp->mhp -= damage;
- X
- X#ifdef MUSE
- X if(mtmp->mhp < 1) {
- X if(m_using) monkilled(mtmp, "", AD_RBRE);
- X else killed(mtmp);
- X }
- X#else
- X if(mtmp->mhp < 1) killed(mtmp);
- X#endif
- X return(resisted);
- X}
- X
- Xvoid
- Xmakewish()
- X{
- X char buf[BUFSZ];
- X register struct obj *otmp;
- X int tries = 0;
- X
- X if (flags.verbose) You("may wish for an object.");
- Xretry:
- X getlin("For what do you wish?", buf);
- X if(buf[0] == '\033') buf[0] = 0;
- X /*
- X * Note: if they wished for and got a non-object successfully,
- X * otmp == &zeroobj
- X */
- X otmp = readobjnam(buf);
- X if (!otmp) {
- X pline("Nothing fitting that description exists in the game.");
- X if (++tries < 5) goto retry;
- X pline(thats_enough_tries);
- X if (!(otmp = readobjnam((char *)0)))
- X return; /* for safety; should never happen */
- X }
- X if (otmp != &zeroobj) {
- X if(otmp->oartifact && !touch_artifact(otmp,&youmonst))
- X dropy(otmp);
- X else
- X /* The(aobjnam()) is safe since otmp is unidentified -dlc */
- X (void) hold_another_object(otmp, u.uswallow ?
- X "Oops! %s out of your reach!" :
- X Is_airlevel(&u.uz) ?
- X "Oops! %s out of your grasp!" :
- X "Oops! %s to the floor!",
- X The(aobjnam(otmp, Is_airlevel(&u.uz) ?
- X "slip" : "drop")),
- X (const char *)0);
- X u.ublesscnt += rn1(100,50); /* the gods take notice */
- X }
- X}
- X
- X/*zap.c*/
- END_OF_FILE
- if test 32988 -ne `wc -c <'src/zap.c2'`; then
- echo shar: \"'src/zap.c2'\" unpacked with wrong size!
- fi
- # end of 'src/zap.c2'
- fi
- echo shar: End of archive 61 \(of 108\).
- cp /dev/null ark61isdone
- 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
-