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