[net.sources.games] vms extended rogue part 4 of 4

rich@sdcsvax.UUCP (rich) (08/04/86)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	random.c
#	rogue.doc
#	room.c
#	room.h
#	score.c
#	special.c
#	throw.c
#	use.c
#	zap.c
# This archive created: Mon Aug  4 11:42:51 1986
# By:	rich ( lack of)
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'random.c'
then
	echo shar: "will not over-write existing file 'random.c'"
else
cat << \SHAR_EOF > 'random.c'
#include "macros.h"

get_rand(x, y)
int x, y;
{
	int s,r;

	two_sort(x, y);

	r = rand()>>3;
	r = (r % ((y-x)+1)) + x;
	s = (int) r;
	return(s);
}

rand_percent(percentage)
{
	return(get_rand(1, 100) <= percentage);
}
SHAR_EOF
fi
if test -f 'rogue.doc'
then
	echo shar: "will not over-write existing file 'rogue.doc'"
else
cat << \SHAR_EOF > 'rogue.doc'
	VEROGUE (vms extended rogue), is based on the public domain 
versionof rogue, converted to VMS by Rich Stewart , and highly
modified by Rich Stewart and Rich Batch. In the future the game
shall go in the direction of srouge. The game is played much as regular
rogue. There are no hidden passages or rings (yet). Here is a list 
of the meanings of the keys:

	^C		-  quit
	.		-  rest a turn
	i		-  inventory rogue pack
	f		-  fight
	F		-  fight harder
	h		-  move left
	j		-  move down
	k		-  move up
	l		-  move right
	y		-  move up and to the left
	u		-  move up and to the right
	n		-  move down and to the left
	b 		-  move down and to the right
	<shift><direct> -  move until blocked
	<cntrl><direct> -  move until adjacent
	e		-  eat
	q		-  quaff potion
	r		-  read scroll
	m		-  move onto
	d		-  drop
	^P		-  recall last message
	>		-  go down stairs
	<		-  go up stairs
	I		-  inventory a single item
	R		-  redaw screen
	T		-  take off armor
	W		-  put on armor
	P		-  put on armor
	w		-  wield
	c		-  call an item
	z		-  zap a wand
	t		-  throw a weapon
	^Z		-  suspend process {ok, spawn a sub process}
	!		-  spawn a command
	v		-  version
	Q		-  quit
	/		-  identify monster
	?		-  get help on a character




---------------------------------------------------------
SHAR_EOF
fi
if test -f 'room.c'
then
	echo shar: "will not over-write existing file 'room.c'"
else
cat << \SHAR_EOF > 'room.c'
#include curses.h
#include "room.h"
#include "object.h"
#include "move.h"

short current_room;
room rooms[MAXROOMS];
extern short detect_monster;
extern short blind;

light_up_room()
{
	short i, j;

	if (blind) return;
	for (i = rooms[current_room].top_row;
	i <= rooms[current_room].bottom_row; i++) {
		for (j = rooms[current_room].left_col;
		j <= rooms[current_room].right_col; j++) {
			mvaddch(i, j, get_room_char(screen[i][j], i, j));
		}
	}
	mvaddch(rogue.row, rogue.col, rogue.fchar);
}

light_passage(row, col)
{
	short i, j, i_end, j_end;

	if (blind) return;

	i_end = (row < (LINES-2)) ? 1 : 0;
	j_end = (col < (COLS-1)) ? 1 : 0;

	for (i = ((row > MIN_ROW) ? -1 : 0); i <= i_end; i++) {
		for (j = ((col > 0) ? -1 : 0); j <= j_end; j++) {
			if (is_passable(row+i, col+j)) {
				mvaddch(row+i, col+j,
				get_room_char(screen[row+i][col+j],
				row+i, col+j));
			}
		}
	}
}

darken_room(rn)
short rn;
{
	short i, j;

	if (blind) return;

	for (i = rooms[rn].top_row + 1;
	i < rooms[rn].bottom_row; i++) {
		for (j = rooms[rn].left_col + 1;
		j < rooms[rn].right_col; j++) {
			if (!is_object(i, j) &&
			   !(detect_monster && (screen[i][j] & MONSTER))) {
				if (!hiding_xeroc(i, j)) {
					mvaddch(i, j, ' ');
				}
			}
		}
	}
}

get_room_char(mask, row, col)
register short mask;
register short row, col;
{
	if (mask & MONSTER) {
		return(get_monster_char_row_col(row, col));
	}
	if (mask & SCROLL) {
		return('?');
	}
	if (mask & POTION) {
		return('!');
	}
	if (mask & FOOD) {
		return(':');
	}
	if (mask & WAND) {
		return('/');
	}
	if (mask & ARMOR) {
		return(']');
	}
	if (mask & WEAPON) {
		return(')');
	}
	if (mask & GOLD) {
		return('*');
	}
	if (mask & TUNNEL) {
		return('#');
	}
	if (mask & HORWALL) {
		return('-');
	}
	if (mask & VERTWALL) {
		return('|');
	}
	if (mask & AMULET) {
		return(',');
	}
	if (mask & FLOOR) {
		return('.');
	}
	if (mask & DOOR) {
		return('+');
	}
	if (mask & STAIRS) {
		return('%');
	}
	return(' ');
}

get_rand_row_col(row, col, mask)
short *row, *col;
unsigned short mask;
{
	short rn;
AGAIN:
	do {
		*row = get_rand(MIN_ROW, SROWS-2);
		*col = get_rand(0, SCOLS-1);
		rn = get_room_number(*row, *col);
	} while (!(screen[*row][*col] & mask) || (rn == NO_ROOM));
	if (screen[*row][*col] & (~mask)) goto AGAIN;
}

get_rand_room()
{
	short i;

	do {
		i = get_rand(0, MAXROOMS-1);
	} while (!rooms[i].is_room);

	return(i);
}

fill_room_with_objects(rn)
{
	short i;
	object *obj, *get_rand_object();
	short n, N, row, col;

	N = ((rooms[rn].bottom_row - rooms[rn].top_row) - 1) *
	    ((rooms[rn].right_col - rooms[rn].left_col) - 1);
	n =  get_rand(5, 10);
	if (n > N) n = N - 2;

	for (i = 0; i < n; i++) {
		do {
			row = get_rand(rooms[rn].top_row+1,
				       rooms[rn].bottom_row-1);
			col = get_rand(rooms[rn].left_col+1,
				       rooms[rn].right_col-1);
		} while (screen[row][col] != FLOOR);

		obj = get_rand_object();
		put_object_at(obj, row, col);
	}
	return(n);
}

get_room_number(row, col)
{
	short i;

	for (i = 0; i < MAXROOMS; i++) {
		if ((row >= rooms[i].top_row)&&(row <= rooms[i].bottom_row) &&
		    (col >= rooms[i].left_col)&&(col <= rooms[i].right_col)) {
			return(i);
		}
	}
	return(NO_ROOM);
}

shell()
{
/*
	char *getenv(), *rindex();
	char *sh;
	int status;

	move(LINES-1, 0);
	refresh_vms();
	stop_window();
	putchar('\n');

	if (!(sh = getenv("SHELL"))) {
		sh = "/bin/sh";
	}

	if (!fork()) {
		if (setreuid(-1, getuid()) < 0) exit(1);
		execl(sh, rindex(sh, '/') + 1, 0);
		exit(0);
	}
	wait(&status);
	start_window();
	wrefresh(curscr);
*/
}
SHAR_EOF
fi
if test -f 'room.h'
then
	echo shar: "will not over-write existing file 'room.h'"
else
cat << \SHAR_EOF > 'room.h'
#define MAXROOMS 9

#define NO_ROOM -1		/* these two only for doors[] */
#define DEAD_END -2

#define PASSAGE -3		/* current_room value */

#define SCOREFILE "dsk:[richs.games.rogue]SCORE_FILE"

SHAR_EOF
fi
if test -f 'score.c'
then
	echo shar: "will not over-write existing file 'score.c'"
else
cat << \SHAR_EOF > 'score.c'
#include curses.h
#include ctype
#include "object.h"
#include "monster.h"
#include "room.h"
#include file.h
extern char *player_name;
extern char *monster_names[];
extern short has_amulet, max_level;

killed_by(monster, other)
object *monster;
short other;
{
	char buf[80];
	short i;


	if (other != QUIT) {
		rogue.gold = ((rogue.gold * 9) / 10);
	}

	if (other) {
		switch(other) {
		case HYPOTHERMIA:
			strcpy(buf, "died of hypothermia");
			break;
		case STARVATION:
			strcpy(buf, "died of starvation");
			break;
		case QUIT:
			strcpy(buf, "quit");
			break;
		}
	} else {

	for(i=0;i!=MONSTERS;i++)
		if(monster_tab[i].ichar==monster->ichar)
			break;
		strcpy(buf, "Killed by ");
		if (is_vowel(monster_names[i])) {
			strcat(buf, "an ");
		} else {
			strcat(buf, "a ");
		}
		strcat(buf, monster_names[i]);
	}
	strcat(buf, " with ");
	sprintf(buf+strlen(buf), "%d gold", rogue.gold);
	message(buf, 0);
	message("");
	score(monster, other);
}

win()
{
	rogue.armor = 0;	/* disarm and relax */
	rogue.weapon = 0;

	clear();
	mvaddstr(10, 11, "@   @  @@@   @   @      @  @  @   @@@   @   @   @");
	mvaddstr(11, 11, " @ @  @   @  @   @      @  @  @  @   @  @@  @   @");
	mvaddstr(12, 11, "  @   @   @  @   @      @  @  @  @   @  @ @ @   @");
	mvaddstr(13, 11, "  @   @   @  @   @      @  @  @  @   @  @  @@");
	mvaddstr(14, 11, "  @    @@@    @@@        @@ @@    @@@   @   @   @");
	mvaddstr(17, 11, "Congratulations,  you have  been admitted  to  the");
	mvaddstr(18, 11, "Fighter's Guild.   You return home,  sell all your");
	mvaddstr(19, 11, "treasures at great profit and retire into comfort.");
	message("");
	message("");
	id_all();
	sell_pack();
	score((object *) 0, WIN);
}

quit()
{
char getchartt();
	message("really quit?", 1);
	if (getchartt() != 'y') {
		check_message();
		return;
	}
	check_message();

	killed_by(0, QUIT);
}

score(monster, other)
object *monster;
{
	int fd;


	while (access(SCOREFILE, 2) || access(SCOREFILE, 4)) {
		umask(0);
		if ((fd = creat(SCOREFILE, 0666)) < 0) {
			message("cannot find/read/write score file");
			message(SCOREFILE);
			message("I hope you didn't have a good game");
			ttclose();
		} else {
			close(fd);
		}
	}
	put_scores(monster, other);
}

put_scores(monster, other)
object *monster;
{
	short i, j, n, rank = 10, x, dont_insert = 0;
	char scores[10][82];
	char getchartt();
	int fd, s;

	fd = open(SCOREFILE, O_RDWR, 0);

	for (i = 0; i < 10; i++) {
L:		if (((n = read(fd, &scores[i][0], 80)) < 80) && (n != 0)) {
			message("error in score file format");
			message("");
        		printf("space to continue, n=%d",n);
			getchartt();
			clean_up("sorry, score file is out of order");
		} else if (n == 0) {
			break;
		}
		if (!ncmp(scores[i]+16, player_name)) {
			x = 7;
			while (scores[i][x] == ' ') x++;
			s = get_number(scores[i] + x);
			if (s <= rogue.gold) {
				goto L;
			} else {
				dont_insert = 1;
			}
		}
	}
	if (dont_insert) goto DI;

	for (j = 0; j < i; j++) {
		if (rank > 9) {

			x = 7;
			while (scores[j][x] == ' ') x++;
			s = get_number(scores[j] + x);

			if (s <= rogue.gold) {
				rank = j;
			}
		}
	}
	if (i == 0) {
		rank = 0;
	} else if ((i < 10) && (rank > 9)) {
		rank = i;
	}
	if (rank <= 9) {
		insert_score(scores, rank, i, monster, other);

		if (i < 10) {
			i++;
		}
	}
	lseek(fd, 0, 0);
DI:
	clear();
	mvaddstr(3, 22, "Rogue Hall of Fame");
	mvaddstr(8, 0, "Rank\tScore\tName");


	for (j = 0; j < i; j++) {
		if (j == rank) {
			standout();
		}
		if (j == 9) {
			scores[j][0] = '1';
			scores[j][1] = '0';
		} else {
			scores[j][0] = ' ';
			scores[j][1] = j + '1';
		}
		mvaddstr(j+10, 0, scores[j]);
		if (rank < 10) {
			write(fd, scores[j], 80);
		}
		if (j == rank) {
			standend();
		}
	}
	close(fd);
        mvaddstr(21,20,"space to continue");
	refresh_vms();
	getchartt();
	clean_up("");
}

insert_score(scores, rank, n, monster, other)
char scores[][82];
short rank, n;
object *monster;
{
	short i, k;
	char buf[82];

	for (i = (n - 1); i >= rank; i--) {
		if (i < 9) {
			strcpy(scores[i+1], scores[i]);
		}
	}
	sprintf(buf, "%2d      %5d   %s: ", rank+1, rogue.gold, player_name);

	if (other) {
		switch(other) {
		case HYPOTHERMIA:
			strcat(buf, "died of hypothermia");
			break;
		case STARVATION:
			strcat(buf, "died of starvation");
			break;
		case QUIT:
			strcat(buf, "quit");
			break;
		case WIN:
			strcat(buf, "a total winner");
			break;
		}
	} else {
	for(i=0;i!=MONSTERS;i++)
		if(monster_tab[i].ichar==monster->ichar)
			break;
		strcat(buf, "killed by ");
		if (is_vowel(monster_names[i])) {
			strcat(buf, "an ");
		} else {
			strcat(buf, "a ");
		}
		strcat(buf, monster_names[i]);
	}
	sprintf(buf+strlen(buf), " on level %d ",  max_level);
	if ((other != WIN) && has_amulet) {
		strcat(buf, "with amulet");
	}
	for (i = strlen(buf); i < 79; i++) {
		buf[i] = ' ';
	}
	buf[79] = 0;
	strcpy(scores[rank], buf);
}

is_vowel(ch)
short ch;
{
	return( (ch == 'a') ||
		(ch == 'e') ||
		(ch == 'i') ||
		(ch == 'o') ||
		(ch == 'u') );
}

sell_pack()
{
	object *obj;
	short row = 2, val;
	char buf[80];

	obj = rogue.pack.next_object;

	clear();

	while (obj) {
		mvaddstr(1, 0, "Value      Item");
		if (obj->what_is == FOOD) {
			goto NEXT;
		}
		obj->identified = 1;
		val = get_value(obj);
		rogue.gold += val;

		if (row < SROWS) {
			sprintf(buf, "%5d      ", val);
			get_description(obj, buf+11);
			mvaddstr(row++, 0, buf);
		}
NEXT:		obj = obj->next_object;
	}
	refresh_vms();
	message("");
}

get_value(obj)
object *obj;
{
	short wc;
	int val;

	wc = obj->which_kind;

	switch(obj->what_is) {
	case WEAPON:
		val = id_weapons[wc].value;
		if ((wc == ARROW) || (wc == SHURIKEN)) {
			val *= obj->quantity;
		}
		val += (obj->damage_enchantment * 85);
		val += (obj->to_hit_enchantment * 85);
		break;
	case ARMOR:
		val = id_armors[wc].value;
		val += (obj->damage_enchantment * 75);
		if (obj->is_protected) {
			val += 200;
		}
		break;
	case WAND:
		val = id_wands[wc].value * obj->class;
		break;
	case SCROLL:
		val = id_scrolls[wc].value * obj->quantity;
		break;
	case POTION:
		val = id_potions[wc].value * obj->quantity;
		break;
	case AMULET:
		val = 5000;
		break;
	}
	if (val <= 0) {
		val = 10;
	}
	return(val);
}

id_all()
{
	short i;

	for (i = 0; i < SCROLLS; i++) {
		id_scrolls[i].id_status = IDENTIFIED;
	}
	for (i = 0; i < WEAPONS; i++) {
		id_weapons[i].id_status = IDENTIFIED;
	}
	for (i = 0; i < ARMORS; i++) {
		id_armors[i].id_status = IDENTIFIED;
	}
	for (i = 0; i < WANDS; i++) {
		id_wands[i].id_status = IDENTIFIED;
	}
	for (i = 0; i < POTIONS; i++) {
		id_potions[i].id_status = IDENTIFIED;
	}
}

ncmp(s1, s2)
char *s1, *s2;
{
	short i = 0;
	int r;

	while(s1[i] != ':') i++;
	s1[i] = 0;
	r = strcmp(s1, s2);
	s1[i] = ':';
	return(r);
}
SHAR_EOF
fi
if test -f 'special.c'
then
	echo shar: "will not over-write existing file 'special.c'"
else
cat << \SHAR_EOF > 'special.c'
#include curses.h
#include "object.h"
#include "move.h"
#include "monster.h"

short being_held;

extern short current_level, max_level, has_amulet, detect_monster, halluc;
extern int level_points[];

special_hit(monster)
object *monster;
{
   if ((current_level >= monster->is_protected) &&
       (current_level <= monster->is_cursed))
   {
	switch(monster->ichar) {
	case 'A':
		if ((current_level >= AQUATAR1) &&
		    (current_level <= AQUATAR2)) rust(monster);
		break;
	case 'F':
		if ((current_level >= FLYTRAP1) &&
		    (current_level <= FLYTRAP2)) being_held = 1;
		break;
	case 'I':
		if ((current_level >= ICEMSTR1) &&
		    (current_level <= ICEMSTR2)) freeze(monster);
		break;
	case 'L':
		if ((current_level >= LEPCHAN1) &&
		    (current_level <= LEPCHAN2)) steal_gold(monster);
		break;
	case 'N':
		if ((current_level >= NYMPH1) &&
		    (current_level <= NYMPH2)) steal_item(monster);
		break;
	case 'R':
		if ((current_level >= RSNAKE1) &&
		    (current_level <= RSNAKE2)) sting(monster);
		break;
	case 'V':
		if ((current_level >= VAMPIRE1) &&
		    (current_level <= VAMPIRE2)) drain_life();
		break;
	case 'W':
		if ((current_level >= WRAITH1) &&
		    (current_level <= WRAITH2)) drain_level();
		break;
	case 's':
		if ((current_level >= SPIDER1) &&
		    (current_level <= SPIDER2)) acid_trip(monster);
		break;
	}
   }
}

rust(monster)
object *monster;
{
	if (!rogue.armor || (get_armor_class(rogue.armor) <= 1) ||
	    (rogue.armor->which_kind == LEATHER)) {
		return;
	}
	if (rogue.armor->is_protected) {
		if (!monster->identified) {
			message("the rust vanishes instantly", 0);
			monster->identified = 1;
		}
	} else {
		rogue.armor->damage_enchantment--;
		message("your armor weakens", 0);
		print_stats();
	}
}
acid(monster)
object *monster;
{
	message("the dragon spits acid upon you",0);
	if (rogue.armor->is_protected && (!(rand()%12)) ) {
		if (!monster->identified) {
			message("the acid has no effect",0);
			monster->identified = 1;
		}
	} else {
		rogue.armor->damage_enchantment--;
		message("your armor weakens", 0);
		print_stats();
	}
}

freeze(monster)
object *monster;
{
	short freeze_percent = 99;
	short i, n;

	if (rand_percent(12)) return;

	freeze_percent -= (rogue.strength_current+(rogue.strength_current/2));
	freeze_percent -= rogue.exp * 4;
	freeze_percent -= (rogue.armor->damage_enchantment * 5);
	freeze_percent -= (rogue.hp_max / 3);

	if (freeze_percent > 10) {
		monster->identified = 1;
		message("you are frozen", 1);

		n = get_rand(5, 9);
		for (i = 0; i < n; i++) {
			move_monsters();
		}
		if (rand_percent(freeze_percent)) {
			for (i = 0; i < 50; i++) {
				move_monsters();
			}
			killed_by((object *)0, HYPOTHERMIA);
		}
		message("you can move again", 1);
		monster->identified = 0;
	}
}

steal_gold(monster)
object *monster;
{
	int amount;

	if (rand_percent(15)) return;

	if (rogue.gold > 50) {
		amount = rogue.gold > 1000 ? get_rand(8, 15) : get_rand(2, 5);
		amount = rogue.gold / amount;
	} else {
		amount = rogue.gold/2;
	}
	amount += (get_rand(0, 2) - 1) * (rogue.exp + current_level);
	if ((amount <= 0) && (rogue.gold > 0)) {
		amount = rogue.gold;
	}

	if (amount > 0) {
		rogue.gold -= amount;
		message("your purse feels lighter", 0);
		print_stats();
	}
	disappear(monster);
}

steal_item(monster)
object *monster;
{
	object *obj;
	short i, n, has_something = 0;
	char description[80];

	if (rand_percent(15)) return;

	obj = rogue.pack.next_object;

	if (!obj) {
		goto DSPR;
	}
	while (obj) {
		if ((obj != rogue.armor) && (obj != rogue.weapon)) {
			has_something = 1;
			break;
		}
		obj = obj->next_object;
	}
	if (!has_something) goto DSPR;

	n = get_rand(0, MAX_PACK_COUNT);
	obj = rogue.pack.next_object;

	for (i = 0; i <= n; i++) {
		obj = obj->next_object;
		while (!obj || (obj == rogue.weapon) || (obj == rogue.armor)) {
			if (!obj) {
				obj = rogue.pack.next_object;
			} else {
				obj = obj->next_object;
			}
		}
	}
	strcpy(description, "she stole ");
	get_description(obj, description+10);
	message(description, 0);

	if (obj->what_is == AMULET) {
		has_amulet = 0;
	}
	vanish(obj, 0);
DSPR:	disappear(monster);
}

disappear(monster)
object *monster;
{
	short row, col;

	row = monster->row;
	col = monster->col;

	remove_mask(row, col, MONSTER);
	if (can_see(row, col)) {
		mvaddch(row, col, get_room_char(screen[row][col], row, col));
	}
	remove_from_pack(monster, &level_monsters);
	free(monster);
}

cough_up(monster)
object *monster;
{
	object *obj, *get_an_object(),*get_rand_object();
	short row, col, i, j, n;

	if (current_level < max_level) {
		return;
	}

	switch(monster->ichar) {
	case 'L':
		obj = get_an_object();
		obj->what_is = GOLD;
		obj->quantity = get_rand(9, 599);
		break;
	default:
		if (rand_percent(monster->which_kind)) {
			obj = get_rand_object();
			break;
		}
		return;
	}
	row = monster->row;
	col = monster->col;

	for (n = 0; n <= 5; n++) {
		for (i = -n; i <= n; i++) {
			if (try_to_cough(row+n, col+i, obj)) {
				return;
			}
			if (try_to_cough(row-n, col+i, obj)) {
				return;
			}
		}
		for (i = -n; i <= n; i++) {
			if (try_to_cough(row+i, col-n, obj)) {
				return;
			}
			if (try_to_cough(row+i, col+n, obj)) {
				return;
			}
		}
	}
	free(obj);
}

try_to_cough(row, col, obj)
short row, col;
object *obj;
{
	if ((row<MIN_ROW)||(row>(LINES-2))||(col<0)||(col>(COLS-1))) {
		return(0);
	}
	if ((!(screen[row][col] & IS_OBJECT)) &&
	    (screen[row][col] & (TUNNEL|FLOOR|DOOR)) &&
	    !(screen[row][col] & MONSTER)) {
		put_object_at(obj, row, col);
		mvaddch(row, col, get_room_char(screen[row][col], row, col));
		refresh_vms();
		return(1);
	}
	return(0);
}

orc_gold(monster)
object *monster;
{
	short i, j, row, col, rn, s;

	if (monster->identified) {
		return(0);
	}
	if ((rn = get_room_number(monster->row, monster->col)) < 0) {
		return(0);
	}
	for (i = rooms[rn].top_row+1;
	i < rooms[rn].bottom_row; i++) {
		for (j = rooms[rn].left_col+1;
		j < rooms[rn].right_col; j++) {
			if ((screen[i][j] & GOLD) &&
			   !(screen[i][j] & MONSTER)) {
				monster->m_flags |= CAN_GO;
				s = monster_can_go(monster, i, j);
				monster->m_flags &= (~CAN_GO);
				if (s) {
					move_monster_to(monster, i, j);
					monster->m_flags |= IS_ASLEEP;
					monster->m_flags &= (~WAKENS);
					monster->identified = 1;
					return(1);
				}
				monster->identified = 1;
				monster->m_flags |= CAN_GO;
				mv_monster(monster, i, j);
				monster->m_flags &= (~CAN_GO);
				monster->identified = 0;
				return(1);
			}
		}
	}
	return(0);
}

check_orc(monster)
object *monster;
{
	if (monster->ichar == 'O') {
		monster->identified = 1;
	}
}

check_xeroc(monster)
object *monster;
{
	char *monster_name();
	char msg[80];

	if ((monster->ichar == 'X') && monster->identified) {
		wake_up(monster);
		monster->identified = 0;
		mvaddch(monster->row, monster->col,
		get_room_char(screen[monster->row][monster->col],
		monster->row, monster->col));
		check_message();
		sprintf(msg, "wait, that's a %s!", monster_name(monster));
		message(msg, 1);
		return(1);
	}
	return(0);
}

hiding_xeroc(row, col)
register short row, col;
{
	object *object_at(), *monster;

	if ((current_level < XEROC1) || (current_level > XEROC2) ||
	    !(screen[row][col] & MONSTER)) {
		return(0);
	}
	monster = object_at(&level_monsters, row, col);

	if ((monster->ichar == 'X') && monster->identified) {
		return(1);
	}
	return(0);
}

sting(monster)
object *monster;
{
	short ac, sting_chance = 35;
	char msg[80], *monster_name();

	if (rogue.strength_current < 5) return;

	ac = get_armor_class(rogue.armor);

	sting_chance += (6 * (6 - ac));

	if (rogue.exp > 8) {
		sting_chance -= (6 * (rogue.exp - 8));
	}

	if (sting_chance > 100) {
		sting_chance = 100;
	} else if (sting_chance <= 0) {
		sting_chance = 1;
	}
	if (rand_percent(sting_chance)) {
		sprintf(msg, "the %s's bite has weakened you",
		monster_name(monster));
		message(msg, 0);
		rogue.strength_current--;
		print_stats();
	}
}

drain_level()
{
	short hp;
	if (!rand_percent(20) || (rogue.exp <= 7)) {
		return;
	}
	rogue.exp_points = level_points[rogue.exp-2] - get_rand(10, 50);
	rogue.exp -= 2;
	add_exp(1);
	hp = get_rand(3,10);
	rogue.hp_max += hp;
	if (rogue.hp_current > hp + 1) rogue.hp_current -= hp;
}

drain_life()
{
	if (!rand_percent(25) || (rogue.hp_max<=30) || (rogue.hp_current<10)) {
		return;
	}
	message("you feel weaker", 0);
	rogue.hp_max--;
	rogue.hp_current--;
	if (rand_percent(50)) {
		if (rogue.strength_current >= 5) {
			rogue.strength_current--;
			if (rand_percent(50)) {
				rogue.strength_max--;
			}
		}
	}
	print_stats();
}

m_confuse(monster)
object *monster;
{
	char msg[80];
	char *monster_name();

	if (monster->identified) {
		return(0);
	}
	if (!can_see(monster->row, monster->col)) {
		return(0);
	}
	if (rand_percent(45)) {
		monster->identified = 1;
		return(0);
	}
	if (rand_percent(65)) {
		monster->identified = 1;
		sprintf(msg, "the gaze of the %s has confused you",
		monster_name(monster));
		message(msg, 1);
		confuse();
		return(1);
	}
	return(0);
}

paralyze(monster)
object *monster;
{
   short i;
   char msg[80];
   char *monster_name();

   if (monster->identified) return(0);
   if (!can_see(monster->row,monster->col)) return(0);
   if (rand_percent(50))
   {
	monster->identified = 1;
	return(0);
   }
   if (rand_percent(50))
   {
	monster->identified = 1;
	sprintf(msg,"the gaze of the %s has you paralyzed with fear",
		monster_name(monster));
	message(msg,1);
	i = get_rand(2,6);
	while (i--)
	{
	   move_monsters();
	}
	sleep(1);
	message("you feel sanity return",0);
	return (1);
   }
}


acid_trip(monster)
object *monster;
{
   short ac, sting_chance = 40;
   char msg[80], *monster_name();

   if (monster->identified) return (0);

   ac = get_armor_class(rogue.armor);

   sting_chance += (6 * (6 - ac));

   if (rogue.exp > 8) {
	sting_chance -= (6 * (rogue.exp - 8));
   }

   if (sting_chance > 100) {
	sting_chance = 100;
   } else if (sting_chance <= 0) {
	sting_chance = 1;
   }
   if (rand_percent(sting_chance))
   {
	monster->identified = 1;
	sprintf(msg,"the %s's bite leaves you feeling SO funky",
					  monster_name(monster)); 
	message(msg, 1);
	halluc += get_rand(100,300);
	return (1);
   }
}


breath(monster,oder)
object *monster;
int oder;
{
	short row, col;
	char breath_char;

	if (!can_see(monster->row, monster->col)) {
		return(0);
	}
	if (rand_percent(50)) {
		return(0);
	}
	if (!rogue_is_around(monster->row, monster->col)) {

		row = monster->row; col = monster->col;
		get_closer(&row, &col, rogue.row, rogue.col);
		standout();
	
		switch(oder){

		case B_FLAME : breath_char='*';
				break;
		case B_ACID  : breath_char='>';
				break;
		case B_SLEEP : breath_char='<';
				break;
		case B_CONFUSION : breath_char='"';
				break;
		case B_COLD  : breath_char='^';
				break;
		case B_LIGHTNING : breath_char='~';
				break;
		}

		do {
			mvaddch(row, col, breath_char);
			refresh_vms();
			get_closer(&row, &col, rogue.row, rogue.col);
		} while ((row != rogue.row) || (col != rogue.col));
		standend();
		row = monster->row; col = monster->col;
		get_closer(&row, &col, rogue.row, rogue.col);
		do {
			mvaddch(row, col, get_room_char(screen[row][col],
				row, col));
			refresh_vms();
			get_closer(&row, &col, rogue.row, rogue.col);
		} while ((row != rogue.row) || (col != rogue.col));
	}
		switch(oder){

		case B_FLAME : 
			monster_hit(monster, "flame");
		break;
		case B_ACID  : 
			monster_hit(monster, "acid");
		break;
		case B_SLEEP : 
			monster_hit(monster, "sleeping gas");
			if((rand()%5)<2) sleep_scroll();
		break;
		case B_CONFUSION :
			monster_hit(monster, "nerve gas");
			if((rand()%5)<3) confuse();
		break;
		case B_COLD  : 
			monster_hit(monster, "ice");
			if((rand()%5)>3) freeze(monster);
		break;
		case B_LIGHTNING :
			monster_hit(monster, "lightning");
		break;
		}
	return(1);
}

get_closer(row, col, trow, tcol)
short *row, *col;
short trow, tcol;
{
	if (*row < trow) {
		(*row)++;
	} else if (*row > trow) {
		(*row)--;
	}
	if (*col < tcol) {
		(*col)++;
	} else if (*col > tcol) {
		(*col)--;
	}
}
SHAR_EOF
fi
if test -f 'throw.c'
then
	echo shar: "will not over-write existing file 'throw.c'"
else
cat << \SHAR_EOF > 'throw.c'
#include curses.h
#include "object.h"
#include "move.h"
#include "monster.h"

extern short current_room;
extern char *CURSE_MESSAGE;
extern char hit_message[];

throw()
{
	char getchartt();
	short wch;
	short first_miss = 1, f = 1;
	object *weapon, *get_letter_object();
	short dir, row, col;
	object *monster, *get_thrown_at_monster();

	while (!is_direction(dir = getchartt())) {
		putchar(7);
		fflush(stdout);
		if (first_miss) {
			message("direction? ", 0);
			first_miss = 0;
		}
	}
	if (dir == CANCEL) {
		check_message();
		return;
	}
	if ((wch = get_pack_letter("throw what?", WEAPON)) == CANCEL) {
		check_message();
		return;
	}
	check_message();

	if (!(weapon = get_letter_object(wch))) {
		message("no such item.", 0);
		return;
	}
	if (weapon->what_is != WEAPON) {
		wch = get_rand(0, 2);

		switch(wch) {
		case 0:
			message("if you don't want it, drop it!", 0);
			break;
		case 1:
			message("throwing that would do noone any good", 0);
			break;
		case 2:
			message("why would you want to throw that?", 0);
			break;
		}
		return;
	}
	if ((weapon == rogue.weapon) && (weapon->is_cursed)) {
		message(CURSE_MESSAGE, 0);
		return;
	}
	row = rogue.row; col = rogue.col;
	monster = get_thrown_at_monster(dir, &row, &col);
	mvaddch(rogue.row, rogue.col, rogue.fchar);
	refresh_vms();

	if (can_see(row, col) && ((row != rogue.row) || (col != rogue.col))) {
		mvaddch(row, col, get_room_char(screen[row][col], row, col));
	}
	if (monster) {
		wake_up(monster);
		check_orc(monster);

		if (!throw_at_monster(monster, weapon)) {
			f = flop_weapon(weapon, row, col);
		}
	} else {
		f = flop_weapon(weapon, row, col);
	}
	vanish(weapon, 1);
}

throw_at_monster(monster, weapon)
object *monster, *weapon;
{
	short damage, hit_chance;
	char *name_of();
	short t;

	hit_chance = get_hit_chance(weapon);
	t = weapon->quantity;
	weapon->quantity = 1;
	sprintf(hit_message, "the %s", name_of(weapon));
	weapon->quantity = t;

	if (!rand_percent(hit_chance)) {
		strcat(hit_message, "misses  ");
		return(0);
	}
	strcat(hit_message, "hit  ");
	damage = get_weapon_damage(weapon);
	if (((weapon->which_kind == ARROW) && (rogue.weapon &&
	   ((rogue.weapon->which_kind == SHORT_BOW)||
	    (rogue.weapon->which_kind==LONG_BOW)))) ||
	   ((weapon->which_kind == SPEAR) && (rogue.weapon == weapon))||
	   ((weapon->which_kind == JAVELIN) && (rogue.weapon == weapon))||
	   ((weapon->which_kind == HAMMER) && (rogue.weapon == weapon)) ||
	   ((weapon->which_kind == SHURIKEN) && (rogue.weapon == weapon))) {
		damage += get_weapon_damage(rogue.weapon);
		damage = ((damage * 2) / 3);
	}
	monster_damage(monster, damage);
	return(1);
}

object *get_thrown_at_monster(dir, row, col)
short dir;
short *row, *col;
{
	object *object_at();
	short orow, ocol;
	short i;

	orow = *row; ocol = *col;

	for (i = 0; i < 24; i++) {
		get_dir_rc(dir, row, col);
		if ((screen[*row][*col] == BLANK) ||
		     (screen[*row][*col] & (HORWALL | VERTWALL))) {
			*row = orow;
			*col = ocol;
			return(0);
		}
		if ((i != 0) && can_see(orow, ocol)) {
			mvaddch(orow, ocol, get_room_char(screen[orow][ocol],
				orow, ocol));
		}
		if (can_see(*row, *col)) {
			if (!(screen[*row][*col] & MONSTER)) {
				mvaddch(*row, *col, ')');
			}
			refresh_vms();
		}
		orow = *row; ocol = *col;
		if (screen[*row][*col] & MONSTER) {
			if (!hiding_xeroc(*row, *col)) {
				return(object_at(&level_monsters, *row, *col));
			}
		}
		if (screen[*row][*col] & TUNNEL) {
			i += 2;
		}
	}
	return(0);
}

flop_weapon(weapon, row, col)
object *weapon;
short row, col;
{
	object *new_weapon, *get_an_object();
	short i, j, r, c, found = 0, inc1, inc2;
	char msg[80];
	char *name_of();
	inc1 = get_rand(0, 1) ? 1 : -1;
	inc2 = get_rand(0, 1) ? 1 : -1;

	r = row;
	c = col;

	if ((screen[r][c] & ~(FLOOR | TUNNEL | DOOR)) ||
	    ((row == rogue.row) && (col == rogue.col))) {
		for (i = inc1; i != (2 * -inc1); i -= inc1) {
			for (j = inc2; j != (2 * -inc2); j -= inc2) {
				r = row + i;
				c = col + j;

				if ((r > (LINES-2)) || (r < MIN_ROW) ||
				    (c > (COLS-1)) || (c < 0)) {
					continue;
				}
				if (!screen[r][c]) continue;
				if ((screen[r][c] & ~(FLOOR|TUNNEL|DOOR))
				|| ((r == rogue.row) && (c == rogue.col))) {
					continue;
				}
				found = 1;
				goto FOUND;
			}
		}
	} else {
		found = 1;
	}
FOUND:  if (found) {
		new_weapon = get_an_object();
		*new_weapon = *weapon;
		new_weapon->quantity = 1;
		new_weapon->row = r;
		new_weapon->col = c;
		add_mask(r, c, WEAPON);
		add_to_pack(new_weapon, &level_objects, 0);
		if (can_see(r, c)) {
			mvaddch(r, c, get_room_char(screen[r][c], r, c));
		}
	} else {
		short t;

		t = weapon->quantity;
		weapon->quantity = 1;
		sprintf(msg, "the %svanishes as it hits the ground",
		name_of(weapon));
		weapon->quantity = t;
		message(msg, 0);
	}
	return(found);
}
SHAR_EOF
fi
if test -f 'use.c'
then
	echo shar: "will not over-write existing file 'use.c'"
else
cat << \SHAR_EOF > 'use.c'
#include curses.h
#include "object.h"
#include "move.h"
#include "monster.h"
#include "room.h"
#include ctype.h

short halluc = 0;
short blind = 0;
short confused = 0;
short detect_monster = 0;

extern short being_held;

char *strange_feeling = "you have a strange feeling for a moment, then it passes";

extern char *hunger_str;
extern short current_room;
extern int level_points[];

quaff()
{
	short ch, i;
	object *obj, *get_letter_object();
	char msg[SCOLS];

	ch = get_pack_letter("quaff what? ", POTION);

	if (ch == CANCEL) {
		return;
	}
	if (!(obj = get_letter_object(ch))) {
		message("no such item.", 0);
		return;
	}
	if (obj->what_is != POTION) {
		message("you can't drink that", 0);
		return;
	}
	switch(obj->which_kind) {
		case INCREASE_STRENGTH:
			message("you feel stronger now, what bulging muscles!",
			0);
			rogue.strength_current++;
			if (rogue.strength_current > rogue.strength_max) {
				rogue.strength_max = rogue.strength_current;
			}
			break;
		case RESTORE_STRENGTH:
			rogue.strength_current = rogue.strength_max;
			message("this tastes great, you feel warm all over", 0);
			break;
		case HEALING:
			message("you begin to feel better", 0);
			potion_heal(0);
			break;
		case EXTRA_HEALING:
			message("you begin to feel much better", 0);
			potion_heal(1);
			break;
		case POISON:
			rogue.strength_current -= get_rand(1, 3);
			if (rogue.strength_current < 0) {
				rogue.strength_current = 0;
			}
			message("you feel very sick now", 0);
			if (halluc) {
				unhallucinate();
			}
			break;
		case RAISE_LEVEL:
			if (rogue.exp_points < MAX_EP)
			{
			   add_exp((level_points[rogue.exp-1]-rogue.exp_points)+1);
			}
			else
			{
			   message(strange_feeling, 0);
			}
			break;
		case BLINDNESS:
			go_blind();
			break;
		case HALLUCINATION:
			message("oh wow, everything seems so cosmic", 0);
			halluc += get_rand(500, 800);
			break;
		case DETECT_MONSTER:
			if (level_monsters.next_object) {
				show_monsters();
			} else {
				message(strange_feeling, 0);
			}
			detect_monster = 1;
			break;
		case DETECT_OBJECTS:
			if (level_objects.next_object) {
				if (!blind) {
					show_objects();
				}
			} else {
				message(strange_feeling, 0);
			}
			break;
		case CONFUSION:
			message((halluc ? "what a trippy feeling" :
			"you feel confused"), 0);
			confuse();
			break;
	}
	print_stats();
	if (id_potions[obj->which_kind].id_status != CALLED) {
		id_potions[obj->which_kind].id_status = IDENTIFIED;
	}
	vanish(obj, 1);
}

read_scroll()
{
	short ch;
	object *obj, *get_letter_object();
	char msg[SCOLS];
	char *get_ench_color();

	ch = get_pack_letter("read what? ", SCROLL);

	if (ch == CANCEL) {
		return;
	}
	if (!(obj = get_letter_object(ch))) {
		message("no such item.", 0);
		return;
	}
	if (obj->what_is != SCROLL) {
		message("you can't read that", 0);
		return;
	}
	switch(obj->which_kind) {
		case SCARE_MONSTER:
			message("you hear a maniacal laughter in the distance",
			0);
			break;
		case HOLD_MONSTER:
			hold_monster();
			break;
		case ENCHANT_WEAPON:
			if (rogue.weapon) {
				sprintf(msg, "your %sglows %sfor a moment",
				id_weapons[rogue.weapon->which_kind].title,
				get_ench_color());
				message(msg, 0);
				if (get_rand(0, 1) == 1) {
					rogue.weapon->to_hit_enchantment++;
				} else {
					rogue.weapon->damage_enchantment++;
				}
				rogue.weapon->is_cursed = 0;
			} else {
				message("your hands tingle", 0);
			}
			break;
		case ENCHANT_ARMOR:
			if (rogue.armor) {
				sprintf(msg, "your armor glows %sfor a moment",
				get_ench_color());
				message(msg, 0);
				rogue.armor->damage_enchantment++;
				rogue.armor->is_cursed = 0;
				print_stats();
			} else {
				message("your skin crawls", 0);
			}
			break;
		case IDENTIFY:
			message("this is a scroll of identify", 0);
			message("what would you like to identify?", 0);
			obj->identified = 1;
			id_scrolls[obj->which_kind].id_status = IDENTIFIED;
			identify();
			break;
		case TELEPORT:
			teleport();
			break;
		case SLEEP:
			sleep_scroll();
			break;
		case PROTECT_ARMOR:
			if (rogue.armor) {
				message( "your armor is covered by a shimmering gold shield", 0);
				rogue.armor->is_protected = 1;
			} else {
				message("a faint glow dissapates into the air about you",
				0);
			}
			break;
		case REMOVE_CURSE:
			message(
			"you feel as though someone is watching over you", 0);
			if (rogue.armor) {
				rogue.armor->is_cursed = 0;
			}
			if (rogue.weapon) {
				rogue.weapon->is_cursed = 0;
			}
			break;
		case CREATE_MONSTER:
			create_monster();
			break;
		case AGGRAVATE_MONSTER:
			aggravate();
			break;
	}
	if (id_scrolls[obj->which_kind].id_status != CALLED) {
		id_scrolls[obj->which_kind].id_status = IDENTIFIED;
	}
	vanish(obj, 1);
}

vanish(obj, rm)
object *obj;
short rm;
{
	if (obj->quantity > 1) {
		obj->quantity--;
	} else {
		remove_from_pack(obj, &rogue.pack);
		make_avail_ichar(obj->ichar);
		free(obj);
	}
	if (rm) {
		register_move();
	}
}

potion_heal(extra)
{
	float ratio;
	short add;

	ratio = ((float)rogue.hp_current) / rogue.hp_max;

	if (ratio >= 0.90) {
		rogue.hp_max += (extra + 1);
		rogue.hp_current = rogue.hp_max;
	} else {
		if (ratio < 30.00) {
			ratio = 30.00;
		}
		if (extra) {
			ratio += ratio;
		}
		add = (short)(ratio*((float)rogue.hp_max-rogue.hp_current));
		rogue.hp_current += add;
		if (rogue.hp_current > rogue.hp_max) {
			rogue.hp_current = rogue.hp_max;
		}
	}
	if (blind) {
		unblind();
	}
	if (confused && extra) {
		unconfuse();
	}
	if (confused) {
		confused = ((confused - 9) / 2);
		if (confused <= 0) {
			unconfuse();
		}
	}
	if (halluc && extra) {
		unhallucinate();
	} else if (halluc) {
		halluc = (halluc/2) + 1;
	}
}

identify()
{
	short ch;
	object *obj, *get_letter_object();
	struct identify *id_table, *get_id_table();
	char description[SCOLS];
AGAIN:
	ch = get_pack_letter("identify what? ", IS_OBJECT);

	if (ch == CANCEL) {
		return;
	}
	if (!(obj = get_letter_object(ch))) {
		message("no such item, try again", 0);
		message("", 0);
		check_message();
		goto AGAIN;
	}
	obj->identified = 1;
	if (obj->what_is & (SCROLL | POTION | WEAPON | ARMOR | WAND)) {
		id_table = get_id_table(obj);
		id_table[obj->which_kind].id_status = IDENTIFIED;
	}
	get_description(obj, description);
	message(description, 0);
}

eat()
{
	short ch;
	short moves;
	object *obj, *get_letter_object();
	char msg[SCOLS];

	ch = get_pack_letter("eat what? ", FOOD);

	if (ch == CANCEL) {
		return;
	}
	if (!(obj = get_letter_object(ch))) {
		message("no such item.", 0);
		return;
	}
	if (obj->what_is != FOOD) {
		message("you can't eat that", 0);
		return;
	}
	moves = get_rand(800, 1000);

	if (moves >= 900) {
		message("yum, that tasted good", 0);
	} else {
		message("yuk, that food tasted awful", 0);
		add_exp(3);
	}
	rogue.moves_left /= 2;
	rogue.moves_left += moves;
	hunger_str = "";
	print_stats();

	vanish(obj, 1);
}

hold_monster()
{
	short i, j;
	short mcount = 0;
	object *monster, *object_at();
	short row, col;

	for (i = -2; i <= 2; i++) {
		for (j = -2; j <= 2; j++) {
			row = rogue.row + i;
			col = rogue.col + j;
			if ((row < MIN_ROW) || (row > (LINES-2)) || (col < 0) ||
			     (col > (COLS-1))) {
				continue;
			}
			if (screen[row][col] & MONSTER) {
				monster = object_at(&level_monsters, row, col);
				monster->m_flags |= IS_ASLEEP;
				monster->m_flags &= (~WAKENS);
				mcount++;
			}
		}
	}
	if (mcount == 0) {
		message("a deathly silence hangs in the air about you", 0);
	} else if (mcount == 1) {
		message("the monster freezes", 0);
	} else {
		message("the monsters around you freeze", 0);
	}
}

teleport()
{
	if (current_room >= 0) {
		darken_room(current_room);
	} else {
		mvaddch(rogue.row, rogue.col,
		get_room_char(screen[rogue.row][rogue.col], rogue.row,
		rogue.col));
	}
	put_player();
	light_up_room();
	being_held = 0;
}

hallucinate()
{
	object *obj;
	short ch;

	if (blind) return;

	obj = level_objects.next_object;

	while (obj) {
		move(obj->row, obj->col);
		ch = inch();
		if ((((ch < 'A') || (ch > 'Z'))&&((ch<'a') ||(ch>'z')))&&
		    ((obj->row != rogue.row) || (obj->col != rogue.col)))
		if ((ch != ' ')&&(ch != '.')&&(ch != '#')&&(ch != '+')) {
			mvaddch(obj->row, obj->col, get_rand_obj_char());
		}
		obj = obj->next_object;
	}
	obj = level_monsters.next_object;

	while (obj) {
		move(obj->row, obj->col);
		ch = inch();
/*		if ((ch >= 'A') && (ch <= 'Z')) { */
		if(isupper(ch)||islower(ch)){
			if(rand()%2)
				mvaddch(obj->row,obj->col,get_rand('A','Z'));
			else
				mvaddch(obj->row,obj->col,get_rand('a','z'));
		}
		obj = obj->next_object;
	}
}

unhallucinate()
{
	halluc = 0;
	if (current_room == PASSAGE) {
		light_passage(rogue.row, rogue.col);
	} else {
		light_up_room();
	}
	message("everything looks SO boring now", 0);
	if (rogue.moves_left > HUNGRY + 5) rogue.moves_left = HUNGRY + 5;
}

unblind()
{
	blind = 0;
	message("the veil of darkness lifts", 0);
	if (current_room == PASSAGE) {
		light_passage(rogue.row, rogue.col);
	} else {
		light_up_room();
	}
	blind = 0;
	if (detect_monster) {
		show_monsters();
	}
	if (halluc) {
		hallucinate();
	}
}

sleep_scroll()
{
	short i;

	message("you fall asleep", 0);
	sleep(1);
	i = get_rand(4, 10);

	while (i--) {
		move_monsters();
	}
	sleep(1);
	message("you can move again", 0);
}

go_blind()
{
	short i, j;

	if (!blind) {
		message("a cloak of darkness falls around you", 0);
	}
	blind += get_rand(500, 800);

	if (current_room >= 0) {
		for (i = rooms[current_room].top_row + 1;
		     i < rooms[current_room].bottom_row; i++) {
			for (j = rooms[current_room].left_col + 1;
			     j < rooms[current_room].right_col; j++) {
				mvaddch(i, j, ' ');
			}
		}
	}
	mvaddch(rogue.row, rogue.col, rogue.fchar);
	refresh_vms();
}

char *get_ench_color()
{
	if (halluc) {
		return(id_potions[get_rand(0, POTIONS-1)].title);
	}
	return("blue ");
}

confuse()
{
	confused = get_rand(12, 22);
}

unconfuse()
{
	char msg[80];

	confused = 0;
	sprintf(msg, "you feel less %s now", (halluc ? "trippy" : "confused"));
	message(msg, 0);
}

SHAR_EOF
fi
if test -f 'zap.c'
then
	echo shar: "will not over-write existing file 'zap.c'"
else
cat << \SHAR_EOF > 'zap.c'
#include curses.h
#include "object.h"
#include "move.h"
#include "monster.h"

extern short current_room, being_held, current_level;

zapp()
{
	short wch;
	short first_miss = 1;
	object *wand, *get_letter_object();
	short dir, row, col;
	object *monster, *get_zapped_monster();
	char getchartt();

	while (!is_direction(dir = getchartt())) {
		putchar(7);
		fflush(stdout);
		if (first_miss) {
			message("direction? ", 0);
			first_miss = 0;
		}
	}
	if (dir == CANCEL) {
		check_message();
		return;
	}
	if ((wch = get_pack_letter("zap with what?", WAND)) == CANCEL) {
		check_message();
		return;
	}
	check_message();

	if (!(wand = get_letter_object(wch))) {
		message("no such item.", 0);
		return;
	}
	if (wand->what_is != WAND) {
		message("you can't zap with that", 0);
		return;
	}
	if (wand->class <= 0) {
		message("nothing happens", 0);
		goto RM;
	} else {
		wand->class--;
	}
	row = rogue.row; col = rogue.col;
	monster = get_zapped_monster(dir, &row, &col);
	if (monster != 0) {
		wake_up(monster);
		zap_monster(monster, wand->which_kind);
	}
RM:	register_move();
}

object *get_zapped_monster(dir, row, col)
short dir;
short *row, *col;
{
	object *object_at();
	short orow, ocol;
	short i;

	for (;;) {
		orow = *row; ocol = *col;
		get_dir_rc(dir, row, col);
		if (((*row == orow) && (*col == ocol)) ||
		   (screen[*row][*col] & (HORWALL | VERTWALL)) ||
		   (screen[*row][*col] == BLANK)) {
			return(0);
		}
		if (screen[*row][*col] & MONSTER) {
			if (!hiding_xeroc(*row, *col)) {
				return(object_at(&level_monsters, *row, *col));
			}
		}
	}
}

zap_monster(monster, kind)
object *monster;
short kind;
{
	short row, col;
	struct object *nm;

	row = monster->row;
	col = monster->col;
	nm = monster->next_object;

	switch(kind) {
	case SLOW_MONSTER:
		if (monster->m_flags & HASTED) {
			monster->m_flags &= (~HASTED);
		} else {
			monster->quiver = 0;
			monster->m_flags |= SLOWED;
		}
		break;
	case HASTE_MONSTER:
		if (monster->m_flags & SLOWED) {
			monster->m_flags &= (~SLOWED);
		} else {
			monster->m_flags |= HASTED;
		}
		break;
	case TELEPORT_AWAY:
		teleport_away(monster);
		break;
	case KILL_MONSTER:
		rogue.exp_points -= monster->kill_exp;
		monster_damage(monster, monster->quantity);
		break;
	case INVISIBILITY:
		monster->m_flags |= IS_INVIS;
		mvaddch(row, col, get_monster_char(monster));
		break;
	case POLYMORPH:
		if (monster->ichar == 'F') {
			being_held = 0;
		}
MA:		*monster = monster_tab[get_rand(0, MONSTERS-1)];
		if ((monster->ichar == 'X') && ((current_level < XEROC1) ||
		    (current_level > XEROC2))) {
			goto MA;
		}
		monster->what_is = MONSTER;
		monster->row = row; monster->col = col;
		monster->next_object = nm;
		wake_up(monster);
		if (can_see(row, col)) {
			mvaddch(row, col, get_monster_char(monster));
		}
		break;
	case PUT_TO_SLEEP:
		monster->m_flags |= IS_ASLEEP;
		monster->m_flags &= (~WAKENS);
		break;
	case DO_NOTHING:
		message("nothing happens", 0);
		break;
	}
}

teleport_away(monster)
object *monster;
{
	short row, col;

	if (monster->ichar == 'F') {
		being_held = 0;
	}
	get_rand_row_col(&row, &col, (FLOOR | TUNNEL | IS_OBJECT));
	remove_mask(monster->row, monster->col, MONSTER);
	mvaddch(monster->row, monster->col,
	get_room_char(screen[monster->row][monster->col], monster->row,
	monster->col));

	monster->row = row; monster->col = col;
	add_mask(row, col, MONSTER);

	if (can_see(row, col)) {
		mvaddch(row, col, get_monster_char(monster));
	}
}
SHAR_EOF
fi
exit 0
#	End of shell archive
-- 
ihnp4--\                                        
decvax--\	
akgua----\
dcdwest---\
somewhere--\
ucbvax-------- sdcsvax -- rich