[net.sources.games] search -- part 4 of 6

matt@oddjob.UUCP (Matt Crawford) (08/11/85)

: This is a shar archive.  Extract with sh, not csh.
echo x - defines.h
sed -e 's/^X//' > defines.h << '!xxENDITxx!'
X/*
X *
X * search
X *
X * multi-player and multi-system search and destroy.
X *
X * Original by Greg Ordy	1979
X * Rewrite by Sam Leffler	1981
X * Socket code by Dave Pare	1983
X * Ported & improved
X *      by Matt Crawford	1985
X *
X * defines and macros used by search code.
X *
X * Copyright (c) 1979
X *
X * $Header: defines.h,v 2.2 85/08/06 22:25:30 matt Exp $
X * $Log:	defines.h,v $
X * Revision 2.2  85/08/06  22:25:30  matt
X * Change definition of score and error log files for flexibility.
X * 
X * Revision 2.1  85/04/10  17:30:57  matt
X * Major de-linting and minor restructuring.
X * 
X * Revision 1.2  85/02/11  14:59:08  matt
X * raised NPLAYER to 15
X */
X
X#define DEFAULT_IN_PORT 525	/* default internet port number */
X
X/*
X * Configuration definitions
X */
X#define	NPLAYER 16		/* # players supported */
X#define	MAXMAG	'3'		/* upper bound on magnification */
X#define	NBURST  2		/* # concurrent visible shrapnel */
X#define	NALIEN  20		/* # of aliens in game */
X#define	NBASE	3		/* # of starbases */
X#define	NSHANK  12		/* # of shanker aliens */
X#define	NWAND	4		/* # of X-aliens */
X#define	NTORP	26		/* # of available torpedoes (recycled) */
X#define ITCHECK	128		/* # of iterations between new player check */
X#define QSIZE	8		/* size of input q for buffering tty reads */
X/*
X * Energy costs for various items
X */
X#define	SHRAPCOST  20		/* cost of being hit by a piece of shrapnel */
X#define	TPCOST  10		/* energy cost to shoot a torpedo */
X#define	INCOST  1		/* cost for staying invisible */
X
X#define	SCABLETTER  27
X#define	TSIZE	37		/* lifetime of a torpedo */
X/*
X * State bits
X */
X#define TRUE	1
X#define FALSE	0
X
X#define	ALIVE	0		/* player/alien/torpedo alive */
X#define	DEAD	7		/* player/alien/torpedo dead */
X
X#define OFF	17
X#define ON	23
X/*
X * Alien types -- normal, shankers, X-aliens
X */
X#define	NORM	11
X#define	SHANK	13
X#define	WANDER	17
X/*
X * Alien monikers -- shown on screen
X */
X#define	NAMEAL	'#'		/* normal type */
X#define	NAMESH	'@'		/* shanker */
X#define	NAMEWD	'X'		/* X-alien */
X#define	NAMEP	'%'		/* planet component */
X/*
X * Input directional keyboard definitions
X */
X#define	NO	'8'
X#define	NE	'9'
X#define	EA	'6'
X#define	SE	'3'
X#define	SO	'2'
X#define	SW	'1'
X#define	WE	'4'
X#define	NW	'7'
X/*
X * Other sundry commands
X */
X#define	FIRE	'0'
X/*
X * Union type qualifiers -- used with varargs
X */
X#define PLAYER	1
X#define ALIEN	2
X#define PLANET	3
X#define SBASE	4
X#define TORPEDO	5
X
X#define		onscreen(ox,oy,x,y)     (ox >= (x - XWIND*mf) && \
Xox <= (x + XWIND * mf) && \
Xoy >= (y - YWIND * mf) && \
Xoy <= (y + YWIND * mf))
X
X#define NULL	0
X#define NULLCH	((char *)0)
X#define NULLINT	((int *)0)
X#define NOTHING	((thing *)0)
X#define NOBODY	((t_player *)0)
X
X#define isbase(p)	((p) < (thing *)&sbase[NBASE] && \
X			 (p) >= (thing *)sbase)
X#define isplayer(p)	((p) < (thing *)&player[NPLAYER] && \
X			 (p) >= (thing *)player)
X#define isalien(p)	((p) < (thing *)&alien[NALIEN] && \
X			 (p) >= (thing *)alien)
X#define istorp(p)	((p) < (thing *)&torps[NTORP] && \
X			 (p) >= (thing *)torps)
X
X/*#define clear(p)	((void) strcat(p->outputq, p->CL))*/
X/*#define move(x, y, p)	((void) strcat(p->outputq, tgoto((p),(x),(y)) ))*/
X
X
X#define SLOCK		"/tmp/slock"
X#define POINTFILE	LIBDIR/points"
X#define ERRLOG		LIBDIR/errlog"
X
X/*
X * Coordinate definitions for the titles of screen fields --
X *   probably should be defined relative to the screen dimensions.
X */
X#define	POSTITLE	55,1
X#define	EGYTITLE	56,4
X#define	HRTITLE		53,7
X#define	H1TITLE		53,8
X#define	H2TITLE		53,9
X#define	H3TITLE		53,10
X#define	PTTITLE		56,12
X#define	STTITLE		11,16
X#define	INTITLE		4,1
X#define	VLTITLE		5,4
X#define	TMTITLE		7,7
X#define	MFTITLE		5,10
X#define	MSTITLE		11,18
X#define PLTITLE		23,19
X#define XAXISTITLE	CENTX,7
X#define YAXISTITLE	34
X
X
X/*
X * Positions of data fields on screen
X */
X#define POS1DX	55
X#define POS1DY	2
X#define	POS1DATA	POS1DX,POS1DY
X#define POS2DX	60
X#define POS2DY	2
X#define	POS2DATA	POS2DX,POS2DY
X#define EGYDATAX	56
X#define EGYDATAY	5
X#define	EGYDATA		EGYDATAX,EGYDATAY
X#define H1DATAX		55
X#define H1DATAY		8
X#define	H1DATA		H1DATAX,H1DATAY
X#define H2DATAX		55
X#define H2DATAY		9
X#define	H2DATA		H2DATAX,H2DATAY
X#define H3DATAX		55
X#define H3DATAY		10
X#define	H3DATA		H3DATAX,H3DATAY
X#define PTDATAX		57
X#define PTDATAY		13
X#define	PTDATA		PTDATAX,PTDATAY
X#define STDATAX		19
X#define STDATAY		16
X#define	STDATA		STDATAX,STDATAY
X#define INDATAX		7
X#define INDATAY		2
X#define	INDATA		INDATAX,INDATAY
X#define VLDATAX		5
X#define VLDATAY		5
X#define	VLDATA		VLDATAX,VLDATAY
X#define TMDATAX		6
X#define TMDATAY		8
X#define	TMDATA		TMDATAX,TMDATAY
X#define MFDATAX		8
X#define MFDATAY		11
X#define	MFDATA		MFDATAX,MFDATAY
X#define MSDATAX		21
X#define MSDATAY		18
X#define	MSDATA		MSDATAX,MSDATAY
X#define PROMPTX		11
X#define PROMPTY		19
X
X/*
X * Definition of screen origin of viewport -- objects are located
X *  relative when displayed in lists.c
X */
X#define	CENTX	19
X#define	CENTY	0
X
X/*
X * Dimensions of viewport
X */
X#define	XWIND	15
X#define	YWIND	7
!xxENDITxx!
echo x - structs.h
sed -e 's/^X//' > structs.h << '!xxENDITxx!'
X/*
X *
X * search
X *
X * multi-player and multi-system search and destroy.
X *
X * Original by Greg Ordy	1979
X * Rewrite by Sam Leffler	1981
X * Socket code by Dave Pare	1983
X * Ported & improved
X *      by Matt Crawford	1985
X *
X * file contains data structure declarations used in search.
X * originally these were spread across several .h files.
X *
X * Copyright (c) 1979
X *
X * $Header: structs.h,v 2.2 85/08/06 22:29:49 matt Exp $
X * $Log:	structs.h,v $
X * Revision 2.2  85/08/06  22:29:49  matt
X * Change handling of "r", "b", "g", "j", "q" commands to
X * provide better feedback, using per-player message buffer.
X * 
X * Revision 2.1  85/04/10  17:32:03  matt
X * Major de-linting and minor restructuring.
X * 
X * Revision 1.4  85/02/11  12:44:06  matt
X * added GUTS mode
X * 
X * Revision 1.3  84/07/08  13:40:29  matt
X * Added two bytes of padding to the t_file structure.  Vax compiler
X * added them implicitly but Sun compiler did not, giving "bad new
X * player read".
X * 
X * Revision 1.2  84/07/07  18:11:31  matt
X * Rearranged structure t_file because it gets sent across the
X * net and may be padded differently by different compilers.
X * 
X */
X
Xstruct plist {
X	char	zx;
X	char	zy;
X	char	zchar;
X	char	zflg;
X	struct plist *zpnt;
X};
X
X/*
X * Shrapnel description data base
X */
Xtypedef struct {
X	char    cbx;		/* x coord of center */
X	char    cby;		/* y coord of center */
X	char    cbactive;	/* any pieces still visible */
X	char    cbcnt;		/* time left to stay active */
X	char    shrap[9][2];	/* offsets from center of pieces */
X	char    shrapd[9];	/* offset from center of each piece */
X} t_burst;
X
X/*
X * Player structure -- contains everything you'd ever
X *  want to know about a player in the game
X */
Xtypedef struct {
X	char	plname[20];	/* player's name */
X	short	energy;		/* current energy level */
X	short	maxe;		/* max energy to accumulate */
X	char	curx;		/* current x coord */
X	char	cury;		/* current y coord */
X	char	gmess[40];	/* group message buffer */
X/* status stuff */
X	struct {
X		unsigned orb : 1;	/* in orbit? */
X		unsigned bur : 1;	/* pending shrapnel damage */
X		unsigned ap : 1;	/* in the middle of an autopilot */
X		unsigned crash : 1;	/* crash into quartone? */
X		unsigned alive : 1;	/* player alive? */
X		unsigned killed : 1;	/* was the player killed? */
X		unsigned invis : 1;	/* are we invisible */
X		unsigned begin : 1;	/* new player? */
X		unsigned guts : 1;	/* wants to play "guts" */
X	} status;
X/* points */
X	short	points;		/* current point total for this round */
X	long	pltime;		/* playing time accumulated */
X	short	pkills;		/* kills of other players accumulated */
X	short	phits;		/* hits of other players accumulated */
X	short	ahits;		/* alien hits accumulated */
X/* i/o */
X	int	socket;		/* the input socket */
X	int	suspended;	/* saves socket fd when we are suspended */
X	char	cmdpend;	/* pending command */
X	char	cmd;		/* current command */
X	char	inputq[QSIZE];	/* for buffering input from terminal */
X	char	*pinputq;	/* next char to read */
X	char	ninput;		/* # of chars in input q -- must fit QSIZE */
X	char	outputq[2048];	/* characters to output - null terminated */
X	char	*eoq;		/* pointer to the current end-of-queue */
X/* autopilot */
X	union	thing_u	*home[3];	/* autopilot channels */
X	char	*apx;		/* autopilot pointer - x coord */
X	char	*apy;		/* autopilot pointer - y coord */
X	union	thing_u	*whocent;	/* center over who? */
X/* screen stuff */
X	struct	plist *plstp;	/* head of screen list */
X	short	preve;		/* last energy value displayed */
X	short	prevp;		/* last point total displayed */
X	char	mflg;		/* magnification factor */
X	char	offx;		/* x offset from center */
X	char	offy;		/* y offset from center */
X/* quartone stuff */
X	char	ocnt;		/* orbit count */
X	short	qkill;		/* quartonites killed during current xploit */
X	char	nkcnt;		/* nuke count */
X	char	xcount;		/* xploitation count */
X	char	scabcount;	/* scab threshold */
X/* Termcap additions */
X	short	ttyspeed;	/* baud rate for padding */
X	char	PC;		/* pad char */
X	char	*BC;		/* backspace one char */
X	char	*UP;		/* move up one line */
X	char	*CM;		/* cursor motion string */
X	char	*CL;		/* clear screen */
X	char	*CE;		/* clear to end of line */
X/* radio and broadcast message stuff */
X	char	mesgbuf[40];	/* message buffer */
X	char	mesglen;	/* characters in buffer */
X	char	mesgdst;	/* radio message destination */
X} t_player;
X
X/*
X * Definition of an alien being
X */
Xtypedef struct {
X	char	type;		/* shanker, X-alien, etc. */
X	char	onscr;		/* on screen? */
X	char	cx;		/* current x coord */
X	char	cy;		/* current y coord */
X	char	cix;		/* current increment in x direction */
X	char	ciy; 		/* current increment in y direction */
X	char	fx;		/* x firing direction */
X	char	fy;		/* y firing direction */
X	char	stats;		/* state bits */
X	char	hit;		/* # of hits taken */
X	char	count;		/* # in existence */
X	char	aname;		/* alien moniker */
X	union	thing_u	*whotoget;	/* player to attack -- shanker */
X} t_alien;
X
X/*
X * Planet definitions
X */
Xtypedef struct {
X	char	*planetname;	/* planet's name */
X	char	places[17][2];	/* offsets from center of pieces */
X} t_planet;
X
X/*
X * Location of starbases
X */
Xtypedef struct {
X	char	xpos;		/* x coord of center */
X	char	ypos;		/* y coord of center */
X} t_sbase;
X
X/*
X * Info regarding torpedoes
X */
Xtypedef struct {
X	char	torx;		/* current x coord */
X	char	tory;		/* current y coord */
X	union	thing_u	*owner;		/* who shot it? */
X	union	thing_u	*target;	/* destination */
X	char	xinc;		/* velocity increment in x direction */
X	char	yinc;		/* velocity increment in y direction */
X	char	tcount;		/* time to live counter */
X} t_torps;
X
Xtypedef union thing_u {		/* need a tag for recursive structs */
X	t_player	u_player;
X	t_alien		u_alien;
X	t_sbase		u_sbase;
X	t_torps		u_torps;
X} thing;
X
X/*
X * User point totals data base
X */
Xtypedef struct {
X	char	ptname[20];	/* player name */
X	int	ptpoints;	/* total points */
X	int	pthits;		/* total player hits */
X	int	ptahits;	/* total alien hits */
X	int	ptkills;	/* total player kills */
X	int	ptkilled;	/* total times killed */
X	int	ptlast;		/* last game's score */
X	int	ptbest;		/* best score */
X	int	ptgames;	/* # games played */
X} t_totals ;
X
X/*
X * One file structure is read in for each player
X *   that gets into a game
X */
X
Xtypedef struct {
X	char	p_name[20];	/* player's chosen moniker */
X	char	p_BC[20];	/* backspace one character */
X	char	p_UP[20];	/* move up one line */
X	char	p_CM[40];	/* cursor motion string */
X	char	p_CL[20];	/* clear screen */
X	char	p_CE[20];	/* clear to end of line */
X	int	p_speed;	/* terminal's ioctl speed */
X	char	p_PC;		/* pad character */
X	char	p_flags;	/* status bits of player */
X	char	p_xxx[2];	/* padding for portability */
X} t_file;
!xxENDITxx!
echo x - cmds1.c
sed -e 's/^X//' > cmds1.c << '!xxENDITxx!'
X#ifndef lint
Xstatic char rcsid[] = "$Header: cmds1.c,v 2.3 85/08/06 22:28:20 matt Exp $";
X#endif
X/*
X *
X * search
X *
X * multi-player and multi-system search and destroy.
X *
X * Original by Greg Ordy	1979
X * Rewrite by Sam Leffler	1981
X * Socket code by Dave Pare	1983
X * Ported & improved
X *      by Matt Crawford	1985
X *
X * routines to execute player commands
X *
X * Copyright (c) 1979
X *
X * $Log:	cmds1.c,v $
X * Revision 2.3  85/08/06  22:28:20  matt
X * Change handling of "r", "b", "g", "j", "q" commands to
X * provide better feedback, using per-player message buffer.
X * 
X * Revision 2.2  85/05/30  22:43:05  matt
X * You can't send a "Temporary malfunction" message to an alien!!
X * 
X * Revision 2.1  85/04/10  17:30:46  matt
X * Major de-linting and minor restructuring.
X * 
X */
X
X#include "defines.h"
X#include "structs.h"
X
Xint     TDIST = TSIZE;		/* max distance a torpedoe travels */
X
X/*
X * Launch a torpedo.
X * "firer" shot it, using the "where" key, firing in the <ox, oy> direction.
X * "dd" indicates distance until it dies.
X * "mess" indicates if a launch message should be given.
X * "xl" and "yl" give the origin for calculating distance.
X * "type" identifies the type of the firer.
X */
Xvoid launch(firer, where, type, ox, oy, mess, xl, yl, dd)
Xregister thing *firer;
Xchar where, xl, yl, ox, oy;
X{
X	extern	void pstatus();
X	extern	t_torps torps[NTORP];
X	register char x,
X		y;
X	register t_torps *tp,
X		*last;
X
X	last = &torps[NTORP];
X	for (tp = torps; tp < last; tp++) {
X		if (tp->owner == NOTHING) {
X			if (type==PLAYER && firer->u_player.energy<TPCOST) {
X				if (mess) {
X					pstatus(&firer->u_player,
X						"Need more energy!");
X					firer->u_player.cmdpend = 0;
X				}
X				return;
X			}
X			tp->owner = firer;
X			tp->torx = xl;
X			tp->tory = yl;
X			x = ox; y = oy;
X			tp->tcount = dd != 0 ? dd : TDIST;
X			switch (where) {
X
X			case NO: 
X				y--;
X				break;
X			case NE: 
X				x++;
X				y--;
X				break;
X			case EA: 
X				x++;
X				break;
X			case SE: 
X				x++;
X				y++;
X				break;
X			case SO: 
X				y++;
X				break;
X			case SW: 
X				x--;
X				y++;
X				break;
X			case WE: 
X				x--;
X				break;
X			case NW: 
X				x--;
X				y--;
X				break;
X			}
X			if (type != PLAYER) {
X				tp->xinc = x;
X				tp->yinc = y;
X				if (x == 0 && y == 0)
X					tp->owner = NOTHING;
X				return;
X			}
X			if (x == 0 && y == 0) {
X				pstatus(&firer->u_player,
X					"Torpedos must move!");
X				tp->owner = NOTHING;
X				firer->u_player.cmdpend = 0;
X				return;
X			}
X			tp->xinc = x;
X			tp->yinc = y;
X			firer->u_player.energy -= TPCOST;
X			firer->u_player.cmdpend = 0;
X			if (mess)
X		    		pstatus(&firer->u_player, "Launch!");
X			return;
X		}
X	}
X	if (type != PLAYER)
X		return;
X	pstatus(&firer->u_player, "Temporary malfunction!");
X	firer->u_player.cmdpend = 0;
X}
X
X/*
X * Show coordinates of an object locked in on channel "channel".
X */
Xvoid home(p, channel)
Xregister t_player *p;
Xchar channel;
X{
X	extern	void pstatus();
X	void	showhome();
X
X	p->cmdpend = 0;
X	if (channel < '1' || channel > '3') {
X		pstatus(p, "Invalid channel number!");
X		return;
X	}
X	channel -= '1';
X	if (p->home[channel] == NOTHING) {
X		pstatus(p, "Channel not locked on object!");
X		return;
X	}
X	showhome(p, channel);
X}
X
X/*
X * Show the coordinates of a homing radar channel on the screen --
X *  assumes the channel is valid.
X */
Xstatic void showhome(p, channel)
Xregister t_player *p;
Xregister int channel;
X{
X	extern	void put();
X	extern	t_sbase sbase[NBASE];
X	extern	t_alien alien[NALIEN];
X	extern	t_player player[NPLAYER];
X	extern	t_torps torps[NTORP];
X	thing	*val;		/* should be union */
X
X	switch (channel) {
X
X	case 0: 
X		move(H1DATAX, H1DATAY, p);	/* macro */
X		break;
X	case 1: 
X		move(H2DATAX, H2DATAY, p);
X		break;
X	case 2: 
X		move(H3DATAX, H3DATAY, p);
X		break;
X	}
X	val = p->home[channel];
X	if (isalien(val))
X		put(p, "%d  %d", val->u_alien.cx, val->u_alien.cy);
X	else if (isplayer(val))
X		put(p, "%d  %d", val->u_player.curx, val->u_player.cury);
X	else if (isbase(val))
X		put(p, "%d  %d", val->u_sbase.xpos, val->u_sbase.ypos);
X	else
X		put(p, "%d  %d", val->u_torps.torx, val->u_torps.tory);
X}
X
X/*
X * Set channel "channel" so that it's locked in on the object
X *  currently "underneath" player "p".
X */
Xvoid sethome(p, channel)
Xregister t_player *p;
Xchar channel;
X{
X	extern	void pstatus();
X	void	showhome();
X
X	p->cmdpend = 0;
X	if (channel < '1' || channel > '3') {
X		pstatus(p, "Invalid channel number!");
X		return;
X	}
X	channel -= '1';
X	if (p->whocent == NOTHING) {
X		pstatus(p, "Not over an object!");
X		return;
X	}
X	p->home[channel] = p->whocent;
X	showhome(p, channel);
X	pstatus(p, "Locked on!");
X}
X
X/*
X * Invisibility toggle -- useless during solar flares.
X */
Xvoid invisible (p)
Xregister t_player *p;
X{
X	extern	int sfflag,
X		gutsflag;
X	extern	void pmesg(),
X		put();
X
X	move(INDATAX, INDATAY, p);	/* macro */
X	if (p->status.invis == FALSE) {
X		if (sfflag == ON) {
X			put(p, "off");
X			pmesg(p, "From radar-- Solar flare up!!");
X			return;
X		} else if (gutsflag) {
X			put(p, "off");
X			pmesg(p, "No invisibility in GUTS mode");
X			return;
X		}
X		put(p, "on ");
X		p->status.invis = TRUE;
X	} else {
X		put(p, "off");
X		p->status.invis = FALSE;
X	}
X}
X
X/*
X * Dock at a starbase -- causes refueling to take place.
X */
Xvoid dock(p)
Xregister t_player *p;
X{
X	extern	void pstatus(),
X		cput();
X
X	if (!isbase(p->whocent)) {
X		pstatus(p, "Not over a starbase!");
X		return;
X	}
X	pstatus(p, "Successful docking!");
X	if (p->maxe <= 225)
X		p->maxe = p->maxe+25;
X	p->energy = p->maxe;
X	cput(EGYDATA, p, "%d", p->energy);
X}
X
X/*
X * Autopilot on a channel which has previously been locked onto
X *  an object -- normally this is a starbase, but it could be a
X *  player, alien, or even a planet.
X */
Xvoid autopi(p, channel)
Xregister t_player *p;
Xchar channel;
X{
X	extern	t_planet planet;
X	extern	void pstatus();
X	thing	*val;
X	register char *x,
X		*y;
X
X	p->cmdpend = 0;
X	if (channel < '1' || channel > '3') {
X		pstatus(p, "Invalid channel number!");
X		return;
X	}
X	channel -= '1';
X	val = p->home[channel];
X	if (val == NOTHING) {
X		pstatus(p, "Channel not locked on object!");
X		return;
X	}
X	if (isalien(val)) {
X		x = & val->u_alien.cx;
X		y = & val->u_alien.cy;
X	} else if (isplayer(val)) {
X		x = & val->u_player.curx;
X		y = & val->u_player.cury;
X	} else if (isbase(val)) {
X		x = & val->u_sbase.xpos;
X		y = & val->u_sbase.ypos;
X	} else {			/* planet !?!?!? */
X		x = & planet.places[0][0];
X		y = & planet.places[0][1];
X	}
X
X	p->apx = x;
X	p->apy = y;
X	p->status.ap = TRUE;
X	p->status.orb = FALSE;
X	pstatus(p, "Autopilot process begun!");
X}
X
X/*
X * Broadcast a message.
X */
Xvoid bcast(p, letter)
Xregister t_player *p;
Xchar letter;
X{
X	extern	void pmesg(),
X		echomsg(),
X		donemsg(),
X		makescab();
X	register t_player *pl;
X
X	if (letter != '\n' && letter != '\r') {
X		if (letter == SCABLETTER) {	/* no tty tricks! */
X			makescab(p);
X			letter = '^';
X		}
X		echomsg(p, letter);
X	} else {
X
X		for (pl = player; pl < &player[NPLAYER]; pl++)
X			if (pl->status.alive == TRUE)
X				pmesg(pl, "\07From %s -- %s", p->plname, p->mesgbuf);
X		p->cmdpend = 0;
X		donemsg(p);
X	}
X}
X
X/*
X * broadcast and radio message echoing routines
X */
X
Xvoid
Xgathermsg(p)
Xregister t_player *p;
X{
X	if (p->mesgdst >= NPLAYER)
X		pmesg(p, "From radio room-- enter message to group");
X	else if (p->mesgdst > 0)
X		pmesg(p, "From radio room-- enter message to %c (%s)",
X			p->mesgdst-1+'A', player[p->mesgdst-1].plname);
X	else
X		pmesg(p, "From radio room-- enter message");
X	prompt(p, "TEXT: ");
X	p->mesglen = 0;
X	p->mesgbuf[0] = '\0';
X	bflush(p);
X}
X
X/*
X * echoing is relative to the prompt string given above
X */
X#define INPUTSTART PROMPTX+6
X#define	INPUTY	   PROMPTY
X
Xvoid
Xechomsg(p, c)
Xregister t_player *p;
Xchar c;
X{
X	if (c=='\b' || c=='\177') {
X		if (p->mesglen) {
X			cput(p->mesglen+INPUTSTART, INPUTY, p, " \b");
X			p->mesglen--;
X		}
X		p->mesgbuf[p->mesglen] = '\0';
X	} else if (c=='@' || c=='\025') {
X		gathermsg(p);
X		return;
X	} else {
X		/* unprintable cacters show up as blanks */
X		if (c < ' ')
X			c = ' ';
X
X		if (p->mesglen < 35) {
X			p->mesgbuf[p->mesglen++] = c;
X			p->mesgbuf[p->mesglen] = '\0';
X			cput(p->mesglen+INPUTSTART, INPUTY, p, "%c", c);
X		}
X	}
X
X	bflush(p);
X}
X
Xvoid
Xdonemsg(p)
Xregister t_player *p;
X{
X	prompt(p, "");
X	p->mesgdst = 0;
X	p->mesglen = 0;
X	p->mesgbuf[0] = '\0';
X	bflush(p);
X}
!xxENDITxx!
echo x - cmds2.c
sed -e 's/^X//' > cmds2.c << '!xxENDITxx!'
X#ifndef lint
Xstatic char rcsid[] = "$Header: cmds2.c,v 2.2 85/08/06 22:29:33 matt Exp $";
X#endif
X/*
X *
X * search
X *
X * multi-player and multi-system search and destroy.
X *
X * Original by Greg Ordy	1979
X * Rewrite by Sam Leffler	1981
X * Socket code by Dave Pare	1983
X * Ported & improved
X *      by Matt Crawford	1985
X *
X * more routines to execute player commands
X *
X * Copyright (c) 1979
X *
X * $Log:	cmds2.c,v $
X * Revision 2.2  85/08/06  22:29:33  matt
X * Change handling of "r", "b", "g", "j", "q" commands to
X * provide better feedback, using per-player message buffer.
X * 
X * Revision 2.1  85/04/10  17:30:53  matt
X * Major de-linting and minor restructuring.
X * 
X */
X
X#include "defines.h"
X#include "structs.h"
X
Xstatic int nukedir[9][4] = {
X	{  0,-1, 1, 0}, { -1, 0, 1, 0}, { -1, 0, 0,-1},
X	{  0,-1, 0, 1}, {  0, 0, 0, 0}, {  0,-1, 0, 1},
X	{  0, 1, 1, 0}, { -1, 0, 1, 0}, { -1, 0, 0, 1}
X};
X
X/*
X * Launch a nuke.
X */
Xvoid
Xnuke(p, c)
Xregister t_player *p;
Xchar c;
X{
X	extern	void launch();
X	register char x,
X		y;
X	char	ox,
X		oy,
X		c1 = c;
X
X	p->cmdpend = 0;
X	ox = p->offx;
X	oy = p->offy;
X	launch((thing *)p, c, PLAYER, ox, oy, 0, p->curx, p->cury, 10);
X	if(p->nkcnt-- <= 0) {
X		p->nkcnt = 0;
X		return;
X	}
X	c -= '1';
X	if (c < 0 || c > 8)
X		return;
X	x = nukedir[c][0] + p->curx;
X	y = nukedir[c][1] + p->cury;
X	launch((thing *)p, c1, PLAYER, ox, oy, 0, x, y, 8);
X	x = nukedir[c][2] + p->curx;
X	y = nukedir[c][3] + p->cury;
X	launch((thing *)p, c1, PLAYER, ox, oy, 1, x, y, 8);
X}
X
X/*
X * Send a radio message.
X */
Xvoid
Xrmsg(p, letter)
Xregister t_player *p;
Xchar letter;
X{
X	extern	void pstatus(),
X		pmesg(),
X		echomsg(),
X		gathermsg(),
X		donemsg(),
X		makescab();
X	extern	t_player player[NPLAYER];
X	register int i;
X	register t_player *pl;
X
X	if (p->mesgdst == 0) {
X		if (letter >= 'a')
X			letter -= 'a';
X		else if (letter >= 'A')
X			letter -= 'A';
X		else
X			letter = NPLAYER;
X		if (letter < 0 || letter >= NPLAYER)
X			pmesg(p, "From radio room-- frequency jammed!");
X		else if (player[letter].status.alive == TRUE) {
X			p->mesgdst = letter+1;
X			gathermsg(p);
X			return;
X		} else
X			pstatus(p, "Inactive channel requested!");
X		p->cmdpend = 0;
X		p->mesgdst = 0;
X		return;
X	}
X	if (letter != '\n' && letter != '\r') {
X		if (letter == SCABLETTER) {
X			letter = '^';
X			makescab(p);
X		}
X		echomsg(p, letter);
X	} else {
X		pl = &player[p->mesgdst-1];
X		if (pl->status.alive != TRUE)
X			pmesg(p, "From radio room-- Too late!  %c is dead!",
X				p->mesgdst-1+'A');
X		else {
X			pmesg(p, "From radio room -- Message sent!");
X			pmesg(pl, "Private from %s-- %s", p->plname, p->mesgbuf);
X		}
X
X		p->cmdpend = 0;
X		donemsg(p);
X	}
X}
X
X/*
X * Change the magnification factor on the viewing port.
X */
Xvoid
Xmagnif(p, power)
Xregister t_player *p;
Xchar power;
X{
X	extern	void pstatus(),
X		cput();
X
X	p->cmdpend = 0;
X	if (power < '1' || power > MAXMAG) {
X		pstatus(p, "M-factor request out of range!");
X		return;
X	}
X	p->mflg = power-'0';
X	cput(MFDATA, p, "%c", power);
X}
X
X/*
X * Show current facts about a player.
X */
Xvoid
Xfacts(p)
Xregister t_player *p;
X{
X	extern	void	pstatus();
X	extern	long	ptime;
X	long	rate;
X
X	rate = ((long)p->points*100+(long)p->phits*100+
X		(long)p->pkills*1000)/(ptime-p->pltime);
X	pstatus(p, "hits: %dp %da kills: %d level: %d", p->phits,
X		p->ahits, p->pkills, rate);
X}
X
X/*
X * Exploit aliens living on quartone so that nukes may be
X *  fired.
X */
Xvoid
Xxploit(p)
Xregister t_player *p;
X{
X	extern	void pmesg(),
X		makescab();
X	register int i;
X
X	if(p->status.orb == FALSE) {
X		pmesg(p, "Must be in orbit around planet");
X		return;
X	}
X	if(p->status.invis == TRUE) {
X		pmesg(p, "Must be visible to exploit");
X		return;
X	}
X	if(p->nkcnt >= 12) {
X		pmesg(p, "Maximum modifications are complete");
X		return;
X	}
X	p->energy -= 20;
X	p->nkcnt++;
X	i = ((rand()>>4)%40)+60;
X	p->qkill += i;
X	pmesg(p, "Dead: %d total: %d", i, p->qkill);
X	/*
X	 * ouch!  if we kill more than 8000, make the player a scab!
X	 */
X	if(p->qkill > 8000)
X		makescab(p);
X}
!xxENDITxx!