[comp.sources.games] v10i090: nethack3p9 - display oriented dungeons & dragons

billr@saab.CNA.TEK.COM (Bill Randle) (07/14/90)

Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 10, Issue 90
Archive-name: nethack3p9/Part45
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 45 (of 56)."
# Contents:  mac/macinit.c src/music.c src/o_init.c src/spell.c
#   vms/vmstparam.c
# Wrapped by billr@saab on Wed Jul 11 17:12:01 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'mac/macinit.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mac/macinit.c'\"
else
echo shar: Extracting \"'mac/macinit.c'\" \(11148 characters\)
sed "s/^X//" >'mac/macinit.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)macinit.c	3.0	88/08/05
X/* Copyright (c) Johnny Lee, 1989.		 */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/*	Initialization routine for the Macintosh */
X
X#include	"hack.h"
X
X#ifdef MACOS
X# ifdef THINK_C
X#include	<MemoryMgr.h>
X# else
X#include	<Memory.h>
X#define ApplLimit 0x130         /* application limit [pointer]*/
X# endif
X
X/* Global variables */
Xextern WindowPtr	HackWindow;	/* points to NetHack's window */
Xchar	*keys[8];
Xshort macflags;
XBoolean	lowMem;
Xlong	lowMemLimit;
Xtypedef struct defaultData {
X	long	defaultFlags;
X	long	lowMemLimit;
X	Str255	fontName;
X} defaultData;
X#define	fDFZoomWindow	0x02L
X#define	fDFUseDefaultFont	0x01L
Xshort altCurs;
X
X
Xint
Xinitterm(row, col)
Xshort	row, col;
X{
X	register short	i, j;
X	short		tempFont, tempSize, fontNum, size;
X	char	*l, *m;
X	EventRecord	theEvent;
X	FontInfo	fInfo;
X	Handle	temp;
X	MenuHandle	theMenu;
X	OSErr	error;
X	Rect		boundsRect;
X	Str255	appName, font;
X	defaultData	*dD;
X	term_info	*t;
X	
X	/* standard Mac initialization */
X#ifdef THINK_C
X	SetApplLimit((Ptr)ApplLimit - 8192);	/* an extra 8K for stack */
X#else
X	SetApplLimit(*(long *)ApplLimit - 8192);
X#endif	
X	MaxApplZone();
X	UnloadSeg(mprintf);
X	for (i = 2; i<9; i++) {
X		temp = GetResource('CODE', i);
X		HUnlock(temp);
X		MoveHHi(temp);
X		HLock(temp);
X	}
X	
X	MoreMasters();
X	MoreMasters();
X	MoreMasters();
X	MoreMasters();
X	lowMem = (FreeMem() < 700 *1024) ? TRUE : FALSE;
X	InitGraf(&MAINGRAFPORT);
X	
X	InitFonts();
X	InitWindows();
X	InitMenus();
X	InitCursor();
X	FlushEvents(everyEvent, 0);
X	if (error = GetVol((StringPtr)&appName, &tempSize))
X		SysBeep(1);
X	
X	/* Application-specific startup code */
X	theMenu = NewMenu(appleMenu, "\001\024");	/*  apple menu  */
X	{
X		char	tmp[256];
X		Sprintf(&tmp[1],"About NetHack %s\311;(-", VERSION);
X		tmp[0] = (char)strlen(&tmp[1]);
X		AppendMenu(theMenu,tmp);
X	}
X	AddResMenu(theMenu, 'DRVR');
X	InsertMenu(theMenu, 0);
X	DisableItem(theMenu,0);
X
X	t = (term_info *)malloc(sizeof(term_info));
X	t->recordVRefNum = tempSize;
X	
X	for (i = fileMenu; i <= extendMenu; i++) {
X		theMenu = GetMenu(i);
X		if (theMenu) {
X			InsertMenu(theMenu, 0);
X			DisableItem(theMenu, 0);
X		}
X		if (i == editMenu) {
X			t->shortMBarHandle = GetMenuBar();
X		}
X	}
X	t->fullMBarHandle = GetMenuBar();
X	
X	DrawMenuBar();
X	HiliteMenu(0);
X	for (i = 0;i <= 7;i++) {
X		temp = GetResource(HACK_DATA,(i + 100 + appleMenu));
X		if (!temp) {
X			SysBeep(1);
X			panic("Can't get MENU_DATA resource");
X		}
X		MoveHHi(temp);
X		HLock(temp);
X		DetachResource(temp);
X		keys[i] = *temp;
X	}
X
X	macflags = (fToggleNumPad | fDoNonKeyEvt);
X	
X	/* Set font to monaco, user-defined font or to Hackfont if available */
X	if ((SCREEN_BITS.bounds.bottom - SCREEN_BITS.bounds.top) >400
X		&& (SCREEN_BITS.bounds.right - SCREEN_BITS.bounds.left) > 580)
X		size = 12;
X	else
X		size = 9;
X	Strcpy((char *)&font[0], "\006Monaco");
X	
X	temp = GetResource(HACK_DATA, DEFAULT_DATA);
X	if (temp) {
X		HLock(temp);
X		dD = (defaultData *)(*temp);
X		lowMemLimit = dD->lowMemLimit;
X		strncpy((char *)&font[0], (char *)&dD->fontName[0],
X					(short)dD->fontName[0] + 1);
X		if (dD->defaultFlags & fDFZoomWindow)
X			macflags |= fZoomOnContextSwitch;
X		HUnlock(temp);
X		ReleaseResource(temp);
X	}
X			
X	tempFont = MAINGRAFPORT->txFont;
X	tempSize = MAINGRAFPORT->txSize;
X	GetFNum(font, &fontNum);
X	TextFont(fontNum);
X	TextSize(size);
X	GetFontInfo(&fInfo);
X	TextFont(tempFont);
X	TextSize(tempSize);
X	
X	if (!(dD->defaultFlags & fDFUseDefaultFont)) {
X		Strcpy((char *)&appName[0], "\010HackFont");
X		GetFNum(appName,&tempFont);
X		if (tempFont) {
X			fontNum = tempFont;
X			tempFont = MAINGRAFPORT->txFont;
X			TextFont(fontNum);
X			TextSize(size);
X			GetFontInfo(&fInfo);
X			TextFont(tempFont);
X			TextSize(tempSize);
X			macflags |= fUseCustomFont;
X		}
X	}
X	
X	i = fInfo.ascent + fInfo.descent + fInfo.leading;
X	j = fInfo.widMax;
X	if ((row * i + 2 * Screen_Border) >
X		 (SCREEN_BITS.bounds.bottom - SCREEN_BITS.bounds.top)
X		 ||
X		 (col * j + 2 * Screen_Border) >
X		 	(SCREEN_BITS.bounds.right - SCREEN_BITS.bounds.left)) {
X		size = 9;
X		Strcpy((char *)&font[0], "\006Monaco");
X		tempFont = MAINGRAFPORT->txFont;
X		tempSize = MAINGRAFPORT->txSize;
X		GetFNum(font, &fontNum);
X		TextFont(fontNum);
X		TextSize(size);
X		GetFontInfo(&fInfo);
X		TextFont(tempFont);
X		TextSize(tempSize);
X		i = fInfo.ascent + fInfo.descent + fInfo.leading;
X		j = fInfo.widMax;
X		macflags &= ~fUseCustomFont;
X	}		
X		 
X	t->ascent = fInfo.ascent;
X	t->descent = fInfo.descent;
X	t->height = i;
X	t->charWidth = j;
X	
X	t->fontNum = fontNum;
X	t->fontSize = size;
X	t->maxRow = row;
X	t->maxCol = col;
X	t->tcur_x = 0;
X	t->tcur_y = 0;
X	t->auxFileVRefNum = 0;
X	if (error = SysEnvirons(1, &(t->system))) {
X		SysBeep(1);
X	}
X
X	/* Some tweaking to allow for intl. ADB keyboard (unknown) */
X	if (t->system.machineType > envMacPlus && !t->system.keyBoardType) {
X		t->system.keyBoardType = envStandADBKbd;
X	}
X
X#define	KEY_MAP	103
X	temp = GetResource(HACK_DATA, KEY_MAP);
X	if (temp) {
X		MoveHHi(temp);
X		HLock(temp);
X		DetachResource(temp);
X		t->keyMap = (char *)(*temp);
X	} else
X		panic("Can't get keymap resource");
X
X	SetRect(&boundsRect, LEFT_OFFSET, TOP_OFFSET + 10,
X		(col * fInfo.widMax) + LEFT_OFFSET + 2 * Screen_Border,
X		TOP_OFFSET + (row * t->height) + 2 * Screen_Border + 10);
X	
X	t->screen = (char **)malloc(row * sizeof(char *));
X	t->scrAttr = (char **)malloc(row * sizeof(char *));
X	l = malloc(row * col * sizeof(char));
X	m = malloc(row * col * sizeof(char));
X	for (i = 0;i < row;i++) {
X		t->screen[i] = (char *)(l + (i * col * sizeof(char)));
X		t->scrAttr[i] = (char *)(m + (i * col * sizeof(char)));
X	}
X	for (i = 0; i < row; i++) {
X		for (j = 0; j < col; j++) {
X			t->screen[i][j] = ' ';
X			t->scrAttr[i][j] = '\0';
X		}
X	}
X	t->curHilite = 0;
X	t->curAttr = 0;
X
X	/* give time for Multifinder to bring NetHack window to front */
X	for(tempFont = 0; tempFont<10; tempFont++) {
X		SystemTask();
X		(void)GetNextEvent(nullEvent,&theEvent);
X	}
X
X	HackWindow = NewWindow(0L, &boundsRect, "\016NetHack [MOVE]",
X			TRUE, noGrowDocProc, (WindowPtr)-1, FALSE, (long)t);
X
X	t->inColor = 0;
X#ifdef TEXTCOLOR
X	t->color[0] = blackColor;
X	t->color[1] = redColor;
X	t->color[2] = greenColor;
X	t->color[3] = yellowColor;
X	t->color[4] = blueColor;
X	t->color[5] = magentaColor;
X	t->color[6] = cyanColor;
X	t->color[7] = whiteColor;
X
X	if (t->system.hasColorQD) {
X		Rect	r;
X		GDHandle	gd;
X		
X		r = (**(*(WindowPeek)HackWindow).contRgn).rgnBBox;
X		LocalToGlobal(&r.top);
X		LocalToGlobal(&r.bottom);
X		gd = GetMaxDevice(&r);
X		t->inColor = (**(**gd).gdPMap).pixelSize > 1;
X	}
X#endif
X		
X	temp = GetResource(HACK_DATA, MONST_DATA);
X	if (temp) {
X		DetachResource(temp);
X		MoveHHi(temp);
X		HLock(temp);
X		i = GetHandleSize(temp);
X		mons = (struct permonst *)(*temp);
X	} else {
X		panic("Can't get MONST resource data.");
X	}
X	
X	temp = GetResource(HACK_DATA, OBJECT_DATA);
X	if (temp) {
X		DetachResource(temp);
X		MoveHHi(temp);
X		HLock(temp);
X		i = GetHandleSize(temp);
X		objects = (struct objclass *)(*temp);
X		for (j = 0; j< NROFOBJECTS+1; j++) {
X			objects[j].oc_name = sm_obj[j].oc_name;
X			objects[j].oc_descr = sm_obj[j].oc_descr;
X		}
X	} else {
X		panic("Can't get OBJECT resource data.");
X	}
X	
X	for (j = 30; j >= 0; j -= 10) {
X		for (i = 0; i<=8; i++) {
X			t->cursor[i] = GetCursor(100+i+j);	/* self-contained cursors */
X		}
X	}
X	
X	(void)aboutBox(0);	
X	return 0;
X}
X
X/* not really even needed. NH never gets to the end of main(), */
X/* so this never gets called */
Xint
Xfreeterm()
X{
X	return 0;
X}
X
X#ifdef SMALLDATA
X/* SOME [:-( ] Mac compilers have a 32K global & static data limit */
X/* these routines help the HANDICAPPED things */
Xvoid
Xinit_decl()
X{
X	short	i;
X	char	*l;
X	extern char **Map;
X	
X	l = calloc(COLNO , sizeof(struct rm **));
X	level.locations = (struct rm **)l;
X	l = calloc(ROWNO * COLNO , sizeof(struct rm));
X	for (i = 0; i < COLNO; i++) {
X	    level.locations[i] = 
X		(struct rm *)(l + (i * ROWNO * sizeof(struct rm)));
X	}
X	
X	l = calloc(COLNO , sizeof(struct obj ***));
X	level.objects = (struct obj ***)l;
X	l = calloc(ROWNO * COLNO , sizeof(struct obj *));
X	for (i = 0; i < COLNO; i++) {
X	    level.objects[i] = 
X		(struct obj **)(l + (i * ROWNO * sizeof(struct obj *)));
X	}
X	
X	l = calloc(COLNO , sizeof(struct monst ***));
X	level.monsters = (struct monst ***)l;
X	l = calloc(ROWNO * COLNO , sizeof(struct monst *));
X	for (i = 0; i < COLNO; i++) {
X	    level.monsters[i] = 
X		(struct monst **)(l + (i * ROWNO * sizeof(struct monst *)));
X	}
X	level.objlist = (struct obj *)0L;
X	level.monlist = (struct monst *)0L;
X	
Xl = calloc(COLNO, sizeof(char *));
XMap = (char **)l;
Xl = calloc(ROWNO * COLNO, sizeof(char));
Xfor (i = 0; i < COLNO; i++) {
X    Map[i] = 
X	(char *)(l + (i * ROWNO * sizeof(char)));
X}
X
X}
X
X/* Since NetHack usually exits before reaching end of main()	*/
X/* this routine could probably left out.	- J.L.		*/
Xvoid
Xfree_decl()
X{
X
X	free((char *)level.locations[0]);
X	free((char *)level.locations);
X	free((char *)level.objects[0]);
X	free((char *)level.objects);
X	free((char *)level.monsters[0]);
X	free((char *)level.monsters);
X}
X#endif /* SMALLDATA */
X
X#define	OPTIONS			"Nethack prefs"
X
X# ifdef AZTEC
X#undef OMASK
X#define OMASK	O_RDONLY
X# else
X#undef OMASK
X#define OMASK	(O_RDONLY | O_BINARY )
X# endif
X
Xint
Xread_config_file()
X{
X	term_info	*t;
X	int optfd;
X	Str255	name;
X	short	oldVol;
X	
X	optfd = 0;
X	t = (term_info *)GetWRefCon(HackWindow);
X
X	GetVol(name, &oldVol);
X	SetVol(0L, t->system.sysVRefNum);
X	if ( (optfd = open(OPTIONS, OMASK)) <= 0) {
X		SetVol(0L, t->recordVRefNum);
X		optfd = open(OPTIONS, OMASK);
X	}
X	if ( optfd > (short)NULL){
X		read_opts(optfd);
X		(void) close(optfd);
X	}
X	SetVol(0L, oldVol);
X}
X
Xint
Xwrite_opts()
X{
X	int fd;
X	short temp_flags;
X	term_info	*t;
X
X	t = (term_info *)GetWRefCon(HackWindow);
X	SetVol(0L, t->system.sysVRefNum);
X
X	if((fd = open(OPTIONS, O_WRONLY | O_BINARY)) <= 0) {
X		OSErr	result;
X		char	*tmp;
X		
X		SetVol(0L, t->recordVRefNum);
X		if((fd = open(OPTIONS, O_WRONLY | O_BINARY)) <= 0) {
X			SetVol(0L, t->system.sysVRefNum);
X			tmp = CtoPstr(OPTIONS);
X			result = Create((StringPtr)tmp, (short)0, CREATOR, AUXIL_TYPE);
X		 	if (result == noErr)
X		 		fd = open(OPTIONS, O_WRONLY | O_BINARY);
X		}
X	 }
X
X	if (fd < 0)
X		pline("can't create options file!");
X	else {
X		write(fd, &flags, sizeof(flags));
X	
X		write(fd, plname, PL_NSIZ);
X	
X		write(fd, dogname, 63);
X	
X		write(fd, catname, 63);
X		
X		temp_flags = (macflags & fZoomOnContextSwitch) ? 1 : 0;
X		write(fd, &temp_flags, sizeof(short));
X
X		write(fd, &altCurs, sizeof(short));
X	
X#ifdef TUTTI_FRUTTI
X		write(fd, pl_fruit, PL_FSIZ);
X#endif
X		write(fd, inv_order, strlen(inv_order)+1);
X		close(fd);
X	}
X	
X	SetVol(0L, t->recordVRefNum);
X	
X	return 0;
X}
X
Xint
Xread_opts(fd)
Xint fd;
X{	char tmp_order[20];
X	short	temp_flags;
X	
X	read(fd, (char *)&flags, sizeof(flags));
X
X	read(fd, plname, PL_NSIZ);
X
X	read(fd, dogname, 63);
X	
X	read(fd, catname, 63);
X	
X	read(fd, &temp_flags, sizeof(short));
X	if (temp_flags & 0x01)
X		macflags |= fZoomOnContextSwitch;
X	else
X		macflags &= ~fZoomOnContextSwitch;
X
X	read(fd, &altCurs, sizeof(short));
X	
X#ifdef TUTTI_FRUTTI
X	read(fd, pl_fruit, PL_FSIZ);
X#endif
X	read(fd,tmp_order,strlen(inv_order)+1);
X	if(strlen(tmp_order) == strlen(inv_order))
X		Strcpy(inv_order,tmp_order);
X		
X	return 0;
X}
X
X#endif /* MACOS */
END_OF_FILE
if test 11148 -ne `wc -c <'mac/macinit.c'`; then
    echo shar: \"'mac/macinit.c'\" unpacked with wrong size!
fi
# end of 'mac/macinit.c'
fi
if test -f 'src/music.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/music.c'\"
else
echo shar: Extracting \"'src/music.c'\" \(11331 characters\)
sed "s/^X//" >'src/music.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)music.c	3.0	88/10/22
X/* 	Copyright (c) 1989 by Jean-Christophe Collet */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/*
X * This file contains the different functions designed to manipulate the
X * musical instruments and their various effects.
X *
X * Actually the list of instruments / effects is :
X *
X * Flute		may calm snakes if player has enough dexterity
X * Magic flute		may put monsters to sleep:  area of effect depends
X *			on player level.
X * Horn			Will awaken monsters:  area of effect depends on player
X *			level.  May also scare monsters.
X * Fire horn		Acts like a wand of fire.
X * Frost horn		Acts like a wand of cold.
X * Bugle		Will awaken soldiers (if any):  area of effect depends
X *			on player level.
X * Harp			May calm nymph if player has enough dexterity.
X * Magic harp		Charm monsters:  area of effect depends on player
X *			level.
X * Drum			Will awaken monsters like the horn.
X * Drum of earthquake	Will initiate an earthquake whose intensity depends
X *			on player level.  That is, it creates ramdom pits
X *			called here chasms.
X */
X
X
X#include "hack.h"
X
X#ifdef MUSIC
X#include <ctype.h>
X
Xstatic void FDECL(awaken_monsters,(int));
Xstatic void FDECL(put_monsters_to_sleep,(int));
Xstatic void FDECL(charm_snakes,(int));
Xstatic void FDECL(calm_nymphs,(int));
Xstatic void NDECL(awaken_soldiers);
Xstatic void FDECL(charm_monsters,(int));
Xstatic void FDECL(do_earthquake,(int));
Xstatic int FDECL(do_improvisation,(struct obj *));
X
X/*
X * Wake every monster in range...
X */
X
Xstatic void
Xawaken_monsters(distance)
Xint distance;
X{
X	register struct monst *mtmp = fmon;
X
X	while(mtmp) {
X		if (dist(mtmp->mx, mtmp->my) < distance/3) {
X			/* May scare some monsters */
X			if (!resist(mtmp, SCROLL_SYM, 0, NOTELL))
X			  mtmp->mflee = 1;
X		} else if (dist(mtmp->mx, mtmp->my) < distance) {
X			mtmp->msleep = 0;
X			mtmp->mcanmove = 1;
X			mtmp->mfrozen = 0;
X		}
X		mtmp = mtmp->nmon;
X	}
X}
X
X/*
X * Make monsters fall asleep.  Note that they may resist the spell.
X */
X
Xstatic void
Xput_monsters_to_sleep(distance)
Xint distance;
X{
X	register struct monst *mtmp = fmon;
X
X	while(mtmp) {
X		  if (dist(mtmp->mx, mtmp->my) < distance)
X		    if(mtmp->mcanmove && !resist(mtmp, WAND_SYM, 0, NOTELL))
X		      mtmp->mcanmove = mtmp->mfrozen = 0;
X		mtmp = mtmp->nmon;
X	}
X}
X
X/*
X * Charm snakes in range.  Note that the snakes are NOT tamed.
X */
X
Xstatic void
Xcharm_snakes(distance)
Xint distance;
X{
X	register struct monst *mtmp = fmon;
X
X	while (mtmp) {
X		if (mtmp->data->mlet == S_SNAKE && dist(mtmp->mx, mtmp->my) < distance) {
X			mtmp->mpeaceful = 1;
X			if (cansee(mtmp->mx, mtmp->my))
X			  pline("%s freezes and sways with the music, then seems quieter.",defmonnam(mtmp));
X		}
X		mtmp = mtmp->nmon;
X	}
X}
X
X/*
X * Calm nymphs in range.
X */
X
Xstatic void
Xcalm_nymphs(distance)
Xint distance;
X{
X	register struct monst *mtmp = fmon;
X
X	while (mtmp) {
X		if (mtmp->data->mlet == S_NYMPH && dist(mtmp->mx, mtmp->my) < distance) {
X			mtmp->mpeaceful = 1;
X			if (cansee(mtmp->mx, mtmp->my))
X			  pline("%s listens cheerfully to the music, then seems quieter.",defmonnam(mtmp));
X		}
X		mtmp = mtmp->nmon;
X	}
X}
X
X/* Awake only soldiers of the level. */
X
Xstatic void
Xawaken_soldiers() {
X#ifdef ARMY
X#define IS_SOLDIER(dat)	((int)((dat) - mons) >= PM_UNARMORED_SOLDIER && \
X			 (int) ((dat) - mons) <= PM_CAPTAIN)
X	register struct monst *mtmp = fmon;
X
X	while(mtmp) {
X		if (IS_SOLDIER(mtmp->data)) {
X			mtmp->mpeaceful = mtmp->msleep = 0;
X			mtmp->mcanmove = 1;
X		}
X		mtmp = mtmp->nmon;
X	}
X#endif /* ARMY /**/
X}
X
X/* Charm monsters in range.  Note that they may resist the spell. */
X
Xstatic void
Xcharm_monsters(distance)
Xint distance;
X{
X	register struct monst *mtmp = fmon, *mtmp2;
X
X	while(mtmp) {
X		mtmp2 = mtmp->nmon;
X		if(dist(mtmp->mx, mtmp->my) <= distance)
X		    if(!resist(mtmp, SCROLL_SYM, 0, NOTELL))
X			(void) tamedog(mtmp, (struct obj *) 0);
X		mtmp = mtmp2;
X	}
X
X}
X
X/* Generate earthquake :-) of desired force.
X * That is:  create random chasms (pits).
X */
X
Xstatic void
Xdo_earthquake(force)
Xint force;
X{
X	register int x,y;
X	struct monst *mtmp;
X	struct trap *chasm;
X	int start_x, start_y, end_x, end_y;
X
X	start_x = u.ux - (force * 2);
X	start_y = u.uy - (force * 2);
X	end_x = u.ux + (force * 2);
X	end_y = u.uy + (force * 2);
X	if (start_x < 1) start_x = 1;
X	if (start_y < 1) start_y = 1;
X	if (end_x >= COLNO) end_x = COLNO - 1;
X	if (end_y >= ROWNO) end_y = ROWNO - 1;
X	for (x=start_x; x<=end_x; x++)
X	  for (y=start_y; y<=end_y; y++)
X	    if (!rn2(14 - force)) {
X		    switch (levl[x][y].typ) {
X#ifdef FOUNTAINS
X			  case FOUNTAIN : /* Make the fountain disappear */
X			    if (cansee(x,y))
X			      pline("The fountain falls into a chasm.");
X			    goto do_pit;
X#endif
X#ifdef SINKS
X			  case SINK :
X			    if (cansee(x,y))
X			      pline("The kitchen sink falls into a chasm.");
X			    goto do_pit;
X#endif
X#ifdef ALTARS
X			  case ALTAR :
X			    if (cansee(x,y))
X			      pline("The altar falls into a chasm.");
X			    goto do_pit;
X#endif
X#ifdef THRONES
X			  case THRONE :
X			    if (cansee(x,y))
X			      pline("The throne falls into a chasm.");
X				/* Falls into next case */
X#endif
X			  case ROOM :
X			  case CORR : /* Make a pit */
Xdo_pit:			    chasm = maketrap(x,y,PIT);
X			    chasm->tseen = 1;
X
X			    levl[x][y].doormask = 0;
X
X			    /* We have to check whether monsters or player
X			       fall in a chasm... */
X
X			    if (MON_AT(x, y)) {
X				mtmp = m_at(x,y);
X				if(!is_flyer(mtmp->data)) {
X				    mtmp->mtrapped = 1;
X				    if(cansee(x,y))
X					pline("%s falls into a chasm!",
X						Monnam(mtmp));
X				    else if (flags.soundok && humanoid(mtmp->data))
X					You("hear a scream!");
X				    if ((mtmp->mhp -= rnd(6)) <= 0) {
X					if(!cansee(x,y))
X					    pline("It is destroyed!");
X					else {
X					    You("destroy %s!",
X					    mtmp->mtame ?
X						a2_monnam(mtmp, "poor") :
X						mon_nam(mtmp));
X					}
X					xkilled(mtmp,0);
X				    }
X				}
X			    } else if (x == u.ux && y == u.uy) {
X				    if (Levitation
X#ifdef POLYSELF
X					|| is_flyer(uasmon)
X#endif
X					) {
X					    pline("A chasm opens up under you!");
X					    You("don't fall in!");
X				    } else {
X					    You("fall into a chasm!");
X					    u.utrap = rn1(6,2);
X					    u.utraptype = TT_PIT;
X					    losehp(rnd(6),"fell into a chasm",
X						NO_KILLER_PREFIX);
X					    selftouch("Falling, you");
X				    }
X			    } else
X				newsym(x,y);
X			    break;
X			  case DOOR : /* Make the door collapse */
X			    if (levl[x][y].doormask == D_NODOOR) break;
X			    if (cansee(x,y))
X				pline("The door collapses.");
X			    levl[x][y].doormask = D_NODOOR;
X			    mnewsym(x,y);
X			    if (!MON_AT(x, y) && !(x == u.ux && y == u.uy))
X				newsym(x,y);
X			    if (cansee(x,y)) prl(x,y);
X			    break;
X		    }
X	    }
X}
X
X/*
X * The player is trying to extract something from his/her instrument.
X */
X
Xstatic int
Xdo_improvisation(instr)
Xstruct obj *instr;
X{
X	int damage;
X
X	if (Confusion)
X	  pline("What you produce is quite far from music...");
X	else
X	  You("start playing the %s.", xname(instr));
X	switch (instr->otyp) {
X	      case FLUTE:	/* May charm snakes */
X		if (rn2(ACURR(A_DEX)) + u.ulevel > 25)
X		  charm_snakes((int)u.ulevel*3);
X		break;
X	      case MAGIC_FLUTE: /* Make monster fall asleep */
X		if (instr->spe > 0) {
X			instr->spe--;
X			You("produce soft music.");
X			put_monsters_to_sleep((int)u.ulevel*5);
X		}
X		break;
X	      case HORN:	/* Awaken monsters or scare monsters */
X		You("produce a frightful, grave sound.");
X		awaken_monsters((int)u.ulevel*30);
X		break;
X	      case FROST_HORN:	/* Idem wand of cold */
X	      case FIRE_HORN:	/* Idem wand of fire */
X		if (instr->spe > 0) {
X			instr->spe--;
X			if (!getdir(1)) {
X				if (!Blind)
X				    pline("The %s glows then fades.", xname(instr));
X			} else {
X				if (!u.dx && !u.dy && !u.dz) {
X					if((damage = zapyourself(instr)))
X					  losehp(damage,
X		self_pronoun("using a magical horn on %sself", "him"),
X					  NO_KILLER_PREFIX);
X					makeknown(instr->otyp);
X					return(2);
X				}
X				buzz((instr->otyp == FROST_HORN) ? 3 : 1, rn1(6,6), u.ux, u.uy, u.dx, u.dy);
X				makeknown(instr->otyp);
X				return(2);
X			}
X		}
X		break;
X	      case BUGLE:	/* Awaken & attract soldiers */
X		You("extract a loud noise from the %s.",xname(instr));
X		awaken_soldiers();
X		break;
X	      case HARP:	/* May calm Nymph */
X		if (rn2(ACURR(A_DEX)) + u.ulevel > 25)
X		  calm_nymphs((int)u.ulevel*3);
X		break;
X	      case MAGIC_HARP:	/* Charm monsters */
X		if (instr->spe > 0) {
X			pline("The %s produces very attractive music.", xname(instr));
X			instr->spe--;
X			charm_monsters(((int)u.ulevel - 1) / 3 + 1);
X		}
X		break;
X	      case DRUM:	/* Awaken monsters */
X		You("beat a deafening row!");
X		awaken_monsters((int)u.ulevel * 40);
X		break;
X	      case DRUM_OF_EARTHQUAKE:	/* create several pits */
X		if (instr->spe > 0) {
X			You("produce a heavy, thunderous rolling!");
X			pline("The entire dungeon is shaking around you!");
X			instr->spe--;
X			do_earthquake(((int)u.ulevel - 1) / 3 + 1);
X			makeknown(DRUM_OF_EARTHQUAKE);
X		}
X		break;
X	      default:
X		impossible("What a weird instrument (%d)!",instr->otyp);
X		break;
X	}
X	return (2);		/* That takes time */
X}
X
X/*
X * So you want music...
X */
X
Xint
Xdo_play_instrument(instr)
Xstruct obj *instr;
X{
X#ifdef STRONGHOLD
X    char buf[BUFSZ], *s, c = 'y';
X    int x,y;
X    boolean ok;
X
X    if (instr->otyp != DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) {
X	pline("Improvise? ");
X	c = yn();
X    }
X    if (c == 'n') {
X	pline("What tune are you playing? [what 5 notes] ");
X	getlin(buf);
X	for(s=buf;*s;s++)
X		if (islower(*s)) *s=toupper(*s);
X	You("extract a strange sound from the %s!",xname(instr));
X	/* Check if there was the Stronghold drawbridge near
X	 * and if the tune conforms to what we're waiting for.
X	 */
X	if (dlevel == stronghold_level)
X	    if (!strcmp(buf,tune)) {
X		/* Search for the drawbridge */
X		for(y=u.uy-1; y<=u.uy+1; y++)
X		    for(x=u.ux-1;x<=u.ux+1;x++)
X			if(isok(x,y))
X			if (find_drawbridge(&x,&y)) {
X			    if (levl[x][y].typ == DRAWBRIDGE_DOWN)
X				close_drawbridge(x,y);
X			    else
X				open_drawbridge(x,y);
X			    return 0;
X			}
X	    } else if (flags.soundok) {
X		/* Okay, it wasn't the right tune, but perhaps
X		 * we can give the player some hints like in the
X		 * Mastermind game */
X		ok = FALSE;
X		for(y = u.uy-1; y <= u.uy+1 && !ok; y++)
X		    for(x = u.ux-1; x <= u.ux+1 && !ok; x++)
X			if(isok(x,y))
X			if(IS_DRAWBRIDGE(levl[x][y].typ) ||
X			   is_drawbridge_wall(x,y) >= 0)
X				ok = TRUE;
X		if (ok) { /* There is a drawbridge near */
X		    int tumblers, gears;
X		    boolean matched[5];
X
X		    tumblers = gears = 0;
X		    for(x=0; x < 5; x++)
X			matched[x] = FALSE;
X
X		    for(x=0; x < strlen(buf); x++)
X			if(x < 5) {
X			    if(buf[x] == tune[x]) {
X				gears++;
X				matched[x] = TRUE;
X			    } else
X				for(y=0; y < 5; y++)
X				    if(!matched[y] &&
X				       buf[x] == tune[y] &&
X				       buf[y] != tune[y]) {
X					tumblers++;
X					matched[y] = TRUE;
X					break;
X				    }
X			}
X		    if(tumblers)
X			if(gears)
X			    You("hear %d tumbler%s click and %d gear%s turn.",
X				tumblers, plur((long)tumblers),
X				gears, plur((long)gears));
X			else
X			    You("hear %d tumbler%s click.",
X				tumblers, plur((long)tumblers));
X		    else if(gears)
X			You("hear %d gear%s turn.",
X			    gears, plur((long)gears));
X		}
X	    }
X	return 1;
X    } else
X#endif /* STRONGHOLD /**/
X	    return do_improvisation(instr);
X}
X
X#endif /* MUSIC /**/
END_OF_FILE
if test 11331 -ne `wc -c <'src/music.c'`; then
    echo shar: \"'src/music.c'\" unpacked with wrong size!
fi
# end of 'src/music.c'
fi
if test -f 'src/o_init.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/o_init.c'\"
else
echo shar: Extracting \"'src/o_init.c'\" \(9660 characters\)
sed "s/^X//" >'src/o_init.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)o_init.c	3.0	88/07/06
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include	"hack.h"		/* for typedefs */
X
X#if defined(LATTICE) 				/* This is NOT */
X# define MACOS					/* a typo! */
X#endif
X
Xstatic void NDECL(setgemprobs);
Xstatic void FDECL(shuffle,(int,int,BOOLEAN_P));
Xstatic boolean FDECL(interesting_to_discover,(int));
X
X/* note that NROFOBJECTS is the number of legal objects, which does not count
X * the strange object and null object that take up positions 0 and NROFOBJECTS+1
X * in the objects array
X */
X#define TOTAL_OBJS	(NROFOBJECTS+2)
X#ifdef MACOS
Xshort *switches;    /* used to allow position independent loads of app */
X		    /* by storing the number of the description string */
X		    /* [at startup of the game] not the pointer to the string */
X#endif
X
Xconst char obj_symbols[] = {
X	ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM,
X	BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM,
X	POTION_SYM, SCROLL_SYM, WAND_SYM,
X#ifdef SPELLS
X	SPBOOK_SYM,
X#endif
X	RING_SYM, GEM_SYM, 0 };
X
Xint NEARDATA bases[sizeof(obj_symbols)] = DUMMY;
Xstatic int NEARDATA disco[TOTAL_OBJS] = DUMMY;
X
Xint
Xletindex(let) register char let; {
Xregister int i = 0;
Xregister char ch;
X	while((ch = obj_symbols[i++]) != 0)
X		if(ch == let) return(i);
X	return(0);
X}
X
Xstatic void
Xsetgemprobs()
X{
X	register int j,first;
X#ifdef STRONGHOLD
X	int lev = (dlevel > MAXLEVEL) ? MAXLEVEL : dlevel;
X#endif
X
X	first = bases[letindex(GEM_SYM)];
X
X#ifdef STRONGHOLD
X	for(j = 0; j < 9-lev/3; j++)
X#else
X	for(j = 0; j < 9-dlevel/3; j++)
X#endif
X		objects[first+j].oc_prob = 0;
X	first += j;
X	if(first >= LAST_GEM || first > NROFOBJECTS ||
X	    objects[first].oc_olet != GEM_SYM ||
X	    objects[first].oc_name == NULL)
X		Printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n",
X			first, j, LAST_GEM);
X	for(j = first; j < LAST_GEM; j++)
X		objects[j].oc_prob = (184+j-first)/(LAST_GEM-first);
X}
X
X/* shuffle descriptions on objects o_low to o_high */
Xstatic void
Xshuffle(o_low, o_high, domaterial)
X
X	register int o_low, o_high;
X	register boolean domaterial;
X{
X	register int i, j;
X	const char *desc;
X#ifdef TEXTCOLOR
X	int color;
X#endif /* TEXTCOLOR */
X	int tmp;
X#ifdef MACOS
X	short	sw;
X#endif
X
X	for(j=o_low; j <= o_high; j++) {
X		i = o_low + rn2(j+1-o_low);
X		desc = objects[j].oc_descr;
X		objects[j].oc_descr = objects[i].oc_descr;
X		objects[i].oc_descr = desc;
X#ifdef TEXTCOLOR
X		color = objects[j].oc_color;
X		objects[j].oc_color = objects[i].oc_color;
X		objects[i].oc_color = color;
X#endif /* TEXTCOLOR */
X		/* shuffle discovery list */
X		tmp = disco[j];
X		disco[j] = disco[i];
X		disco[i] = tmp;
X		/* shuffle material */
X		if(domaterial) {
X			tmp = objects[j].oc_material;
X			objects[j].oc_material = objects[i].oc_material;
X			objects[i].oc_material = tmp;
X		}
X#ifdef MACOS
X		/* keep track of shuffling of object descriptions */
X		sw=switches[j];
X		switches[j]=switches[i];
X		switches[i]=sw;
X#endif
X	}
X}
X
Xvoid
Xinit_objects(){
Xregister int i, j, first, last, sum, end;
Xregister char let;
X
X	/* bug fix to prevent "initialization error" abort on Intel Xenix.
X	 * reported by mikew@semike
X	 */
X	for(i = 0; i != sizeof(obj_symbols); i++)
X		bases[i] = 0;
X	for(i = 0; i != TOTAL_OBJS; i++)
X		disco[i] = i;
X#ifdef NAMED_ITEMS
X	init_exists();	/* zero out the "artifact exists" list */
X#endif
X	/* init base; if probs given check that they add up to 1000,
X	   otherwise compute probs; shuffle descriptions */
X	end = TOTAL_OBJS;
X	first = 0;
X	while( first < end ) {
X		let = objects[first].oc_olet;
X		last = first+1;
X		while(last < end && objects[last].oc_olet == let
X				 && objects[last].oc_name != NULL) last++;
X		i = letindex(let);
X		if((!i && let != ILLOBJ_SYM && let != '.') || bases[i] != 0)
X			error("initialization error for %c", let);
X		bases[i] = first;
X
X		if(let == GEM_SYM) setgemprobs();
X	check:
X		sum = 0;
X		for(j = first; j < last; j++) sum += objects[j].oc_prob;
X		if(sum == 0) {
X			for(j = first; j < last; j++)
X			    objects[j].oc_prob = (1000+j-first)/(last-first);
X			goto check;
X		}
X		if(sum != 1000)
X			error("init-prob error for %c (%d%%)", let, sum);
X
X		if(objects[first].oc_descr != NULL &&
X		   let != TOOL_SYM && let != WEAPON_SYM && let != ARMOR_SYM) {
X
X			/* shuffle, also some additional descriptions */
X			while(last < end && objects[last].oc_olet == let)
X				last++;
X			j = last;
X			if (let == GEM_SYM) {
X			    while(--j > first)
X				if(!strcmp(objects[j].oc_name,"turquoise")) {
X				    if(rn2(2)) { /* change from green? */
X					objects[j].oc_descr = blue;
X#ifdef TEXTCOLOR
X					objects[j].oc_color = BLUE;
X#endif
X				    }
X				} else if (!strcmp(objects[j].oc_name,"aquamarine")) {
X				    if(rn2(2)) { /* change from green? */
X					objects[j].oc_descr = blue;
X#ifdef TEXTCOLOR
X					objects[j].oc_color = BLUE;
X#endif
X				    }
X				} else if (!strcmp(objects[j].oc_name,"fluorite")) {
X				    switch (rn2(4)) { /* change from violet? */
X					case 0:  break;
X					case 1:
X					    objects[j].oc_descr = blue;
X#ifdef TEXTCOLOR
X					    objects[j].oc_color = BLUE;
X#endif
X					    break;
X					case 2:
X					    objects[j].oc_descr = white;
X#ifdef TEXTCOLOR
X					    objects[j].oc_color = WHITE;
X#endif
X					    break;
X					case 3:
X					    objects[j].oc_descr = green;
X#ifdef TEXTCOLOR
X					    objects[j].oc_color = GREEN;
X#endif
X					    break;
X					}
X				}
X			} else {
X			    if (let == AMULET_SYM || let == POTION_SYM)
X				j--;  /* THE amulet doesn't have description */
X			    /* and water is always "clear" - 3. */
X			    shuffle(first, --j, TRUE);
X			}
X		}
X		first = last;
X	}
X
X	/* shuffle the helmets */
X	shuffle(HELMET, HELM_OF_TELEPATHY, FALSE);
X
X	/* shuffle the gloves */
X	shuffle(LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY, FALSE);
X
X	/* shuffle the cloaks */
X	shuffle(CLOAK_OF_PROTECTION, CLOAK_OF_DISPLACEMENT, FALSE);
X
X	/* shuffle the boots */
X	shuffle(SPEED_BOOTS, LEVITATION_BOOTS, FALSE);
X}
X
Xvoid
Xoinit()			/* level dependent initialization */
X{
X	setgemprobs();
X}
X
Xvoid
Xsavenames(fd)
Xregister int fd;
X{
X	register int i;
X	unsigned int len;
X#ifdef MACOS
X	char	*descr[TOTAL_OBJS];
X#endif
X	struct objclass *now = &objects[0];
X	bwrite(fd, (genericptr_t)&now, sizeof now);
X	bwrite(fd, (genericptr_t)bases, sizeof bases);
X	bwrite(fd, (genericptr_t)disco, sizeof disco);
X#ifdef MACOS
X	for (i = 0 ; i < TOTAL_OBJS; i++) {
X		descr[i] = objects[i].oc_descr;
X		objects[i].oc_descr = (const char *)switches[i];
X	}
X#endif
X	bwrite(fd, (genericptr_t)objects, sizeof(struct objclass) * TOTAL_OBJS);
X	/* as long as we use only one version of Hack we
X	   need not save oc_name and oc_descr, but we must save
X	   oc_uname for all objects */
X	for(i=0; i < TOTAL_OBJS; i++) {
X#ifdef MACOS
X		objects[i].oc_descr = descr[i];
X#endif
X		if(objects[i].oc_uname) {
X			len = strlen(objects[i].oc_uname)+1;
X			bwrite(fd, (genericptr_t)&len, sizeof len);
X			bwrite(fd, (genericptr_t)objects[i].oc_uname, len);
X		}
X	}
X}
X
Xvoid
Xrestnames(fd)
Xregister int fd;
X{
X	register int i;
X	unsigned int len;
X	struct objclass *then;
X	long differ;
X#ifdef MACOS
X	/* provides position-independent save & restore */
X	/* by giving each object a number, keep track of it */
X	/* when shuffled and save the numbers instead of the */
X	/* description strings (which can change between */
X	/* executions of the program) */
X	/* On restore, the retrieved numbers are matched with the */
X	/* numbers and object descriptions in the program */
X	struct descr {
X		char	*name,
X				*descr;
X	} d[TOTAL_OBJS];
X
X	/* save the current object descriptions */
X	for (i = 0; i < TOTAL_OBJS; i++) {
X		d[i].name = objects[i].oc_name;
X		d[i].descr = objects[i].oc_descr;
X	}
X#endif
X	mread(fd, (genericptr_t) &then, sizeof then);
X	mread(fd, (genericptr_t) bases, sizeof bases);
X	mread(fd, (genericptr_t) disco, sizeof disco);
X	mread(fd, (genericptr_t) objects, sizeof(struct objclass) * TOTAL_OBJS);
X#ifdef MACOS
X	for (i = 0; i < TOTAL_OBJS; i++) {
X		objects[i].oc_name = d[i].name;
X		switches[i] = (short)objects[i].oc_descr;
X		objects[i].oc_descr = d[switches[i]].descr;
X	}
X#else
X# if !defined(MSDOS) && !defined(M_XENIX) && !defined(HPUX) && !defined(VAXC)
X	differ = (genericptr_t)&objects[0] - (genericptr_t)then;
X# else
X	differ = (long)&objects[0] - (long)then;
X# endif
X#endif	/* MACOS */
X	for(i=0; i < TOTAL_OBJS; i++) {
X#ifndef MACOS
X		if (objects[i].oc_name) {
X# if !defined(MSDOS) && !defined(M_XENIX) && !defined(HPUX) && !defined(VAXC)
X			objects[i].oc_name += differ;
X# else
X			objects[i].oc_name =
X			    (const char *)((long)(objects[i].oc_name) + differ);
X# endif
X		}
X		if (objects[i].oc_descr) {
X# if !defined(MSDOS) && !defined(M_XENIX) && !defined(HPUX) && !defined(VAXC)
X			objects[i].oc_descr += differ;
X# else
X			objects[i].oc_descr =
X			    (const char *)((long)(objects[i].oc_descr) + differ);
X# endif
X		}
X#endif /* MACOS */
X		if (objects[i].oc_uname) {
X			mread(fd, (genericptr_t) &len, sizeof len);
X			objects[i].oc_uname = (char *) alloc(len);
X			mread(fd, (genericptr_t)objects[i].oc_uname, len);
X		}
X	}
X}
X
Xstatic boolean
Xinteresting_to_discover(i)
Xregister int i;
X{
X    return objects[i].oc_uname != NULL ||
X		(objects[i].oc_name_known && objects[i].oc_descr != NULL);
X}
X
Xint
Xdodiscovered()				/* free after Robert Viduya */
X{
X    register int i, dis;
X    int	ct = 0;
X    char class = -1;
X
X    cornline(0, "Discoveries");
X
X    for (i = 0; i <= NROFOBJECTS; i++) {
X	if (interesting_to_discover(dis = disco[i])) {
X	    ct++;
X	    if (objects[dis].oc_olet != class) {
X		class = objects[dis].oc_olet;
X		cornline(1, let_to_name(class));
X	    }
X	    cornline(1, typename(dis));
X	}
X    }
X    if (ct == 0) {
X	You("haven't discovered anything yet...");
X	cornline(3, NULL);
X    } else
X	cornline(2, NULL);
X
X    return 0;
X}
END_OF_FILE
if test 9660 -ne `wc -c <'src/o_init.c'`; then
    echo shar: \"'src/o_init.c'\" unpacked with wrong size!
fi
# end of 'src/o_init.c'
fi
if test -f 'src/spell.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/spell.c'\"
else
echo shar: Extracting \"'src/spell.c'\" \(11119 characters\)
sed "s/^X//" >'src/spell.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)spell.c	3.0	88/09/18
X *
X *	Copyright (c) M. Stephenson 1988
X */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include "hack.h"
X#ifdef SPELLS
Xstatic schar NEARDATA delay;		/* moves left for this spell */
Xstatic struct obj NEARDATA *book;	/* last/current book being xscribed */
X
X#ifdef HARD
X#define spelluses(spell)	spl_book[spell-1].sp_uses
X#define decrnuses(spell)	spl_book[spell-1].sp_uses--
X#endif /* HARD */
X#define spellev(spell)		spl_book[spell-1].sp_lev
X#define spellname(spell)	objects[spl_book[spell-1].sp_id].oc_name
X#define spellid(spell)		spl_book[spell-1].sp_id
X
Xstatic void FDECL(cursed_book, (int));
XSTATIC_PTR int NDECL(learn);
Xstatic int NDECL(getspell);
Xstatic char FDECL(spellet, (int));
X
Xstatic void
Xcursed_book(lev)
X	register int	lev;
X{
X	switch(rn2(lev)) {
X	case 0:
X		You("feel a wrenching sensation.");
X		tele();		/* teleport him */
X		break;
X	case 1:
X		You("feel threatened.");
X		aggravate();
X		break;
X	case 2:
X		make_blinded(Blinded + rn1(100,250),TRUE);
X		break;
X	case 3:
X		take_gold();
X		break;
X	case 4:
X		pline("These runes were just too much to comprehend.");
X		make_confused(HConfusion + rn1(7,16),FALSE);
X		break;
X	case 5:
X		pline("The book was coated with contact poison!");
X		if (uarmg) {
X		    if (uarmg->rustfree)
X			Your("gloves seem unaffected.");
X		    else if (uarmg->spe > -2) {
X			Your("gloves corrode!");
X			uarmg->spe--;
X		    } else
X			Your("gloves %s quite corroded.",Blind ? "feel":"look");
X		    break;
X		}
X		if(Poison_resistance) {
X		    losestr(rn1(1,2));
X		    losehp(rnd(6), "contact-poisoned spellbook", KILLED_BY_AN);
X		} else {
X		    losestr(rn1(4,3));
X		    losehp(rnd(10), "contact-poisoned spellbook", KILLED_BY_AN);
X		}
X		break;
X	case 6:
X		if(Antimagic) {
X		    shieldeff(u.ux, u.uy);
X		    pline("The book explodes, but you are unharmed!");
X		} else {
X		    pline("As you read the book, it explodes in your %s!",
X			body_part(FACE));
X		    losehp (2*rnd(10)+5, "exploding rune", KILLED_BY_AN);
X		}
X		break;
X	default:
X		rndcurse();
X		break;
X	}
X	return;
X}
X
XSTATIC_PTR
Xint
Xlearn()
X{
X	register int	i;
X	register unsigned booktype;
X
X	if (delay) {	/* not if (delay++), so at end delay == 0 */
X		delay++;
X		return(1); /* still busy */
X	}
X
X	booktype = book->otyp;
X	for (i = 0; i < MAXSPELL; i++)  {
X		if (spl_book[i].sp_id == booktype)  {
X#ifdef HARD
X			Your("knowledge of that spell is keener.");
X			spl_book[i].sp_uses += rn1(3,8-spl_book[i].sp_lev);
X#else
X			pline("Oh, you already know that one!");
X#endif
X			break;
X		} else if (spl_book[i].sp_id == NO_SPELL)  {
X			spl_book[i].sp_id = booktype;
X			spl_book[i].sp_lev = objects[booktype].spl_lev;
X			spl_book[i].sp_flags = objects[booktype].bits;
X#ifdef HARD
X			/* spells have 2 .. 10-level uses. */
X			/* ie 2 or 3 uses w/ most potent */
X			spl_book[i].sp_uses = rn1(3,8-spl_book[i].sp_lev);
X#endif
X			You("add the spell to your repertoire.");
X			makeknown(booktype);
X			break;
X		}
X	}
X	if (i == MAXSPELL) impossible("Too many spells memorized!");
X
X	if (book->cursed) {	/* maybe a demon cursed it */
X		cursed_book(objects[booktype].spl_lev);
X	}
X
X	useup(book);
X	book = 0;
X	return(0);
X}
X
Xint
Xstudy_book(spellbook)
Xregister struct obj *spellbook;
X{
X	register int	 booktype = spellbook->otyp;
X
X	if (delay && spellbook == book)
X		You("continue your efforts to memorize the spell.");
X	else {
X		switch(booktype)  {
X
X/* level 1 spells */
X	case SPE_HEALING:
X	case SPE_DETECT_MONSTERS:
X	case SPE_FORCE_BOLT:
X	case SPE_LIGHT:
X	case SPE_SLEEP:
X	case SPE_KNOCK:
X/* level 2 spells */
X	case SPE_MAGIC_MISSILE:
X	case SPE_CONFUSE_MONSTER:
X	case SPE_SLOW_MONSTER:
X	case SPE_CURE_BLINDNESS:
X	case SPE_CREATE_MONSTER:
X	case SPE_DETECT_FOOD:
X	case SPE_WIZARD_LOCK:
X		delay = -objects[booktype].oc_delay;
X		break;
X/* level 3 spells */
X	case SPE_HASTE_SELF:
X	case SPE_CAUSE_FEAR:
X	case SPE_CURE_SICKNESS:
X	case SPE_DETECT_UNSEEN:
X	case SPE_EXTRA_HEALING:
X	case SPE_CHARM_MONSTER:
X	case SPE_CLAIRVOYANCE:
X/* level 4 spells */
X	case SPE_LEVITATION:
X	case SPE_RESTORE_ABILITY:
X	case SPE_INVISIBILITY:
X	case SPE_FIREBALL:
X	case SPE_DETECT_TREASURE:
X		delay = -(objects[booktype].spl_lev - 1) * objects[booktype].oc_delay;
X		break;
X/* level 5 spells */
X	case SPE_REMOVE_CURSE:
X	case SPE_MAGIC_MAPPING:
X	case SPE_CONE_OF_COLD:
X	case SPE_IDENTIFY:
X	case SPE_DIG:
X/* level 6 spells */
X	case SPE_TURN_UNDEAD:
X	case SPE_POLYMORPH:
X	case SPE_CREATE_FAMILIAR:
X	case SPE_TELEPORT_AWAY:
X		delay = -objects[booktype].spl_lev * objects[booktype].oc_delay;
X		break;
X/* level 7 spells */
X	case SPE_CANCELLATION:
X	case SPE_FINGER_OF_DEATH:
X	case SPE_GENOCIDE:
X		delay = -8 * objects[booktype].oc_delay;
X		break;
X/* impossible */
X	default:
X		impossible("Unknown spellbook, %d;", booktype);
X		return(0);
X	}
X
X		if(!spellbook->blessed &&
X			(spellbook->cursed ||
X			    rn2(20) > (ACURR(A_INT) + 4 + (int)(u.ulevel/2)
X					- 2*objects[booktype].spl_lev))) {
X			cursed_book(objects[booktype].spl_lev);
X			nomul(delay);			/* study time */
X			delay = 0;
X			useup(spellbook);
X			return(1);
X		}
X
X		You("begin to memorize the runes.");
X	}
X
X	book = spellbook;
X	set_occupation(learn, "studying", 0);
X	return(1);
X}
X
Xstatic int
Xgetspell()  {
X
X	register int	maxs, ilet, i;
X	char	 lets[BUFSZ], buf[BUFSZ];
X
X	if (spl_book[0].sp_id == NO_SPELL)  {
X
X		You("don't know any spells right now.");
X		return(0);
X	} else  {
X
X	    for(maxs = 1; (maxs < MAXSPELL) && (spl_book[maxs].sp_id != NO_SPELL); maxs++);
X	    if (maxs >= MAXSPELL)  {
X
X		impossible("Too many spells memorized.");
X		return(0);
X	    }
X
X	    for(i = 0; (i < maxs) && (i < 26); buf[++i] = 0)  buf[i] = 'a' + i;
X	    for(i = 26; (i < maxs) && (i < 52); buf[++i] = 0) buf[i] = 'A' + i - 26;
X
X	    if (maxs == 1)  Strcpy(lets, "a");
X	    else if (maxs < 27)  Sprintf(lets, "a-%c", 'a' + maxs - 1);
X	    else if (maxs == 27)  Sprintf(lets, "a-z A");
X	    else Sprintf(lets, "a-z A-%c", 'A' + maxs - 27);
X	    for(;;)  {
X
X		pline("Cast which spell? [%s ?] ", lets);
X		if ((ilet = readchar()) == '?')  {
X			(void) dovspell();
X			continue;
X		} else if ((ilet == '\033')||(ilet == '\n')||(ilet == ' '))
X			return(0);
X		else for(i = 0; buf[i] != 0; i++)  if(ilet == buf[i])  return(++i);
X		You("don't know that spell.");
X	    }
X	}
X}
X
Xint
Xdocast()
X{
X	register int	 spell;
X
X	spell = getspell();
X	if (!spell) return(0);
X
X	return(spelleffects(spell,FALSE));
X}
X
Xint
Xspelleffects(spell,atme)
Xregister int spell;
Xboolean atme;
X{
X	register int energy, damage;
X#ifdef HARD
X	boolean confused = (Confusion != 0);
X#endif
X	struct obj *pseudo;
X
X#ifdef HARD
X	/* note that trying to cast it decrements the # of uses,    */
X	/* even if the mage does not have enough food/energy to use */
X	/* the spell */
X	switch (spelluses(spell)) {
X		case 0:
X		    pline ("That spell is too hard to recall at the moment.");
X		    return(0);
X		case 1:
X		    pline ("You can barely remember the runes of this spell.");
X		    break;
X		case 2:
X		    pline ("This spell is starting to be over-used.");
X		    break;
X		default:
X		    break;
X	}
X	decrnuses(spell);
X#endif
X	energy = spellev(spell);
X	if (u.uhave_amulet) {
X		You("feel the amulet draining your energy away.");
X		energy *= rnd(6);
X	}
X	if(energy > u.uen)  {
X		You("don't have enough energy to cast that spell.");
X		return(0);
X	} else	if ((u.uhunger <= 100 && spell != SPE_DETECT_FOOD) ||
X						(ACURR(A_STR) < 6))  {
X		You("lack the strength for that spell.");
X		return(0);
X	} else	{
X		if (spell != SPE_DETECT_FOOD)
X			morehungry(energy * 10);
X		u.uen -= energy;
X	}
X	flags.botl = 1;
X
X#ifdef HARD
X	if (confused ||
X	    ((int)(ACURR(A_INT) + Luck) - 3 * spellev(spell)) < 0) {
X
X		if (Hallucination)
X			pline("Far out... a light show!");
X		else	pline("The air around you crackles as you goof up.");
X		return(0);
X	}
X#endif
X
X/*	pseudo is a temporary "false" object containing the spell stats. */
X	pseudo = mksobj(spellid(spell),FALSE);
X	pseudo->blessed = pseudo->cursed = 0;
X	pseudo->quan = 20;			/* do not let useup get it */
X	switch(pseudo->otyp)  {
X
X/* These spells are all duplicates of wand effects */
X	case SPE_FORCE_BOLT:
X	case SPE_SLEEP:
X	case SPE_MAGIC_MISSILE:
X	case SPE_KNOCK:
X	case SPE_SLOW_MONSTER:
X	case SPE_WIZARD_LOCK:
X	case SPE_FIREBALL:
X	case SPE_CONE_OF_COLD:
X	case SPE_DIG:
X	case SPE_TURN_UNDEAD:
X	case SPE_POLYMORPH:
X	case SPE_TELEPORT_AWAY:
X	case SPE_CANCELLATION:
X	case SPE_FINGER_OF_DEATH:
X	case SPE_LIGHT:
X	case SPE_DETECT_UNSEEN:
X#ifdef MACOS
X		if (pseudo->otyp == SPE_DIG)
X		{
X			segments |= SEG_SPELL;
X		}
X#endif
X		if (!(objects[pseudo->otyp].bits & NODIR)) {
X			if (atme) u.dx = u.dy = u.dz = 0;
X			else (void) getdir(1);
X			if(!u.dx && !u.dy && !u.dz) {
X			    if((damage = zapyourself(pseudo)))
X				losehp(damage, 
X		self_pronoun("zapped %sself with a spell", "him"),
X					NO_KILLER_PREFIX);
X			} else	weffects(pseudo);
X		} else weffects(pseudo);
X		break;
X/* These are all duplicates of scroll effects */
X	case SPE_CONFUSE_MONSTER:
X	case SPE_DETECT_FOOD:
X	case SPE_CAUSE_FEAR:
X	case SPE_CHARM_MONSTER:
X	case SPE_REMOVE_CURSE:
X	case SPE_MAGIC_MAPPING:
X	case SPE_CREATE_MONSTER:
X	case SPE_IDENTIFY:
X	case SPE_GENOCIDE:
X		(void) seffects(pseudo);
X		break;
X	case SPE_HASTE_SELF:
X	case SPE_DETECT_TREASURE:
X	case SPE_DETECT_MONSTERS:
X	case SPE_LEVITATION:
X	case SPE_RESTORE_ABILITY:
X	case SPE_INVISIBILITY:
X		(void) peffects(pseudo);
X		break;
X	case SPE_HEALING:
X		You("feel a bit better.");
X		healup(rnd(8), 0, 0, 0);
X		break;
X	case SPE_CURE_BLINDNESS:
X		healup(0, 0, 0, 1);
X		break;
X	case SPE_CURE_SICKNESS:
X		if (Sick) You("are no longer ill.");
X		healup(0, 0, 1, 0);
X		break;
X	case SPE_EXTRA_HEALING:
X		You("feel a fair bit better.");
X		healup(d(2,8), 1, 0, 0);
X		break;
X	case SPE_CREATE_FAMILIAR:
X		make_familiar((struct obj *)0);
X		break;
X	case SPE_CLAIRVOYANCE:
X		do_vicinity_map();
X		break;
X	default:
X		impossible("Unknown spell %d attempted.", spell);
X		obfree(pseudo, (struct obj *)0);
X		return(0);
X	}
X	obfree(pseudo, (struct obj *)0);	/* now, get rid of it */
X	return(1);
X}
X
Xvoid
Xlosespells() {
X	register boolean confused = (Confusion != 0);
X	register int	 n, nzap, i;
X
X	book = 0;
X	for(n = 0;(spl_book[n].sp_id != NO_SPELL) && (n < MAXSPELL); n++);
X	if (!n) return;
X	if (n < MAXSPELL) {
X		nzap = rnd(n);
X		if (nzap < n) nzap += confused;
X		for (i = 0; i < nzap; i++) spl_book[n-i-1].sp_id = NO_SPELL;
X	} else impossible("Too many spells memorized!");
X	return;
X}
X
Xstatic char
Xspellet(spl)
Xint spl;
X{
X	return (spl < 27) ? ('a' + spl - 1) : ('A' + spl - 27);
X}
X
Xint
Xdovspell() {
X
X	register int maxs, i;
X	char     buf[BUFSZ], any[BUFSZ];
X
X	if (spl_book[0].sp_id == NO_SPELL)  {
X
X		You("don't know any spells right now.");
X		return 0;
X	}
X
X	for(maxs = 1; (maxs < MAXSPELL) && (spl_book[maxs].sp_id != NO_SPELL); maxs++);
X	if (maxs >= MAXSPELL)  {
X
X		impossible("Too many spells memorized.");
X		return 0;
X	}
X	morc = 0;		/* just to be sure */
X	cornline(0, "Currently known spells:");
X
X	for(i = 1; i <= maxs; i++) {
X
X#ifdef HARD
X		Sprintf(buf, "%c %c %s (%d)",
X			spellet(i), (spelluses(i)) ? '-' : '*',
X			spellname(i), spellev(i));
X#else
X		Sprintf(buf, "%c %s (%d)",
X			spellet(i),
X			spellname(i), spellev(i));
X#endif
X		cornline(1, buf);
X		any[i-1] = spellet(i);
X  	}
X	any[i-1] = 0;
X	cornline(2, any);
X
X	return 0;
X}
X
X
X#endif /* SPELLS /**/
END_OF_FILE
if test 11119 -ne `wc -c <'src/spell.c'`; then
    echo shar: \"'src/spell.c'\" unpacked with wrong size!
fi
# end of 'src/spell.c'
fi
if test -f 'vms/vmstparam.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'vms/vmstparam.c'\"
else
echo shar: Extracting \"'vms/vmstparam.c'\" \(11344 characters\)
sed "s/^X//" >'vms/vmstparam.c' <<'END_OF_FILE'
X/* Merge parameters into a termcap entry string.
X   Copyright (C) 1985, 1987 Free Software Foundation, Inc.
X
X
X		       NO WARRANTY
X
X  BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
XNO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
XWHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
XRICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
XWITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
XBUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
XFITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
XAND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
XDEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
XCORRECTION.
X
X IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
XSTALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
XWHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
XLIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
XOTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
XUSE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
XDATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
XA FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
XPROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
XDAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
X
X		GENERAL PUBLIC LICENSE TO COPY
X
X  1. You may copy and distribute verbatim copies of this source file
Xas you receive it, in any medium, provided that you conspicuously and
Xappropriately publish on each copy a valid copyright notice "Copyright
X(C) 1986 Free Software Foundation, Inc."; and include following the
Xcopyright notice a verbatim copy of the above disclaimer of warranty
Xand of this License.  You may charge a distribution fee for the
Xphysical act of transferring a copy.
X
X  2. You may modify your copy or copies of this source file or
Xany portion of it, and copy and distribute such modifications under
Xthe terms of Paragraph 1 above, provided that you also do the following:
X
X    a) cause the modified files to carry prominent notices stating
X    that you changed the files and the date of any change; and
X
X    b) cause the whole of any work that you distribute or publish,
X    that in whole or in part contains or is a derivative of this
X    program or any part thereof, to be licensed at no charge to all
X    third parties on terms identical to those contained in this
X    License Agreement (except that you may choose to grant more extensive
X    warranty protection to some or all third parties, at your option).
X
X    c) You may charge a distribution fee for the physical act of
X    transferring a copy, and you may at your option offer warranty
X    protection in exchange for a fee.
X
XMere aggregation of another unrelated program with this program (or its
Xderivative) on a volume of a storage or distribution medium does not bring
Xthe other program under the scope of these terms.
X
X  3. You may copy and distribute this program (or a portion or derivative
Xof it, under Paragraph 2) in object code or executable form under the terms
Xof Paragraphs 1 and 2 above provided that you also do one of the following:
X
X    a) accompany it with the complete corresponding machine-readable
X    source code, which must be distributed under the terms of
X    Paragraphs 1 and 2 above; or,
X
X    b) accompany it with a written offer, valid for at least three
X    years, to give any third party free (except for a nominal
X    shipping charge) a complete machine-readable copy of the
X    corresponding source code, to be distributed under the terms of
X    Paragraphs 1 and 2 above; or,
X
X    c) accompany it with the information you received as to where the
X    corresponding source code may be obtained.  (This alternative is
X    allowed only for noncommercial distribution and only if you
X    received the program in object code or executable form alone.)
X
XFor an executable file, complete source code means all the source code for
Xall modules it contains; but, as a special exception, it need not include
Xsource code for modules which are standard libraries that accompany the
Xoperating system on which the executable file runs.
X
X  4. You may not copy, sublicense, distribute or transfer this program
Xexcept as expressly provided under this License Agreement.  Any attempt
Xotherwise to copy, sublicense, distribute or transfer this program is void and
Xyour rights to use the program under this License agreement shall be
Xautomatically terminated.  However, parties who have received computer
Xsoftware programs from you with this License Agreement will not have
Xtheir licenses terminated so long as such parties remain in full compliance.
X
X  5. If you wish to incorporate parts of this program into other free
Xprograms whose distribution conditions are different, write to the Free
XSoftware Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
Xworked out a simple rule that can be stated here, but we will often permit
Xthis.  We will be guided by the two goals of preserving the free status of
Xall derivatives of our free software and of promoting the sharing and reuse of
Xsoftware.
X
X
XIn other words, you are welcome to use, share and improve this program.
XYou are forbidden to forbid anyone else to use, share and improve
Xwhat you give them.   Help stamp out software-hoarding!  */
X
X
X/* config.h may rename various library functions such as malloc.  */
X#ifdef emacs
X#include "config.h"
X#endif
X
X/* Assuming STRING is the value of a termcap string entry
X   containing `%' constructs to expand parameters,
X   merge in parameter values and store result in block OUTSTRING points to.
X   LEN is the length of OUTSTRING.  If more space is needed,
X   a block is allocated with `malloc'.
X
X   The value returned is the address of the resulting string.
X   This may be OUTSTRING or may be the address of a block got with `malloc'.
X   In the latter case, the caller must free the block.
X
X   The fourth and following args to tparam serve as the parameter values.  */
X
Xstatic char *tparam1 ();
X
X/* VARARGS 2 */
Xchar *
Xtparam (string, outstring, len, arg0, arg1, arg2, arg3)
X     char *string;
X     char *outstring;
X     int len;
X     int arg0, arg1, arg2, arg3;
X{
X#ifdef NO_ARG_ARRAY
X  int arg[4];
X  arg[0] = arg0;
X  arg[1] = arg1;
X  arg[2] = arg2;
X  arg[3] = arg3;
X  return tparam1 (string, outstring, len, 0, 0, arg);
X#else
X  return tparam1 (string, outstring, len, 0, 0, &arg0);
X#endif
X}
X
Xchar *BC;
Xchar *UP;
X
Xstatic char tgoto_buf[50];
X
Xchar *
Xtgoto (cm, hpos, vpos)
X     char *cm;
X     int hpos, vpos;
X{
X  int args[2];
X  if (!cm)
X    return 0;
X  args[0] = vpos;
X  args[1] = hpos;
X  return tparam1 (cm, tgoto_buf, 50, UP, BC, args);
X}
X
Xstatic char *
Xtparam1 (string, outstring, len, up, left, argp)
X     char *string;
X     char *outstring;
X     int len;
X     char *up, *left;
X     register int *argp;
X{
X  register int c;
X  register char *p = string;
X  register char *op = outstring;
X  char *outend;
X  int outlen = 0;
X
X  register int tem;
X  int *oargp = argp;
X  int doleft = 0;
X  int doup = 0;
X
X  outend = outstring + len;
X
X  while (1)
X    {
X      /* If the buffer might be too short, make it bigger.  */
X      if (op + 5 >= outend)
X	{
X	  register char *new;
X	  if (outlen == 0)
X	    {
X	      new = (char *) malloc (outlen = 40 + len);
X	      outend += 40;
X	    }
X	  else
X	    {
X	      outend += outlen;
X	      new = (char *) realloc (outstring, outlen *= 2);
X	    }
X	  op += new - outstring;
X	  outend += new - outstring;
X	  outstring = new;
X	}
X      if (!(c = *p++))
X	break;
X      if (c == '%')
X	{
X	  c = *p++;
X	  tem = *argp;
X	  switch (c)
X	    {
X	    case 'd':		/* %d means output in decimal */
X	      if (tem < 10)
X		goto onedigit;
X	      if (tem < 100)
X		goto twodigit;
X	    case '3':		/* %3 means output in decimal, 3 digits. */
X	      if (tem > 999)
X		{
X		  *op++ = tem / 1000 + '0';
X		  tem %= 1000;
X		}
X	      *op++ = tem / 100 + '0';
X	    case '2':		/* %2 means output in decimal, 2 digits. */
X	    twodigit:
X	      tem %= 100;
X	      *op++ = tem / 10 + '0';
X	    onedigit:
X	      *op++ = tem % 10 + '0';
X	      argp++;
X	      break;
X
X	    case 'C':
X	      /* For c-100: print quotient of value by 96, if nonzero,
X		 then do like %+ */
X	      if (tem >= 96)
X		{
X		  *op++ = tem / 96;
X		  tem %= 96;
X		}
X	    case '+':		/* %+x means add character code of char x */
X	      tem += *p++;
X	    case '.':		/* %. means output as character */
X	      if (left)
X		{
X		  /* If want to forbid output of 0 and \n and \t,
X		     and this is one of them, increment it.  */
X		  while (tem == 0 || tem == '\n' || tem == '\t')
X		    {
X		      tem++;
X		      if (argp == oargp)
X			doleft++, outend -= strlen (left);
X		      else
X			doup++, outend -= strlen (up);
X		    }
X		}
X	      *op++ = tem | 0200;
X	    case 'f':		/* %f means discard next arg */
X	      argp++;
X	      break;
X
X	    case 'b':		/* %b means back up one arg (and re-use it) */
X	      argp--;
X	      break;
X
X	    case 'r':		/* %r means interchange following two args */
X	      argp[0] = argp[1];
X	      argp[1] = tem;
X	      oargp++;
X	      break;
X
X	    case '>':		/* %>xy means if arg is > char code of x, */
X	      if (argp[0] > *p++) /* then add char code of y to the arg, */
X		argp[0] += *p;	/* and in any case don't output. */
X	      p++;		/* Leave the arg to be output later. */
X	      break;
X
X	    case 'a':		/* %a means arithmetic */
X	      /* Next character says what operation.
X		 Add or subtract either a constant or some other arg */
X	      /* First following character is + to add or - to subtract
X		 or = to assign.  */
X	      /* Next following char is 'p' and an arg spec
X		 (0100 plus position of that arg relative to this one)
X		 or 'c' and a constant stored in a character */
X	      tem = p[2] & 0177;
X	      if (p[1] == 'p')
X		tem = argp[tem - 0100];
X	      if (p[0] == '-')
X		argp[0] -= tem;
X	      else if (p[0] == '+')
X		argp[0] += tem;
X	      else if (p[0] == '*')
X		argp[0] *= tem;
X	      else if (p[0] == '/')
X		argp[0] /= tem;
X	      else
X		argp[0] = tem;
X
X	      p += 3;
X	      break;
X
X	    case 'i':		/* %i means add one to arg, */
X	      argp[0] ++;	/* and leave it to be output later. */
X	      argp[1] ++;	/* Increment the following arg, too!  */
X	      break;
X
X	    case '%':		/* %% means output %; no arg. */
X	      goto ordinary;
X
X	    case 'n':		/* %n means xor each of next two args with 140 */
X	      argp[0] ^= 0140;
X	      argp[1] ^= 0140;
X	      break;
X
X	    case 'm':		/* %m means xor each of next two args with 177 */
X	      argp[0] ^= 0177;
X	      argp[1] ^= 0177;
X	      break;
X
X	    case 'B':		/* %B means express arg as BCD char code. */
X	      argp[0] += 6 * (tem / 10);
X	      break;
X
X	    case 'D':		/* %D means weird Delta Data transformation */
X	      argp[0] -= 2 * (tem % 16);
X	      break;
X	    }
X	}
X      else
X	/* Ordinary character in the argument string.  */
X      ordinary:
X	*op++ = c;
X    }
X  *op = 0;
X  while (doleft-- > 0)
X    strcpy (op, left);
X  while (doup-- > 0)
X    strcpy (op, up);
X  return outstring;
X}
X
X#ifdef DEBUG
X
Xmain (argc, argv)
X     int argc;
X     char **argv;
X{
X  char buf[50];
X  int args[3];
X  args[0] = atoi (argv[2]);
X  args[1] = atoi (argv[3]);
X  args[2] = atoi (argv[4]);
X  tparam1 (argv[1], buf, "LEFT", "UP", args);
X  printf ("%s\n", buf);
X  return 0;
X}
X
X#endif /* DEBUG */
END_OF_FILE
if test 11344 -ne `wc -c <'vms/vmstparam.c'`; then
    echo shar: \"'vms/vmstparam.c'\" unpacked with wrong size!
fi
# end of 'vms/vmstparam.c'
fi
echo shar: End of archive 45 \(of 56\).
cp /dev/null ark45isdone
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
    echo Building monst.c from monst.c1 and monst.c2
    cat src/monst.c1 src/monst.c2 > src/monst.c
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0