view smessage.c @ 3:5a977ccbc7a9 default tip

Empty changelog
author darius
date Sat, 06 Dec 1997 05:41:29 +0000
parents
children
line wrap: on
line source

/* $Id: smessage.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */

/*
 * smessage.c
 */
#include "copyright.h"

#include <stdio.h>
#include <math.h>
#include <signal.h>
#include <string.h>
#include <ctype.h>
#include "Wlib.h"
#include "defs.h"
#include "struct.h"
#include "data.h"
#include "proto.h"
#include "gameconf.h"

#define ADDRLEN 10
#define M_XOFF	5
#ifndef AMIGA
#define M_YOFF	5
#else
#define M_YOFF 1
#endif

#define MSGLEN	80

/* XFIX */
#define BLANKCHAR(col, n) W_ClearArea(messagew, M_XOFF+W_Textwidth*(col), \
	M_YOFF, W_Textwidth * (n), W_Textheight);
#define DRAWCURSOR(col) W_WriteText(messagew, M_XOFF+W_Textwidth*(col), \
	M_YOFF, textColor, &cursor, 1, W_RegularFont);

static int lcount;
static char buf[MSGLEN];
static char cursor = '_';

char    addr, *addr_str;

/* Prototypes */
static void smessage_first P((int ichar));
 /*static*/ char *getaddr P((int who));
 /*static*/ char *getaddr2 P((int flags, int recip));

void
message_expose()
{
    if (!messpend)
	return;

    W_WriteText(messagew, M_XOFF, M_YOFF, textColor, addr_str,
		strlen(addr_str), W_RegularFont);
    W_WriteText(messagew, M_XOFF + ADDRLEN * W_Textwidth, M_YOFF, textColor,
		buf, lcount - ADDRLEN, W_RegularFont);
    DRAWCURSOR(lcount);
}

void
smessage_ahead(head, ichar)
    char    head;
    char    ichar;
{
    if (messpend == 0) {
	smessage_first(head);
    }
    smessage(ichar);
}

static void
smessage_first(ichar)
    char    ichar;
{
    messpend = 1;

    /* clear out message window in case messages went there */
    W_ClearWindow(messagew);
    if (mdisplayed) {
	BLANKCHAR(0, lastcount);
	mdisplayed = 0;
    }
    /* Put the proper recipient in the window */
    if (/*(ichar == 't') || */
    /* that's a player number! */
    /* YUCK! */
	(ichar == 'T'))
	addr = teaminfo[me->p_teami].letter;
    else
	addr = ichar;
    addr_str = getaddr(addr);
    if (addr_str == 0) {
	/* print error message */
	messpend = 0;
#ifdef NOWARP
	message_off();
#else
	W_WarpPointer(NULL);
#endif
    } else {
	W_WriteText(messagew, M_XOFF, M_YOFF, textColor, addr_str,
		    strlen(addr_str), W_RegularFont);
	lcount = ADDRLEN;
	DRAWCURSOR(ADDRLEN);
    }
}

void
smessage(ichar)
    int     ichar;
{
    register int i;
    char    twochar[2], *delim;

    if (messpend == 0) {
	if(lowercaset && ichar == 't')
	    ichar='T';
	else if(lowercaset && (ichar == 'T'))
	    ichar='t';
	smessage_first(ichar);
	return;
    }
    switch (ichar) {
    case '\b':			/* character erase */
    case '\177':
	if (--lcount < ADDRLEN) {
	    lcount = ADDRLEN;
	    break;
	}
	BLANKCHAR(lcount + 1, 1);
	DRAWCURSOR(lcount);
	break;

    case 'w'+256:		/* word erase */
	i = 0;
	/* back up over blanks */
	while (--lcount >= ADDRLEN &&
	       isspace((unsigned char) buf[lcount - ADDRLEN] & ~(0x80)))
	    i++;
	lcount++;
	/* back up over non-blanks */
	while (--lcount >= ADDRLEN &&
	       !isspace((unsigned char) buf[lcount - ADDRLEN] & ~(0x80)))
	    i++;
	lcount++;

	if (i > 0) {
	    BLANKCHAR(lcount, i + 1);
	    DRAWCURSOR(lcount);
	}
	break;

    case 'u'+256:		/* kill line */
    case 'x'+256:
	if (lcount > ADDRLEN) {
	    BLANKCHAR(ADDRLEN, lcount - ADDRLEN + 1);
	    lcount = ADDRLEN;
	    DRAWCURSOR(ADDRLEN);
	}
	break;

    case '\033':		/* abort message */
	BLANKCHAR(0, lcount + 1);
	mdisplayed = 0;
	messpend = 0;
#ifdef NOWARP
	message_off();
#else
	W_WarpPointer(NULL);
#endif
	break;

    case '\r':			/* send message */
	buf[lcount - ADDRLEN] = '\0';
	messpend = 0;
	sendCharMessage(buf, addr);
	BLANKCHAR(0, lcount + 1);
	mdisplayed = 0;
	lcount = 0;
	break;

    default:			/* add character */
	if (lcount >= 79) {	/* send mesg and continue mesg */
	     if (addr == 'M')
		  if ((delim = strchr(buf, '>') + 1) == NULL) {
		       W_Beep();
		       break;
		  }
		  else {
		       i = delim - buf;
		       buf[lcount - ADDRLEN + 1] = '\0';
		       sendCharMessage(buf, addr);
		       memset(delim, '\0', sizeof(buf) - i);
		       BLANKCHAR(i, lcount + 1);
		       W_WriteText(messagew, M_XOFF, M_YOFF, textColor,
				   addr_str, strlen(addr_str), W_RegularFont);
		       W_WriteText(messagew, M_XOFF+(strlen(addr_str) +
						     1) * W_Textwidth,
				   M_YOFF, textColor, buf, strlen(buf), W_RegularFont);
		       lcount = i + ADDRLEN;
		       DRAWCURSOR(i + ADDRLEN);
		  }
	     else {
		  buf[lcount - ADDRLEN + 1] = '\0';
		  sendCharMessage(buf, addr);
		  BLANKCHAR(0, lcount + 1);
		  W_WriteText(messagew, M_XOFF, M_YOFF, textColor, addr_str,
			      strlen(addr_str), W_RegularFont);
		  lcount = ADDRLEN;
		  DRAWCURSOR(ADDRLEN);
	     }
	}
	if (ichar > 255)
	    break;
	twochar[0] = ichar;
	twochar[1] = cursor;
	W_WriteText(messagew, M_XOFF + W_Textwidth * lcount, M_YOFF,
		    textColor, twochar, 2, W_RegularFont);
	buf[(lcount++) - ADDRLEN] = ichar;
	break;
    }
}

void
sendCharMessage(buf, ch)
    char   *buf;
    int     ch;
{
     char tmp[MSGLEN], *delim;
     int i, count;

/* uses ch to find out what kind of message it is and then sends
   it there */
    switch ((char) ch) {
    case 'A':
	pmessage(buf, 0, MALL);
	break;
    case 'F':
	pmessage(buf, FEDm, MTEAM);
	break;
    case 'R':
	pmessage(buf, ROMm, MTEAM);
	break;
    case 'K':
	pmessage(buf, KLIm, MTEAM);
	break;
    case 'O':
	pmessage(buf, ORIm, MTEAM);
	break;
    case 'G':
	pmessage(buf, 0, MGOD);
	break;
#ifdef TOOLS
        case '!':
          pmessage(buf, 0, MTOOLS);
          break;
#endif
    case 'T':
	pmessage(buf, idx_to_mask(me->p_teami), MTEAM);
	break;
   case 'M':
	/* mcast format: hit M and list of target addresses followed */
	/* by greater than(>) and message. the entire mesg including */
	/* addresses will be sent to each address */
	if((delim = strchr(buf, '>')) != NULL) {
	     count = delim - buf; /* number of addresses */
	     strncpy(tmp, buf, count);
	     if(strchr(tmp, ' ') == NULL)
		  for(i=0; i < count; i++) { /* dont do tmp[0] is M */
		       sendCharMessage(buf, tmp[i]);
		  }
	}
	break;
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
	pmessage(buf, ch - '0', MINDIV);
	break;
    case 'a':
    case 'b':
    case 'c':
    case 'd':
    case 'e':
    case 'f':
    case 'g':
    case 'h':
    case 'i':
    case 'j':
    case 'k':
    case 'l':
    case 'm':
    case 'n':
    case 'o':
    case 'p':
    case 'q':
    case 'r':
    case 's':
    case 't':
    case 'u':
    case 'v':
    case 'w':
    case 'x':
    case 'y':
    case 'z':
	pmessage(buf, ch - 'a' + 10, MINDIV);
	break;
    default:
	{
	    int     i;
	    for (i = 0; i < number_of_teams; i++) {
		if (ch == teaminfo[i].letter)
		    break;
	    }
	    if (i < number_of_teams) {
		pmessage(buf, idx_to_mask(i), MTEAM);
		break;
	    }
	}
	warning("Not legal recipient");
    }
}

void
pmessage(str, recip, group)
    char   *str;
    int     recip;
    int     group;
{
    char    newbuf[100];

    strcpy(lastMessage, str);
    switch(group) {
#ifdef TOOLS
    case MTOOLS:
	sendTools(str);
	break;
#endif
    default:
	sendMessage(str, group, recip);
    }
    if ((group == MTEAM && recip != idx_to_mask(me->p_teami)) ||
	(group == MINDIV && recip != me->p_no)) {
	sprintf(newbuf, "%s  %s",
		getaddr2(group, (group == MTEAM) ?
			 mask_to_idx(recip) : recip),
		str);
	newbuf[79] = 0;
	dmessage(newbuf, group, me->p_no, recip);
    }
#ifdef NOWARP
    message_off();
#else
    W_WarpPointer(NULL);
#endif
}

/*static */
char   *
getaddr(who)
    char    who;
{
    switch (who) {
    case 'A':
	return (getaddr2(MALL, 0));
    case 'F':
	return (getaddr2(MTEAM, FEDi));
    case 'R':
	return (getaddr2(MTEAM, ROMi));
    case 'K':
	return (getaddr2(MTEAM, KLIi));
    case 'O':
	return (getaddr2(MTEAM, ORIi));
    case 'G':
	return (getaddr2(MGOD, 0));
#ifdef TOOLS
    case '!':
      return (getaddr2(MTOOLS, 0));
#endif
   case 'M':
	return (getaddr2(MCAST, 0));;
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
	if (isPlaying(&players[who - '0'])) {
	    return (getaddr2(MINDIV, who - '0'));
	} else {
	    warning("Player is not in game");
	    return (0);
	}
	break;
    case 'a':
    case 'b':
    case 'c':
    case 'd':
    case 'e':
    case 'f':
    case 'g':
    case 'h':
    case 'i':
    case 'j':
    case 'k':
    case 'l':
    case 'm':
    case 'n':
    case 'o':
    case 'p':
    case 'q':
    case 'r':
    case 's':
    case 't':
    case 'u':
    case 'v':
    case 'w':
    case 'x':
    case 'y':
    case 'z':
	if (who - 'a' + 10 > nplayers) {
	    warning("Invalid player number");
	    return (0);
	} else if (isPlaying(&players[who - 'a' + 10])) {
	    return (getaddr2(MINDIV, who - 'a' + 10));
	} else {
	    warning("Player is not in game");
	    return (0);
	}
	break;
    default:
	{
	    int     i;
	    for (i = 0; i < number_of_teams; i++) {
		if (addr == teaminfo[i].letter)
		    break;
	    }
	    if (i < number_of_teams) {
		return getaddr2(MTEAM, i);
	    }
	}
	warning("Not legal recipient");
	return (0);
    }
}

/*static*/
char   *
getaddr2(flags, recip)
    int     flags;
    int     recip;
{
    static char addrmesg[ADDRLEN];

    (void) sprintf(addrmesg, " %c%c->", teaminfo[me->p_teami].letter, shipnos[me->p_no]);
    switch (flags) {
    case MALL:
	(void) sprintf(&addrmesg[5], "ALL");
	break;
    case MTEAM:
	(void) sprintf(&addrmesg[5], teaminfo[recip].shortname);
	break;
    case MINDIV:
	(void) sprintf(&addrmesg[5], "%c%c ",
		   teaminfo[players[recip].p_teami].letter, shipnos[recip]);
	break;
    case MGOD:
	(void) sprintf(&addrmesg[5], "GOD");
	break;
#ifdef TOOLS
    case MTOOLS:
	(void) sprintf(addrmesg, "  Shell>");
	break;
#endif
   case MCAST:
	(void) sprintf(&addrmesg[5], "MCAS");
    }

    return (addrmesg);
}

/* Used in NEWMACRO, useful elsewhere also */
int
getgroup(addr, recip)
    char    addr;
    int    *recip;
{
    *recip = 0;

    switch (addr) {
    case 'A':
	*recip = 0;
	return (MALL);
	break;
    case 'T':			/* had to add this...why didn't COW-lite need
				   it?? -JR */
	*recip = idx_to_mask(me->p_teami);
	return (MTEAM);
	break;
    case 'F':
	*recip = FEDm;
	return (MTEAM);
	break;
    case 'R':
	*recip = ROMm;
	return (MTEAM);
	break;
    case 'K':
	*recip = KLIm;
	return (MTEAM);
	break;
    case 'O':
	*recip = ORIm;
	return (MTEAM);
	break;
    case 'G':
	*recip = 0;
	return (MGOD);
	break;
#ifdef TOOLS
    case '!':
	*recip = 0;
	return (MTOOLS);
	break;
#endif
    case 'M':
	*recip = 0;
	return (MMOO);
	break;
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
	if (players[addr - '0'].p_status == PFREE) {
	    warning("That player left the game. message not sent.");
	    return 0;
	}
	*recip = addr - '0';
	return (MINDIV);
	break;
    case 'a':
    case 'b':
    case 'c':
    case 'd':
    case 'e':
    case 'f':
    case 'g':
    case 'h':
    case 'i':
    case 'j':
    case 'k':
    case 'l':
    case 'm':
    case 'n':
    case 'o':
    case 'p':
    case 'q':
    case 'r':
    case 's':
    case 't':
    case 'u':
    case 'v':
    case 'w':
    case 'x':
    case 'y':
    case 'z':
	if (players[addr - 'a' + 10].p_status == PFREE) {
	    warning("That player left the game. message not sent.");
	    return 0;
	}
	*recip = addr - 'a' + 10;
	return (MINDIV);
	break;
    default:
	warning("Not legal recipient");
    }
    return 0;
}





/*-------------------------------EMERGENCY--------------------------------*/
/*  This function sends a distress message out to the player's team.  */
void
emergency()
{
    char    ebuf[120];		/* to sprintf into */
    char    buf2[20];

    sprintf(ebuf, "Distress  %c%c",	/* get team and end */
	    teaminfo[me->p_teami].letter, shipnos[me->p_no]);
    switch (myship->s_type) {
    case STARBASE:
	strcat(ebuf, " (Starbase): ");
	break;
    case WARBASE:
	strcat(ebuf, " (Warbase): ");
	break;
    case JUMPSHIP:
	strcat(ebuf, " (Jumpship): ");
	break;
    default:
	strcat(ebuf, ": ");
    }
    if (me->p_damage != 0) {
	if (me->p_damage > me->p_ship->s_maxdamage - 30)
	    sprintf(buf2, "DEAD MAN  ");
	else
	    sprintf(buf2, "damg: %d%%  ", (100 * me->p_damage) / me->p_ship->s_maxdamage);
	strcat(ebuf, buf2);
    }
    if (me->p_shield < me->p_ship->s_maxshield) {
	if (me->p_shield < 5)
	    sprintf(buf2, "NO SHIELDS  ");
	else
	    sprintf(buf2, "shld: %d%%  ", (100 * me->p_shield) / me->p_ship->s_maxshield);
	strcat(ebuf, buf2);
    }
    if (me->p_wtemp > 0) {
	if (me->p_flags & PFWEP)
	    sprintf(buf2, "WTEMP  ");
	else
	    sprintf(buf2, "W %d%%  ", (100 * me->p_wtemp) / me->p_ship->s_maxwpntemp);
	strcat(ebuf, buf2);
    }
    if (me->p_etemp > 0) {
	if (me->p_flags & PFENG)
	    sprintf(buf2, "ETEMP  ");
	else
	    sprintf(buf2, "E %d%%  ", (100 * me->p_etemp) / me->p_ship->s_maxegntemp);
	strcat(ebuf, buf2);
    }
    if (me->p_fuel < me->p_ship->s_maxfuel) {
	if (me->p_fuel < 400)
	    sprintf(buf2, "NO FUEL  ");
	else
	    sprintf(buf2, "F %d%%  ", (100 * me->p_fuel) / me->p_ship->s_maxfuel);
	strcat(ebuf, buf2);
    }
    if ((int) strlen(ebuf) < 12)
	strcat(ebuf, "  perfect health  ");
    if (me->p_armies > 0) {
	sprintf(buf2, "%d ARMIES!", me->p_armies);
	strcat(ebuf, buf2);
    }
    pmessage(ebuf, idx_to_mask(me->p_teami), MTEAM);
}



void
carry_report()
{
    char    ebuf[MSGLEN], *pntr;
    double  dist, closedist;
    struct planet *k, *p = NULL;

    closedist = blk_gwidth;

    for (k = &planets[0]; k < &planets[nplanets]; k++) {
	dist = hypot((double) (me->p_x - k->pl_x),
		     (double) (me->p_y - k->pl_y));
	if (dist < closedist) {
	    p = k;
	    closedist = dist;
	}
    }
    if (myship->s_type == STARBASE)
        sprintf(ebuf, "Your Starbase is carrying %d armies.  ", me->p_armies);
    else
        sprintf(ebuf, "I am carrying %d armies.  ", me->p_armies);
    for (pntr = ebuf; *pntr; pntr++);
    if (paradise) {
	sprintf(pntr, "Sector: %d-%d  ", (me->p_x / GRIDSIZE) + 1,
		(me->p_y / GRIDSIZE) + 1);
	for (; *pntr; pntr++);
    }
    sprintf(pntr, "%sear %s", (me->p_flags & PFCLOAK) ? "Cloaked n" : "N",
	    p->pl_name);
    pmessage(ebuf, idx_to_mask(me->p_teami), MTEAM);
}

#ifdef NOWARP
void
message_on()
{
    if (warp) {
	W_WarpPointer(messagew);
    }
#ifdef TCURSORS
    else {
	messageon = 1;
	W_DefineTextCursor(w);
	W_DefineTextCursor(mapw);
    }
#endif				/* TCURSORS */
}

void
message_off()
{
#ifdef TCURSORS
    if (!warp) {
	messageon = 0;
	W_RevertCursor(w);
	W_RevertCursor(mapw);
    }
#endif				/* TCURSORS */
}
#endif				/* NOWARP */