billr@saab.CNA.TEK.COM (Bill Randle) (07/12/90)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu> Posting-number: Volume 10, Issue 83 Archive-name: nethack3p9/Part38 Supersedes: NetHack3: Volume 7, Issue 56-93 #! /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 38 (of 56)." # Contents: UPDATE5 amiga/amiwind.c src/termcap.c src/u_init.c # Wrapped by billr@saab on Wed Jul 11 17:11:48 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'UPDATE5' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'UPDATE5'\" else echo shar: Extracting \"'UPDATE5'\" \(2225 characters\) sed "s/^X//" >'UPDATE5' <<'END_OF_FILE' X-------- XUPDATE 5 X-------- X XOld bones and save files should at least be syntactically correct this time, Xbut you should still throw them out if you don't want to be confronted with Xmonsters permanently masquerading as different monsters (since some of the Xmonsters' letters have changed). X X XNote that the posted shop fix was a stopgap patch, not an official patch, so Xit should be reversed before applying these patches. If you do not reverse Xit, probably nothing worse than a failure of one shk.c band will happen this Xtime. In general, however, you will have to do considerable hand-patching if Xyou leave intermediate patches in. X X XThe major bug fix in Patch 5 is moving the color definitions to color.h, thus Xbreaking the annoying dependency loop when bootstrapping NetHack. X XPatch 5 contains Johnny Lee's provision of a port to the Macintosh. The XMacintosh files live in a new subdirectory, 'mac'. We know that many of you Xwere waiting for a Mac port, and for you we are happy to have it. X XBasic support for several new other compilers or machines (see README), but Xthese probably need some more tweaking. X XA major new feature in Patch 5 is timed-out eating, i.e., being able to be Xinterrupted while eating by monsters attack. Mike Stephenson provided the Xbasic structure for dealing with partially eaten food. We believe that the Xonly remaining flaws in this code are occasional non-optimal messages which Xare generated by it (we are working on correcting this). X XIncorrect iron ball behavior and bugs in the iron ball code were Xsystematically corrected by Kevin Darcy who communicated with us about it Xand mailed us his patches. (Yes, Kevin, as you can see, it went in, and Xwith only one minor change.) X XThere were other, smaller, patches which were mailed to us and which were Ximplemented. To repeat: we are very happy to receive bug-fixing patches Xand code-enhancement patches. But please do as Kevin did, namely, tell us Xabout it in advance. X XDifficulties with dropping objects in shops, burning to death in hell, Xwielding amulets, pets eating corpses were fixed. So were scores of other Xsmall but annoying bugs. X XMICROPORT_BUG was added to cater to compilers that don't like large Xstructures. X END_OF_FILE if test 2225 -ne `wc -c <'UPDATE5'`; then echo shar: \"'UPDATE5'\" unpacked with wrong size! fi # end of 'UPDATE5' fi 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'\" \(17495 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#include "hack.h" X X#undef TRUE X#undef FALSE X#undef COUNT X#undef NULL 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#ifdef LATTICE X#include <dos.h> X#include <proto/exec.h> X#include <proto/graphics.h> X#include <proto/intuition.h> X#include <proto/diskfont.h> X#include <proto/console.h> X#endif X X#include "Amiga:amimenu.c" X X/* X * Versions we need of various libraries. We can't use LIBRARY_VERSION X * as defined in <exec/types.h> because some of the libraries we need X * don't have that version number in the 1.2 ROM. X */ X X#define INTUITION_VERSION 33L X#define GRAPHICS_VERSION 33L X#define DISKFONT_VERSION 34L X#define ICON_VERSION 34L X X/* First, external declarations... */ X Xextern struct Library *IconBase; Xstruct Library *ConsoleDevice; X X#ifdef AZTEC_C Xvoid FDECL(Alert, (long, char *)); Xvoid NDECL(Forbid); Xvoid NDECL(Permit); Xstruct Process *FDECL(FindTask, (char *)); Xstruct Library *FDECL(OpenLibrary, (char *, long)); Xvoid FDECL(CloseLibrary, (struct Library *)); Xstruct Message *FDECL(GetMsg, (struct MsgPort *)); Xvoid FDECL(ReplyMsg, (struct Message *)); Xlong FDECL(OpenDevice, (char *, long, struct IORequest *, long)); Xvoid FDECL(CloseDevice, (struct IORequest *)); Xlong FDECL(DoIO, (struct IORequest *)); Xstruct TextFont *FDECL(OpenDiskFont, (struct TextAttr *)); Xstruct TextFont *FDECL(OpenFont, (struct TextAttr *)); Xvoid FDECL(CloseFont, (struct TextFont *)); Xvoid FDECL(LoadRGB4, (struct ViewPort *, unsigned short *, long)); Xlong FDECL(SetFont, (struct RastPort *, struct TextFont*)); Xstruct MsgPort *FDECL(CreatePort, (char *, long)); Xvoid FDECL(DeletePort, (struct MsgPort *)); Xstruct Screen *FDECL(OpenScreen, (struct NewScreen *)); Xstruct Window *FDECL(OpenWindow, (struct NewWindow *)); Xvoid FDECL(CloseWindow, (struct Window *)); Xvoid FDECL(SetMenuStrip, (struct Window *, struct Menu *)); Xvoid FDECL(ClearMenuStrip, (struct Window *)); Xstruct MenuItem *FDECL(ItemAddress, (struct Menu *, long)); Xlong FDECL(RawKeyConvert, (struct InputEvent *, char *, long, struct KeyMap *)); X#endif X Xstatic int NDECL(BufferGetchar); Xstatic void FDECL(ConvertKey, (register struct IntuiMessage *)); Xstatic void FDECL(ProcessMessage, (register struct IntuiMessage *)); X#ifdef AMIFLUSH Xstatic struct Message *FDECL(GetFMsg,(struct MsgPort *)); X#endif Xvoid NDECL(Initialize); 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 Xextern struct Library *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#define BARHEIGHT 11 X#define WINDOWHEIGHT 192 X#define WIDTH 640 X X#ifdef TEXTCOLOR X#define DEPTH 3 Xstatic unsigned short palette[] = { X 0x0000, /* Black */ X 0x0DDD, /* White */ X 0x0C75, /* Brown */ X 0x0B08, /* Cyan */ X 0x00B0, /* Green */ X 0x0F08, /* Magenta */ X 0x055F, /* Blue */ X 0x0F00, /* Red */ X}; X#else X#define DEPTH 2 X#endif 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 , 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 Xstatic void 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 alt = (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT )) != 0; X /* Allow ALT to function as a META key ... */ X qualifier &= ~(IEQUALIFIER_LALT | IEQUALIFIER_RALT); X numeric_pad = (qualifier & IEQUALIFIER_NUMERICPAD) != 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 don't X * serve 'text' input, normally. Also, parsing their escape X * 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 (!flags.num_pad) /* Give digits if set, letters otherwise */ X goto wasarrow; 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 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 (!flags.num_pad && numeric_pad && length >= '1' && length <= '9') { Xwasarrow: 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 if (alt) X length |= 0x80; 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 void 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((struct Message *) 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#ifdef AMIFLUSH X (message = (struct IntuiMessage *) GetFMsg(HackWindow->UserPort))) X#else X (message = (struct IntuiMessage *) GetMsg(HackWindow->UserPort)) ) X#endif X ProcessMessage(message); X X return (int) 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 WaitPort(HackWindow->UserPort); 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((struct IORequest *) &ConsoleIO); X Buffered = 0; X } X} X X/* X * Queue a single character for output to the console screen. X */ X Xvoid 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 = strlen(string); X X if (len + Buffered >= CONBUFFER) X WindowFlush(); X X 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 X/*VARARGS1*/ X#if defined(USE_STDARG) || defined(USE_VARARGS) Xvoid XWindowPrintf VA_DECL(char *, fmt) X VA_START(fmt); X VA_INIT(fmt, char *); X WindowFlush(); /* Don't know if all will fit */ X vsprintf(ConsoleBuffer, fmt, VA_ARGS); X ConsoleIO.io_Command = CMD_WRITE; X ConsoleIO.io_Data = (APTR)ConsoleBuffer; X ConsoleIO.io_Length = -1; X DoIO((struct IORequest *) &ConsoleIO); X VA_END(); X} X#else 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 AZTEC_36 /* Efficient but not portable */ X format(WindowPutchar, fmt, &args); X#else X WindowFlush(); /* Don't know if all will fit */ X sprintf(ConsoleBuffer, fmt, args, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); X ConsoleIO.io_Command = CMD_WRITE; X ConsoleIO.io_Data = (APTR)ConsoleBuffer; X ConsoleIO.io_Length = -1; X DoIO((struct IORequest *) &ConsoleIO); X#endif X} X#endif 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((struct IORequest *) &ConsoleIO); X ConsoleDevice = NULL; X } X if (ConsoleIO.io_Message.mn_ReplyPort) X DeletePort(ConsoleIO.io_Message.mn_ReplyPort); X if (HackWindow) { X register struct IntuiMessage *msg; X X ((struct Process *) FindTask(NULL))->pr_WindowPtr = (APTR) pr_WindowPtr; X ClearMenuStrip(HackWindow); X Forbid(); X while (msg = (struct IntuiMessage *) GetMsg(HackWindow->UserPort)) X ReplyMsg((struct Message *) 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#ifdef LATTICE X { X/* __emit(0x4afc); /* illegal instruction */ X __emit(0x40fc); /* divide by */ X __emit(0x0000); /* #0 */ X /* NOTE: don't move CleanUp() above here - */ X /* it is too likely to kill the system */ X /* before it can get the SnapShot out, if */ X /* there is something really wrong. */ X__builtin_printf("abort botch"); /* (KL)TEMP */ X } X#endif X CleanUp(); X#undef exit X#ifdef AZTEC_C X _abort(); X#endif X exit((int) rc); 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", INTUITION_VERSION)) X == NULL) X Abort(AG_OpenLib | AO_Intuition); X X#ifdef HACKFONT X X if ( (GfxBase = OpenLibrary("graphics.library", GRAPHICS_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", DISKFONT_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", ICON_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#ifdef TEXTCOLOR X LoadRGB4(&HackScreen->ViewPort, palette, 8L); X#endif 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 = (struct Process *) 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 ConsoleIO.io_Message.mn_ReplyPort = CreatePort(NULL, 0L); X if (OpenDevice("console.device", 0L, (struct IORequest *) &ConsoleIO, 0L) != 0) X Abort(AG_OpenDev | AO_ConsoleDev); X X ConsoleDevice = (struct Library *) ConsoleIO.io_Device; X X Buffered = 0; X KbdBuffered = 0; X X /* set CRMOD on */ X WindowFPuts("\23320h"); X X Initialized = 1; X} X X#ifdef AMIFLUSH X/* This routine adapted from AmigaMail IV-37 by Michael Sinz */ Xstatic struct Message * XGetFMsg(port) X struct MsgPort *port; X { X struct IntuiMessage *msg,*succ,*succ1; X X if(msg=(struct IntuiMessage *)GetMsg(port)){ X if(!flags.amiflush)return(msg); X if(msg->Class==RAWKEY){ X Forbid(); X succ=(struct IntuiMessage *)(port->mp_MsgList.lh_Head); X while(succ1=(struct IntuiMessage *) X (succ->ExecMessage.mn_Node.ln_Succ)){ X if(succ->Class==RAWKEY){ X Remove((struct Node *)succ); X ReplyMsg((struct Message *)succ); X } X succ=succ1; X } X Permit(); X } X } X return(msg); X} X#endif END_OF_FILE if test 17495 -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/termcap.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/termcap.c'\" else echo shar: Extracting \"'src/termcap.c'\" \(17330 characters\) sed "s/^X//" >'src/termcap.c' <<'END_OF_FILE' X/* SCCS Id: @(#)termcap.c 3.0 88/11/20 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#define MONATTK_H /* comment line for pre-compiled headers */ X/* block some unused #defines to avoid overloading some cpp's */ X#include "hack.h" /* for ROWNO, COLNO, *HI, *HE, *AS, *AE */ X X#include <ctype.h> /* for isdigit() */ X X#include "termcap.h" X X#if (!defined(SYSV) && !defined(HPUX)) || defined(TOS) || defined(UNIXPC) X# ifndef LINT Xextern /* it is defined in libtermlib (libtermcap) */ X# endif X short ospeed; /* terminal baudrate; used by tputs */ X#else Xshort ospeed = 0; /* gets around "not defined" error message */ X#endif X X X#ifdef MICROPORT_286_BUG X#define Tgetstr(key) (tgetstr(key,tbuf)) X#else X#define Tgetstr(key) (tgetstr(key,&tbufptr)) X#endif /* MICROPORT_286_BUG **/ X XSTATIC_DCL void FDECL(nocmov, (int, int)); X#ifdef TEXTCOLOR X# ifdef TERMLIB X# ifdef OVLB Xstatic void NDECL(init_hilite); X# endif /* OVLB */ X# endif X#endif X XSTATIC_VAR char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE; XSTATIC_VAR char *VS, *VE, *US, *UE; XSTATIC_VAR char *MR, *ME; X#if 0 XSTATIC_VAR char *MB, *MH; XSTATIC_VAR char *MD; /* may already be in use below */ X#endif X#ifdef TERMLIB X# ifdef TEXTCOLOR XSTATIC_VAR char *MD; X# endif XSTATIC_VAR int SG; X#ifdef OVLB XSTATIC_OVL char PC = '\0'; X#else /* OVLB */ XSTATIC_DCL char PC; X#endif /* OVLB */ XSTATIC_VAR char tbuf[512]; X#endif X X#ifdef OVLB Xstatic char nullstr[] = ""; X#endif /* OVLB */ X X#ifndef TERMLIB XSTATIC_VAR char tgotobuf[20]; X# ifdef TOS X#define tgoto(fmt, x, y) (Sprintf(tgotobuf, fmt, y+' ', x+' '), tgotobuf) X# else X#define tgoto(fmt, x, y) (Sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf) X# endif X#endif /* TERMLIB */ X X#ifdef OVLB X Xvoid Xstartup() X{ X#ifdef TERMLIB X register const char *term; X register char *tptr; X char *tbufptr, *pc; X#endif X register int i; X X#ifdef TERMLIB X# ifdef VMS X term = getenv("EMACS_TERM"); X if (!term) X term = getenv("NETHACK_TERM"); X if (!term) X# endif X term = getenv("TERM"); X#endif X /* Set the default map symbols */ X (void) memcpy((genericptr_t) showsyms, X (genericptr_t) defsyms, sizeof showsyms); X X X#ifdef TERMLIB X if(!term) X#endif X#if defined(TOS) && defined(__GNUC__) && defined(TERMLIB) X term = "builtin"; /* library has a default */ X#else X# ifdef MACOS X /* dummy termcap for the Mac */ X HO = "\033[H"; X CL = "\033[2J"; /* a pseudo-ANSI termcap */ X CE = "\033[K"; X CM = "\033[%d;%dH"; /* not used */ X UP = "\033[A"; X ND = "\033[C"; X XD = "\033[B"; X BC = "\033[D"; X TI = TE = SE = UE = US = HE = "\033[0m"; X SO = "\033[1m"; X AS = VS = VE = AE = ""; X CO = COLNO; X LI = ROWNO + 3; X /* use special font ? */ X { X extern short macflags; X if (macflags & fUseCustomFont) X { X Handle theRes; X unsigned char *sym; X short i; X X sym = &showsyms[S_stone]; X theRes = GetResource(HACK_DATA,102); X HLock(theRes); X strncpy((char *)sym,(char *)(*theRes),32); X HUnlock(theRes); X ReleaseResource(theRes); X } X } X# ifdef TEXTCOLOR X for (i = 0; i < MAXCOLORS; i++) { X hilites[i] = (char *) alloc(sizeof("E[cc")); X Sprintf(hilites[i], "\033[c%c", (char)(i+'a')); X } X# endif X# else /* MACOS */ X# ifdef ANSI_DEFAULT X# ifdef TOS X { X CO = 80; LI = 25; X TI = VS = VE = TE = ""; X HO = "\033H"; X CL = "\033E"; /* the VT52 termcap */ X CE = "\033K"; X UP = "\033A"; X CM = "\033Y%c%c"; /* used with function tgoto() */ X ND = "\033C"; X XD = "\033B"; X BC = "\033D"; X SO = "\033p"; X SE = "\033q"; X HI = "\033p"; X#ifdef TEXTCOLOR X HE = "\033q\033b\017"; X for (i = 0; i < SIZE(hilites); i++) { X hilites[i] = (char *) alloc(sizeof("Eb1")); X Sprintf(hilites[i], (i%4)?"\033b%c" : "\033p", i); X } X#else X HE = "\033q"; X#endif X } X# else /* TOS */ X { X# ifdef DGK X get_scr_size(); X if(CO < COLNO || LI < ROWNO+3) X setclipped(); X# endif X HO = "\033[H"; X CL = "\033[2J"; /* the ANSI termcap */ X/* CD = "\033[J"; */ X CE = "\033[K"; X# ifndef TERMLIB X CM = "\033[%d;%dH"; X# else X CM = "\033[%i%d;%dH"; X# endif X UP = "\033[A"; X ND = "\033[C"; X XD = "\033[B"; X# ifdef MSDOS /* backspaces are non-destructive */ X BC = "\b"; X# else X BC = "\033[D"; X# endif X HI = SO = "\033[1m"; X US = "\033[4m"; X MR = "\033[7m"; X TI = HE = SE = UE = ME = "\033[0m"; X /* strictly, SE should be 2, and UE should be 24, X but we can't trust all ANSI emulators to be X that complete. -3. */ X# if !defined(MSDOS) || (defined(TERMLIB) && defined(AMIGA)) X AS = "\016"; X AE = "\017"; X# endif X TE = VS = VE = ""; X# ifdef TEXTCOLOR X for (i = 0; i < MAXCOLORS / 2; i++) { X hilites[i] = (char *) alloc(sizeof("\033[0;3%dm")); X hilites[i+BRIGHT] = (char *) alloc(sizeof("\033[1;3%dm")); X# ifdef MSDOS X Sprintf(hilites[i], (i == BLUE ? "\033[1;3%dm" : "\033[0;3%dm"), i); X# else X Sprintf(hilites[i], "\033[0;3%dm", i); X# endif X Sprintf(hilites[i+BRIGHT], "\033[1;3%dm", i); X } X# endif X return; X } X# endif /* TOS */ X# else X error("Can't get TERM."); X# endif /* ANSI_DEFAULT */ X# endif /* MACOS */ X#endif /* __GNUC__ && TOS && TERMCAP */ X#ifdef TERMLIB X tptr = (char *) alloc(1024); X X tbufptr = tbuf; X if(!strncmp(term, "5620", 4)) X flags.nonull = 1; /* this should be a termcap flag */ X if(tgetent(tptr, term) < 1) X error("Unknown terminal type: %s.", term); X if(pc = Tgetstr("pc")) X PC = *pc; X# ifdef TERMINFO X if(!(BC = Tgetstr("le"))) { X# else X if(!(BC = Tgetstr("bc"))) { X# endif X# if !defined(MINIMAL_TERM) && !defined(HISX) X if(!tgetflag("bs")) X error("Terminal must backspace."); X# endif X BC = tbufptr; X tbufptr += 2; X *BC = '\b'; X } X# ifdef MINIMAL_TERM X HO = NULL; X# else X HO = Tgetstr("ho"); X# endif X /* X * LI and CO are set in ioctl.c via a TIOCGWINSZ if available. If X * the kernel has values for either we should use them rather than X * the values from TERMCAP ... X */ X# ifndef DGK X if (!CO) CO = tgetnum("co"); X if (!LI) LI = tgetnum("li"); X# else X# if defined(TOS) && defined(__GNUC__) X if (!strcmp(term, "builtin")) X get_scr_size(); X else { X# endif X CO = tgetnum("co"); X LI = tgetnum("li"); X if (!LI || !CO) /* if we don't override it */ X get_scr_size(); X# if defined(TOS) && defined(__GNUC__) X } X# endif X# endif X if(CO < COLNO || LI < ROWNO+3) X setclipped(); X if(!(CL = Tgetstr("cl"))) X error("Hack needs CL."); X ND = Tgetstr("nd"); X if(tgetflag("os")) X error("Hack can't have OS."); X CE = Tgetstr("ce"); X UP = Tgetstr("up"); X /* It seems that xd is no longer supported, and we should use X a linefeed instead; unfortunately this requires resetting X CRMOD, and many output routines will have to be modified X slightly. Let's leave that till the next release. */ X XD = Tgetstr("xd"); X/* not: XD = Tgetstr("do"); */ X if(!(CM = Tgetstr("cm"))) { X if(!UP && !HO) X error("Hack needs CM or UP or HO."); X Printf("Playing hack on terminals without cm is suspect...\n"); X getret(); X } X SO = Tgetstr("so"); X SE = Tgetstr("se"); X US = Tgetstr("us"); X UE = Tgetstr("ue"); X SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */ X if(!SO || !SE || (SG > 0)) SO = SE = US = UE = nullstr; X TI = Tgetstr("ti"); X TE = Tgetstr("te"); X VS = VE = nullstr; X# ifdef TERMINFO X VS = Tgetstr("eA"); /* enable graphics */ X# endif X# if 0 X MB = Tgetstr("mb"); /* blink */ X MD = Tgetstr("md"); /* boldface */ X MH = Tgetstr("mh"); /* dim */ X# endif X MR = Tgetstr("mr"); /* reverse */ X ME = Tgetstr("me"); X X /* Get rid of padding numbers for HI and HE. Hope they X * aren't really needed!!! HI and HE are ouputted to the X * pager as a string - so how can you send it NULLS??? X * -jsb X */ X HI = (char *) alloc((unsigned)(strlen(SO)+1)); X HE = (char *) alloc((unsigned)(strlen(SE)+1)); X i = 0; X while(isdigit(SO[i])) i++; X Strcpy(HI, &SO[i]); X i = 0; X while(isdigit(SE[i])) i++; X Strcpy(HE, &SE[i]); X AS = Tgetstr("as"); X AE = Tgetstr("ae"); X CD = Tgetstr("cd"); X# ifdef TEXTCOLOR X MD = Tgetstr("md"); X# endif X set_whole_screen(); /* uses LI and CD */ X if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n"); X free((genericptr_t)tptr); X# ifdef TEXTCOLOR X init_hilite(); X# if defined(TOS) && defined(__GNUC__) X if (!strcmp(term, "builtin")) X HE="\033q\033b3\033c0"; /* to turn off colors, too */ X# endif X# endif X#endif /* TERMLIB */ X} X Xvoid Xstart_screen() X{ X xputs(TI); X xputs(VS); X if (flags.DECgraphics) { X /* select the line-drawing character set as the alternate X * character set X * do not select NA ASCII as the primary character set X * since people may reasonably be using the UK set X */ X xputs("\033)0"); X /* 'as' and 'ae' are missing from some termcaps */ X if (!AS) AS = "\016"; /* ^N */ X if (!AE) AE = "\017"; /* ^O */ X } X} X Xvoid Xend_screen() X{ X clear_screen(); X xputs(VE); X xputs(TE); X} X X/* Cursor movements */ X X#endif /* OVLB */ X#ifdef OVL0 X X#ifdef CLIPPING X/* if (x,y) is currently viewable, move the cursor there and return TRUE */ Xboolean Xwin_curs(x, y) Xint x, y; X{ X if (clipping && (x<=clipx || x>=clipxmax || y<=clipy || y>=clipymax)) X return FALSE; X y -= clipy; X x -= clipx; X curs(x, y+2); X return TRUE; X} X#endif X X#endif /* OVLB */ X#ifdef OVLB Xvoid Xcurs(x, y) Xregister int x, y; /* not xchar: perhaps xchar is unsigned and X curx-x would be unsigned as well */ X{ X if (y == cury && x == curx) X return; X if(!ND && (curx != x || x <= 3)) { /* Extremely primitive */ X cmov(x, y); /* bunker!wtm */ X return; X } X if(abs(cury-y) <= 3 && abs(curx-x) <= 3) X nocmov(x, y); X else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) { X (void) putchar('\r'); X curx = 1; X nocmov(x, y); X } else if(!CM) { X nocmov(x, y); X } else X cmov(x, y); X} X X#endif /* OVLB */ X#ifdef OVL0 X/* Note to OVLx tinkerers. The placement of this overlay controls the location X of the function xputc(). This function is not currnently in trampoli.[ch] X files for what is deemed to be performance reasons. If this define is moved X and or xputc() is taken out of the ROOT overlay, then action must be taken X in trampoli.[ch]. */ X XSTATIC_OVL void Xnocmov(x, y) Xint x,y; X{ X if (cury > y) { X if(UP) { X while (cury > y) { /* Go up. */ X xputs(UP); X cury--; X } X } else if(CM) { X cmov(x, y); X } else if(HO) { X home(); X curs(x, y); X } /* else impossible("..."); */ X } else if (cury < y) { X if(XD) { X while(cury < y) { X xputs(XD); X cury++; X } X } else if(CM) { X cmov(x, y); X } else { X while(cury < y) { X xputc('\n'); X curx = 1; X cury++; X } X } X } X if (curx < x) { /* Go to the right. */ X if(!ND) cmov(x, y); else /* bah */ X /* should instead print what is there already */ X while (curx < x) { X xputs(ND); X curx++; X } X } else if (curx > x) { X while (curx > x) { /* Go to the left. */ X xputs(BC); X curx--; X } X } X} X Xvoid Xcmov(x, y) Xregister int x, y; X{ X#ifdef MACOS X mcurs(x-1, y-1); X#else X xputs(tgoto(CM, x-1, y-1)); X#endif X cury = y; X curx = x; X} X X/* See note at OVLx ifdef above. xputc() is a special function. */ Xvoid Xxputc(c) Xchar c; X{ X#ifdef MACOS X mputc(c); X#else X (void) fputc(c, stdout); X#endif X} X Xvoid Xxputs(s) Xconst char *s; X{ X#ifndef MACOS X# ifndef TERMLIB X (void) fputs(s, stdout); X# else X# ifdef __STDC__ X tputs(s, 1, (int (*)())xputc); X# else X tputs(s, 1, xputc); X# endif X# endif X#else X mputs(s); X#endif X} X Xvoid Xcl_end() { X if(CE) X xputs(CE); X else { /* no-CE fix - free after Harold Rynes */ X /* this looks terrible, especially on a slow terminal X but is better than nothing */ X register int cx = curx, cy = cury; X X while(curx < CO) { X xputc(' '); X curx++; X } X curs(cx, cy); X } X} X X#endif /* OVL0 */ X#ifdef OVLB X Xvoid Xclear_screen() { X xputs(CL); X home(); X} X X#endif /* OVLB */ X#ifdef OVL0 X Xvoid Xhome() X{ X if(HO) X xputs(HO); X else if(CM) X xputs(tgoto(CM, 0, 0)); X else X curs(1, 1); /* using UP ... */ X curx = cury = 1; X} X Xvoid Xstandoutbeg() X{ X if(SO) xputs(SO); X} X Xvoid Xstandoutend() X{ X if(SE) xputs(SE); X} X Xvoid Xrevbeg() X{ X if(MR) xputs(MR); X} X X#if 0 /* if you need one of these, uncomment it (here and in extern.h) */ Xvoid Xboldbeg() X{ X if(MD) xputs(MD); X} X Xvoid Xblinkbeg() X{ X if(MB) xputs(MB); X} X Xvoid Xdimbeg() X/* not in most termcap entries */ X{ X if(MH) xputs(MH); X} X#endif X Xvoid Xm_end() X{ X if(ME) xputs(ME); X} X X#endif /* OVL0 */ X#ifdef OVLB X Xvoid Xbacksp() X{ X xputs(BC); X} X Xvoid Xbell() X{ X if (flags.silent) return; X (void) putchar('\007'); /* curx does not change */ X (void) fflush(stdout); X} X X#endif /* OVLB */ X#ifdef OVL0 X X#ifdef ASCIIGRAPH Xvoid Xgraph_on() { X if (AS) xputs(AS); X} X Xvoid Xgraph_off() { X if (AE) xputs(AE); X} X#endif X X#endif /* OVL0 */ X#ifdef OVL1 X X#if !defined(MSDOS) && !defined(MACOS) X# ifdef VMS Xstatic const short tmspc10[] = { /* from termcap */ X 0, 2000, 1333, 909, 743, 666, 333, 166, 83, 55, 50, 41, 27, 20, 13, 10, X 5 X}; X# else Xstatic const short tmspc10[] = { /* from termcap */ X 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5 X}; X# endif X#endif X Xvoid Xdelay_output() { X /* delay 50 ms - could also use a 'nap'-system call */ X /* BUG: if the padding character is visible, as it is on the 5620 X then this looks terrible. */ X#if defined(MSDOS) || defined(MACOS) X /* simulate the delay with "cursor here" */ X register int i; X for (i = 0; i < 3; i++) { X cmov(curx, cury); X (void) fflush(stdout); X } X#else /* MSDOS || MACOS */ X if(!flags.nonull) X# ifdef TERMINFO X /* cbosgd!cbcephus!pds for SYS V R2 */ X# ifdef __STDC__ X tputs("$<50>", 1, (int (*)())xputc); X# else X tputs("$<50>", 1, xputc); X# endif X# else X# ifdef __STDC__ X tputs("50", 1, (int (*)())xputc); X# else X tputs("50", 1, xputc); X# endif X# endif X X else if(ospeed > 0 && ospeed < SIZE(tmspc10)) if(CM) { X /* delay by sending cm(here) an appropriate number of times */ X register int cmlen = strlen(tgoto(CM, curx-1, cury-1)); X register int i = 500 + tmspc10[ospeed]/2; X X while(i > 0) { X cmov(curx, cury); X i -= cmlen*tmspc10[ospeed]; X } X } X#endif /* MSDOS || MACOS */ X} X X#endif /* OVL1 */ X#ifdef OVLB X Xvoid Xcl_eos() /* free after Robert Viduya */ X{ /* must only be called with curx = 1 */ X X if(CD) X xputs(CD); X else { X register int cx = curx, cy = cury; X while(cury <= LI-2) { X cl_end(); X xputc('\n'); X curx = 1; X cury++; X } X cl_end(); X curs(cx, cy); X } X} X X#if defined(TEXTCOLOR) && defined(TERMLIB) X# ifdef UNIX X/* X * Sets up color highlighting, using terminfo(4) escape sequences (highlight X * code found in pri.c). It is assumed that the background color is black. X */ X/* terminfo indexes for the basic colors it guarantees */ X#define COLOR_BLACK 1 /* fake out to avoid black on black */ X#define COLOR_BLUE 1 X#define COLOR_GREEN 2 X#define COLOR_CYAN 3 X#define COLOR_RED 4 X#define COLOR_MAGENTA 5 X#define COLOR_YELLOW 6 X#define COLOR_WHITE 7 X X/* map ANSI RGB to terminfo BGR */ Xconst int ti_map[8] = { X COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, X COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE }; X Xstatic void Xinit_hilite() X{ X register int c; X# ifdef TERMINFO X char *setf, *scratch; X extern char *tparm(); X# endif X X for (c = 0; c < MAXCOLORS; c++) X hilites[c] = HI; X X# ifdef TERMINFO X if (tgetnum("Co") < 8 || (setf = tgetstr("Sf", 0)) == NULL) X return; X X for (c = 0; c < MAXCOLORS / 2; c++) { X scratch = tparm(setf, ti_map[c]); X hilites[c] = (char *) alloc(strlen(scratch) + 1); X hilites[c+BRIGHT] = (char*) alloc(strlen(scratch)+strlen(MD)+1); X Strcpy(hilites[c], scratch); X Strcpy(hilites[c+BRIGHT], MD); X Strcat(hilites[c+BRIGHT], scratch); X } X# endif X} X X# else /* UNIX */ X X/* X * Sets up highlighting sequences, using ANSI escape sequences (highlight code X * found in pri.c). The termcap entry for HI (from SO) is scanned to find the X * background color. X */ X Xstatic void Xinit_hilite() X{ X# ifdef TOS X int c; X# else X int backg = BLACK, foreg = WHITE, len; X register int c, color; X# endif X X for (c = 0; c < SIZE(hilites); c++) X hilites[c] = HI; X X# ifdef TOS X hilites[BROWN] = "\033b0\033c1"; X hilites[RED] = "\033b1"; X hilites[MAGENTA] = hilites[MAGENTA|BRIGHT] = "\033b1\033c2"; X hilites[CYAN] = hilites[CYAN|BRIGHT] = "\033b3\033c2"; X hilites[BLUE] = hilites[BLUE|BRIGHT] = "\033b2"; X hilites[GREEN] = hilites[GREEN|BRIGHT] = "\033b2\033c3"; X hilites[GRAY] = "\033b3\033c0"; X hilites[ORANGE_COLORED] = "\033b3\033c1"; X hilites[YELLOW] = "\033b1\033c3"; X hilites[WHITE] = "\033b0\033c3"; X# else /* TOS */ X /* find the background color, HI[len] == 'm' */ X len = strlen(HI) - 1; X X if (HI[len] != 'm' || len < 3) return; X X c = 2; X while (c < len) { X if ((color = atoi(&HI[c])) == 0) { X /* this also catches errors */ X foreg = WHITE; backg = BLACK; X /* X } else if (color == 1) { X foreg |= BRIGHT; X */ X } else if (color >= 30 && color <= 37) { X foreg = color - 30; X } else if (color >= 40 && color <= 47) { X backg = color - 40; X } X while (isdigit(HI[++c])); X c++; X } X X for (c = 0; c < MAXCOLORS / 2; c++) X /* avoid invisibility */ X if (foreg != c && backg != c) { X hilites[c] = (char *) alloc(sizeof("\033[0;3%d;4%dm")); X hilites[c+BRIGHT] = (char *) alloc(sizeof("\033[1;3%d;4%dm")); X#ifdef MSDOS /* brighten low-visibility colors */ X if (c == BLUE) X Sprintf(hilites[c], "\033[1;3%d;4%dm", c, backg); X else X#endif X Sprintf(hilites[c], "\033[0;3%d;4%dm", c, backg); X Sprintf(hilites[c+BRIGHT], "\033[1;3%d;4%dm", c, backg); X } X# endif /* TOS */ X} X# endif /* UNIX */ X#endif /* TEXTCOLOR */ X X#endif /* OVLB */ END_OF_FILE if test 17330 -ne `wc -c <'src/termcap.c'`; then echo shar: \"'src/termcap.c'\" unpacked with wrong size! fi # end of 'src/termcap.c' fi if test -f 'src/u_init.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/u_init.c'\" else echo shar: Extracting \"'src/u_init.c'\" \(18113 characters\) sed "s/^X//" >'src/u_init.c' <<'END_OF_FILE' X/* SCCS Id: @(#)u_init.c 3.0 89/11/15 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#include "hack.h" X Xstruct trobj { X unsigned short int trotyp; X schar trspe; X char trolet; X Bitfield(trquan,6); X Bitfield(trknown,1); X Bitfield(trbless,2); X}; X Xstatic void FDECL(ini_inv, (struct trobj *)); Xstatic void FDECL(knows_class,(CHAR_P)); Xstatic int FDECL(role_index,(CHAR_P)); X X#define UNDEF_TYP 0 X#define UNDEF_SPE '\177' X#define UNDEF_BLESS 2 X Xconst char *(roles[]) = { /* must all have distinct first letter */ X /* roles[2] and [6] are changed for females */ X /* in all cases, the corresponding male and female */ X /* roles must start with the same letter */ X "Archeologist", "Barbarian", "Cave-man", "Elf", "Healer", "Knight", X "Priest", "Rogue", "Samurai", "Tourist", "Valkyrie", "Wizard" X}; X Xconst char *pl_classes = "ABCEHKPRSTVW"; X Xstruct you zerou; X Xstruct trobj Cave_man[] = { X#define C_ARROWS 2 X { CLUB, 1, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { BOW, 1, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { ARROW, 0, WEAPON_SYM, 25, 1, UNDEF_BLESS }, /* quan is variable */ X { LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Barbarian[] = { X { TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { AXE, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { RING_MAIL, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { FOOD_RATION, 0, FOOD_SYM, 1, 1, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Knight[] = { X { LONG_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { SPEAR, 2, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { RING_MAIL, 1, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { HELMET, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { SMALL_SHIELD, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { LEATHER_GLOVES, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Elf[] = { X#define E_ARROWS 2 X#define E_ARMOR 3 X#ifdef TOLKIEN X { ELVEN_SHORT_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { ELVEN_BOW, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { ELVEN_ARROW, 0, WEAPON_SYM, 25, 1, UNDEF_BLESS }, X { UNDEF_TYP, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { LEMBAS_WAFER, 0, FOOD_SYM, 2, 1, 0 }, X#else X { SHORT_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { BOW, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { ARROW, 0, WEAPON_SYM, 25, 1, UNDEF_BLESS }, X { ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { FOOD_RATION, 0, FOOD_SYM, 2, 1, 0 }, X#endif X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Valkyrie[] = { X { LONG_SWORD, 1, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { DAGGER, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { SMALL_SHIELD, 3, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { FOOD_RATION, 0, FOOD_SYM, 1, 1, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Healer[] = { X { SCALPEL, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { LEATHER_GLOVES, 1, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { STETHOSCOPE, 0, TOOL_SYM, 1, 1, 0 }, X { POT_HEALING, 0, POTION_SYM, 4, 1, UNDEF_BLESS }, X { POT_EXTRA_HEALING, 0, POTION_SYM, 4, 1, UNDEF_BLESS }, X { WAN_SLEEP, UNDEF_SPE, WAND_SYM, 1, 1, UNDEF_BLESS }, X#ifdef SPELLS X /* always blessed, so it's guaranteed readable */ X { SPE_HEALING, 0, SPBOOK_SYM, 1, 1, 1 }, X { SPE_EXTRA_HEALING, 0, SPBOOK_SYM, 1, 1, 1 }, X#endif X { APPLE, 0, FOOD_SYM, 5, 1, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Archeologist[] = { X /* if adventure has a name... idea from tan@uvm-gen */ X { BULLWHIP, 2, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { FEDORA, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { FOOD_RATION, 0, FOOD_SYM, 3, 1, 0 }, X { PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 1, UNDEF_BLESS }, X { TINNING_KIT, 0, TOOL_SYM, 1, 1, UNDEF_BLESS }, X { SACK, 0, TOOL_SYM, 1, 0, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Tinopener[] = { X { TIN_OPENER, 0, TOOL_SYM, 1, 1, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Magicmarker[] = { X { MAGIC_MARKER, UNDEF_SPE, TOOL_SYM, 1, 1, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Lamp[] = { X { LAMP, 5, TOOL_SYM, 1, 1, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X X#ifndef HARD Xstruct trobj Saving[] = { X { AMULET_OF_LIFE_SAVING, 0, TOOL_SYM, 1, 1, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X#endif X X#ifdef EXPLORE_MODE Xstruct trobj Wishing[] = { X { WAN_WISHING, 3, WAND_SYM, 1, 1, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X#endif X X#ifdef WALKIES Xstruct trobj Leash[] = { X { LEASH, 0, TOOL_SYM, 1, 1, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X#endif X Xstruct trobj Blindfold[] = { X { BLINDFOLD, 0, TOOL_SYM, 1, 1, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Tourist[] = { X#define T_DARTS 0 X { DART, 2, WEAPON_SYM, 25, 1, UNDEF_BLESS }, /* quan is variable */ X { UNDEF_TYP, UNDEF_SPE, FOOD_SYM, 10, 1, 0 }, X { POT_EXTRA_HEALING, 0, POTION_SYM, 2, 1, UNDEF_BLESS }, X { SCR_MAGIC_MAPPING, 0, SCROLL_SYM, 4, 1, UNDEF_BLESS }, X { EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1, 0 }, X#ifdef SHIRT X { HAWAIIAN_SHIRT, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X#endif X { CREDIT_CARD, 0, TOOL_SYM, 1, 1, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Rogue[] = { X#define R_DAGGERS 1 X { SHORT_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { DAGGER, 0, WEAPON_SYM, 10, 1, 0 }, /* quan is variable */ X { LEATHER_ARMOR, 1, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { POT_SICKNESS, 0, POTION_SYM, 1, 1, 0 }, X { LOCK_PICK, 9, TOOL_SYM, 1, 1, 0 }, X { SACK, 0, TOOL_SYM, 1, 0, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Wizard[] = { X#define W_MULTSTART 2 X#ifdef SPELLS X# define W_MULTEND 6 X#else X# define W_MULTEND 5 X#endif X { ATHAME, 1, WEAPON_SYM, 1, 1, 1 }, /* for dealing with ghosts */ X { CLOAK_OF_MAGIC_RESISTANCE, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { UNDEF_TYP, UNDEF_SPE, WAND_SYM, 1, 1, UNDEF_BLESS }, X { UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 1, UNDEF_BLESS }, X { UNDEF_TYP, UNDEF_SPE, POTION_SYM, 3, 1, UNDEF_BLESS }, X { UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 1, UNDEF_BLESS }, X#ifdef SPELLS X { UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 1, 1, UNDEF_BLESS }, X#endif X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Samurai[] = { X { KATANA, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, X { SHORT_SWORD, 0, WEAPON_SYM, 1, 1, UNDEF_BLESS }, /* the wakizashi */ X { SHURIKEN, 0, WEAPON_SYM, 9, 1, UNDEF_BLESS }, /* quan is variable */ X { SPLINT_MAIL, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { FORTUNE_COOKIE, 0, FOOD_SYM, 3, 1, 0 }, X { 0, 0, 0, 0, 0, 0 } X}; X Xstruct trobj Priest[] = { X { MACE, 1, WEAPON_SYM, 1, 1, 1 }, X { CHAIN_MAIL, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { SMALL_SHIELD, 0, ARMOR_SYM, 1, 1, UNDEF_BLESS }, X { POT_WATER, 0, POTION_SYM, 4, 1, 1 }, /* holy water */ X { CLOVE_OF_GARLIC, 0, FOOD_SYM, 1, 1, 0 }, X#ifdef SPELLS X { UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 2, 1, UNDEF_BLESS }, X#endif X { 0, 0, 0, 0, 0, 0 } X}; X Xstatic void Xknows_class(sym) Xregister char sym; X{ X register unsigned ct; X for (ct = 1; ct <= NROFOBJECTS; ct++) X if (objects[ct].oc_olet == sym) { X makeknown(ct); X objects[ct].oc_descr = NULL; /* not a "discovery" */ X } X} X Xstatic int Xrole_index(pc) Xchar pc; X{ X register const char *cp; X X if(cp = index(pl_classes, pc)) X return(cp - pl_classes); X return(-1); X} X Xvoid Xu_init() X{ X register int i; X char pick, pc; X#ifdef __GNULINT__ X pick = i = 0; /* prevent "used before set" warnings */ X#endif X Printf("\nNetHack, Copyright 1985, 1986, 1987, 1988, 1989, 1990."); X Printf("\n By Stichting Mathematisch Centrum and M. Stephenson."); X Printf("\n See license for details.\n\n"); X X if(flags.female) { /* should have been set in NETHACKOPTIONS */ X roles[2] = "Cave-woman"; X roles[6] = "Priestess"; X } X X if(pc = pl_character[0]) { X if('a' <= pc && pc <= 'z') pc += 'A'-'a'; X if((i = role_index(pc)) >= 0) X goto got_suffix; X Printf("\nUnknown role: %c\n", pc); X pl_character[0] = pc = 0; X } X X#ifndef MACOS X X Printf("\nShall I pick a character for you? [Y,N, or Q(quit)] "); X X while(!index("yYnNqQ", (pick = readchar())) && !index(quitchars, pick)) X bell(); X X if(index(quitchars, pick)) pick = 'Y'; X else if('a' <= pick && pick <= 'z') pick += 'A'-'a'; X X Printf("%c\n", pick); /* echo */ X X if (pick == 'Q') { X clearlocks(); X settty(NULL); X exit(0); X } X X if (pick == 'Y') X goto beginner; X X Printf("\nWhat kind of character are you:\n\n"); X Printf(" %s,", An(roles[0])); X for(i = 1; i < SIZE(roles); i++) { X Printf(" %s", an(roles[i])); X if((((i + 1) % 4) == 0) && (i != SIZE(roles) -1)) X Printf(",\n "); X else if(i < SIZE(roles) - 2) Printf(","); X if(i == SIZE(roles) - 2) Printf(" or"); X } X Printf("?\n ["); X for(i = 0; i < SIZE(roles); i++) Printf("%c,", pl_classes[i]); X Printf(" or Q] "); X X while(pc = readchar()) { X if('a' <= pc && pc <= 'z') pc += 'A'-'a'; X if (pc == 'Q') { X clearlocks(); X settty(NULL); X exit(0); X } X if((i = role_index(pc)) >= 0) { X Printf("%c\n", pc); /* echo */ X (void) fflush(stdout); /* should be seen */ X break; X } X if(pc == '\n') break; X bell(); X } X if(pc == '\n') pc = 0; X X#else X flags.wantspace = FALSE; X#endif /* MACOS */ X Xbeginner: X if(!pc) { X i = rn2(SIZE(roles)); X pc = pl_classes[i]; X Printf("\nThis game you will be %s.\n", an(roles[i])); X getret(); X /* give him some feedback in case mklev takes much time */ X (void) putchar('\n'); X (void) fflush(stdout); X } X Xgot_suffix: X X (void) strncpy(pl_character, roles[i], PL_CSIZ-1); X pl_character[PL_CSIZ-1] = 0; X flags.beginner = 1; X u = zerou; X u.usym = S_HUMAN; X u.umoved = FALSE; X u.ugrave_arise = -1; X X u.ulevel = 0; /* set up some of the initial attributes */ X u.uhp = u.uhpmax = newhp(); X adjabil(0,1); X u.ulevel = 1; X X u.uluck = u.moreluck = 0; X init_uhunger(); X uarm = uarmc = uarmh = uarms = uarmg = uarmf = X#ifdef SHIRT X uarmu = X#endif X uwep = uball = uchain = uleft = uright = 0; X X#ifdef SPELLS X u.uen = u.uenmax = 1; X for (i = 0; i <= MAXSPELL; i++) spl_book[i].sp_id = NO_SPELL; X#endif X#ifdef THEOLOGY X u.ublesscnt = 300; /* no prayers just yet */ X u.ublessed = 0; /* not worthy yet */ X u.ugangr = 0; /* gods not angry */ X#endif X#if defined(THEOLOGY) && defined(ELBERETH) X u.uhand_of_elbereth = 0; X#endif X#ifdef MEDUSA X u.ukilled_medusa = 0; X#endif X#ifdef HARD X u.udemigod = u.udg_cnt = 0; /* not a demi-god yet... */ X#endif X#ifdef POLYSELF X u.umonnum = u.ulycn = -1; X u.mh = u.mhmax = u.mtimedone = 0; X set_uasmon(); X#endif X switch(pc) { X /* pc will always be in uppercase by this point */ X case 'C': X Cave_man[C_ARROWS].trquan = 12 + rnd(30); X ini_inv(Cave_man); X break; X case 'T': X Tourist[T_DARTS].trquan = 20 + rnd(20); X u.ugold = u.ugold0 = rnd(1000); X ini_inv(Tourist); X if(!rn2(25)) ini_inv(Tinopener); X else if(!rn2(25)) ini_inv(Magicmarker); X#ifdef WALKIES X else if(!rn2(25)) ini_inv(Leash); X#endif X break; X case 'R': X Rogue[R_DAGGERS].trquan = 5 + rnd(10); X u.ugold = u.ugold0 = 0; X ini_inv(Rogue); X if(!rn2(5)) ini_inv(Blindfold); X makeknown(SACK); X break; X case 'W': X#ifdef SPELLS X u.uen = u.uenmax += rn2(4); X#endif X ini_inv(Wizard); X if(!rn2(5)) ini_inv(Magicmarker); X if(!rn2(5)) ini_inv(Blindfold); X break; X case 'A': X ini_inv(Archeologist); X if(!rn2(10)) ini_inv(Tinopener); X else if(!rn2(4)) ini_inv(Lamp); X else if(!rn2(10)) ini_inv(Magicmarker); X knows_class(GEM_SYM); X makeknown(SACK); X /* We can't set trknown for it, then it'd be "uncursed" X * sack... X */ X break; X case 'E': X Elf[E_ARROWS].trquan = 15+rnd(20); X#ifdef TOLKIEN X Elf[E_ARMOR].trotyp = ((rn2(100) >= 50) X ? ELVEN_MITHRIL_COAT : ELVEN_CLOAK); X /* rn2(100) > 50 necessary because some random number X * generators are bad enough to seriously skew the X * results if we use rn2(2)... --KAA X */ X#endif X ini_inv(Elf); X if(!rn2(5)) ini_inv(Blindfold); X else if(!rn2(6)) ini_inv(Lamp); X#ifdef TOLKIEN X /* makeknown(ELVEN_SHORT_SWORD); X * no need to do this since the initial inventory contains one, X * so ini_inv already did it for us X */ X objects[ELVEN_SHORT_SWORD].oc_descr = NULL; X /* makeknown(ELVEN_ARROW); */ X objects[ELVEN_ARROW].oc_descr = NULL; X /* makeknown(ELVEN_BOW); */ X objects[ELVEN_BOW].oc_descr = NULL; X makeknown(ELVEN_SPEAR); X objects[ELVEN_SPEAR].oc_descr = NULL; X makeknown(ELVEN_DAGGER); X objects[ELVEN_DAGGER].oc_descr = NULL; X makeknown(ELVEN_BROADSWORD); X objects[ELVEN_BROADSWORD].oc_descr = NULL; X#endif X makeknown(ELVEN_CLOAK); X objects[ELVEN_CLOAK].oc_descr = NULL; X break; X case 'V': X flags.female = TRUE; X ini_inv(Valkyrie); X if(!rn2(6)) ini_inv(Lamp); X knows_class(WEAPON_SYM); X break; X case 'H': X u.ugold = u.ugold0 = rnd(1000)+1000; X ini_inv(Healer); X if(!rn2(25)) ini_inv(Lamp); X break; X case 'K': X ini_inv(Knight); X knows_class(WEAPON_SYM); X break; X case 'B': X ini_inv(Barbarian); X if(!rn2(6)) ini_inv(Lamp); X knows_class(WEAPON_SYM); X break; X case 'S': X ini_inv(Samurai); X if(!rn2(5)) ini_inv(Blindfold); X knows_class(WEAPON_SYM); X break; X case 'P': X#ifdef SPELLS X u.uen = u.uenmax += rn2(4); X#endif X ini_inv(Priest); X if(!rn2(10)) ini_inv(Magicmarker); X else if(!rn2(10)) ini_inv(Lamp); X break; X X default: /* impossible */ X break; X } X#ifndef HARD X ini_inv(Saving); /* give beginners an extra chance */ X#endif X#ifdef EXPLORE_MODE X if (discover) X ini_inv(Wishing); X#endif X find_ac(); /* get initial ac value */ X init_attr((pick != 'Y') ? 75 : 77); /* init attribute values */ X max_rank_sz(); /* set max str size for class ranks */ X/* X * Do we really need this? X */ X for(i = 0; i < A_MAX; i++) X if(!rn2(20)) { X register int xd = rn2(7) - 2; /* biased variation */ X adjattrib(i, xd, TRUE); X if (ABASE(i) < AMAX(i)) AMAX(i) = ABASE(i); X } X X /* make sure he can carry all he has - especially for T's */ X while(inv_weight() > 0) X adjattrib(A_STR, 1, TRUE); X X#ifdef THEOLOGY X u.ualignbase[0] = u.ualignbase[1] = u.ualigntyp; X#endif X} X Xstatic void Xini_inv(trop) Xregister struct trobj *trop; X{ X struct obj *obj; X while(trop->trolet) { X boolean undefined = (trop->trotyp == UNDEF_TYP); X X if (!undefined) X obj = mksobj((int)trop->trotyp,FALSE); X else obj = mkobj(trop->trolet,FALSE); X X /* For random objects, do not create certain overly powerful X * items: wand of wishing, ring of levitation, or the X * polymorph/polymorph control combination. Specific objects, X * i.e. the discovery wishing, are still OK. X * Also, don't get a couple of really useless items. (Note: X * punishment isn't "useless". Some players who start out with X * one will immediately read it and use the iron ball as a X * weapon.) X */ X if (undefined) { X#ifdef POLYSELF X static unsigned NEARDATA nocreate = STRANGE_OBJECT; X# ifdef SPELLS X static unsigned NEARDATA nocreate2 = STRANGE_OBJECT; X# endif X#endif X static unsigned NEARDATA nocreate3 = STRANGE_OBJECT; X X while(obj->otyp == WAN_WISHING X#ifdef POLYSELF X || obj->otyp == nocreate X# ifdef SPELLS X || obj->otyp == nocreate2 X# endif X#endif X || obj->otyp == nocreate3 X#ifdef ELBERETH X || obj->otyp == RIN_LEVITATION X#endif X /* 'useless' items */ X || obj->otyp == POT_HALLUCINATION X || obj->otyp == SCR_AMNESIA X || obj->otyp == SCR_FIRE X || obj->otyp == RIN_AGGRAVATE_MONSTER X || obj->otyp == RIN_HUNGER X || obj->otyp == WAN_NOTHING X ) { X free((genericptr_t) obj); X obj = mkobj(trop->trolet, FALSE); X } X X /* Don't start with +0 or negative rings */ X if(objects[obj->otyp].oc_charged && obj->spe <= 0) X obj->spe = rne(3); X X /* Heavily relies on the fact that 1) we create wands X * before rings, 2) that we create rings before X * spellbooks, and that 3) not more than 1 object of a X * particular symbol is to be prohibited. (For more X * objects, we need more nocreate variables...) X */ X#ifdef POLYSELF X switch (obj->otyp) { X case WAN_POLYMORPH: X case RIN_POLYMORPH: X nocreate = RIN_POLYMORPH_CONTROL; X break; X case RIN_POLYMORPH_CONTROL: X nocreate = RIN_POLYMORPH; X# ifdef SPELLS X nocreate2 = SPE_POLYMORPH; X# endif /* SPELLS */ X } X#endif /* POLYSELF */ X /* Don't have 2 of the same ring */ X if (obj->olet == RING_SYM) X nocreate3 = obj->otyp; X } X X obj->bknown = trop->trknown; X if(objects[obj->otyp].oc_uses_known) obj->known = trop->trknown; X /* not obj->dknown = 1; - let him look at it at least once */ X obj->cursed = 0; X if(obj->olet == TOOL_SYM){ /* problem with multiple tools */ X obj->quan = 1; /* might be > because of grenades */ X } X if(obj->olet == WEAPON_SYM) { X obj->quan = trop->trquan; X trop->trquan = 1; X } X if(obj->olet == FOOD_SYM && undefined) { X obj->known = 1; X /* needed for tins and eggs; harmless otherwise */ X obj->bknown = 1; X } X /* X * The below lines not needed because they don't correspond X * to any actual inventory; nobody gets random tools. X else if(obj->olet == TOOL_SYM && undefined) { X obj->bknown = (obj->otyp != BAG_OF_TRICKS X && obj->otyp != SACK X && obj->otyp != CHEST X && obj->otyp != LARGE_BOX X && obj->otyp != ICE_BOX); X } X */ X if(trop->trspe != UNDEF_SPE) X obj->spe = trop->trspe; X if(trop->trbless != UNDEF_BLESS) X obj->blessed = trop->trbless; X X if (!Is_container(obj)) X obj->owt = weight(obj); X /* defined after setting otyp+quan */ X obj = addinv(obj); X X /* Make the type known if necessary */ X if (objects[obj->otyp].oc_descr && obj->known) X makeknown(obj->otyp); X X if(obj->olet == ARMOR_SYM){ X if (is_shield(obj) && !uarms) X setworn(obj, W_ARMS); X else if (is_helmet(obj) && !uarmh) X setworn(obj, W_ARMH); X else if (is_gloves(obj) && !uarmg) X setworn(obj, W_ARMG); X#ifdef SHIRT X else if (obj->otyp == HAWAIIAN_SHIRT && !uarmu) X setworn(obj, W_ARMU); X#endif X else if (is_cloak(obj) && !uarmc) X setworn(obj, W_ARMC); X else if (is_boots(obj) && !uarmf) X setworn(obj, W_ARMF); X else if (!uarm) X setworn(obj, W_ARM); X } X /* below changed by GAN 01/09/87 to allow wielding of X * pick-axe or can-opener if there is no weapon X */ X if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE || X obj->otyp == TIN_OPENER) X if(!uwep) setuwep(obj); X#ifndef PYRAMID_BUG X if(--trop->trquan) continue; /* make a similar object */ X#else X if(trop->trquan) { /* check if zero first */ X --trop->trquan; X if(trop->trquan) X continue; /* make a similar object */ X } X#endif X trop++; X } X} X Xvoid Xplnamesuffix() { X register char *p; X if(p = rindex(plname, '-')) { X *p = 0; X pl_character[0] = p[1]; X pl_character[1] = 0; X if(!plname[0]) { X askname(); X plnamesuffix(); X } X } X} END_OF_FILE if test 18113 -ne `wc -c <'src/u_init.c'`; then echo shar: \"'src/u_init.c'\" unpacked with wrong size! fi # end of 'src/u_init.c' fi echo shar: End of archive 38 \(of 56\). cp /dev/null ark38isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 56 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