[comp.sources.games] v07i080: NetHack3 - display oriented dungeons & dragons

billr@saab.CNA.TEK.COM (Bill Randle) (07/25/89)

Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 7, Issue 80
Archive-name: NetHack3/Part25



#! /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 25 (of 38)."
# Contents:  amiga/amiwind.c src/priest.c src/sounds.c src/weapon.c
# Wrapped by billr@saab on Sun Jul 23 21:33:08 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'amiga/amiwind.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'amiga/amiwind.c'\"
else
echo shar: Extracting \"'amiga/amiwind.c'\" \(13755 characters\)
sed "s/^X//" >'amiga/amiwind.c' <<'END_OF_FILE'
X/*
X *  amiwind.c	(C) Copyright 1989 by Olaf Seibert (KosmoSoft)
X */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/*
X *  Here is some very Amiga specific stuff, dealing with
X *  screens, windows, menus, and input via IntuiMessages.
X */
X
X#define MANX			/* Define for the Manx compiler */
X
X
X#include <exec/types.h>
X#include <exec/alerts.h>
X#include <exec/io.h>
X#include <exec/devices.h>
X#include <devices/console.h>
X#include <devices/conunit.h>
X#include <intuition/intuition.h>
X#include <libraries/dosextens.h>
X
X#undef TRUE			/* All these are also defined in */
X#undef FALSE			/* the Amiga system include files */
X#undef COUNT
X#undef NULL
X
X#include "hack.h"
X
X#include "amimenu.c"
X
X/*  First, external declarations... */
X
Xstruct Library *OpenLibrary();
Xstruct Screen *OpenScreen();
Xstruct Window *OpenWindow();
Xstruct TextFont *OpenDiskFont(), *OpenFont();
Xstruct IntuiMessage *GetMsg();
Xstruct MenuItem *ItemAddress();
Xstruct Process *FindTask();         /* Cheating */
Xlong DeadKeyConvert(), OpenDevice(), CloseDevice();
Xextern struct Library *IconBase;
Xvoid abort();
X
X/*  Now our own variables */
X
Xstruct Library *IntuitionBase;
Xstruct Screen *HackScreen;
Xstruct Window *HackWindow;
Xstruct Window *pr_WindowPtr;
Xstruct IOStdReq ConsoleIO;
Xchar Initialized = 0;
X
X#ifdef HACKFONT
Xstruct Library *GfxBase;
Xstruct Library *DiskfontBase;
X#endif
X
Xstruct Device *ConsoleDevice;
X
X#define CSI	    '\x9b'
X#define NO_CHAR     -1
X#define RAWHELP     0x5F	/* Rawkey code of the HELP key */
X
X/*
X *  It is assumed that all multiple-character outputs are
X *  at most CONBUFFER characters each.
X */
X
X#define CONBUFFER   512
Xstatic char ConsoleBuffer[CONBUFFER];
Xstatic unsigned short Buffered;
X
X#define KBDBUFFER   10
Xstatic unsigned char KbdBuffer[KBDBUFFER];
Xstatic unsigned char KbdBuffered;
X
X#define BufferQueueChar(ch) (KbdBuffer[KbdBuffered++] = ch)
X
X/*
X *  It seems Intuition won't OpenDiskFont our diskFont, so we get the
X *  closest match, which is of course topaz/8. (and if not, it is still
X *  an 8-pixel font, so everything still looks ok)
X */
X
X#ifdef HACKFONT
X
Xstruct TextFont *HackFont;
XUBYTE FontName[] = "NetHack:hack.font";
X#define 	    SIZEOF_DISKNAME	8
X
X#endif
X
Xstruct TextAttr Hack80 = {
X#ifdef HACKFONT
X    &FontName[SIZEOF_DISKNAME],
X#else
X    (UBYTE *) "topaz.font",
X#endif
X    TOPAZ_EIGHTY, FS_NORMAL, FPF_DISKFONT | FPF_ROMFONT
X};
X
X
X#define BARHEIGHT	11
X#define WINDOWHEIGHT	192
X#define WIDTH		640
X#define DEPTH		2
X
Xstruct NewScreen NewHackScreen = {
X    0, 0, WIDTH, BARHEIGHT + WINDOWHEIGHT, DEPTH,
X    0, 1,     /* DetailPen, BlockPen */
X    HIRES,
X    CUSTOMSCREEN,
X    &Hack80,  /* Font */
X    (UBYTE *) " NetHack 3.0 - Ported by Olaf Seibert (KosmoSoft)",
X    NULL,     /* Gadgets */
X    NULL,     /* CustomBitmap */
X};
X
Xstruct NewWindow NewHackWindow = {
X    /* left, top, width, height, detailpen, blockpen */
X    0, BARHEIGHT, WIDTH, WINDOWHEIGHT, -1, -1,
X    RAWKEY | MENUPICK
X#ifdef MAIL
X		      | DISKINSERTED
X#endif
X
X    , BORDERLESS | BACKDROP | ACTIVATE,
X    NULL, NULL, NULL,
X    NULL, NULL, -1,-1,-1,-1, CUSTOMSCREEN
X};
X
Xstatic int BufferGetchar()
X{
X    register unsigned char *from, *to;
X    register int c;
X    register short i;
X
X    if (KbdBuffered) {
X	c = KbdBuffer[0];
X	KbdBuffered--;
X	to = KbdBuffer;
X	from = to + 1;
X	/* Move the remaining characters */
X	for (i = KbdBuffered; i > 0; i--) {
X	    *to++ = *from++;
X	}
X	return c;
X    }
X
X    return NO_CHAR;
X}
X
X/*
X *  This should remind you remotely of DeadKeyConvert,
X *  but we are cheating a bit.
X *  We want complete control over the numeric keypad, and no
X *  dead keys... (they are assumed to be on Alted keys)
X *  Also assumed is that the IntuiMessage is of type RAWKEY.
X *  For some reason, IECODE_UP_PREFIX events seem to be lost when they
X *  occur while our console window is inactive. This is particulary
X *  troublesome with qualifier keys... Is this because I never
X *  RawKeyConvert those events???
X */
X
Xint ConvertKey(message)
Xregister struct IntuiMessage *message;
X{
X    static struct InputEvent theEvent;
X    static char       numpad[] = "bjnh.lyku";
X    static char  ctrl_numpad[] = "\x02\x0A\x0E\x08.\x0C\x19\x0B\x15";
X    static char shift_numpad[] = "BJNH.LYKU";
X
X    unsigned char buffer[1];
X    register char length;
X    register ULONG qualifier = message->Qualifier;
X    char numeric_pad, shift, control, alt;
X
X    control = (qualifier &  IEQUALIFIER_CONTROL) != 0;
X    shift   = (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) != 0;
X
X    /*
X     *	Shortcut for HELP and arrow keys... I suppose this is allowed...
X     *	the defines are in intuition/intuition.h, and the keys
X     *	don't serve 'text' input, normally.
X     *	Also, parsing their escape sequences is such a mess...
X     */
X
X    switch (message->Code) {
X    case RAWHELP:
X	length = '?';
X	goto no_arrow;
X    case CURSORLEFT:
X	length = 'h'; goto arrow;
X    case CURSORDOWN:
X	length = 'j'; goto arrow;
X    case CURSORUP:
X	length = 'k'; goto arrow;
X    case CURSORRIGHT:
X	length = 'l';
X    arrow:
X	if (control)
X	    length &= 0x1F;	    /* ToControl... */
X	else if (shift)
X	    length &= 0x5F;	    /* ToUpper... */
X    no_arrow:
X	BufferQueueChar(length);
X	return;
X    }
X
X#ifdef BETA
X    if (!ConsoleDevice) { /* Should never happen */
X	abort(AG_IOError | AO_ConsoleDev);
X	return;
X    }
X#endif
X
X    numeric_pad = (qualifier & IEQUALIFIER_NUMERICPAD) != 0;
X    if (alt = (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) != 0)
X		/* Don't want dead keys... */
X	qualifier &= ~(IEQUALIFIER_LALT | IEQUALIFIER_RALT);
X
X    theEvent.ie_Class = IECLASS_RAWKEY;
X    theEvent.ie_Code = message->Code;
X    theEvent.ie_Qualifier = numeric_pad ? IEQUALIFIER_NUMERICPAD :
X					  qualifier;
X    theEvent.ie_EventAddress = (APTR) *(message->IAddress);
X
X    length = RawKeyConvert(&theEvent, buffer, (long) sizeof(buffer), NULL);
X
X    if (length == 1) {   /* Plain ASCII character */
X	length = buffer[0];
X	if (numeric_pad && length >= '1' && length <= '9') {
X	    length -= '1';
X	    if (control) {
X		length = ctrl_numpad[length];
X	    } else if (shift) {
X		length = shift_numpad[length];
X	    } else {
X		length = numpad[length];
X	    }
X	}
X	BufferQueueChar(length);
X    } /* else shift, ctrl, alt, amiga, F-key, shift-tab, etc */
X}
X
X/*
X *  Process an incoming IntuiMessage.
X *  It would certainly look nicer if this could be done using a
X *  PA_SOFTINT message port, but we cannot call RawKeyConvert()
X *  during a software interrupt.
X *  Anyway, kbhit() is called often enough, and usually gets
X *  ahead of input demands, when the user types ahead.
X */
X
Xstatic char ProcessMessage(message)
Xregister struct IntuiMessage *message;
X{
X    switch(message->Class) {
X    case MENUPICK:
X	{
X	    USHORT thismenu;
X	    struct MenuItem *item = NULL;
X
X	    thismenu = message->Code;
X	    while (thismenu != MENUNULL) {
X		item = ItemAddress(&HackMenu, (ULONG) thismenu);
X		if (KbdBuffered < KBDBUFFER)
X		    BufferQueueChar(item->Command); /* Unused: No COMMSEQ */
X		thismenu = item->NextSelect;
X	    }
X	}
X	break;
X    case RAWKEY:
X	if (!(message->Code & IECODE_UP_PREFIX))
X	    ConvertKey(message);    /* May queue multiple characters */
X	break;			    /* but doesn't do that yet       */
X#ifdef MAIL
X    case DISKINSERTED:
X	{
X	    extern int mustgetmail;
X
X	    if (mustgetmail < 0)
X		mustgetmail = rn1(100,50);
X	}
X#endif
X    }
X    ReplyMsg(message);
X}
X
X/*
X *  Get all incoming messages and fill up the keyboard buffer,
X *  thus allowing Intuition to (maybe) free up the IntuiMessages.
X *  Return when no more messages left, or keyboard buffer half full.
X *  We need to do this since there is no one-to-one correspondence
X *  between characters and incoming messages.
X */
X
Xint kbhit()
X{
X    register struct IntuiMessage *message;
X
X    while( (KbdBuffered < KBDBUFFER / 2) &&
X	    (message = GetMsg(HackWindow->UserPort)) )
X	ProcessMessage(message);
X
X    return KbdBuffered;
X}
X
X/*
X *  Get a character from the keyboard buffer, waiting if
X *  not available.
X */
X
Xint WindowGetchar()
X{
X    while ( !kbhit() ) {
X	Wait( 1L << HackWindow->UserPort->mp_SigBit );
X    }
X    return BufferGetchar();
X}
X
X/*
X *  Flush the output waiting in the console output buffer.
X */
X
Xvoid WindowFlush()
X{
X#ifdef BETA
X    if (!ConsoleDevice) { /* Should never happen */
X	abort(AG_IOError | AO_ConsoleDev);
X	return;
X    }
X#endif
X
X    if (Buffered) {
X	ConsoleIO.io_Command = CMD_WRITE;
X	ConsoleIO.io_Data = (APTR)ConsoleBuffer;
X	ConsoleIO.io_Length = Buffered;
X	DoIO(&ConsoleIO);
X	Buffered = 0;
X    }
X}
X
X/*
X *  Queue a single character for output to the console screen.
X */
X
Xint WindowPutchar(c)
Xchar c;
X{
X    if (Buffered >= CONBUFFER)
X	WindowFlush();
X
X    ConsoleBuffer[Buffered++] = c;
X}
X
X/*
X *  Queue an entire string for output to the console screen,
X *  flushing the existing characters first, if necessary.
X *  Do not append a newline.
X */
X
Xvoid WindowFPuts(string)
Xchar *string;
X{
X    register int len = _BUILTIN_strlen(string);
X
X    if (len + Buffered >= CONBUFFER)
X	WindowFlush();
X
X    _BUILTIN_strcpy(ConsoleBuffer + Buffered, string);
X    Buffered += len;
X}
X
X/*
X *  Queue an entire string for output to the console screen,
X *  flushing the existing characters first, if necessary.
X *  Append a newline.
X */
X
Xvoid WindowPuts(string)
Xchar *string;
X{
X    WindowFPuts(string);
X    WindowPutchar('\n');
X}
X
X/*
X *  Queue a formatted string for output to the console screen,
X *  flushing the existing characters first, if necessary.
X */
X
Xvoid WindowPrintf(fmt, args, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
Xchar *fmt;
Xlong args, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9;
X{
X#ifdef MANX	    /* Efficient but not portable */
X    format(WindowPutchar, fmt, &args);
X#else
X    WindowFlush();  /* Don't know if all will fit */
X# ifdef __STDC__    /* Cheap and portable way */
X    vsprintf(ConsoleBuffer, fmt, &args);
X# else		    /* Expensive... */
X    sprintf(ConsoleBuffer, fmt, args, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
X# endif
X    ConsoleIO.io_Command = CMD_WRITE;
X    ConsoleIO.io_Data = (APTR)ConsoleBuffer;
X    ConsoleIO.io_Length = -1;
X    DoIO(&ConsoleIO);
X#endif
X}
X
X/*
X *  Clean up everything. But before we do, ask the user to hit return
X *  when there is something that s/he should read.
X */
X
Xvoid CleanUp()
X{
X    /* Clean up resources */
X    if (ConsoleIO.io_Device) {
X	register struct ConUnit *cu;
X
X	cu = (struct ConUnit *)ConsoleIO.io_Unit;
X	if (cu->cu_XCCP != 1 || cu->cu_YCCP != 1)
X	    getret();
X
X	CloseDevice(&ConsoleIO);
X	ConsoleDevice = NULL;
X    }
X    if (HackWindow) {
X	register struct IntuiMessage *msg;
X
X	FindTask(NULL)->pr_WindowPtr = (APTR) pr_WindowPtr;
X	ClearMenuStrip(HackWindow);
X	Forbid();
X	while (msg = GetMsg(HackWindow->UserPort))
X	    ReplyMsg(msg);
X	CloseWindow(HackWindow);
X	Permit();
X	HackWindow = NULL;
X    }
X    if (HackScreen) {
X	CloseScreen(HackScreen);
X	HackScreen = NULL;
X    }
X    /* if (IconBase) {
X	CloseLibrary(IconBase);
X	IconBase = NULL;
X    } */
X#ifdef HACKFONT
X    if (HackFont) {
X	CloseFont(HackFont);
X	HackFont = NULL;
X    }
X    if (DiskfontBase) {
X	CloseLibrary(DiskfontBase);
X	DiskfontBase = NULL;
X    }
X    if (GfxBase) {
X	CloseLibrary(GfxBase);
X	GfxBase = NULL;
X    }
X#endif
X    if (IntuitionBase) {
X	CloseLibrary(IntuitionBase);
X	IntuitionBase = NULL;
X    }
X
X    Initialized = 0;
X}
X
Xvoid abort(rc)
Xlong rc;
X{
X#ifdef CHDIR
X    extern char orgdir[];
X    chdir(orgdir);
X#endif
X    if (Initialized && ConsoleDevice) {
X	printf("\n\nAbort with alert code %08lx...\n", rc);
X	getret();
X    } else
X	Alert(rc, 0L);
X    CleanUp();
X#undef exit
X    exit(rc);
X}
X
X/*  Used by library routines, and the debugger */
X
Xvoid _abort()
X{
X    abort(-10L);
X}
X
X/*
X *  Open everything we need.
X */
X
Xvoid Initialize()
X{
X    if (Initialized)
X	return;
X
X    if ( (IntuitionBase = OpenLibrary("intuition.library", LIBRARY_VERSION))
X	  == NULL)
X	abort(AG_OpenLib | AO_Intuition);
X
X#ifdef HACKFONT
X
X    if ( (GfxBase = OpenLibrary("graphics.library", LIBRARY_VERSION)) == NULL)
X	abort(AG_OpenLib | AO_GraphicsLib);
X
X    /*
X     *	Force our own font to be loaded, if possible.
X     *	If we can open diskfont.library, but not our font, we can close
X     *	the diskfont.library again since it just wastes memory.
X     *	Even if we can open the font, we don't need the diskfont.library
X     *	anymore, since CloseFont is a graphics.library function.
X     */
X
X    if ((HackFont = OpenFont(&Hack80)) == NULL) {
X	if (DiskfontBase = OpenLibrary("diskfont.library", LIBRARY_VERSION)) {
X	    Hack80.ta_Name -= SIZEOF_DISKNAME;
X	    HackFont = OpenDiskFont(&Hack80);
X	    Hack80.ta_Name += SIZEOF_DISKNAME;
X	    CloseLibrary(DiskfontBase);
X	    DiskfontBase = NULL;
X	}
X    }
X#endif
X
X    /* if ( (IconBase = OpenLibrary("icon.library", LIBRARY_VERSION)) == NULL)
X	abort(AG_OpenLib | AO_IconLib); */
X
X    /*
X     *	Now Intuition is supposed to use our HackFont for the screen,
X     *	since we have a corresponding TextAttr, but it *doesn't*.
X     *	So, we need to do a SetFont() a bit later on.
X     */
X    if ( (HackScreen = OpenScreen(&NewHackScreen)) == NULL)
X	abort(AN_OpenScreen & ~AT_DeadEnd);
X
X    NewHackWindow.Screen = HackScreen;
X
X    if ( (HackWindow = OpenWindow(&NewHackWindow)) == NULL)
X	abort(AN_OpenWindow & ~AT_DeadEnd);
X
X    SetMenuStrip(HackWindow, &HackMenu);
X    {
X	register struct Process *myProcess = FindTask(NULL);
X	pr_WindowPtr = (struct Window *)myProcess->pr_WindowPtr;
X	myProcess->pr_WindowPtr = (APTR) HackWindow;
X    }
X#ifdef HACKFONT
X    if (HackFont)
X	SetFont(HackWindow->RPort, HackFont);
X#endif
X
X    ConsoleIO.io_Data = (APTR) HackWindow;
X    ConsoleIO.io_Length = sizeof(*HackWindow);
X    if (OpenDevice("console.device", 0L, &ConsoleIO, 0L) != 0)
X	abort(AG_OpenDev | AO_ConsoleDev);
X
X    ConsoleDevice = ConsoleIO.io_Device;
X
X    Buffered = 0;
X    KbdBuffered = 0;
X
X    /* set CRMOD on */
X    WindowFPuts("\23320h");
X
X    Initialized = 1;
X}
END_OF_FILE
if test 13755 -ne `wc -c <'amiga/amiwind.c'`; then
    echo shar: \"'amiga/amiwind.c'\" unpacked with wrong size!
fi
# end of 'amiga/amiwind.c'
fi
if test -f 'src/priest.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/priest.c'\"
else
echo shar: Extracting \"'src/priest.c'\" \(13697 characters\)
sed "s/^X//" >'src/priest.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)priest.c	3.0	89/06/26
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* Copyright (c) Izchak Miller, Steve Linhart, 1989. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/* block some unused #defines to avoid overloading some cpp's */
X#define MONATTK_H
X#include "hack.h"
X#include "mfndpos.h"
X#include "eshk.h"
X#include "epri.h"
X
X/* used for the insides of shk_move and pri_move */
Xint
Xmove_special(mtmp,monroom,appr,uondoor,avoid,omx,omy,gx,gy)
Xregister struct monst *mtmp;
Xschar monroom,appr;
Xboolean uondoor,avoid;
Xregister xchar omx,omy,gx,gy;
X{
X	register xchar nx,ny,nix,niy;
X	register schar i;
X	schar chcnt,cnt;
X	coord poss[9];
X	long info[9];
X	long allowflags;
X	struct obj *ib = 0;
X
X	if(omx == gx && omy == gy)
X		return(0);
X	if(mtmp->mconf) {
X		avoid = FALSE;
X		appr = 0;
X	}
X
X	nix = omx;
X	niy = omy;
X	if (mtmp->isshk) allowflags = ALLOW_SSM;
X	else allowflags = ALLOW_SSM | ALLOW_SANCT;
X	if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK|ALLOW_WALL);
X	if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK;
X	if (tunnels(mtmp->data) &&
X		    (!needspick(mtmp->data) || m_carrying(mtmp, PICK_AXE)))
X		allowflags |= ALLOW_DIG;
X	cnt = mfndpos(mtmp, poss, info, allowflags);
X	if (allowflags & ALLOW_DIG) if(!mdig_tunnel(mtmp)) return(-2);
X
X	if(mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */
X		for(i=0; i<cnt; i++)
X		    if(!(info[i] & NOTONL)) goto pick_move;
X		avoid = FALSE;
X	}
X
X#define	GDIST(x,y)	(dist2(x,y,gx,gy))
Xpick_move:
X	chcnt = 0;
X	for(i=0; i<cnt; i++) {
X		nx = poss[i].x;
X		ny = poss[i].y;
X		if(levl[nx][ny].typ == ROOM ||
X#if defined(ALTARS) && defined(THEOLOGY)
X			(mtmp->ispriest &&
X			    levl[nx][ny].typ == ALTAR) ||
X#endif
X			(mtmp->isshk &&
X			    (monroom != ESHK(mtmp)->shoproom
X			    || ESHK(mtmp)->following))) {
X		    if(avoid && (info[i] & NOTONL))
X			continue;
X		    if((!appr && !rn2(++chcnt)) ||
X			(appr && GDIST(nx,ny) < GDIST(nix,niy))) {
X			    nix = nx;
X			    niy = ny;
X		    }
X		}
X	}
X#if defined(ALTARS) && defined(THEOLOGY)
X	if(mtmp->ispriest && avoid &&
X			nix == omx && niy == omy && online(omx,omy)) {
X		/* might as well move closer as long it's going to stay
X		 * lined up */
X		avoid = FALSE;
X		goto pick_move;
X	}
X#endif
X
X	if(nix != omx || niy != omy) {
X		levl[omx][omy].mmask = 0;
X		levl[nix][niy].mmask = 1;
X		mtmp->mx = nix;
X		mtmp->my = niy;
X		pmon(mtmp);
X		if(ib) {
X			if (cansee(mtmp->mx,mtmp->my))
X			    pline("%s picks up %s.", Monnam(mtmp),
X				distant_name(ib,doname));
X			freeobj(ib);
X			mpickobj(mtmp, ib);
X		}
X		return(1);
X	}
X	return(0);
X}
X
X#if defined(ALTARS) && defined(THEOLOGY)
X
Xstruct mkroom *
Xin_temple(x, y)
Xregister int x, y;
X{
X	register int roomno = inroom(x, y);
X
X	if (roomno < 0 || rooms[roomno].rtype != TEMPLE) return(FALSE);
X	return(&rooms[roomno]);
X}
X
Xstatic boolean
Xhistemple_at(priest, x, y)
Xregister struct monst *priest;
Xregister int x, y;
X{
X	return(EPRI(priest)->shroom == inroom(x, y) && 
X	       EPRI(priest)->shrlevel == dlevel);
X}
X
X/*
X * pri_move: return 1: he moved  0: he didn't  -1: let m_move do it  -2: died
X */
Xint
Xpri_move(priest)
Xregister struct monst *priest;
X{
X	register xchar gx,gy,omx,omy;
X	schar temple;
X	boolean avoid = TRUE;
X
X	omx = priest->mx;
X	omy = priest->my;
X
X	if(!histemple_at(priest, omx, omy)) return(-1);
X
X	temple = EPRI(priest)->shroom;
X	
X	gx = EPRI(priest)->shrpos.x;
X	gy = EPRI(priest)->shrpos.y;
X
X	gx += rn1(3,-1);	/* mill around the altar */
X	gy += rn1(3,-1);
X
X	if(!priest->mpeaceful) {
X		if(dist(omx,omy) < 3) {
X			if(Displaced)
X				Your("displaced image doesn't fool %s!",
X					mon_nam(priest));
X			(void) mattacku(priest);
X			return(0);
X		} else if(temple == inroom(u.ux,u.uy)) {
X			/* don't chase player outside temple */
X			long saveBlind = Blinded;
X			struct obj *saveUblindf = ublindf;
X			Blinded = 0;
X			ublindf = (struct obj *)0;
X			if(priest->mcansee && !Invis && cansee(omx,omy)) {
X				gx = u.ux;
X				gy = u.uy;
X			}
X			Blinded = saveBlind;
X			ublindf = saveUblindf;
X			avoid = FALSE;
X		}
X	} else if(Invis) avoid = FALSE;
X	
X	return(move_special(priest,temple,TRUE,FALSE,avoid,omx,omy,gx,gy));
X}
X
X/* exclusevely for mktemple() */
Xvoid
Xpriestini(lvl, sx, sy, align)
Xregister int lvl, sx, sy, align;
X{
X	register struct monst *priest;
X	register struct obj *otmp = (struct obj *)0;
X#ifdef SPELLS
X	register int cnt;
X#endif
X
X	if (priest = makemon(&mons[!rn2(2) ? PM_TEMPLE_PRIEST : 
X			PM_TEMPLE_PRIESTESS], sx+1, sy)) {
X		EPRI(priest)->shroom = inroom(sx, sy);
X		EPRI(priest)->shralign = align;
X		EPRI(priest)->shrpos.x = sx;
X		EPRI(priest)->shrpos.y = sy;
X		EPRI(priest)->shrlevel = lvl;
X		EPRI(priest)->ismale = 
X				(priest->data == &mons[PM_TEMPLE_PRIEST]);
X		Strcpy(EPRI(priest)->deitynam, a_gname_at(sx, sy));
X		priest->mtrapseen = ~0;	/* traps are known */
X		priest->mpeaceful = 1;
X		priest->ispriest = 1;
X		priest->msleep = 0;
X
X		/* now his/her goodies... */
X		(void) mongets(priest, CHAIN_MAIL);
X		(void) mongets(priest, SMALL_SHIELD);
X
X		/* Do NOT put the rest in m_initinv.    */
X		/* Priests created elsewhere than in a  */
X		/* temple should not carry these items, */
X		/* except for the mace.			*/
X#ifdef SPELLS
X		cnt = rn1(2,3);
X		while(cnt) {
X		    otmp = mkobj(SPBOOK_SYM, FALSE);
X		    if(otmp) mpickobj(priest, otmp);
X		    cnt--;
X		}
X#endif
X		if(p_coaligned(priest)) {
X		    (void) mongets(priest, rn2(2) ? CLOAK_OF_PROTECTION
X						  : CLOAK_OF_MAGIC_RESISTANCE);
X#ifdef NAMED_ITEMS
X		    otmp = mk_aligned_artifact(EPRI(priest)->shralign);
X		    if(otmp) {
X			otmp->spe = rnd(4);
X			mpickobj(priest, otmp);
X		    }
X#endif
X		} else {
X		    if(!rn2(5)) 
X			otmp = mksobj(CLOAK_OF_MAGIC_RESISTANCE, FALSE); 
X		    else otmp = mksobj(CLOAK_OF_PROTECTION, FALSE); 
X		    if(otmp) {
X			if(!rn2(2)) curse(otmp);
X			mpickobj(priest, otmp);
X		    }
X		    otmp = mksobj(MACE, FALSE);
X		    if(otmp) {
X			otmp->spe = rnd(3);
X			if(!rn2(2)) curse(otmp);
X			mpickobj(priest, otmp);
X		    }
X		}
X	}
X}
X
Xchar *
Xpriestname(priest)
Xregister struct monst *priest;
X{
X	static char pname[PL_NSIZ];
X
X	Strcpy(pname, "the ");
X	if(priest->minvis) Strcat(pname, "invisible ");
X	if(priest->data != &mons[PM_TEMPLE_PRIEST] &&
X			priest->data != &mons[PM_TEMPLE_PRIESTESS]) {
X		Strcat(pname, priest->data->mname);
X		Strcat(pname, " ");
X	}
X	if(EPRI(priest)->ismale)
X		Strcat(pname, "priest of ");
X	else 	Strcat(pname, "priestess of ");
X	Strcat(pname, EPRI(priest)->deitynam);
X	return(pname);
X}
X
Xboolean
Xp_coaligned(priest)
Xstruct monst *priest;
X{
X	return(!strcmp(u_gname(), EPRI(priest)->deitynam));
X}
X
Xstatic int
Xt_alignment(troom)
Xstruct mkroom *troom;
X{
X	int x, y;
X
X	shrine_pos(&x,&y,troom);
X
X	if(IS_ALTAR(levl[x][y].typ) && (levl[x][y].altarmask & A_SHRINE) != 0)
X		return(levl[x][y].altarmask & ~A_SHRINE); 
X	return(-2); /* arbitrary non-alignment type value */
X}
X
Xstatic boolean
Xis_shrined(troom)
Xstruct mkroom *troom;
X{
X	int x, y;
X
X	shrine_pos(&x,&y,troom);
X
X	if(IS_ALTAR(levl[x][y].typ) && (levl[x][y].altarmask & A_SHRINE) != 0)
X		return(TRUE);
X	return(FALSE);
X}
X
Xstatic boolean
Xt_coaligned(troom)
Xstruct mkroom *troom;
X{
X	return(t_alignment(troom) == u.ualigntyp + 1);
X}
X
Xstruct monst *
Xfindpriest(troom)
Xstruct mkroom *troom;
X{
X	register struct monst *mtmp;
X
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X	    if(mtmp->ispriest && histemple_at(mtmp,mtmp->mx,mtmp->my)
X			&& &rooms[EPRI(mtmp)->shroom] == troom)
X		return(mtmp);
X	return (struct monst *)0;
X}
X
Xstatic boolean
Xp_inhistemple(troom)
Xstruct mkroom *troom;
X{
X	register struct monst *priest;
X
X	priest = findpriest(troom);
X	if(priest) return(TRUE);
X	return(FALSE);
X}
X
Xvoid
Xintemple() {
X	register struct mkroom *troom;
X
X	if(troom = in_temple(u.ux, u.uy)) {
X	    boolean shrined = is_shrined(troom);
X	    boolean tended = p_inhistemple(troom);
X
X	    if(!in_temple(u.ux0, u.uy0)) {
X		pline("Pilgrim, you enter a%s place!",
X			(!(shrined || tended) ? " desecrated and deserted" :
X			 !shrined ? " desecrated" :
X			 !tended ? "n untended sacred" :
X			  " sacred"));
X		if(!t_coaligned(troom) || u.ualign < -5 || !shrined || !tended)
X		    You("have a%s forbidding feeling...",
X				(!shrined || !tended) ? "" :
X				 " strange");
X		else You("experience a strange sense of peace.");
X	    } else if(!(shrined || tended) && !rn2(5)) {
X		switch(rn2(3)) {
X		    case 0: You("have an eerie feeling..."); break;
X		    case 1: You("feel like you are being watched."); break;
X		    default: pline("A shiver runs down your spine."); break;
X		}
X		if(!rn2(5)) {
X		    struct monst *mtmp;
X
X		    if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy))) return;
X		    pline("An enormous ghost appears next to you!");
X		    mnexto(mtmp);
X		    mtmp->mpeaceful = 0;
X		    if(flags.verbose)
X		        You("are frightened to death, and unable to move.");
X		    nomul(-3);
X		    nomovemsg = "You regain your composure.";
X		}
X	    }
X	}
X}
X
Xvoid
Xpriest_talk(priest)
Xregister struct monst *priest;
X{
X	boolean coaligned = p_coaligned(priest);
X	boolean strayed = (u.ualign < 0);
X 
X	if(priest->mflee) {
X	    kludge("%s doesn't want anything to do with you!", 
X				Monnam(priest));
X	    priest->mtame = priest->mpeaceful = 0;
X	    return;
X	}
X
X	/* priests don't chat unless peaceful and in their own temple */
X	if(!histemple_at(priest,priest->mx,priest->my) || priest->mtame ||
X		 !priest->mpeaceful || priest->mfroz || priest->msleep) {
X            if(priest->mfroz || priest->msleep) {
X	        kludge("%s breaks out of his reverie!", Monnam(priest));
X                priest->mfroz = priest->msleep = 0;
X	    }
X	    /* The following is now impossible according to monst.c, */
X	    /* but it should stay just in case we change the latter. */
X	    if(priest->mtame)
X		kludge("%s breaks out of your taming spell!", Monnam(priest));
X	    priest->mtame = priest->mpeaceful = 0;
X	    switch(rn2(3)) {
X	        case 0: 
X		   verbalize("Thou wouldst have words, eh?  I'll give thee a word or two!"); 
X		   break;
X	        case 1: 
X		   verbalize("Talk?  Here is what I have to say!"); 
X		   break;
X	        default: 
X		   verbalize("Pilgrim, I have lost mine desire to talk.");
X		   break;
X	    }
X	    return;
X	}
X
X	/* he desecrated the temple and now he wants to chat? */
X	if(!is_shrined(&rooms[inroom(priest->mx, priest->my)])
X		&& priest->mpeaceful) {
X	    verbalize("Begone!  Thou desecratest this holy place with thy presence.");
X	    priest->mpeaceful = 0;
X	    return;
X	} 
X
X	if(!u.ugold) {
X	    if(coaligned && !strayed) {
X	        kludge("%s gives you two bits for an ale.", Monnam(priest));
X	        u.ugold = 2L;
X		if (priest->mgold) priest->mgold -= 2L;
X	    } else
X		kludge("%s is not interested.", Monnam(priest));
X	    return;
X	} else {
X	    long offer;
X
X	    kludge("%s asks you for a contribution for the temple.",
X			Monnam(priest));
X	    if((offer = bribe(priest)) == 0) {
X		verbalize("Thou shalt regret thine action!");
X		if(coaligned) u.ualign--;
X	    } else if(offer < (u.ulevel * 200)) {
X		if(u.ugold > (offer * 2L)) verbalize("Cheapskate.");
X		else {
X		    verbalize("I thank thee for thy contribution.");
X		    /*  give player some token  */
X		}
X	    } else if(offer < (u.ulevel * 400)) {
X		verbalize("Thou art indeed a pious individual.");
X		if(u.ugold < (offer * 2L)) { 
X		    if(coaligned && u.ualign < -5) u.ualign++;
X		    verbalize("I bestow upon thee a blessing.");
X		    Clairvoyant += rn1(500,500);
X		}
X	    } else if(offer < (u.ulevel * 600)) {
X		verbalize("Thy devotion has been rewarded.");
X		if (!(Protection & INTRINSIC))  {
X			Protection |= INTRINSIC;
X			if (!u.ublessed)  u.ublessed = rnd(3) + 1;
X		} else u.ublessed++;
X	    } else {
X		verbalize("Thy selfless generosity is deeply appreciated.");
X		if(u.ugold < (offer * 2L) && coaligned) {
X		    if(strayed && (moves - u.ucleansed) > 5000L) { 
X			u.ualign = 0; /* cleanse him */
X			u.ucleansed = moves;
X		    } else { 
X		        u.ualign += 2;
X		    }
X		}
X	    }
X	}
X}
X
Xboolean
Xu_in_sanctuary(troom) 
Xregister struct mkroom *troom;
X{
X	register struct mkroom *troom2;
X
X	troom2 = in_temple(u.ux, u.uy);
X
X	return(troom && troom2 && troom == troom2 && is_shrined(troom2) && 
X			t_coaligned(troom2) && u.ualign > -5);
X}
X
Xvoid
Xghod_hitsu() 	/* when attacking a priest in his temple */
X{
X	int x, y, ax, ay;
X	struct monst *priest;
X	struct mkroom *troom = in_temple(u.ux, u.uy);
X
X	if(!troom || !is_shrined(troom)) return;
X
X	/* shrine converted by human sacrifice */
X	if((priest = findpriest(troom)) && 
X	    strcmp(EPRI(priest)->deitynam,
X		a_gname_at(EPRI(priest)->shrpos.x, EPRI(priest)->shrpos.y))) 
X		    return;
X
X	shrine_pos(&x,&y,troom);
X	ax = x;
X	ay = y;
X
X	if((u.ux == x && u.uy == y) || !linedup(u.ux, u.uy, x, y)) {
X	    if(IS_DOOR(levl[u.ux][u.uy].typ)) {
X		if(u.ux == troom->lx - 1) {
X		    x = troom->hx;
X		    y = u.uy;
X		} else if(u.ux == troom->hx + 1) {
X		    x = troom->lx;
X		    y = u.uy;
X		} else if(u.uy == troom->ly - 1) {
X		    x = u.ux;
X		    y = troom->hy;
X		} else if(u.uy == troom->hy + 1) {
X		    x = u.ux;
X		    y = troom->ly;
X		}
X	    } else {
X		switch(rn2(4)) {
X		case 0:  x = u.ux; y = troom->ly; break;
X		case 1:  x = u.ux; y = troom->hy; break;
X		case 2:  x = troom->lx; y = u.uy; break;
X		default: x = troom->hx; y = u.uy; break;
X		}
X	    }
X	    if(!linedup(u.ux, u.uy, x, y)) return;
X	}
X
X	switch(rn2(3)) {
X	case 0: 
X	    pline("%s roars in anger:  \"Thou shalt suffer!\"", 
X			a_gname_at(ax, ay));
X	    break;
X	case 1: 
X	    pline("%s's voice booms:  \"How darest thou harm my servant!\"",
X			a_gname_at(ax, ay));
X	    break;
X	default: 
X	    pline("%s roars:  \"Thou dost profane my shrine!\"",
X			a_gname_at(ax, ay));
X	    break;
X	}
X
X	buzz(-15, 6, x, y, sgn(tbx), sgn(tby)); /* -15: bolt of lightning */
X}
X
Xvoid
Xangry_priest()
X{
X	register struct monst *priest;
X
X	if(!(priest = findpriest(in_temple(u.ux, u.uy)))) return;
X	wakeup(priest);
X}
X#endif /* ALTARS && THEOLOGY */
END_OF_FILE
if test 13697 -ne `wc -c <'src/priest.c'`; then
    echo shar: \"'src/priest.c'\" unpacked with wrong size!
fi
# end of 'src/priest.c'
fi
if test -f 'src/sounds.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/sounds.c'\"
else
echo shar: Extracting \"'src/sounds.c'\" \(14344 characters\)
sed "s/^X//" >'src/sounds.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)sounds.c	3.0	88/06/19 */
X/* NetHack may be freely redistributed.  See license for details. */
X/* Copyright (c) 1989 Janet Walz, Mike Threepoint */
X
X/* block some unused #defines to avoid overloading some cpp's */
X
X#define ONAMES_H
X#include "hack.h"
X#include "edog.h"
X
Xvoid
Xverbalize(str)
Xregister char *str;
X{
X	if(flags.soundok) pline("\"%s\"", str);
X}
X
X#ifdef SOUNDS
X
Xvoid
Xdosounds()
X{
X    register xchar hallu;
X    register struct mkroom *sroom;
X    register xchar roomtype;
X    register int croomno;
X
X    hallu = Hallucination ? 1 : 0;
X
X    if(!flags.soundok || u.uswallow) return;
X
X    if (fountsound && !rn2(400))
X	switch (rn2(3)+hallu) {
X	    case 0:
X		You("hear bubbling water.");
X		break;
X	    case 1:
X		You("hear water falling on coins...");
X		break;
X	    case 2:
X		You("hear the splashing of a naiad.");
X		break;
X	    case 3:
X		You("seem to hear a soda fountain!");
X		break;
X	}
X    if (sinksound && !rn2(300))
X	switch (rn2(2)+hallu) {
X	    case 0:
X		You("hear a slow drip.");
X		break;
X	    case 1:
X		You("hear a gurgling noise.");
X		break;
X	    case 2:
X		You("seem to hear dishes being washed!");
X		break;
X	}
X    if (!rn2(300)) {
X	roomtype = OROOM;
X	for (sroom = &rooms[0]; ; sroom++) {	/* find any special room */
X	    if (sroom->hx < 0) break;		/* no more rooms */
X	    if (sroom->rtype != OROOM) {
X		if (sroom->rtype < SHOPBASE)
X		    roomtype = sroom->rtype;
X		else {
X		    croomno = inroom(u.ux,u.uy);
X		    if (croomno == -1 || sroom != &rooms[croomno])
X			/* player not presently in shop */
X			/* other special room types disappear when player
X			   enters */
X			roomtype = SHOPBASE;
X		}
X		break;
X	    }
X	}
X	switch (roomtype) {
X#ifdef THRONES
X	    case COURT:
X		switch (rn2(3)+hallu) {
X		    case 0:
X			You("hear the tones of courtly conversation.");
X			break;
X		    case 1:
X			You("hear a sceptre being pounded in judgement.");
X			break;
X		    case 2:
X			pline("Someone just shouted \"Off with %s head!\"",
X			    flags.female ? "her" : "his");
X			break;
X		    case 3:
X			You("seem to hear Queen Beruthiel's cats!");
X			break;
X		}
X		break;
X#endif
X	    case SWAMP:
X		switch (rn2(2)+hallu) {
X		    case 0:
X			You("hear mosquitoes!");
X			break;
X		    case 1:
X			You("smell marsh gas!");	/* so it's a smell...*/
X			break;
X		    case 2:
X			You("seem to hear Donald Duck.");
X			break;
X		}
X		break;
X	    case VAULT:
X		switch (rn2(2)+hallu) {
X		    case 0:
X			You("hear someone counting money.");
X			break;
X		    case 1:
X			You("hear the footsteps of a guard on patrol.");
X			break;
X		    case 2:
X			You("seem to hear Ebenezer Scrooge!");
X			break;
X		}
X		break;
X	    case BEEHIVE:
X		switch (rn2(2)+hallu) {
X		    case 0:
X			You("hear a low buzzing.");
X			break;
X		    case 1:
X			You("hear an angry drone.");
X			break;
X		    case 2:
X			You("seem to hear bees in your %shelmet!",
X			    uarmh ? "" : "(nonexistent) ");
X			break;
X		}
X		break;
X	    case MORGUE:
X		switch (rn2(2)+hallu) {
X		    case 0:
X		    You("suddenly realize it is unnaturally quiet.");
X			break;
X		    case 1:
X			pline("The hair on the back of your %s stands up.",
X				body_part(NECK));
X			break;
X		    case 2:
X			pline("The hair on your %s seems to stand up.",
X				body_part(HEAD));
X			break;
X		}
X		break;
X	    case BARRACKS:
X		switch (rn2(3)+hallu) {
X		    case 0:
X			You("hear dice being thrown.");
X			break;
X		    case 1:
X			You("hear blades being honed.");
X			break;
X		    case 2:
X			You("hear loud snoring.");
X			break;
X		    case 3:
X			You("seem to hear General MacArthur!");
X			break;
X		}
X		break;
X	    case ZOO:
X		switch (rn2(2)+hallu) {
X		    case 0:
XYou("hear a sound reminding you of an elephant stepping on a peanut.");
X			break;
X		    case 1:
X		    You("hear a sound reminding you of a trained seal.");
X			break;
X		    case 2:
X			You("seem to hear Doctor Doolittle!");
X			break;
X		}
X		break;
X	    case SHOPBASE:
X		switch (rn2(2)+hallu) {
X		    case 0:
X			You("hear the chime of a cash register.");
X			break;
X		    case 1:
X			You("hear someone cursing shoplifters.");
X			break;
X		    case 2:
X			You("seem to hear Neiman and Marcus arguing!");
X			break;
X		}
X		break;
X	    default:
X		break;
X	}
X    }
X}
X
X
X#include "eshk.h"
X
X#define NOTANGRY(mon)	mon->mpeaceful
X#define ANGRY(mon)	!NOTANGRY(mon)
X
Xvoid
Xgrowl(mtmp)
Xregister struct monst *mtmp;
X{
X    /* presumably nearness and soundok checks have already been made */
X    switch (mtmp->data->msound) {
X	case MS_SILENT:
X	    break;
X	case MS_MEW:
X	case MS_HISS:
X	    pline("%s hisses!", Monnam(mtmp));
X	    break;
X	case MS_BARK:
X	case MS_GROWL:
X	    pline("%s growls!", Monnam(mtmp));
X	    break;
X	case MS_ROAR:
X	    pline("%s roars!", Monnam(mtmp));
X	    break;
X	case MS_BUZZ:
X	    kludge("%s buzzes!", Monnam(mtmp));
X	    break;
X	case MS_SQEEK:
X	    kludge("%s squeals!", Monnam(mtmp));
X	    break;
X	case MS_SQAWK:
X	    kludge("%s screeches!", Monnam(mtmp));
X	    break;
X	case MS_NEIGH:
X	    kludge("%s neighs!", Monnam(mtmp));
X	    break;
X    }
X}
X
Xvoid
Xyelp(mtmp)
Xregister struct monst *mtmp;
X/* the sounds of mistreated pets */
X{
X    /* presumably nearness and soundok checks have already been made */
X    switch (mtmp->data->msound) {
X	case MS_MEW:
X	    pline("%s yowls!", Monnam(mtmp));
X	    break;
X	case MS_BARK:
X	case MS_GROWL:
X	    pline("%s yelps!", Monnam(mtmp));
X	    break;
X	case MS_ROAR:
X	    kludge("%s snarls!", Monnam(mtmp));
X	    break;
X	case MS_SQEEK:
X	    kludge("%s squeals!", Monnam(mtmp));
X	    break;
X	case MS_SQAWK:
X	    kludge("%s screaks!", Monnam(mtmp));
X	    break;
X    }
X}
X
Xvoid
Xwhimper(mtmp)
Xregister struct monst *mtmp;
X/* the sounds of distressed pets */
X{
X    /* presumably nearness and soundok checks have already been made */
X    switch (mtmp->data->msound) {
X	case MS_MEW:
X	case MS_GROWL:
X	    pline("%s whimpers.", Monnam(mtmp));
X	    break;
X	case MS_BARK:
X	    pline("%s whines.", Monnam(mtmp));
X	    break;
X	case MS_SQEEK:
X	    kludge("%s squeals.", Monnam(mtmp));
X	    break;
X    }
X}
X#endif /* SOUNDS */
X
X
Xstatic int
Xdomonnoise(mtmp)
Xregister struct monst *mtmp;
X{
X    /* presumably nearness checks have already been made */
X    if (!flags.soundok) return(0);
X    switch (mtmp->data->msound) {
X#ifdef ORACLE
X	case MS_ORACLE:
X	    return doconsult(mtmp);
X#endif
X#if defined(ALTARS) && defined(THEOLOGY)
X	case MS_PRIEST:
X	    priest_talk(mtmp);
X	    break;
X#endif
X#ifdef SOUNDS
X	case MS_SILENT:
X	    break;
X	case MS_SQEEK:
X	    kludge("%s squeaks.", Monnam(mtmp));
X	    break;
X	case MS_SQAWK:
X	    kludge("%s squawks.", Monnam(mtmp));
X	    break;
X	case MS_MEW:
X	    if (mtmp->mtame) {
X		if (mtmp->mconf || mtmp->mflee || mtmp->mtrapped || 
X		    moves > EDOG(mtmp)->hungrytime || mtmp->mtame < 5)
X		    kludge("%s yowls.", Monnam(mtmp));
X		else if (EDOG(mtmp)->hungrytime > moves + 1000)
X		    kludge("%s purrs.", Monnam(mtmp));
X		else
X		    kludge("%s mews.", Monnam(mtmp));
X	    }
X	case MS_HISS:
X	    if (!mtmp->mpeaceful && !mtmp->mtame)
X		kludge("%s hisses!", Monnam(mtmp));
X	    break;
X	case MS_BUZZ:
X	    if (!mtmp->mpeaceful && !mtmp->mtame)
X		kludge("%s buzzes angrily.", Monnam(mtmp));
X	    break;
X	case MS_GRUNT:
X	    kludge("%s grunts.", Monnam(mtmp));
X	    break;
X	case MS_BARK:
X	    if (flags.moonphase == FULL_MOON && night()) {
X		kludge("%s howls.", Monnam(mtmp));
X		break;
X	    } else if (mtmp->mtame || mtmp->mpeaceful) {
X		if (mtmp->mtame &&
X		    (mtmp->mconf || mtmp->mflee || mtmp->mtrapped ||
X		     moves > EDOG(mtmp)->hungrytime || mtmp->mtame < 5))
X		    kludge("%s whines.", Monnam(mtmp));
X		else if (EDOG(mtmp)->hungrytime > moves + 1000)
X		    kludge("%s yips.", Monnam(mtmp));
X		else
X		    kludge("%s barks.", Monnam(mtmp));
X		break;
X	    }
X	case MS_GROWL:
X	    if (!mtmp->mpeaceful && !mtmp->mtame)
X		kludge("%s growls!", Monnam(mtmp));
X	    break;
X	case MS_ROAR:
X	    if (!mtmp->mpeaceful && !mtmp->mtame)
X		kludge("%s roars!", Monnam(mtmp));
X	    break;
X	case MS_NEIGH:
X	    kludge("%s neighs.", Monnam(mtmp));
X	    break;
X	case MS_WAIL:
X	    kludge("%s wails mournfully.", Monnam(mtmp));
X	    break;
X	case MS_GURGLE:
X	    kludge("%s gurgles.", Monnam(mtmp));
X	    break;
X	case MS_SHRIEK:
X	    kludge("%s shrieks.", Monnam(mtmp));
X	    aggravate();
X	    break;
X	case MS_IMITATE:
X	    kludge("%s imitates you.", Monnam(mtmp));
X	    break;
X	case MS_DJINNI:
X	    if (mtmp->mtame) verbalize("Thank you for freeing me!");
X	    else if (mtmp->mpeaceful) verbalize("I'm free!");
X	    else verbalize("This will teach you not to disturb me!");
X	    break;
X	case MS_MUMBLE:
X	    kludge("%s mumbles incomprehensibly.", Monnam(mtmp));
X	    break;
X	case MS_HUMANOID:
X	    /* Generic humanoid behaviour. */
X	    if (!mtmp->mpeaceful || !mtmp->mtame) break;
X	    if (mtmp->mhp < 10)
X		kludge("%s moans.", Monnam(mtmp));
X	    else if (mtmp->mflee)
X		kludge("%s wants nothing to do with you.", Monnam(mtmp));
X	    else if (mtmp->mconf || mtmp->mstun)
X		verbalize(!rn2(3) ? "Huh?" : rn2(2) ? "What?" : "Eh?");
X	    else if (mtmp->mblinded)
X		verbalize("I can't see!");
X	    else if (mtmp->mtrapped)
X		verbalize("I'm trapped!");
X	    else if (mtmp->mhp < mtmp->mhpmax/2)
X		kludge("%s asks for a potion of healing.", Monnam(mtmp));
X	    /* Specific monster's interests */
X	    else if (is_elf(mtmp->data))
X		kludge("%s complains about orcs.", Monnam(mtmp));
X	    else if (is_dwarf(mtmp->data))
X		kludge("%s talks about mining.", Monnam(mtmp));
X	    else if (likes_magic(mtmp->data))
X		kludge("%s talks about spellcraft.", Monnam(mtmp));
X	    else if (carnivorous(mtmp->data))
X		kludge("%s discusses what kinds of meat are safe to eat.", Monnam(mtmp));
X	    else switch (monsndx(mtmp->data)){
X# ifdef TOLKIEN
X		case PM_HOBBIT:
X		    if (mtmp->mhpmax - mtmp->mhp >= 10)
Xkludge("%s complains about unpleasant dungeon conditions.", Monnam(mtmp));
X		    else
X		    	kludge("%s asks you about the One Ring.", Monnam(mtmp));
X		    break;
X# endif
X		case PM_ARCHEOLOGIST:
Xkludge("%s describes a recent article in \"Spelunker Today\" magazine.", Monnam(mtmp));
X		    break;
X		default:
X		    kludge("%s discusses dungeon exploration.", Monnam(mtmp));
X	    }
X	    break;
X	case MS_SEDUCE:
X# ifdef SEDUCE
X	    if ((mtmp->data==&mons[PM_SUCCUBUS] ||
X		mtmp->data==&mons[PM_INCUBUS])) {
X		doseduce(mtmp);
X		break;
X	    }
X# endif
X	    switch (poly_gender() == 0 ? rn2(3) : 0) {
X		case 2:
X			verbalize("Hello, sailor.");
X			break;
X		case 1:
X			kludge("%s comes on to you.", Monnam(mtmp));
X			break;
X		default:
X			kludge("%s cajoles you.", Monnam(mtmp));
X	    }
X	    break;
X# ifdef KOPS
X	case MS_ARREST:
X	    if (mtmp->mpeaceful)
X		pline("\"Just the facts, %s.\"",
X		      flags.female ? "Ma'am" : "Sir");
X	    else switch (rn2(3)) {
X		case 1:
X		    verbalize("Anything you say can be used against you.");
X		    break;
X		case 2:
X		    verbalize("You're under arrest!");
X		    break;
X		default:
X		    verbalize("Stop in the name of the Law!");
X	    }
X	    break;
X# endif
X	case MS_LAUGH:
X	    switch (rn2(4)) {
X		case 1:
X		    kludge("%s giggles.", Monnam(mtmp));
X		    break;
X		case 2:
X		    kludge("%s chuckles.", Monnam(mtmp));
X		    break;
X		case 3:
X		    kludge("%s snickers.", Monnam(mtmp));
X		    break;
X		default:
X		    kludge("%s laughs.", Monnam(mtmp));
X	    }
X	    break;
X# ifdef HARD
X	case MS_BRIBE:
X	    if (mtmp->mpeaceful && !mtmp->mtame) {
X		(void) demon_talk(mtmp);
X		break;
X	    }
X# endif
X	case MS_JEER:
X	    kludge("%s jeers at you.", Monnam(mtmp));
X	    break;
X	case MS_CUSS:
X	    cuss(mtmp);
X	    break;
X	case MS_GUARD:
X	    if (u.ugold)
X		verbalize("Please drop that gold and follow me.");
X	    else
X		verbalize("Please follow me.");
X	    break;
X	case MS_NURSE:
X	    if (uwep)
X		verbalize("Put that weapon away before you hurt someone!");
X	    else if (uarmc || uarm || uarmh || uarms || uarmg || uarmf)
X		if (pl_character[0] == 'H')
X		    verbalize("Doc, I can't help you unless you cooperate.");
X		else
X		    verbalize("Please undress so I can examine you.");
X# ifdef SHIRT
X	    else if (uarmu)
X		verbalize("Take off your shirt, please.");
X# endif
X	    else verbalize("Relax, this won't hurt a bit.");
X	    break;
X	case MS_SELL: /* pitch, pay, total */
X	    if (ANGRY(mtmp))
X		kludge("%s mentions how much %s dislikes %s customers.",
X			ESHK(mtmp)->shknam,
X			ESHK(mtmp)->ismale ? "he" : "she",
X			ESHK(mtmp)->robbed ? "non-paying" : "rude");
X	    else if (ESHK(mtmp)->following)
X		if (strncmp(ESHK(mtmp)->customer, plname, PL_NSIZ)) {
X		    pline("\"Hello %s!  I was looking for %s.\"",
X			    plname, ESHK(mtmp)->customer);
X		    ESHK(mtmp)->following = 0;
X		} else {
X		    pline("\"Hello %s!  Didn't you forget to pay?\"",
X			    plname);
X		}
X	    else if (ESHK(mtmp)->robbed)
X		kludge("%s complains about a recent robbery.", ESHK(mtmp)->shknam);
X	    else if (ESHK(mtmp)->billct)
X		kludge("%s reminds you that you haven't paid yet.", ESHK(mtmp)->shknam);
X	    else if (mtmp->mgold < 50)
X		kludge("%s complains that business is bad.", ESHK(mtmp)->shknam);
X	    else if (mtmp->mgold > 4000)
X		kludge("%s says that business is good.", ESHK(mtmp)->shknam);
X	    else
X		kludge("%s talks about the problem of shoplifters.", ESHK(mtmp)->shknam);
X	    break;
X# ifdef ARMY
X	case MS_SOLDIER:
X	    if (!mtmp->mpeaceful)
X	    switch (rn2(3)) {
X		case 2:
X		    verbalize("Resistance is useless!");
X		    break;
X		case 1:
X		    verbalize("You're dog meat!");
X		    break;
X		default:
X		    verbalize("Surrender!");
X	    }
X	    break;
X# endif
X#endif /* SOUNDS */
X    }
X    return(1);
X}
X
X
Xint
Xdotalk()
X{
X    register struct monst *mtmp;
X    register int tx,ty;
X
X    if (u.uswallow) {
X	pline("They won't hear you out there.");
X	return(0);
X    }
X
X    pline("Talk to whom? [in what direction] ");
X    (void) getdir(0);
X
X    if (u.dz) {
X	pline("They won't hear you %s there.", u.dz < 0 ? "up" : "down");
X	return(0);
X    }
X
X    if (u.dx == 0 && u.dy == 0) {
X/*
X * Let's not include this.  It raises all sorts of questions: can you wear
X * 2 helmets, 2 amulets, 3 pairs of gloves or 6 rings as a marilith,
X * etc...  --KAA
X#ifdef POLYSELF
X	if (u.umonnum == PM_ETTIN) {
X	    You("discover that your other head makes boring conversation.");
X	    return(1);
X	}
X#endif
X*/
X	pline("Talking to yourself is a bad habit for a dungeoneer.");
X	return(0);
X    }
X
X    tx = u.ux+u.dx; ty = u.uy+u.dy;
X    if (!cansee(tx,ty) || !levl[tx][ty].mmask || (mtmp = m_at(tx, ty))->mimic) {
X	pline("I see nobody there.");
X	return(0);
X    }
X    if (mtmp->mfroz || mtmp->msleep) {
X	kludge("%s seems not to notice you.", Monnam(mtmp));
X	return 0;
X    }
X
X    return domonnoise(mtmp);
X}
END_OF_FILE
if test 14344 -ne `wc -c <'src/sounds.c'`; then
    echo shar: \"'src/sounds.c'\" unpacked with wrong size!
fi
# end of 'src/sounds.c'
fi
if test -f 'src/weapon.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/weapon.c'\"
else
echo shar: Extracting \"'src/weapon.c'\" \(8980 characters\)
sed "s/^X//" >'src/weapon.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)weapon.c	3.0	89/04/24
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/*
X *	This module contains code for calculation of "to hit" and damage
X *	bonuses for any given weapon used, as well as weapons selection
X *	code for monsters.
X */
X#include	"hack.h"
X
Xstatic const char kebabable[] = { S_XORN, S_DRAGON, S_NAGA, S_GIANT, 0 };
X
X/*
X * 	hitval returns an integer representing the "to hit" bonuses
X *	of "otmp" against the monster type "ptr".
X */
Xint
Xhitval(otmp, ptr)
Xstruct	obj *otmp;
Xstruct	permonst *ptr;
X{
X	int	tmp = 0;
X
X	if(otmp->olet == WEAPON_SYM || otmp->otyp == PICK_AXE)
X		tmp += otmp->spe;
X
X/*	Put weapon specific "to hit" bonuses in below:		*/
X	switch(otmp->otyp) {
X
X#ifdef TOLKIEN
X	    case DWARVISH_MATTOCK:
X#endif
X	    case TWO_HANDED_SWORD:	tmp -= 1; break;
X	    case KATANA:		tmp += 1; break;
X#ifdef TOLKIEN
X	    case ELVEN_DAGGER:
X	    case ORCISH_DAGGER:
X#endif
X	    case DAGGER:
X	    case SHURIKEN:		tmp += 2; break;
X#ifdef WORM
X	    case CRYSKNIFE:		tmp += 3; break;
X#endif
X	}
X
X/*	Put weapon vs. monster type "to hit" bonuses in below:	*/
X
X	/* Blessed weapons used against undead or demons */
X	if(otmp->olet == WEAPON_SYM && otmp->blessed &&
X	   (is_demon(ptr) || is_undead(ptr))) tmp += 2;
X
X	if(otmp->otyp >= SPEAR && otmp->otyp <= JAVELIN &&
X	   index(kebabable, ptr->mlet)) tmp += 2;
X
X/*	Put specially named weapon "to hit" bonuses in below:	*/
X#ifdef NAMED_ITEMS
X	tmp += spec_abon(otmp, ptr);
X#endif
X	return(tmp);
X}
X
X/*
X * 	dmgval returns an integer representing the damage bonuses
X *	of "otmp" against the monster type "ptr".
X */
Xint
Xdmgval(otmp, ptr)
Xstruct	obj *otmp;
Xstruct	permonst *ptr;
X{
X	int	tmp = 0;
X
X	if(otmp->otyp == CREAM_PIE)	return(0);
X
X	if(bigmonst(ptr)) {
X	    if(objects[otmp->otyp].wldam)
X		tmp = rnd(objects[otmp->otyp].wldam);
X	    switch (otmp->otyp) {
X		case CROSSBOW_BOLT:
X		case MORNING_STAR:
X		case PARTISAN:
X#ifdef TOLKIEN
X		case ELVEN_BROADSWORD:
X#endif
X		case BROADSWORD:	tmp += 1; break;
X
X		case FLAIL:
X		case RANSEUR:
X		case VOULGE:		tmp += rnd(4); break;
X
X		case ACID_VENOM:
X		case HALBERD:
X		case SPETUM:		tmp += rnd(6); break;
X
X		case BARDICHE:
X		case TRIDENT:		tmp += d(2,4); break;
X
X#ifdef TOLKIEN
X		case DWARVISH_MATTOCK:
X#endif
X		case TWO_HANDED_SWORD:	tmp += d(2,6); break;
X	    }
X	} else {
X	    if(objects[otmp->otyp].wsdam)
X		tmp = rnd(objects[otmp->otyp].wsdam);
X	    switch (otmp->otyp) {
X		case CROSSBOW_BOLT:
X		case MACE:
X		case FLAIL:
X		case SPETUM:
X		case TRIDENT:		tmp += 1; break;
X
X		case BARDICHE:
X		case BILL_GUISARME:
X		case GUISARME:
X		case LUCERN_HAMMER:
X		case MORNING_STAR:
X		case RANSEUR:
X		case BROADSWORD:
X#ifdef TOLKIEN
X		case ELVEN_BROADSWORD:
X#endif
X		case VOULGE:		tmp += rnd(4); break;
X
X		case ACID_VENOM:	tmp += rnd(6); break;
X	    }
X	}
X	if (otmp->otyp == BULLWHIP && thick_skinned(ptr))
X		/* thick skinned/scaled creatures don't feel it */
X		tmp = 0;
X	if (otmp->olet == WEAPON_SYM || otmp->otyp == PICK_AXE)
X		tmp += otmp->spe;
X
X/*	Put weapon vs. monster type damage bonuses in below:	*/
X	if(otmp->olet == WEAPON_SYM) {
X	    if (otmp->blessed && (is_undead(ptr) || is_demon(ptr)))
X		tmp += rnd(4);
X	}
X
X/*	Put specially named weapon damage bonuses in below:	*/
X#ifdef NAMED_ITEMS
X	tmp += spec_dbon(otmp, ptr, tmp);
X#endif
X	return(tmp);
X}
X
Xvoid
Xset_uasmon() {		/* update the "uasmon" structure */
X
X#ifdef POLYSELF
X	if(u.umonnum >= 0) uasmon = &mons[u.umonnum];
X	else {
X#endif
X
X		uasmon = &playermon;
X		playermon.mlevel = u.ulevel;
X		playermon.ac = u.uac;
X		playermon.mr = (u.ulevel > 8) ? 5 * (u.ulevel-7) : u.ulevel;
X#ifdef POLYSELF
X	}
X#endif
X	return;
X}
X
X#define	Oselect(x)	if((otmp = m_carrying(mtmp, x))) return(otmp);
X
X#ifdef TOLKIEN
Xstatic const int rwep[] =
X	{ DWARVISH_SPEAR, ELVEN_SPEAR, SPEAR, ORCISH_SPEAR, JAVELIN,
X	  SHURIKEN, ELVEN_ARROW, ARROW, ORCISH_ARROW, CROSSBOW_BOLT,
X	  ELVEN_DAGGER, DAGGER, ORCISH_DAGGER, KNIFE, ROCK, LOADSTONE,
X	  LUCKSTONE, DART, BOOMERANG, CREAM_PIE
X	  /* note: CREAM_PIE should NOT be #ifdef KOPS */
X	  };
X#else
Xstatic const int rwep[] =
X	{ SPEAR, JAVELIN, SHURIKEN, ARROW, CROSSBOW_BOLT, DAGGER, KNIFE,
X	  ROCK, LOADSTONE, LUCKSTONE, DART, BOOMERANG, CREAM_PIE
X	  /* note: CREAM_PIE should NOT be #ifdef KOPS */
X	  };
X#endif
X
Xstruct obj *
Xselect_rwep(mtmp)	/* select a ranged weapon for the monster */
Xregister struct monst *mtmp;
X{
X	register struct obj *otmp;
X	int i;
X#ifdef KOPS
X	char mlet = mtmp->data->mlet;
X
X	if(mlet == S_KOP)	/* pies are first choice for Kops */
X	    Oselect(CREAM_PIE);
X#endif
X	if(throws_rocks(mtmp->data))	/* ...boulders for giants */
X	    Oselect(BOULDER);
X	/*
X	 * other than these two specific cases, always select the
X	 * most potent ranged weapon to hand.
X	 */
X	for (i = 0; i < SIZE(rwep); i++) {
X	    boolean no_propellor = FALSE;
X	    int prop;
X
X	    /* shooting gems from slings; this goes just before the darts */
X	    if (rwep[i]==DART && !likes_gems(mtmp->data)
X			/* && m_carrying(mtmp, SLING) */) {
X		for(otmp=mtmp->minvent; otmp; otmp=otmp->nobj) {
X		    if(otmp->olet==GEM_SYM &&
X				(otmp->otyp != LOADSTONE || !otmp->cursed))
X			return(otmp);
X		}
X	    }
X	    prop = (objects[rwep[i]]).w_propellor;
X	    if (prop > 0) {
X		switch (prop) {
X		case WP_BOW:
X#ifdef TOLKIEN
X		  no_propellor = !(m_carrying(mtmp, BOW) ||
X				   m_carrying(mtmp, ELVEN_BOW) ||
X				   m_carrying(mtmp, ORCISH_BOW));
X#else
X		  no_propellor = !(m_carrying(mtmp, BOW));
X#endif
X		  break;
X		/* case WP_SLING:
X		  no_propellor = (m_carrying(mtmp, SLING) != 0);
X		  break; */
X		case WP_CROSSBOW:
X		  no_propellor = (m_carrying(mtmp, CROSSBOW) != 0);
X		}
X	      }
X	    if (!no_propellor) Oselect(rwep[i]);
X	  }
X
X	/* failure */
X	return (struct obj *)0;
X}
X
X#ifdef TOLKIEN
X/* 0 = used by any monster; 1 = only used by strong monsters */
Xstatic const int hwep[][2] =
X	{ {DWARVISH_MATTOCK,1}, {TWO_HANDED_SWORD,1}, {KATANA,0},
X#ifdef WORM
X	  {CRYSKNIFE,0},
X#endif
X	  {TRIDENT,0}, {LONG_SWORD,0}, {ELVEN_BROADSWORD,0}, {BROADSWORD,0},
X	  {LUCERN_HAMMER,1}, {SCIMITAR,1}, {HALBERD,1}, {PARTISAN,1},
X	  {LANCE,1}, {FAUCHARD,1}, {BILL_GUISARME,1}, {BEC_DE_CORBIN,1},
X	  {GUISARME,1}, {RANSEUR,1}, {SPETUM,1}, {VOULGE,1}, {BARDICHE,0},
X	  {MORNING_STAR,0}, {GLAIVE,0}, {ELVEN_SHORT_SWORD,0},
X	  {DWARVISH_SHORT_SWORD,0}, {SHORT_SWORD,0}, {ORCISH_SHORT_SWORD,0},
X	  {MACE,0}, {AXE,0}, {DWARVISH_SPEAR,0}, {ELVEN_SPEAR,0}, {SPEAR,0},
X	  {ORCISH_SPEAR,0}, {FLAIL,0}, {QUARTERSTAFF,1}, {JAVELIN,0},
X	  {AKLYS,0}, {CLUB,0}, {PICK_AXE,0},
X#ifdef KOPS
X	  {RUBBER_HOSE,0},
X#endif /* KOPS */
X	  {ELVEN_DAGGER,0}, {DAGGER,0}, {ORCISH_DAGGER,0}, {SCALPEL,0},
X	  {KNIFE,0},
X#ifdef WORM
X	  {WORM_TOOTH,0},
X#endif
X	  {BULLWHIP,0}
X	};
X#else /* TOLKIEN */
X/* 0 = used by any monster; 1 = only used by strong monsters */
Xstatic const int hwep[][2] =
X	{ {TWO_HANDED_SWORD,1}, {KATANA,0},
X#ifdef WORM
X	  {CRYSKNIFE,0},
X#endif
X	  {TRIDENT,0}, {LONG_SWORD,0}, {BROADSWORD,0}, {LUCERN_HAMMER,1},
X	  {SCIMITAR,1}, {HALBERD,1}, {PARTISAN,1}, {LANCE,1}, {FAUCHARD,1},
X	  {BILL_GUISARME,1}, {BEC_DE_CORBIN,1}, {GUISARME,1}, {RANSEUR,1},
X	  {SPETUM,1}, {VOULGE,1}, {BARDICHE,0}, {MORNING_STAR,0}, {GLAIVE,0},
X	  {SHORT_SWORD,0}, {MACE,0}, {AXE,0}, {SPEAR,0}, {FLAIL,0},
X	  {QUARTERSTAFF,1}, {JAVELIN,0}, {AKLYS,0}, {CLUB,0}, {PICK_AXE,0},
X#ifdef KOPS
X	  {RUBBER_HOSE,0},
X#endif /* KOPS */
X	  {DAGGER,0}, {SCALPEL,0}, {KNIFE,0},
X#ifdef WORM
X	  {WORM_TOOTH,0},
X#endif
X	  {BULLWHIP,0}
X	};
X#endif /* TOLKIEN */
X
Xstruct obj *
Xselect_hwep(mtmp)	/* select a hand to hand weapon for the monster */
Xregister struct monst *mtmp;
X{
X	register struct obj *otmp;
X	int i;
X	boolean strong = strongmonst(mtmp->data);
X
X	if(is_giant(mtmp->data))	/* giants just love to use clubs */
X	    Oselect(CLUB);
X
X	/* only strong monsters can wield big (esp. long) weapons */
X	/* all monsters can wield the remaining weapons */
X	for (i = 0; i < SIZE(hwep); i++)
X	    if (strong || hwep[i][1]==0)
X		Oselect(hwep[i][0]);
X
X	/* failure */
X	return (struct obj *)0;
X}
X
Xint
Xabon() {	/* attack bonus for strength & dexterity */
X	int	sbon;
X
X#ifdef POLYSELF
X	if (u.umonnum >= 0) return(adj_lev(&mons[u.umonnum])-3);
X#endif
X	if(ACURR(A_STR) < 6) sbon = -2;
X	else if(ACURR(A_STR) < 8) sbon = -1;
X	else if(ACURR(A_STR) < 17) sbon = 0;
X	else if(ACURR(A_STR) < 69) sbon = 1;	/* up to 18/50 */
X	else if(ACURR(A_STR) < 118) sbon = 2;
X	else sbon = 3;
X
X	if(ACURR(A_DEX) < 4) return(sbon-3);
X	else if(ACURR(A_DEX) < 6) return(sbon-2);
X	else if(ACURR(A_DEX) < 8) return(sbon-1);
X	else if(ACURR(A_DEX) < 14) return(sbon);
X	else return(sbon+ACURR(A_DEX)-15);
X}
X
Xint
Xdbon() {	/* damage bonus for strength */
X#ifdef POLYSELF
X	if (u.umonnum >= 0) return(0);
X#endif
X
X	if(ACURR(A_STR) < 6) return(-1);
X	else if(ACURR(A_STR) < 16) return(0);
X	else if(ACURR(A_STR) < 18) return(1);
X	else if(ACURR(A_STR) == 18) return(2);		/* up to 18 */
X	else if(ACURR(A_STR) < 94) return(3);		/* up to 18/75 */
X	else if(ACURR(A_STR) < 109) return(4);		/* up to 18/90 */
X	else if(ACURR(A_STR) < 118) return(5);	/* up to 18/99 */
X	else return(6);
X}
END_OF_FILE
if test 8980 -ne `wc -c <'src/weapon.c'`; then
    echo shar: \"'src/weapon.c'\" unpacked with wrong size!
fi
# end of 'src/weapon.c'
fi
echo shar: End of archive 25 \(of 38\).
cp /dev/null ark25isdone
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 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 38 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