[comp.sources.games.bugs] Unofficial mdg changes, 2 of 3

michael@stb.info.com (Michael Gersten) (04/06/91)

cat > players.c <<  SHAR_EOF_players.c
/*
	MDG Multiuser Dungeon Game -- players.c player code
	
	MDG is Copyright 1990 John C. Gonnerman
	This program is subject to the general MDG 
	copyright statement (see enclosed file, Copyright).
*/

static char *sccsvers = "@(#) players.c\t(1.5)\tcreated 1/3/91";

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include "setup.h"
#include "files.h"
#include "struct.h"

extern char *progname;

extern int errno;
extern char *sys_errlist[];

extern struct player_seg *pseg;
extern struct map_seg *mseg;

extern int player_size;

extern int memory[];


saveplayer(indx)
int indx;
{
	char fname[128];
	FILE *fp;
	int i;
	time_t time();

	if(pseg->p[indx].playernum == -1) /* no such player */
		return;

	if(pseg->p[indx].loc.sector == LOC_NONESUCH 
	&& pseg->p[indx].lives < 0) {	/* he died */
		pseg->p[indx].playernum = -1;
		pseg->player_sem++;
		return;
	}

	sprintf(fname, "%s/pl%05d", PLAYERDIR, pseg->p[indx].playernum);

	/* mark player's items as old */

	for(i = 0; i < pseg->item_count; i++)
		if(pseg->itm[i].loc.sector == LOC_PLAYER
		&& pseg->itm[i].loc.x == pseg->p[indx].playernum)
			pseg->itm[i].loc.y = ITEM_OLD;

	/* save player's file */

	if((fp = fopen(fname, "w")) == NULL)
		return;
		
	fprintf(fp, "%s\n", pseg->p[indx].name);
	fprintf(fp, "%ld\n", pseg->p[indx].gold);

	for(i = 0; i < 26; i++) {
		fprintf(fp, "%hd ", pseg->p[indx].spells[i]);
		if(((i + 1) % 13) == 0)
			putc('\n', fp);
	}

	fprintf(fp, "%hd:%hd\n", pseg->p[indx].max_hp, 
		pseg->p[indx].hitpoints);

	fprintf(fp, "%hd:%hd\n", pseg->p[indx].max_mp, 
		pseg->p[indx].magicpts);

	fprintf(fp, "%hd\n", pseg->p[indx].fighting);

	fprintf(fp, "[%d/%d]\n", pseg->p[indx].loc.x, pseg->p[indx].home);

	fprintf(fp, "%d\n", pseg->p[indx].lives);

	fprintf(fp, "%ld\n", time(NULL) - DATE_OFFSET);

	fprintf(fp, "%hd\n", pseg->p[indx].createpts);

	fprintf(fp, "al = %hd\n", pseg->p[indx].alignment);

	fclose(fp);

	pseg->p[indx].playernum = -1;

	pseg->player_sem++;
}


dmsg_all(msg)
char *msg;
{
	int i;

	for(i = 0; i < MAX_PLAYERS; i++)
		if(pseg->p[i].playernum >= 0)
			dmsg_add(i, msg);
}


int loadplayer(indx, playernum)
int indx, playernum;
{
	char fname[128], altfname[128], profname[128], *p;
	char tmpname[PNAMELEN];
	long time_out, time_old, time_diff;
	time_t time();
	FILE *fp;
	int i, startsect;

	sprintf(fname, "%s/pl%05d", PLAYERDIR, playernum);
	sprintf(altfname, "%s/default", PLAYERDIR);
	sprintf(profname, "%s/pr%05d", PLAYERDIR, playernum);

	pseg->weapon[indx] = -1;
	pseg->armor[indx] = -1;
	pseg->shield[indx] = -1;
	for (i=0; i<NUM_MSG; i++)
		pseg->p[indx].dmsg[i][0] = '\0';
	pseg->p[indx].dmsg_loc = -1;
	pseg->p[indx].brief = 0;
	pseg->p[indx].clock = 0;
	pseg->p[indx].detect = 0;
	pseg->p[indx].light = 0;
	pseg->p[indx].blocked = 0;
	pseg->p[indx].invis = 0;
	pseg->p[indx].knight = 0;
	pseg->p[indx].user_spell = 0;
	pseg->p[indx].gold_hidden = 0;
	pseg->p[indx].ma_count = 0;
	pseg->p[indx].m_armor = 0;
	pseg->p[indx].createpts = 0;

	memory[indx] = LOC_NONESUCH;

	if((fp = fopen(profname, "r")) == NULL)
		pseg->p[indx].name[0] = '\0';
	else {
		fgets(pseg->p[indx].name, 20, fp);
		fclose(fp);
	}

	if((fp = fopen(fname, "r")) == NULL 
	&& (fp = fopen(altfname, "r")) == NULL)
		return;

	fgets(tmpname, 20, fp);
	loguser(playernum, tmpname);

	if(pseg->p[indx].name[0] == '\0')
		strcpy(pseg->p[indx].name, tmpname);

	for(p = pseg->p[indx].name; *p; p++)
		if(*p == '\n')
			*p = '\0';

	if(pseg->p[indx].name[0] == '\0')
		get_handle(pseg->p[indx].name, playernum);

	fscanf(fp, "%ld\n", &(pseg->p[indx].gold));

	for(i = 0; i < 26; i++)
		fscanf(fp, "%hd", &(pseg->p[indx].spells[i]));

	fscanf(fp, "%hd:%hd\n", &(pseg->p[indx].max_hp),
		&(pseg->p[indx].hitpoints));

	fscanf(fp, "%hd:%hd\n", &(pseg->p[indx].max_mp),
		&(pseg->p[indx].magicpts));

	fscanf(fp, "%hd\n", &(pseg->p[indx].fighting));

	fscanf(fp, "[%d/%d]\n", &startsect, &(pseg->p[indx].home));

	fscanf(fp, "%d\n", &(pseg->p[indx].lives));

	fscanf(fp, "%ld\n", &time_old);

	fscanf(fp, "%hd\n", &(pseg->p[indx].createpts));

	fscanf(fp, "al = %hd\n", &(pseg->p[indx].alignment));

	fclose(fp);

	for(i = 0; i < MAX_PLAYERS; i++)
		pseg->p[indx].partners[i] = pseg->p[indx].alignment;

	time_diff = (time(NULL) - DATE_OFFSET) - time_old;

	if(time_diff > 600)
		time_diff = 600;

	time_out = time_diff / TIME_TO_HEAL;

	while(time_out--)
		heal_a_player(indx);

	if(startsect < 0 || startsect >= mseg->max_areas)
		startsect = 0;

	if(place(indx, startsect) == -1
	&& place(indx, 0) == -1)
		return;

	pseg->p[indx].prev_sect = startsect;

	pseg->p[indx].playernum = playernum;

	for(i = 0; i < PMAX_ITEMS; i++)
		pseg->p[indx].items[i] = -1;

	for(i = 0; i < pseg->item_count; i++)
		if(pseg->itm[i].loc.sector == LOC_PLAYER
		&& pseg->itm[i].loc.x == pseg->p[indx].playernum) {
			insert_item(indx, i);
			freshen_item(i);
		}

	move_sym(&(pseg->p[indx].loc), 1 + indx);

	pseg->player_sem++;
}

/* This currently logs users to the errorlog file. May want to
	change this. */

loguser(playernum, name)
char *name;
{
	char buf[60];
	sprintf(buf, "User %d as player %s\n", playernum, name);
	fprintf(stderr, buf);
}

place(p_indx, startsect)
int p_indx, startsect;
{
	int rc, x, y;

	for(x = MAPCOLS / 3; x < (2 * (MAPCOLS / 3)); x++)
	for(y = MAPROWS / 3; y < 2 * (MAPROWS / 3); y++) {
		if(try_spot(p_indx, startsect, x, y) == 0)
			return 0;
	}

	return -1;
}


int try_spot(p_indx, startsect, x, y)
int p_indx, startsect, x, y;
{
	if(isdigit(mseg->m[startsect].map[y][x]))
		return -1;

	if(mseg->m[startsect].map[y][x] == '~'
	|| mseg->m[startsect].map[y][x] == '%'
	|| mseg->m[startsect].map[y][x] == '^')
		return -1;

	if(move_to(&(pseg->p[p_indx].loc), startsect, x, y, p_indx) == 0)
		return 0;

	return -1;
}


abortplayer(indx)
int indx;
{
	int sector, x, y, under;

	sector = pseg->p[indx].loc.sector;
	x = pseg->p[indx].loc.x;
	y = pseg->p[indx].loc.y;
	under = pseg->p[indx].loc.under;

	if(sector < 0)
		return;

	mseg->m[sector].map[y][x] = under;

	drop_new(indx, sector, x, y);

	pseg->p[indx].playernum = -1;

	pseg->player_sem++;

	mseg->map_sem++;

	notify(sector);
}


drop_new(p_indx, sector, x, y)
int p_indx, sector, x, y;
{
	int i, playernum;

	playernum = pseg->p[p_indx].playernum;

	for(i = 0; i < pseg->item_count; i++)
		if(pseg->itm[i].loc.sector == LOC_PLAYER
		&& pseg->itm[i].loc.x == playernum
		&& pseg->itm[i].loc.y == ITEM_NEW)
			if(put_item(i, sector, x, y) == -1)
				pseg->itm[i].loc.sector = LOC_NONESUCH;

	notify(sector);
}


del_player(p_indx)
int p_indx;
{
	char fname[128];
	int temp_x;

	pseg->p[p_indx].lives--;

	if(pseg->p[p_indx].lives >= 0) {
		pseg->p[p_indx].hitpoints = 1;
		temp_x = pseg->p[p_indx].loc.x;
		pseg->p[p_indx].loc.x = 0;
		pseg->p[p_indx].gold = 0;
		pseg->player_sem++;
		saveplayer(p_indx);
		pseg->p[p_indx].loc.x = temp_x;
		pseg->p[p_indx].hitpoints = 0;
		pseg->player_sem++;
		tell_player(p_indx);
	} else {
		sprintf(fname, "%s/pl%05d", PLAYERDIR, 
			pseg->p[p_indx].playernum);
		unlink(fname);
	}
}


heal_players()
{
	int indx;

	for(indx = 0; indx < MAX_PLAYERS; indx++) {
		if(pseg->p[indx].playernum >= 0 
		&& pseg->p[indx].loc.sector >= 0
		&& ++pseg->p[indx].clock > TIME_TO_HEAL)
			heal_a_player(indx);
		if(pseg->p[indx].playernum >= 0
		&& (pseg->p[indx].loc.sector == LOC_NONESUCH
		|| pseg->p[indx].loc.sector == LOC_HOME)) {
			pseg->player_sem++;
			tell_player(indx);
		}
	}
}


heal_a_player(indx)
int indx;
{
	pseg->p[indx].clock = 0;

	if(pseg->p[indx].hitpoints < pseg->p[indx].max_hp) {
		pseg->p[indx].hitpoints += 
			rnd(pseg->p[indx].max_hp / HEAL_DIV);
		if(pseg->p[indx].hitpoints > pseg->p[indx].max_hp)
			pseg->p[indx].hitpoints = pseg->p[indx].max_hp;
		pseg->player_sem++;
	} 
	
	if(pseg->p[indx].hitpoints > MIN_HPS
	&& pseg->p[indx].magicpts < pseg->p[indx].max_mp) {
		pseg->p[indx].magicpts += CHARGE_INC;
		pseg->player_sem++;
	}

	tell_player(indx);
}


/* end of file. */
SHAR_EOF_players.c
cat > godpower.c <<  SHAR_EOF_godpower.c
/*
	MDG Multiuser Dungeon Game -- godpower.c godlike power code
	
	MDG is Copyright 1990 John C. Gonnerman
	This program is subject to the general MDG 
	copyright statement (see enclosed file, Copyright).
*/

static char *sccsvers = "@(#) godpower.c\t(1.1)\tcreated 12/25/90";

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#include "setup.h"
#include "struct.h"

extern char *progname;

extern struct map_seg *mseg;
extern struct player_seg *pseg;

extern int trap_adder[];

char *mapspots = "={}:;-| 0123456789%#@^,<>~`+.";

struct {
	char type;
	short limit;
} mod_limits[] = {
	POTION,		 1,
	SCROLL,		 1,
	ARMOR, 		 3,
	SHIELD,		 2,
	WEAPON,		 5,
	MISSILE,	 5,
	OBJECT, 	 1,
	NOTE, 		 0,
	CASH, 		 0,
	CRYSTAL,	 0,
	' ',		-1,
};

int memory[MAX_PLAYERS];


int get_limit(type)
char type;
{
	int i;

	for(i = 0; mod_limits[i].limit >= 0; i++)
		if(mod_limits[i].type == type)
			return mod_limits[i].limit;

	return -1;
}


god_power(p_indx, mptr)
int p_indx;
struct dmessage *mptr;
{
	char buf[35];
	int sector, dir, what, which, how, at_spot, points, mult;
	struct location where;

	switch(mptr->subcmd) {

	case 'l' :
		god_link(p_indx, mptr->arg, mptr->ext_arg);
		break;

	case 'm' :
		dir = mptr->arg;
		what = mptr->ext_arg;
		where = pseg->p[p_indx].loc;
		get_dest(&where, dir);

		if((sector = where.sector) < 0) {
			dmsg_add(p_indx, "Can't change that.");
			return;
		}

		if(strchr(mapspots, what) == NULL) {
			dmsg_add(p_indx, "Code invalid.");
			return;
		}

		mult = 1;

		if(what >= '0' && what <= '9')
			mult += trap_adder[what-'0'];

		if((points = checklimit(p_indx, sector, mult)) == -1)
			return;

		at_spot = mseg->m[sector].map[where.y][where.x];

		if(is_item(at_spot) 
		|| is_critter(at_spot) 
		|| is_player(at_spot)) {
			dmsg_add(p_indx, "Clear spot first.");
			return;
		}

		mseg->m[sector].map[where.y][where.x] = what;
		mseg->save_map = 1;
		mseg->map_sem++;

		pseg->p[p_indx].createpts -= points;

		break;

	case 's' :
		sector = pseg->p[p_indx].loc.sector;

		ch_stat(p_indx, sector, mptr->arg, mptr->ext_arg);

		break;

	case 't' :
		sector = mptr->arg;

		if((points = checklimit(p_indx, sector, 3)) == -1)
			return;

		if(mptr->text[0] == '\0')
			return;

		pseg->p[p_indx].createpts -= points;
		pseg->player_sem++;
		strcpy(mseg->m[sector].title, mptr->text);
		mseg->save_map = 1;
		mseg->map_sem++;
		break;

	case 'r' :
		sector = pseg->p[p_indx].loc.sector;

		sprintf(buf, "[ Light %d, Level %d, # %d ]",
			mseg->m[sector].light, mseg->m[sector].level, sector);
		dmsg_add(p_indx, buf);

		sprintf(buf, "[ Jump %d, God Limit %d, '%c' ]",
			mseg->m[sector].jump_inhibit, 
			mseg->m[sector].god_limit, 
			mseg->m[sector].border_ch);
		dmsg_add(p_indx, buf);

		{ int i;
		sector = pseg->p[p_indx].loc.sector;
		sprintf(buf, "N/S/E/W/U/D:");
		for (i=0; i<6; i++)
			sprintf(buf + strlen(buf), " %d",
				mseg->m[sector].links[i]);
		dmsg_add(p_indx, buf);
		sprintf(buf, "Gates:");
		for (i=6; i<13; i++)
			sprintf(buf + strlen(buf), " %d",
				mseg->m[sector].links[i]);
		dmsg_add(p_indx, buf);
		break;
		}

	case 'i' :
		what = mptr->arg;

		sprintf(buf, "[ %s '%c' ]", 
			pseg->itm[what].name,
			pseg->itm[what].type);
		dmsg_add(p_indx, buf);

		tell_about(what, p_indx);

		break;

	case 'n' :
		what = mptr->arg;

		if(pseg->p[p_indx].createpts < 3) {
			dmsg_add(p_indx, "Need 3 CP to change item.");
			break;
		}

		strncpy(pseg->itm[what].name, mptr->text, INAMELEN - 1);

		pseg->p[p_indx].createpts -= 3;
		pseg->player_sem++;

		pseg->itm[what].name[INAMELEN-1] = '\0';
		pseg->item_sem++;

		dmsg_add(p_indx, "Item Changed.");
		break;

	case 'a' :
		what = mptr->arg;
		which = mptr->ext_arg;
		ch_i_stat(p_indx, what, which);
		break;
	}
}


ch_i_stat(p_indx, i_indx, which)
int p_indx, i_indx, which;
{
	int m, need;
	char buf[35];

	need = 3;

	if(which == 'c')
		need = 9;

	if(pseg->p[p_indx].createpts < need) {
		sprintf(buf, "Need %d CP to change item.", need);
		dmsg_add(p_indx, buf);
		return;
	}

	if(which == 'c') {
		switch(pseg->itm[i_indx].curse) {
		case 0 :
			pseg->itm[i_indx].curse = 1;
			dmsg_add(p_indx, "Item Cursed.");
			break;
		default :
			pseg->itm[i_indx].curse = 0;
			dmsg_add(p_indx, "Item Uncursed.");
			break;
		}
	} else {
		if((m = get_limit(pseg->itm[i_indx].type)) == -1
		|| pseg->itm[i_indx].mod_count == -1) {
			dmsg_add(p_indx, "Can't change that.");
			return;
		}

		if(pseg->itm[i_indx].mod_count >= m) {
			dmsg_add(p_indx, "Can't change that.");
			return;
		}

		switch(pseg->itm[i_indx].type) {
		case ARMOR :
		case SHIELD :
		case WEAPON :
			if(which == 'r') {
				dmsg_add(p_indx, "Can't change that.");
				return;
			}
			break;

		case MISSILE :
			break;
	
		default:
			dmsg_add(p_indx, "Can't change that.");
			return;
		}

		switch(which) {
		case 'v' : /* value */
			pseg->itm[i_indx].effect++;
			break;
		case 'r' : /* range */
			pseg->itm[i_indx].range++;
			break;
		}

		pseg->itm[i_indx].value *= 1.5;
		pseg->itm[i_indx].mod_count++;
	}

	pseg->p[p_indx].createpts -= need;
	pseg->player_sem++;

	pseg->item_sem++;

	dmsg_add(p_indx, "Item Changed.");
}


ch_stat(p_indx, sector, what, how)
int p_indx, sector, what, how;
{
	int diff, points;
	char buf[35];

	if((points = checklimit(p_indx, sector, 4)) == -1)
		return;

	switch(how) {
	case '+' :
		diff = 1;
		break;
	case '-' :
		diff = -1;
		break;
	default :
		dmsg_add(p_indx, "Must specify + or -");
		return;
	}

	switch(what) {
	case 'l' : /* level */
		if(mseg->m[sector].level == 0 && diff == -1) {
			dmsg_add(p_indx, "Level is 0");
			return;
		}
		mseg->m[sector].level += diff;
		break;
	case 'i' : /* illumination */
		if(mseg->m[sector].light == -1 && diff == -1) {
			dmsg_add(p_indx, "Light is -1");
			return;
		}
		if(mseg->m[sector].light == 2 && diff == 1) {
			dmsg_add(p_indx, "Light is 2");
			return;
		}
		mseg->m[sector].light += diff;
		break;
	case 'j' : /* jump_inhibit */
		if(mseg->m[sector].jump_inhibit == 0 && diff == -1) {
			dmsg_add(p_indx, "Jump Inhibit is 0");
			return;
		}
		mseg->m[sector].jump_inhibit += diff;
		break;
	}

	mseg->save_map = 1;
	mseg->map_sem++;
	pseg->p[p_indx].createpts -= points;
	pseg->player_sem++;
	notify(sector);
}


tell_about(i_indx, p_indx)
int i_indx, p_indx;
{
	char buf[35];

	switch(pseg->itm[i_indx].type) {
	case POTION :
	case SCROLL :
	case NOTE :
	case OBJECT :
		sprintf(buf, "[ M%hd %s]", 
			pseg->itm[i_indx].mod_count,
			(pseg->itm[i_indx].curse ? "C " : ""));
		dmsg_add(p_indx, buf);
		break;

	case ARMOR :
	case SHIELD :
	case WEAPON :
		sprintf(buf, "[ M%hd V%d %s]", 
			pseg->itm[i_indx].mod_count,
			pseg->itm[i_indx].effect,
			(pseg->itm[i_indx].curse ? "C " : ""));
		dmsg_add(p_indx, buf);
		break;
		
	case MISSILE :
		sprintf(buf, "[ M%hd V%d R%d %s]", 
			pseg->itm[i_indx].mod_count,
			pseg->itm[i_indx].effect,
			pseg->itm[i_indx].range,
			(pseg->itm[i_indx].curse ? "C " : ""));
		dmsg_add(p_indx, buf);
		break;
	}
}


god_link(p_indx, how, which)
int p_indx, how, which;
{
	int points, sector;

	sector = pseg->p[p_indx].loc.sector;

	switch(how) {
	case 'r' : /* remember */
		memory[p_indx] = sector;
		dmsg_add(p_indx, "Sector memorized.");
		break;

	case 'c' : /* create */

		if((points = checklimit(p_indx, sector, 5)) == -1)
			return;

		if(memory[p_indx] < 0) {
			dmsg_add(p_indx, "No sector memorized.");
			return;
		}

		mseg->m[sector].links[L_GATE+which] = memory[p_indx];

		pseg->p[p_indx].createpts -= points;
		pseg->player_sem++;

		mseg->save_map = 1;
		mseg->map_sem++;

		dmsg_add(p_indx, "Linked!");

		break;

	default :
		dmsg_add(p_indx, "Huh?");
		break;
	}
}


int checklimit(p_indx, sector, mult)
int p_indx, sector, mult;
{
	char buf[35];
	int points;

	if(mseg->m[sector].god_limit < 1) {
		dmsg_add(p_indx, "Can't change that.");
		return -1;
	}

	points = mseg->m[sector].god_limit * mult;

	if(pseg->p[p_indx].createpts < points) {
		sprintf(buf, "Need %d CP.", points);
		dmsg_add(p_indx, buf);
		return -1;
	}

	return points;
}


/* end of file. */
SHAR_EOF_godpower.c
cat > input.c <<  SHAR_EOF_input.c
/*
	MDG Multiuser Dungeon Game -- input.c reader-task
	
	MDG is Copyright 1990 John C. Gonnerman
	This program is subject to the general MDG 
	copyright statement (see enclosed file, Copyright).
*/

static char *sccsvers = "@(#) input.c\t(1.5)\tcreated 1/3/91";

#include <curses.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <ctype.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>

#include "setup.h"
#include "struct.h"
#include "messages.h"
#include "effect.h"

#define GOD1PROMPT \
"God Power: c)reate, r)eveal, m)ap, s)tats, t)itle, l)ink, or i)tem? "

char *gates = "={}:;-|";

char *progname;

struct player_seg *pseg;
struct map_seg *mseg;

extern int errno;
extern char *sys_errlist[];

extern char *spell_names[];

int pid, dqid, gseg_id, playernum, player_indx;
char handle[20];

char old_buf[35] = "";

struct game_msg *gseg;


input_process()
{
	int ch;
	void input_exit();

	strcpy(gseg->buf, WELCOME);
	tell_viewer();

	signal(SIGHUP, input_exit);

	while((ch = getchar()) != EOF)
		send_message(ch);
}


void input_exit(sig)
int sig;
{
	shmdt(gseg);

	exit(0);
}


send_t_message(ch)
int ch;
{
	struct dmessage msg_buf;
	int in_ch, item_indx;

	msg_buf.msg_type = 1L;
	msg_buf.playernum = playernum;

	switch(ch) {

	case '\f' :
		redraw_scr();
		break;

	case 'n' : /* next */
		gseg->trader_offset += 10;
		tell_viewer();
		break;

	case 'p' : /* previous */
		if(gseg->trader_offset > 0)
			gseg->trader_offset -= 10;
		tell_viewer();
		break;

	case 'b' : /* buy */
		msg_buf.cmd = 'B';

		strcpy(gseg->buf, "buy what? (0-9) ");
		tell_viewer();

		in_ch = getchar() - '0';

		gseg->buf[0] = '\0';
		tell_viewer();

		if(in_ch < 0 || in_ch > 9)
			break;

		if((msg_buf.arg = trader_item(in_ch)) == -1)
			break;

		tell_daemon(&msg_buf);

		break;

	case 'v' : /* value */
		strcpy(gseg->buf, "value what? (1-7) ");
		tell_viewer();

		in_ch = getchar() - '0';

		if((item_indx = find_item(player_indx, in_ch)) >= 0) {
			sprintf(gseg->buf, "%s is worth %d\n",
				pseg->itm[item_indx].name,
				pseg->itm[item_indx].value);
			tell_viewer();
		}

		break;

	case 's' : /* sell */
		strcpy(gseg->buf, "sell what? (1-7) ");
		tell_viewer();

		in_ch = getchar() - '0';

		if((item_indx = find_item(player_indx, in_ch)) >= 0) {
			msg_buf.cmd = 'S';
			msg_buf.arg = item_indx;
			tell_daemon(&msg_buf);
		}

		gseg->buf[0] = '\0';
		tell_viewer();

		break;

	case 'l' : /* leave */
		msg_buf.cmd = 'L';
		tell_daemon(&msg_buf);
		break;
	}
}


send_message(ch)
int ch;
{
	struct dmessage msg_buf;
	int in_ch, item_indx;

	if(gseg->trader_offset >= 0) {
		send_t_message(ch);
		return;
	}

	msg_buf.msg_type = 1L;
	msg_buf.playernum = playernum;

	if(isupper(ch)) {
		msg_buf.cmd = 'c';
		msg_buf.subcmd = ch - 'A';
		if((msg_buf.arg = get_spell_arg(tolower(ch))) == -1) {
			strcpy(gseg->buf, "* aborted *");
			tell_viewer();
			return;
		}
		get_spell_text(tolower(ch), msg_buf.text);
		tell_daemon(&msg_buf);

	} else switch(ch) {

	case '\n' :
	case '\r' :
		gseg->buf[0] = '\0';
		tell_viewer();
		break;

	case '\f' :
		redraw_scr();
		break;

	case '*' :
	case '?' :
		help();
		break;

	case ';' :
		telltime();
		break;

	case 't' : /* take */
	case '0' :
		msg_buf.cmd = 't';
		tell_daemon(&msg_buf);
		break;

	case 'k' :
	case '8' :
		msg_buf.cmd = 'm';
		msg_buf.subcmd = L_NORTH;
		tell_daemon(&msg_buf);
		break;

	case 'j' :
	case '2' :
		msg_buf.cmd = 'm';
		msg_buf.subcmd = L_SOUTH;
		tell_daemon(&msg_buf);
		break;

	case 'l' :
	case '6' :
		msg_buf.cmd = 'm';
		msg_buf.subcmd = L_EAST;
		tell_daemon(&msg_buf);
		break;

	case 'h' :
	case '4' :
		msg_buf.cmd = 'm';
		msg_buf.subcmd = L_WEST;
		tell_daemon(&msg_buf);
		break;

	case 'y' :
	case '7' :
		msg_buf.cmd = 'm';
		msg_buf.subcmd = L_NWEST;
		tell_daemon(&msg_buf);
		break;

	case 'u' :
	case '9' :
		msg_buf.cmd = 'm';
		msg_buf.subcmd = L_NEAST;
		tell_daemon(&msg_buf);
		break;

	case 'b' :
	case '1' :
		msg_buf.cmd = 'm';
		msg_buf.subcmd = L_SWEST;
		tell_daemon(&msg_buf);
		break;

	case 'n' :
	case '3' :
		msg_buf.cmd = 'm';
		msg_buf.subcmd = L_SEAST;
		tell_daemon(&msg_buf);
		break;

	case 'e' : /* enter */
	case '5' :
		msg_buf.cmd = 'e';
		tell_daemon(&msg_buf);
		break;

	case 'd' : /* drop */
	case '/' : /* drop */
		strcpy(gseg->buf, "drop what? (0-7) ");
		tell_viewer();

		in_ch = getchar() - '0';

		if(in_ch == 0) {
			strcpy(gseg->buf, "drop gold where? (hjkl) ");
			tell_viewer();
			if((msg_buf.subcmd = get_dir()) != -1
			&& (msg_buf.arg = get_amount()) > 0) {
				msg_buf.cmd = 'D';
				tell_daemon(&msg_buf);
			}
		} else if(in_ch > 0 && in_ch <= PMAX_ITEMS)
			if((item_indx = find_item(player_indx, in_ch)) >= 0) {
				sprintf(gseg->buf, 
					"drop %d where? (hjkl) ", in_ch);
				tell_viewer();
				if((msg_buf.subcmd = get_dir()) != -1) {
					msg_buf.cmd = 'd';
					msg_buf.arg = item_indx;
					tell_daemon(&msg_buf);
				}
			}

		gseg->buf[0] = '\0';
		tell_viewer();

		break;

	case ')' : /* cast */
	case 'c' : /* cast */
		strcpy(gseg->buf, "cast which spell? (a-z) ");
		tell_viewer();

		in_ch = tolower(getchar());

		if(in_ch >= 'a' && in_ch <= 'z') {
			msg_buf.cmd = 'c';
			msg_buf.subcmd = in_ch - 'a';
			if((msg_buf.arg = get_spell_arg(in_ch)) == -1) {
				strcpy(gseg->buf, "* aborted *");
				tell_viewer();
				return;
			}
			get_spell_text(in_ch, msg_buf.text);
			tell_daemon(&msg_buf);
		}

		gseg->buf[0] = '\0';
		tell_viewer();

		break;

	case 'g' : /* god power */
		if(pseg->p[player_indx].createpts < 1)
			break;

		strcpy(gseg->buf, GOD1PROMPT);
		tell_viewer();

		in_ch = tolower(getchar());

		get_god_cmd(in_ch);

		gseg->buf[0] = '\0';
		tell_viewer();

		break;

	case 'v' : /* verbose */
		
		msg_buf.cmd = 'v';
		tell_daemon(&msg_buf);

		break;

	case '(' : /* activate */
	case 'a' : /* activate */
		strcpy(gseg->buf, "activate what? (1-7) ");
		tell_viewer();

		in_ch = getchar() - '0';

		activate_it(in_ch);

		gseg->buf[0] = '\0';
		tell_viewer();

		break;

	case '!' : /* activate 1 */

		activate_it(1);
		break;

	case '@' : /* activate 2 */

		activate_it(2);
		break;

	case '#' : /* activate 3 */

		activate_it(3);
		break;

	case '$' : /* activate 4 */

		activate_it(4);
		break;

	case '%' : /* activate 5 */

		activate_it(5);
		break;

	case '^' : /* activate 6 */

		activate_it(6);
		break;

	case '&' : /* activate 7 */

		activate_it(7);
		break;

	case 'w' : /* write */
		strcpy(gseg->buf, "write what? (1-7) ");
		tell_viewer();

		in_ch = getchar() - '1';

		write_it(in_ch);

		gseg->buf[0] = '\0';
		tell_viewer();

		break;

	case '.' : /* say */
	case 's' : /* say */
		say_it();
		break;

	case '+' : /* partner */
	case 'p' : /* partner */
		partner();
		break;
	}
}


activate_it(in_ch)
int in_ch;
{
	struct dmessage msg_buf;
	int item_indx;

	if(in_ch > 0 && in_ch <= PMAX_ITEMS) {
		item_indx = find_item(player_indx, in_ch);

		if(item_indx >= 0) {
			msg_buf.msg_type = 1L;
			msg_buf.playernum = playernum;
			msg_buf.cmd = 'u';
			msg_buf.subcmd = item_indx;
			msg_buf.arg = get_use_dir(item_indx);
			tell_daemon(&msg_buf);
		}
	}
}


partner()
{
	struct dmessage msg_buf;
	int pard;

	strcpy(gseg->buf, "partner with who? ");
	tell_viewer();

	pard = toupper(getchar()) - '1';

	gseg->buf[0] = '\0';
	tell_viewer();

	msg_buf.msg_type = 1L;
	msg_buf.playernum = playernum;
	msg_buf.cmd = 'p';
	msg_buf.subcmd = pard;
	tell_daemon(&msg_buf);
}


write_it(ch)
int ch;
{
	struct dmessage msg_buf;
	int i_indx;

	if(ch < 0 || ch > 6)
		return;

	i_indx = pseg->p[player_indx].items[ch];

	if(i_indx < 0 || pseg->itm[i_indx].type != NOTE)
		return;

	msg_buf.msg_type = 1L;
	msg_buf.playernum = playernum;

	msg_buf.cmd = 'w';
	msg_buf.arg = i_indx;
	get_message(msg_buf.text);

	if(msg_buf.text[0] != '\0')
		tell_daemon(&msg_buf);
}


say_it()
{
	struct dmessage msg_buf;

	msg_buf.msg_type = 1L;
	msg_buf.playernum = playernum;

	msg_buf.cmd = 's';
	get_message(msg_buf.text);

	if(msg_buf.text[0] != '\0')
		tell_daemon(&msg_buf);
}


get_message(text)
char *text;
{
	char inbuf[35];
	int pos, ch;

	pos = 0;
	ch = '\0';
	inbuf[0] = '\0';
	text[0] = '\0';

	while(ch != '\n' && ch != '\r') {
		strcpy(gseg->buf, "Message (^R = Recall, ESC = Cancel) : ");
		strcat(gseg->buf, inbuf);
		strcat(gseg->buf, "_");
		tell_viewer();

		ch = getchar();

		switch(ch) {
		case '\033' :
			inbuf[pos] = '\0';
			gseg->buf[0] = '\0';
			tell_viewer();
			return;
		case '\b' :
			if(pos)
				pos--;
			inbuf[pos] = '\0';
			break;
		case '\n' :
		case '\r' :
		case '\f' :
		case '\t' :
			break;
		case '\022' :
			strcpy(inbuf, old_buf);
			pos = strlen(inbuf);
			break;
		default :
			if(isprint(ch) && pos < 30) {
				inbuf[pos++] = ch;
				inbuf[pos] = '\0';
			}
			break;
		}
	}

	gseg->buf[0] = '\0';
	tell_viewer();

	strcpy(text, inbuf);
	strcpy(old_buf, inbuf);
}


int get_amount()
{
	char inbuf[9];
	int pos, ch;

	pos = 0;
	ch = '\0';
	inbuf[0] = '\0';

	while(ch != '\n' && ch != '\r') {
		sprintf(gseg->buf, "How much? (ESC to cancel): %s_", inbuf);
		tell_viewer();

		ch = getchar();

		switch(ch) {
		case '\033' :
			gseg->buf[0] = '\0';
			tell_viewer();
			return;
		case '\b' :
			if(pos)
				pos--;
			inbuf[pos] = '\0';
			break;
		case '\n' :
		case '\r' :
		case '\f' :
		case '\t' :
			break;
		default :
			if(isdigit(ch) && pos < 7) {
				inbuf[pos++] = ch;
				inbuf[pos] = '\0';
			}
			break;
		}
	}

	return atoi(inbuf);
}


int get_dir()
{
	switch(tolower(getchar())) {
	case 'h' :
	case '4' :
		return L_WEST;
	case 'j' :
	case '2' :
		return L_SOUTH;
	case 'k' :
	case '8' :
		return L_NORTH;
	case 'l' :
	case '6' :
		return L_EAST;
	case 'y' :
	case '7' :
		return L_NWEST;
	case 'b' :
	case '1' :
		return L_SWEST;
	case 'n' :
	case '3' :
		return L_SEAST;
	case 'u' :
	case '9' :
		return L_NEAST;
	}

	return -1;
}


get_use_dir(indx)
int indx;
{
	if(pseg->itm[indx].type == WEAPON
	|| pseg->itm[indx].type == SHIELD
	|| pseg->itm[indx].type == ARMOR
	|| pseg->itm[indx].type == NOTE)
		return 0;

	if(pseg->itm[indx].type == MISSILE) {
		sprintf(gseg->buf, "fire %s which way? (hjkl) ",
			pseg->itm[indx].name);
		tell_viewer();
		return get_dir();
	}

	switch(pseg->itm[indx].effect) {
	case TELEPORT :
	case HEALING :
		return 0;
	case FIREBALLS : /* fireball */
	case LIGHTNING : /* lightning */
	case COLD : /* cold */
		sprintf(gseg->buf, "activate %s which way? (hjkl) ",
			pseg->itm[indx].name);
		tell_viewer();
		return get_dir();
	default :
		return 0;
	}
}


get_spell_text(spell, text)
int spell;
char *text;
{
	switch(spell) {
	case 'w' :
		get_message(text);
		break;
	}
}


int get_spell_arg(spell)
int spell;
{
	int in_ch, item_indx;

	switch(spell) {
	case 'c' : /* cold */
	case 'f' : /* fireball */
	case 'l' : /* lightning */
	case 'm' : /* missile */
	case 'r' : /* death ray */
		sprintf(gseg->buf, "cast %s which way? (hjkl) ",
			spell_names[spell - 'a']);
		tell_viewer();
		return get_dir();

	case 'n' : /* nightmare */
	case 's' : /* seek */
	case 'y' : /* yank */
		sprintf(gseg->buf, "%s who? ",
			spell_names[spell - 'a']);
		tell_viewer();
		in_ch = getchar();
		return (isdigit(in_ch) ? in_ch - '1' : -1);

	case 'o' : /* obscure */
		strcpy(gseg->buf, "obscure what item? (0-7) ");
		tell_viewer();
		in_ch = getchar() - '0';
		if(in_ch == 0)
			return -1;
		if(in_ch > 0 && in_ch <= PMAX_ITEMS)
			item_indx = find_item(player_indx, in_ch);
		return item_indx;

	case 'v' : /* verify */
		strcpy(gseg->buf, "verify what item? (0-7) ");
		tell_viewer();
		in_ch = getchar() - '0';
		if(in_ch == 0)
			return -1;
		if(in_ch > 0 && in_ch <= PMAX_ITEMS)
			item_indx = find_item(player_indx, in_ch);
		return item_indx;

	case 'w' : /* whisper */
		strcpy(gseg->buf, "whisper to who? ");
		tell_viewer();
		in_ch = getchar();
		return (isdigit(in_ch) ? in_ch - '1' : -1);

	default :
		return 0;
	}
}


redraw_scr()
{
	gseg->clear_ok = 1;

	tell_viewer();
}


tell_daemon(mptr)
struct dmessage *mptr;
{
	msgsnd(dqid, mptr, DMSGSIZ, IPC_NOWAIT);
}


tell_viewer()
{
	struct sembuf ops[1];

	ops[0].sem_num = player_indx;
	ops[0].sem_op = 1;
	ops[0].sem_flg = 0;

	semop(pseg->sid, ops, 1);
}


int find_item(p_indx, p_item_indx)
int p_indx, p_item_indx;
{
	int i, cnt;

	cnt = 0;

	if(p_item_indx < 1 || p_item_indx > PMAX_ITEMS)
		return -1;

	return pseg->p[p_indx].items[p_item_indx - 1];
}


get_god_cmd(ch)
int ch;
{
	struct dmessage msg_buf;
	char in_ch;
	int item_indx;

	msg_buf.msg_type = 1L;
	msg_buf.playernum = playernum;
	msg_buf.cmd = 'g';
	msg_buf.subcmd = ch;

	switch(ch) {
	case 'c' :
		strcpy (gseg->buf, "Creation not ready yet");
		tell_viewer();
		break;
	case 'l' :
		strcpy(gseg->buf, "God Power: r)emember or c)reate? ");
		tell_viewer();
		msg_buf.arg = tolower(getchar());
		if(msg_buf.arg == 'c') {
			strcpy(gseg->buf, "God Power: select link 1-7? ");
			tell_viewer();
			msg_buf.ext_arg = getchar() - '1';
			if(msg_buf.ext_arg > 6 || msg_buf.ext_arg < 0)
				msg_buf.ext_arg = 0;
		}
		tell_daemon(&msg_buf);
		break;

	case 'm' :
		strcpy(gseg->buf, "God Power: which way? (hjkl) ");
		tell_viewer();
		msg_buf.arg = get_dir();
		strcpy(gseg->buf, "God Power: change to what code? ");
		tell_viewer();
		if((msg_buf.ext_arg = getchar()) == '=')
			msg_buf.ext_arg = get_gate();
		tell_daemon(&msg_buf);
		break;

	case 's' :
		strcpy(gseg->buf, 
			"God Power: l)evel, j)ump inhibit, i)llumination? ");
		tell_viewer();
		msg_buf.arg = tolower(getchar());
		strcpy(gseg->buf, "God Power: + (more) or - (less)? ");
		msg_buf.ext_arg = getchar();
		tell_daemon(&msg_buf);
		break;

	case 't' :
		msg_buf.arg = pseg->p[player_indx].loc.sector;
		get_message(msg_buf.text);
		tell_daemon(&msg_buf);
		break;

	case 'r':
		tell_daemon(&msg_buf);
		break;

	case 'i' :
		strcpy(gseg->buf, "God Power: which item? ");
		tell_viewer();
		in_ch = getchar() - '0';
		if((item_indx = find_item(player_indx, in_ch)) < 0)
			break;
		msg_buf.arg = item_indx;
		strcpy(gseg->buf, 
			"God Power: n)ame, r)eveal, a)lter, or c)urse item? ");
		tell_viewer();
		in_ch = tolower(getchar());

		if(in_ch == 'a') {
			msg_buf.subcmd = in_ch;
			msg_buf.ext_arg = get_item_stat(item_indx);
			tell_daemon(&msg_buf);
		} else if(in_ch == 'n') {
			msg_buf.subcmd = in_ch;
			get_message(msg_buf.text);
			tell_daemon(&msg_buf);
		} else if(in_ch == 'r') {
			tell_daemon(&msg_buf);
		} else if(in_ch == 'c') {
			msg_buf.subcmd = 'a';
			msg_buf.ext_arg = 'c';
			tell_daemon(&msg_buf);
		}

		break;
	}
}


int get_item_stat(i_indx)
int i_indx;
{
	strcpy(gseg->buf, "God Power: alter v)alue or r)ange? ");
	tell_viewer();

	return tolower(getchar());
}


int get_gate()
{
	strcpy(gseg->buf, "God Power: select gate number 1-7 > ");
	tell_viewer();

	switch(getchar()) {
	case '2' :
		return '{';
	case '3' :
		return '}';
	case '4' :
		return ':';
	case '5' :
		return ';';
	case '6' :
		return '-';
	case '7' :
		return '|';
	default :
		return '=';
	}
}


/* end of file. */
SHAR_EOF_input.c
-- 
		Michael
michael@stb.info.com denwa!stb!michael anes.ucla.edu!stb!michael 
"Space is an illusion; disk space doubly so"