/*	$NetBSD: object.c,v 1.17 2019/02/03 03:19:25 mrg Exp $	*/

/* object.c		Larn is copyrighted 1986 by Noah Morgan. */

#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: object.c,v 1.17 2019/02/03 03:19:25 mrg Exp $");
#endif				/* not lint */
#include "header.h"
#include "extern.h"

static void finditem(int);
static void ostairs(int);
static void opotion(int);
static void oscroll(int);
static void oorb(void);
static void opit(void);
static void obottomless(void);
static void oelevator(int);
static void ostatue(void);
static void omirror(void);
static void obook(void);
static void ocookie(void);
static void ogold(int);
static void ohome(void);

/*
	lookforobject

	subroutine to look for an object and give the player his options
	if an object was found.
 */
void
lookforobject(void)
{
	int    i, j;
	if (c[TIMESTOP])
		return;		/* can't find objects if time is stopped	 */
	i = item[playerx][playery];
	if (i == 0)
		return;
	showcell(playerx, playery);
	cursors();
	yrepcount = 0;
	switch (i) {
	case OGOLDPILE:
	case OMAXGOLD:
	case OKGOLD:
	case ODGOLD:
		lprcat("\n\nYou have found some gold!");
		ogold(i);
		break;

	case OPOTION:
		lprcat("\n\nYou have found a magic potion");
		i = iarg[playerx][playery];
		if (potionname[i][0] != 0)
			lprintf(" of%s", potionname[i]);
		opotion(i);
		break;

	case OSCROLL:
		lprcat("\n\nYou have found a magic scroll");
		i = iarg[playerx][playery];
		if (scrollname[i][0] != 0)
			lprintf(" of%s", scrollname[i]);
		oscroll(i);
		break;

	case OALTAR:
		if (nearbymonst())
			return;
		lprcat("\n\nThere is a Holy Altar here!");
		oaltar();
		break;

	case OBOOK:
		lprcat("\n\nYou have found a book.");
		obook();
		break;

	case OCOOKIE:
		lprcat("\n\nYou have found a fortune cookie.");
		ocookie();
		break;

	case OTHRONE:
		if (nearbymonst())
			return;
		lprintf("\n\nThere is %s here!", objectname[i]);
		othrone(0);
		break;

	case OTHRONE2:
		if (nearbymonst())
			return;
		lprintf("\n\nThere is %s here!", objectname[i]);
		othrone(1);
		break;

	case ODEADTHRONE:
		lprintf("\n\nThere is %s here!", objectname[i]);
		odeadthrone();
		break;

	case OORB:
		lprcat("\n\nYou have found the Orb!!!!!");
		oorb();
		break;

	case OPIT:
		lprcat("\n\nYou're standing at the top of a pit.");
		opit();
		break;

	case OSTAIRSUP:
		lprcat("\n\nThere is a circular staircase here");
		ostairs(1);	/* up */
		break;

	case OELEVATORUP:
		lprcat("\n\nYou feel heavy for a moment, but the feeling disappears");
		oelevator(1);	/* up  */
		break;

	case OFOUNTAIN:
		if (nearbymonst())
			return;
		lprcat("\n\nThere is a fountain here");
		ofountain();
		break;

	case OSTATUE:
		if (nearbymonst())
			return;
		lprcat("\n\nYou are standing in front of a statue");
		ostatue();
		break;

	case OCHEST:
		lprcat("\n\nThere is a chest here");
		ochest();
		break;

	case OIVTELETRAP:
		if (rnd(11) < 6)
			return;
		item[playerx][playery] = OTELEPORTER;
		know[playerx][playery] = 1;

		/* FALLTHROUGH */
	case OTELEPORTER:
		lprcat("\nZaaaappp!  You've been teleported!\n");
		beep();
		nap(3000);
		oteleport(0);
		break;

	case OSCHOOL:
		if (nearbymonst())
			return;
		lprcat("\n\nYou have found the College of Larn.");
		lprcat("\nDo you (g) go inside, or (i) stay here? ");
		i = 0;
		while ((i != 'g') && (i != 'i') && (i != '\33'))
			i = ttgetch();
		if (i == 'g') {
			oschool();	/* the college of larn	 */
		} else
			lprcat(" stay here");
		break;

	case OMIRROR:
		if (nearbymonst())
			return;
		lprcat("\n\nThere is a mirror here");
		omirror();
		break;

	case OBANK2:
	case OBANK:
		if (nearbymonst())
			return;
		if (i == OBANK)
			lprcat("\n\nYou have found the bank of Larn.");
		else
			lprcat("\n\nYou have found a branch office of the bank of Larn.");
		lprcat("\nDo you (g) go inside, or (i) stay here? ");
		j = 0;
		while ((j != 'g') && (j != 'i') && (j != '\33'))
			j = ttgetch();
		if (j == 'g') {
			if (i == OBANK)
				obank();
			else
				obank2();	/* the bank of larn  */
		} else
			lprcat(" stay here");
		break;

	case ODEADFOUNTAIN:
		if (nearbymonst())
			return;
		lprcat("\n\nThere is a dead fountain here");
		break;

	case ODNDSTORE:
		if (nearbymonst())
			return;
		lprcat("\n\nThere is a DND store here.");
		lprcat("\nDo you (g) go inside, or (i) stay here? ");
		i = 0;
		while ((i != 'g') && (i != 'i') && (i != '\33'))
			i = ttgetch();
		if (i == 'g')
			dndstore();	/* the dnd adventurers store  */
		else
			lprcat(" stay here");
		break;

	case OSTAIRSDOWN:
		lprcat("\n\nThere is a circular staircase here");
		ostairs(-1);	/* down */
		break;

	case OELEVATORDOWN:
		lprcat("\n\nYou feel light for a moment, but the feeling disappears");
		oelevator(-1);	/* down	 */
		break;

	case OOPENDOOR:
		lprintf("\n\nYou have found %s", objectname[i]);
		lprcat("\nDo you (c) close it");
		iopts();
		i = 0;
		while ((i != 'c') && (i != 'i') && (i != '\33'))
			i = ttgetch();
		if ((i == '\33') || (i == 'i')) {
			ignore();
			break;
		}
		lprcat("close");
		forget();
		item[playerx][playery] = OCLOSEDDOOR;
		iarg[playerx][playery] = 0;
		playerx = lastpx;
		playery = lastpy;
		break;

	case OCLOSEDDOOR:
		lprintf("\n\nYou have found %s", objectname[i]);
		lprcat("\nDo you (o) try to open it");
		iopts();
		i = 0;
		while ((i != 'o') && (i != 'i') && (i != '\33'))
			i = ttgetch();
		if ((i == '\33') || (i == 'i')) {
			ignore();
			playerx = lastpx;
			playery = lastpy;
			break;
		} else {
			lprcat("open");
			if (rnd(11) < 7) {
				switch (iarg[playerx][playery]) {
				case 6:
					c[AGGRAVATE] += rnd(400);
					break;

				case 7:
					lprcat("\nYou are jolted by an electric shock ");
					lastnum = 274;
					losehp(rnd(20));
					bottomline();
					break;

				case 8:
					loselevel();
					break;

				case 9:
					lprcat("\nYou suddenly feel weaker ");
					if (c[STRENGTH] > 3)
						c[STRENGTH]--;
					bottomline();
					break;

				default:
					break;
				}
				playerx = lastpx;
				playery = lastpy;
			} else {
				forget();
				item[playerx][playery] = OOPENDOOR;
			}
		}
		break;

	case OENTRANCE:
		lprcat("\nYou have found ");
		lprcat(objectname[OENTRANCE]);
		lprcat("\nDo you (g) go inside");
		iopts();
		i = 0;
		while ((i != 'g') && (i != 'i') && (i != '\33'))
			i = ttgetch();
		if (i == 'g') {
			newcavelevel(1);
			playerx = 33;
			playery = MAXY - 2;
			item[33][MAXY - 1] = know[33][MAXY - 1] = mitem[33][MAXY - 1] = 0;
			draws(0, MAXX, 0, MAXY);
			bot_linex();
			return;
		} else
			ignore();
		break;

	case OVOLDOWN:
		lprcat("\nYou have found ");
		lprcat(objectname[OVOLDOWN]);
		lprcat("\nDo you (c) climb down");
		iopts();
		i = 0;
		while ((i != 'c') && (i != 'i') && (i != '\33'))
			i = ttgetch();
		if ((i == '\33') || (i == 'i')) {
			ignore();
			break;
		}
		if (level != 0) {
			lprcat("\nThe shaft only extends 5 feet downward!");
			return;
		}
		if (packweight() > 45 + 3 * (c[STRENGTH] + c[STREXTRA])) {
			lprcat("\nYou slip and fall down the shaft");
			beep();
			lastnum = 275;
			losehp(30 + rnd(20));
			bottomhp();
		} else
			lprcat("climb down");
		nap(3000);
		newcavelevel(MAXLEVEL);
		for (i = 0; i < MAXY; i++)
			for (j = 0; j < MAXX; j++)	/* put player near
							 * volcano shaft */
				if (item[j][i] == OVOLUP) {
					playerx = j;
					playery = i;
					j = MAXX;
					i = MAXY;
					positionplayer();
				}
		draws(0, MAXX, 0, MAXY);
		bot_linex();
		return;

	case OVOLUP:
		lprcat("\nYou have found ");
		lprcat(objectname[OVOLUP]);
		lprcat("\nDo you (c) climb up");
		iopts();
		i = 0;
		while ((i != 'c') && (i != 'i') && (i != '\33'))
			i = ttgetch();
		if ((i == '\33') || (i == 'i')) {
			ignore();
			break;
		}
		if (level != 11) {
			lprcat("\nThe shaft only extends 8 feet upwards before you find a blockage!");
			return;
		}
		if (packweight() > 45 + 5 * (c[STRENGTH] + c[STREXTRA])) {
			lprcat("\nYou slip and fall down the shaft");
			beep();
			lastnum = 275;
			losehp(15 + rnd(20));
			bottomhp();
			return;
		}
		lprcat("climb up");
		lflush();
		nap(3000);
		newcavelevel(0);
		for (i = 0; i < MAXY; i++)
			for (j = 0; j < MAXX; j++)	/* put player near
							 * volcano shaft */
				if (item[j][i] == OVOLDOWN) {
					playerx = j;
					playery = i;
					j = MAXX;
					i = MAXY;
					positionplayer();
				}
		draws(0, MAXX, 0, MAXY);
		bot_linex();
		return;

	case OTRAPARROWIV:
		if (rnd(17) < 13)
			return;	/* for an arrow trap */
		item[playerx][playery] = OTRAPARROW;
		know[playerx][playery] = 0;

		/* FALLTHROUGH */
	case OTRAPARROW:
		lprcat("\nYou are hit by an arrow");
		beep();		/* for an arrow trap */
		lastnum = 259;
		losehp(rnd(10) + level);
		bottomhp();
		return;

	case OIVDARTRAP:
		if (rnd(17) < 13)
			return;	/* for a dart trap */
		item[playerx][playery] = ODARTRAP;
		know[playerx][playery] = 0;

		/* FALLTHROUGH */
	case ODARTRAP:
		lprcat("\nYou are hit by a dart");
		beep();		/* for a dart trap */
		lastnum = 260;
		losehp(rnd(5));
		if ((--c[STRENGTH]) < 3)
			c[STRENGTH] = 3;
		bottomline();
		return;

	case OIVTRAPDOOR:
		if (rnd(17) < 13)
			return;	/* for a trap door */
		item[playerx][playery] = OTRAPDOOR;
		know[playerx][playery] = 1;

		/* FALLTHROUGH */
	case OTRAPDOOR:
		lastnum = 272;	/* a trap door */
		if ((level == MAXLEVEL - 1) || (level == MAXLEVEL + MAXVLEVEL - 1)) {
			lprcat("\nYou fell through a bottomless trap door!");
			beep();
			nap(3000);
			died(271);
		}
		lprcat("\nYou fall through a trap door!");
		beep();		/* for a trap door */
		losehp(rnd(5 + level));
		nap(2000);
		newcavelevel(level + 1);
		draws(0, MAXX, 0, MAXY);
		bot_linex();
		return;


	case OTRADEPOST:
		if (nearbymonst())
			return;
		lprcat("\nYou have found the Larn trading Post.");
		lprcat("\nDo you (g) go inside, or (i) stay here? ");
		i = 0;
		while ((i != 'g') && (i != 'i') && (i != '\33'))
			i = ttgetch();
		if (i == 'g')
			otradepost();
		else
			lprcat("stay here");
		return;

	case OHOME:
		if (nearbymonst())
			return;
		lprcat("\nYou have found your way home.");
		lprcat("\nDo you (g) go inside, or (i) stay here? ");
		i = 0;
		while ((i != 'g') && (i != 'i') && (i != '\33'))
			i = ttgetch();
		if (i == 'g')
			ohome();
		else
			lprcat("stay here");
		return;

	case OWALL:
		break;

	case OANNIHILATION:
		died(283);
		return;		/* annihilated by sphere of annihilation */

	case OLRS:
		if (nearbymonst())
			return;
		lprcat("\n\nThere is an LRS office here.");
		lprcat("\nDo you (g) go inside, or (i) stay here? ");
		i = 0;
		while ((i != 'g') && (i != 'i') && (i != '\33'))
			i = ttgetch();
		if (i == 'g')
			olrs();	/* the larn revenue service */
		else
			lprcat(" stay here");
		break;

	default:
		finditem(i);
		break;
	};
}

/*
	function to say what object we found and ask if player wants to take it
 */
static void
finditem(int theitem)
{
	int             tmp, i;
	lprintf("\n\nYou have found %s ", objectname[theitem]);
	tmp = iarg[playerx][playery];
	switch (theitem) {
	case ODIAMOND:
	case ORUBY:
	case OEMERALD:
	case OSAPPHIRE:
	case OSPIRITSCARAB:
	case OORBOFDRAGON:
	case OCUBEofUNDEAD:
	case ONOTHEFT:
		break;

	default:
		if (tmp > 0)
			lprintf("+ %ld", (long) tmp);
		else if (tmp < 0)
			lprintf(" %ld", (long) tmp);
	}
	lprcat("\nDo you want to (t) take it");
	iopts();
	i = 0;
	while (i != 't' && i != 'i' && i != '\33')
		i = ttgetch();
	if (i == 't') {
		lprcat("take");
		if (take(theitem, tmp) == 0)
			forget();
		return;
	}
	ignore();
}



/*
	subroutine to process the stair cases
	if dir > 0 the up else down
 */
static void
ostairs(int dir)
{
	int    k;
	lprcat("\nDo you (s) stay here  ");
	if (dir > 0)
		lprcat("(u) go up  ");
	else
		lprcat("(d) go down  ");
	lprcat("or (f) kick stairs? ");

	while (1)
		switch (ttgetch()) {
		case '\33':
		case 's':
		case 'i':
			lprcat("stay here");
			return;

		case 'f':
			lprcat("kick stairs");
			if (rnd(2) == 1)
				lprcat("\nI hope you feel better.  Showing anger rids you of frustration.");
			else {
				k = rnd((level + 1) << 1);
				lprintf("\nYou hurt your foot dumb dumb!  You suffer %ld hit points", (long) k);
				lastnum = 276;
				losehp(k);
				bottomline();
			}
			return;

		case 'u':
			lprcat("go up");
			if (dir < 0)
				lprcat("\nThe stairs don't go up!");
			else if (level >= 2 && level != 11) {
				k = level;
				newcavelevel(level - 1);
				draws(0, MAXX, 0, MAXY);
				bot_linex();
			} else
				lprcat("\nThe stairs lead to a dead end!");
			return;

		case 'd':
			lprcat("go down");
			if (dir > 0)
				lprcat("\nThe stairs don't go down!");
			else if (level != 0 && level != 10 && level != 13) {
				k = level;
				newcavelevel(level + 1);
				draws(0, MAXX, 0, MAXY);
				bot_linex();
			} else
				lprcat("\nThe stairs lead to a dead end!");
			return;
		};
}



/*
	subroutine to handle a teleport trap +/- 1 level maximum
 */
void
oteleport(int err)
{
	int    tmp;
	if (err)
		if (rnd(151) < 3)
			died(264);	/* stuck in a rock */
	c[TELEFLAG] = 1;	/* show ?? on bottomline if been teleported	 */
	if (level == 0)
		tmp = 0;
	else if (level < MAXLEVEL) {
		tmp = rnd(5) + level - 3;
		if (tmp >= MAXLEVEL)
			tmp = MAXLEVEL - 1;
		if (tmp < 1)
			tmp = 1;
	} else {
		tmp = rnd(3) + level - 2;
		if (tmp >= MAXLEVEL + MAXVLEVEL)
			tmp = MAXLEVEL + MAXVLEVEL - 1;
		if (tmp < MAXLEVEL)
			tmp = MAXLEVEL;
	}
	playerx = rnd(MAXX - 2);
	playery = rnd(MAXY - 2);
	if (level != tmp)
		newcavelevel(tmp);
	positionplayer();
	draws(0, MAXX, 0, MAXY);
	bot_linex();
}


/*
	function to process a potion
 */
static void
opotion(int pot)
{
	lprcat("\nDo you (d) drink it, (t) take it");
	iopts();
	while (1)
		switch (ttgetch()) {
		case '\33':
		case 'i':
			ignore();
			return;

		case 'd':
			lprcat("drink\n");
			forget();	/* destroy potion	 */
			quaffpotion(pot);
			return;

		case 't':
			lprcat("take\n");
			if (take(OPOTION, pot) == 0)
				forget();
			return;
		};
}

/*
	function to drink a potion
 */
void
quaffpotion(int pot)
{
	int    i, j, k;
	if (pot < 0 || pot >= MAXPOTION)
		return;		/* check for within bounds */
	potionname[pot] = potionhide[pot];
	switch (pot) {
	case 9:
		lprcat("\nYou feel greedy . . .");
		nap(2000);
		for (i = 0; i < MAXY; i++)
			for (j = 0; j < MAXX; j++)
				if ((item[j][i] == OGOLDPILE) || (item[j][i] == OMAXGOLD)) {
					know[j][i] = 1;
					show1cell(j, i);
				}
		showplayer();
		return;

	case 19:
		lprcat("\nYou feel greedy . . .");
		nap(2000);
		for (i = 0; i < MAXY; i++)
			for (j = 0; j < MAXX; j++) {
				k = item[j][i];
				if ((k == ODIAMOND) || (k == ORUBY) || (k == OEMERALD) || (k == OMAXGOLD)
				    || (k == OSAPPHIRE) || (k == OLARNEYE) || (k == OGOLDPILE)) {
					know[j][i] = 1;
					show1cell(j, i);
				}
			}
		showplayer();
		return;

	case 20:
		c[HP] = c[HPMAX];
		break;		/* instant healing */

	case 1:
		lprcat("\nYou feel better");
		if (c[HP] == c[HPMAX])
			raisemhp(1);
		else if ((c[HP] += rnd(20) + 20 + c[LEVEL]) > c[HPMAX])
			c[HP] = c[HPMAX];
		break;

	case 2:
		lprcat("\nSuddenly, you feel much more skillful!");
		raiselevel();
		raisemhp(1);
		return;

	case 3:
		lprcat("\nYou feel strange for a moment");
		c[rund(6)]++;
		break;

	case 4:
		lprcat("\nYou feel more self confident!");
		c[WISDOM] += rnd(2);
		break;

	case 5:
		lprcat("\nWow!  You feel great!");
		if (c[STRENGTH] < 12)
			c[STRENGTH] = 12;
		else
			c[STRENGTH]++;
		break;

	case 6:
		lprcat("\nYour charm went up by one!");
		c[CHARISMA]++;
		break;

	case 8:
		lprcat("\nYour intelligence went up by one!");
		c[INTELLIGENCE]++;
		break;

	case 10:
		for (i = 0; i < MAXY; i++)
			for (j = 0; j < MAXX; j++)
				if (mitem[j][i]) {
					know[j][i] = 1;
					show1cell(j, i);
				}
		 /* monster detection	 */ return;

	case 12:
		lprcat("\nThis potion has no taste to it");
		return;

	case 15:
		lprcat("\nWOW!!!  You feel Super-fantastic!!!");
		if (c[HERO] == 0)
			for (i = 0; i < 6; i++)
				c[i] += 11;
		c[HERO] += 250;
		break;

	case 16:
		lprcat("\nYou have a greater intestinal constitude!");
		c[CONSTITUTION]++;
		break;

	case 17:
		lprcat("\nYou now have incredibly bulging muscles!!!");
		if (c[GIANTSTR] == 0)
			c[STREXTRA] += 21;
		c[GIANTSTR] += 700;
		break;

	case 18:
		lprcat("\nYou feel a chill run up your spine!");
		c[FIRERESISTANCE] += 1000;
		break;

	case 0:
		lprcat("\nYou fall asleep. . .");
		i = rnd(11) - (c[CONSTITUTION] >> 2) + 2;
		while (--i > 0) {
			parse2();
			nap(1000);
		}
		cursors();
		lprcat("\nYou woke up!");
		return;

	case 7:
		lprcat("\nYou become dizzy!");
		if (--c[STRENGTH] < 3)
			c[STRENGTH] = 3;
		break;

	case 11:
		lprcat("\nYou stagger for a moment . .");
		for (i = 0; i < MAXY; i++)
			for (j = 0; j < MAXX; j++)
				know[j][i] = 0;
		nap(2000);
		draws(0, MAXX, 0, MAXY);	/* potion of forgetfulness */
		return;

	case 13:
		lprcat("\nYou can't see anything!");	/* blindness */
		c[BLINDCOUNT] += 500;
		return;

	case 14:
		lprcat("\nYou feel confused");
		c[CONFUSE] += 20 + rnd(9);
		return;

	case 21:
		lprcat("\nYou don't seem to be affected");
		return;		/* cure dianthroritis */

	case 22:
		lprcat("\nYou feel a sickness engulf you");	/* poison */
		c[HALFDAM] += 200 + rnd(200);
		return;

	case 23:
		lprcat("\nYou feel your vision sharpen");	/* see invisible */
		c[SEEINVISIBLE] += rnd(1000) + 400;
		monstnamelist[INVISIBLESTALKER] = 'I';
		return;
	};
	bottomline();		/* show new stats		 */
	return;
}


/*
	function to process a magic scroll
 */
static void
oscroll(int typ)
{
	lprcat("\nDo you ");
	if (c[BLINDCOUNT] == 0)
		lprcat("(r) read it, ");
	lprcat("(t) take it");
	iopts();
	while (1)
		switch (ttgetch()) {
		case '\33':
		case 'i':
			ignore();
			return;

		case 'r':
			if (c[BLINDCOUNT])
				break;
			lprcat("read");
			forget();
			if (typ == 2 || typ == 15) {
				show1cell(playerx, playery);
				cursors();
			}
			 /* destroy it	 */ read_scroll(typ);
			return;

		case 't':
			lprcat("take");
			if (take(OSCROLL, typ) == 0)
				forget();	/* destroy it	 */
			return;
		};
}

/*
	data for the function to read a scroll
 */
static int      xh, yh, yl, xl;
static u_char     curse[] = {
	BLINDCOUNT, CONFUSE, AGGRAVATE, HASTEMONST, ITCHING,
	LAUGHING, DRAINSTRENGTH, CLUMSINESS, INFEEBLEMENT, HALFDAM
};

static u_char     exten[] = {
	PROTECTIONTIME, DEXCOUNT, STRCOUNT, CHARMCOUNT, INVISIBILITY,
	CANCELLATION, HASTESELF, GLOBE, SCAREMONST, HOLDMONST, TIMESTOP
};

static u_char time_change[] = {
	HASTESELF, HERO, ALTPRO, PROTECTIONTIME, DEXCOUNT, STRCOUNT,
	GIANTSTR, CHARMCOUNT, INVISIBILITY, CANCELLATION, HASTESELF,
	AGGRAVATE, SCAREMONST, STEALTH, AWARENESS, HOLDMONST,
	HASTEMONST, FIRERESISTANCE, GLOBE, SPIRITPRO, UNDEADPRO,
	HALFDAM, SEEINVISIBLE, ITCHING, CLUMSINESS, WTW
};

/*
 *	function to adjust time when time warping and taking courses in school
 */
void
adjusttime(long tim)
{
	int    j;
	for (j = 0; j < 26; j++)/* adjust time related parameters */
		if (c[time_change[j]])
			if ((c[time_change[j]] -= tim) < 1)
				c[time_change[j]] = 1;
	regen();
}

/*
	function to read a scroll
 */
void
read_scroll(int typ)
{
	int    i, j;
	if (typ < 0 || typ >= MAXSCROLL)
		return;		/* be sure we are within bounds */
	scrollname[typ] = scrollhide[typ];
	switch (typ) {
	case 0:
		lprcat("\nYour armor glows for a moment");
		enchantarmor();
		return;

	case 1:
		lprcat("\nYour weapon glows for a moment");
		enchweapon();
		return;		/* enchant weapon */

	case 2:
		lprcat("\nYou have been granted enlightenment!");
		yh = min(playery + 7, MAXY);
		xh = min(playerx + 25, MAXX);
		yl = max(playery - 7, 0);
		xl = max(playerx - 25, 0);
		for (i = yl; i < yh; i++)
			for (j = xl; j < xh; j++)
				know[j][i] = 1;
		nap(2000);
		draws(xl, xh, yl, yh);
		return;

	case 3:
		lprcat("\nThis scroll seems to be blank");
		return;

	case 4:
		createmonster(makemonst(level + 1));
		return;		/* this one creates a monster  */

	case 5:
		something(level);	/* create artifact		 */
		return;

	case 6:
		c[AGGRAVATE] += 800;
		return;		/* aggravate monsters */

	case 7:
		gltime += (i = rnd(1000) - 850);	/* time warp */
		if (i >= 0)
			lprintf("\nYou went forward in time by %ld mobuls", (long) ((i + 99) / 100));
		else
			lprintf("\nYou went backward in time by %ld mobuls", (long) (-(i + 99) / 100));
		adjusttime((long) i);	/* adjust time for time warping */
		return;

	case 8:
		oteleport(0);
		return;		/* teleportation */

	case 9:
		c[AWARENESS] += 1800;
		return;		/* expanded awareness	 */

	case 10:
		c[HASTEMONST] += rnd(55) + 12;
		return;		/* haste monster */

	case 11:
		for (i = 0; i < MAXY; i++)
			for (j = 0; j < MAXX; j++)
				if (mitem[j][i])
					hitp[j][i] = monster[mitem[j][i]].hitpoints;
		return;		/* monster healing */
	case 12:
		c[SPIRITPRO] += 300 + rnd(200);
		bottomline();
		return;		/* spirit protection */

	case 13:
		c[UNDEADPRO] += 300 + rnd(200);
		bottomline();
		return;		/* undead protection */

	case 14:
		c[STEALTH] += 250 + rnd(250);
		bottomline();
		return;		/* stealth */

	case 15:
		lprcat("\nYou have been granted enlightenment!");	/* magic mapping */
		for (i = 0; i < MAXY; i++)
			for (j = 0; j < MAXX; j++)
				know[j][i] = 1;
		nap(2000);
		draws(0, MAXX, 0, MAXY);
		return;

	case 16:
		c[HOLDMONST] += 30;
		bottomline();
		return;		/* hold monster */

	case 17:
		for (i = 0; i < 26; i++)	/* gem perfection */
			switch (iven[i]) {
			case ODIAMOND:
			case ORUBY:
			case OEMERALD:
			case OSAPPHIRE:
				j = ivenarg[i];
				j &= 255;
				j <<= 1;
				if (j > 255)
					j = 255;	/* double value */
				ivenarg[i] = j;
				break;
			}
		break;

	case 18:
		for (i = 0; i < 11; i++)
			c[exten[i]] <<= 1;	/* spell extension */
		break;

	case 19:
		for (i = 0; i < 26; i++) {	/* identify */
			if (iven[i] == OPOTION)
				potionname[ivenarg[i]] = potionhide[ivenarg[i]];
			if (iven[i] == OSCROLL)
				scrollname[ivenarg[i]] = scrollhide[ivenarg[i]];
		}
		break;

	case 20:
		for (i = 0; i < 10; i++)	/* remove curse */
			if (c[curse[i]])
				c[curse[i]] = 1;
		break;

	case 21:
		annihilate();
		break;		/* scroll of annihilation */

	case 22:
		godirect(22, 150, "The ray hits the %s", 0, ' ');	/* pulverization */
		break;
	case 23:
		c[LIFEPROT]++;
		break;		/* life protection */
	};
}



static void
oorb(void)
{
}

static void
opit(void)
{
	int    i;
	if (rnd(101) < 81) {
		if (rnd(70) > 9 * c[DEXTERITY] - packweight() || rnd(101) < 5) {
			if (level == MAXLEVEL - 1)
				obottomless();
			else if (level == MAXLEVEL + MAXVLEVEL - 1)
				obottomless();
			else {
				if (rnd(101) < 20) {
					i = 0;
					lprcat("\nYou fell into a pit!  Your fall is cushioned by an unknown force\n");
				} else {
					i = rnd(level * 3 + 3);
					lprintf("\nYou fell into a pit!  You suffer %ld hit points damage", (long) i);
					lastnum = 261;	/* if he dies scoreboard
							 * will say so */
				}
				losehp(i);
				nap(2000);
				newcavelevel(level + 1);
				draws(0, MAXX, 0, MAXY);
			}
		}
	}
}

static void
obottomless(void)
{
	lprcat("\nYou fell into a bottomless pit!");
	beep();
	nap(3000);
	died(262);
}

static void
oelevator(int dir)
{
#ifdef lint
	int             x;
	x = dir;
	dir = x;
#endif	/* lint */
}

static void
ostatue(void)
{
}

static void
omirror(void)
{
}

static void
obook(void)
{
	lprcat("\nDo you ");
	if (c[BLINDCOUNT] == 0)
		lprcat("(r) read it, ");
	lprcat("(t) take it");
	iopts();
	while (1)
		switch (ttgetch()) {
		case '\33':
		case 'i':
			ignore();
			return;

		case 'r':
			if (c[BLINDCOUNT])
				break;
			lprcat("read");
			 /* no more book	 */ readbook(iarg[playerx][playery]);
			forget();
			return;

		case 't':
			lprcat("take");
			if (take(OBOOK, iarg[playerx][playery]) == 0)
				forget();	/* no more book	 */
			return;
		};
}

/*
	function to read a book
 */
void
readbook(int lev)
{
	int    i, tmp;
	if (lev <= 3)
		i = rund((tmp = splev[lev]) ? tmp : 1);
	else
		i = rnd((tmp = splev[lev] - 9) ? tmp : 1) + 9;
	spelknow[i] = 1;
	lprintf("\nSpell \"%s\":  %s\n%s", spelcode[i], spelname[i], speldescript[i]);
	if (rnd(10) == 4) {
		lprcat("\nYour int went up by one!");
		c[INTELLIGENCE]++;
		bottomline();
	}
}

static void
ocookie(void)
{
	const char *p;

	lprcat("\nDo you (e) eat it, (t) take it");
	iopts();
	while (1)
		switch (ttgetch()) {
		case '\33':
		case 'i':
			ignore();
			return;

		case 'e':
			lprcat("eat\nThe cookie tasted good.");
			forget();	/* no more cookie	 */
			if (c[BLINDCOUNT])
				return;
			if (!(p = fortune()))
				return;
			lprcat("  A message inside the cookie reads:\n");
			lprcat(p);
			return;

		case 't':
			lprcat("take");
			if (take(OCOOKIE, 0) == 0)
				forget();	/* no more book	 */
			return;
		};
}


/*
 * routine to pick up some gold -- if arg==OMAXGOLD then the pile is worth
 * 100* the argument
 */
static void
ogold(int arg)
{
	long   i;
	i = iarg[playerx][playery];
	if (arg == OMAXGOLD)
		i *= 100;
	else if (arg == OKGOLD)
		i *= 1000;
	else if (arg == ODGOLD)
		i *= 10;
	lprintf("\nIt is worth %ld!", (long) i);
	c[GOLD] += i;
	bottomgold();
	item[playerx][playery] = know[playerx][playery] = 0;	/* destroy gold	 */
}

static void
ohome(void)
{
	int    i;
	nosignal = 1;		/* disable signals */
	for (i = 0; i < 26; i++)
		if (iven[i] == OPOTION)
			if (ivenarg[i] == 21) {
				iven[i] = 0;	/* remove the potion of cure
						 * dianthroritis from
						 * inventory */
				clear();
				lprcat("Congratulations.  You found a potion of cure dianthroritis.\n");
				lprcat("\nFrankly, No one thought you could do it.  Boy!  Did you surprise them!\n");
				if (gltime > TIMELIMIT) {
					lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
					lprcat("You didn't make it in time.  In your agony, you kill the doctor,\nyour wife, and yourself!  Too bad!\n");
					nap(5000);
					died(269);
				} else {
					lprcat("\nThe doctor is now administering the potion, and in a few moments\n");
					lprcat("Your daughter should be well on her way to recovery.\n");
					nap(6000);
					lprcat("\nThe potion is");
					nap(3000);
					lprcat(" working!  The doctor thinks that\n");
					lprcat("your daughter will recover in a few days.  Congratulations!\n");
					beep();
					nap(5000);
					died(263);
				}
			}
	while (1) {
		clear();
		lprintf("Welcome home %s.  Latest word from the doctor is not good.\n", logname);

		if (gltime > TIMELIMIT) {
			lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
			lprcat("You didn't make it in time.  In your agony, you kill the doctor,\nyour wife, and yourself!  Too bad!\n");
			nap(5000);
			died(269);
		}
		lprcat("\nThe diagnosis is confirmed as dianthroritis.  He guesses that\n");
		lprintf("your daughter has only %ld mobuls left in this world.  It's up to you,\n", (long) ((TIMELIMIT - gltime + 99) / 100));
		lprintf("%s, to find the only hope for your daughter, the very rare\n", logname);
		lprcat("potion of cure dianthroritis.  It is rumored that only deep in the\n");
		lprcat("depths of the caves can this potion be found.\n\n\n");
		lprcat("\n     ----- press ");
		standout("return");
		lprcat(" to continue, ");
		standout("escape");
		lprcat(" to leave ----- ");
		i = ttgetch();
		while (i != '\33' && i != '\n')
			i = ttgetch();
		if (i == '\33') {
			drawscreen();
			nosignal = 0;	/* enable signals */
			return;
		}
	}
}

/* routine to save program space	 */
void
iopts(void)
{
	lprcat(", or (i) ignore it? ");
}

void
ignore(void)
{
	lprcat("ignore\n");
}
