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