/* small permutation on the newmacro code... this takes a pointer to
   ** a distress structure and a pointer to a macro syntax string,
   ** and converts it into a line of text.
   **  9/1/93 - jn
    struct distress *dist;	the info
    char   *cry;		the call for help! (output) - should be array
    char   *pm;			macro to parse, used for distress and macro
 */
int
makedistress(struct distress *dist, char *cry, char *pm)
{
    char    buf1[10 * MAXMACLEN];
    char   *pbuf1;
    char    buf2[10 * MAXMACLEN];
    char    buf3[10 * MAXMACLEN];
    char    tmp[10 * MAXMACLEN];
    int     index1 = 0;
    int     index2 = 0;
    int     index3 = 0;
    int     cap = 0;
    struct player *sender;
    struct player *j;
    struct planet *l;
    extern int ping_tloss_sc;	/* total % loss 0--100, server to client */
    extern int ping_tloss_cs;	/* total % loss 0--100, client to server */
    extern int ping_av;		/* average rt */
    extern int ping_sd;		/* standard deviation */
    char    c;


    sender = &players[dist->sender];

    if (!(*pm)) {
	cry[0] = '\0';
	return (0);
    }
    buf1[0] = '\0';
    pbuf1 = buf1;

    /* first step is to substitute variables */
    while (*pm) {
	if (*pm == '%') {
	    pm++;

	    if (!pm)
		continue;

	    switch (c = *(pm++)) {
	    case ' ':
		APPEND(pbuf1, " \0");
		break;
	    case 'O':		/* push a 3 character team name into buf */
		cap = 1;
	    case 'o':		/* push a 3 character team name into buf */
		APPEND_CAP(pbuf1, cap, teaminfo[sender->p_teami].shortname);
		cap = 0;
		break;
	    case 'a':		/* push army number into buf */
		APPEND_INT(pbuf1, dist->arms);
		break;
	    case 'd':		/* push damage into buf */
		APPEND_INT(pbuf1, dist->dam);
		break;
	    case 's':		/* push shields into buf */
		APPEND_INT(pbuf1, dist->shld);
		break;
	    case 'f':		/* push fuel into buf */
		APPEND_INT(pbuf1, dist->fuelp);
		break;
	    case 'w':		/* push wtemp into buf */
		APPEND_INT(pbuf1, dist->wtmp);
		break;
	    case 'e':		/* push etemp into buf */
		APPEND_INT(pbuf1, dist->etmp);
		break;

	    case 'P':		/* push player id into buf */
	    case 'G':		/* push friendly player id into buf */
	    case 'H':		/* push enemy target player id into buf */

	    case 'p':		/* push player id into buf */
	    case 'g':		/* push friendly player id into buf */
	    case 'h':		/* push enemy target player id into buf */

		switch (c) {
		case 'p':
		    j = &players[dist->tclose_j];
		    break;
		case 'g':
		    j = &players[dist->tclose_fr];
		    break;
		case 'h':
		    j = &players[dist->tclose_en];
		    break;
		case 'P':
		    j = &players[dist->close_j];
		    break;
		case 'G':
		    j = &players[dist->close_fr];
		    break;
		default:
		    j = &players[dist->close_en];
		    break;
		}
		tmp[0] = j->p_mapchars[1];
		tmp[1] = '\0';
		APPEND(pbuf1, tmp);
		break;

	    case 'n':		/* push planet armies into buf */
		l = &planets[dist->tclose_pl];
		APPEND_INT(pbuf1,
			   ((l->pl_info & idx_to_mask(sender->p_teami))
			    ? l->pl_armies : -1));
		break;
	    case 'B':
		cap = 1;
	    case 'b':		/* push planet into buf */
		l = &planets[dist->close_pl];
		tmp[0] = l->pl_name[0] - 'A' + 'a';
		tmp[1] = l->pl_name[1];
		tmp[2] = l->pl_name[2];
		tmp[3] = '\0';
		APPEND_CAP(pbuf1, cap, tmp);
		cap = 0;
		break;
	    case 'L':
		cap = 1;
	    case 'l':		/* push planet into buf */
		l = &planets[dist->tclose_pl];
		tmp[0] = l->pl_name[0] - 'A' + 'a';
		tmp[1] = l->pl_name[1];
		tmp[2] = l->pl_name[2];
		tmp[3] = '\0';
		APPEND_CAP(pbuf1, cap, tmp);
		cap = 0;
		break;
	    case 'Z':		/* push a 3 character team name into buf */
		cap = 1;
	    case 'z':		/* push a 3 character team name into buf */
		l = &planets[dist->tclose_pl];
		APPEND_CAP(pbuf1, cap,
			   teaminfo[mask_to_idx(l->pl_owner)].shortname);
		cap = 0;
		break;
	    case 't':		/* push a team character into buf */
		l = &planets[dist->tclose_pl];
		tmp[0] = teaminfo[mask_to_idx(l->pl_owner)].letter;
		tmp[1] = '\0';
		APPEND(pbuf1, tmp);
		break;
	    case 'T':		/* push my team into buf */
		tmp[0] = teaminfo[sender->p_teami].letter;
		tmp[1] = '\0';
		APPEND(pbuf1, tmp);
		break;
	    case 'c':		/* push my id char into buf */
		tmp[0] = sender->p_mapchars[1];
		tmp[1] = '\0';
		APPEND(pbuf1, tmp);
		break;
	    case 'W':		/* push WTEMP flag into buf */
		if (dist->wtmpflag)
		    tmp[0] = '1';
		else
		    tmp[0] = '0';
		tmp[1] = '\0';
		APPEND(pbuf1, tmp);
		break;
	    case 'E':		/* push ETEMP flag into buf */
		if (dist->etempflag)
		    tmp[0] = '1';
		else
		    tmp[0] = '0';
		tmp[1] = '\0';
		APPEND(pbuf1, tmp);
		break;
	    case 'K':
		cap = 1;
	    case 'k':
		if (cap)
		    j = &players[dist->tclose_en];
		else
		    j = sender;

		if (j->p_ship->s_type == STARBASE)
		    sprintf(tmp, "%5.2f", j->p_stats.st_sbkills / 100.0);
		else
		    sprintf(tmp, "%5.2f", (j->p_stats.st_kills + j->p_stats.st_tkills) / 100.0);
		APPEND(pbuf1, tmp);
		break;

	    case 'U':		/* push player name into buf */
		cap = 1;
	    case 'u':		/* push player name into buf */
		j = &players[dist->tclose_en];
		APPEND_CAP(pbuf1, cap, j->p_name);
		cap = 0;
		break;
	    case 'I':		/* my player name into buf */
		cap = 1;
	    case 'i':		/* my player name into buf */
		APPEND_CAP(pbuf1, cap, sender->p_name);
		cap = 0;
		break;
	    case 'S':		/* push ship type into buf */
		*pbuf1++ = sender->p_ship->s_desig[0];
		*pbuf1++ = sender->p_ship->s_desig[1];
		break;
	    case 'M':		/* push capitalized lastMessage into buf */
		cap = 1;
	    case 'm':		/* push lastMessage into buf */
		APPEND_CAP(pbuf1, cap, lastMessage);
		cap = 0;
		break;

	    case 'v':		/* push average ping round trip time into buf */
		APPEND_INT(pbuf1, ping_av);
		break;

	    case 'V':		/* push ping stdev into buf */
		APPEND_INT(pbuf1, ping_sd);
		break;

	    case 'y':		/* push packet loss into buf */
		/* this is the weighting formula used be socket.c ntserv */
		APPEND_INT(pbuf1, (2 * ping_tloss_sc + ping_tloss_cs) / 3);
		break;
	    case '*':		/* push %} into buf */
		APPEND(pbuf1, "%*\0");
		break;
	    case '}':		/* push %} into buf */
		APPEND(pbuf1, "%}\0");
		break;
	    case '{':		/* push %{ into buf */
		APPEND(pbuf1, "%{\0");
		break;
	    case '!':		/* push %! into buf */
		APPEND(pbuf1, "%!\0");
		break;
	    case '?':		/* push %? into buf */
		APPEND(pbuf1, "%?\0");
		break;
	    case '%':		/* push %% into buf */
		APPEND(pbuf1, "%%\0");
		break;
	    default:
/* try to continue
** bad macro character is skipped entirely,
** the message will be parsed without whatever %. has occurred. - jn
*/
		warning("Bad Macro character in distress!");
		fprintf(stderr, "Unrecognizable special character in distress pass 1: %c\n", *(pm - 1));
		break;
	    }
	} else {
	    tmp[0] = *pm;
	    tmp[1] = '\0';
	    APPEND(pbuf1, tmp);
	    pm++;
	}

    }

    *pbuf1 = '\0';

    /* second step is to evaluate tests, buf1->buf2 */
    testmacro(buf1, buf2, &index1, &index2);
    buf2[index2] = '\0';

    if (index2 <= 0) {
	cry[0] = '\0';
	return (0);
    }
    index2 = 0;

    /* third step is to include conditional text, buf2->buf3 */
    condmacro(buf2, buf3, &index2, &index3, 1);

    if (index3 <= 0) {
	cry[0] = '\0';
	return (0);
    }
    buf3[index3] = '\0';

    cry[0] = '\0';
    strncat(cry, buf3, MSG_LEN);

    return (index3);
}
Example #2
0
/* small permutation on the newmacro code... this takes a pointer to
   ** a distress structure and a pointer to a macro syntax string,
   ** and converts it into a line of text.
   **  9/1/93 - jn
 */
int makedistress (struct distress *dist, /* the info */
                   char *cry, 	/* the call for help! (output) -
                                   should be array */
                   char *pm)	/* macro to parse, used for distress and
                                   macro */
{
  char buf1[10 * MAXMACLEN];
  char *pbuf1;
  char buf2[10 * MAXMACLEN];
  char buf3[10 * MAXMACLEN];
  char tmp[10 * MAXMACLEN];
  int index = 0;
  int index2 = 0;
  int index3 = 0;
  int cap = 0;
  struct player *sender;
  struct player *j;
  struct planet *l;
  char c;
  char *macro;

  sender = &players[dist->sender];

  if (!(*pm))
    {
      cry[0] = '\0';
      return (0);
    }

  buf1[0] = '\0';
  pbuf1 = buf1;

  macro = pm;

  /* first step is to substitute variables */
  while (*pm)
    {
      if (*pm == '%')
	{
	  pm++;

	  if (!pm)
	      continue;

	  switch (c = *(pm++))
	    {
	    case ' ':
	      APPEND (pbuf1, " \0");
	      break;
	    case 'O':		/* push a 3 character team name into buf */
	      cap = 1;
	    case 'o':		/* push a 3 character team name into buf */
	      if (sender->p_team != ALLTEAM)
		APPEND_CAP (pbuf1, cap, teamshort[sender->p_team]);
	      cap = 0;
	      break;
	    case 'a':		/* push army number into buf */
	      APPEND_INT(pbuf1, dist->arms);
	      break;
	    case 'd':		/* push damage into buf */
	      APPEND_INT (pbuf1, dist->dam);
	      break;
	    case 's':		/* push shields into buf */
	      APPEND_INT (pbuf1, dist->shld);
	      break;
	    case 'f':		/* push fuel into buf */
	      APPEND_INT (pbuf1, dist->fuelp);
	      break;
	    case 'w':		/* push wtemp into buf */
	      APPEND_INT (pbuf1, dist->wtmp);
	      break;
	    case 'e':		/* push etemp into buf */
	      APPEND_INT (pbuf1, dist->etmp);
	      break;

	    case 'P':		/* push player id into buf */
	    case 'G':		/* push friendly player id into buf */
	    case 'H':		/* push enemy target player id into buf */

	    case 'p':		/* push player id into buf */
	    case 'g':		/* push friendly player id into buf */
	    case 'h':		/* push enemy target player id into buf */

	      switch (c)
		{
		case 'p':
		  j = &players[dist->tclose_j];
		  break;
		case 'g':
		  j = &players[dist->tclose_fr];
		  break;
		case 'h':
		  j = &players[dist->tclose_en];
		  break;
		case 'P':
		  j = &players[dist->close_j];
		  break;
		case 'G':
		  j = &players[dist->close_fr];
		  break;
		default:
		  j = &players[dist->close_en];
		  break;
		}
	      tmp[0] = j->p_mapchars[1];
	      tmp[1] = '\0';
	      APPEND (pbuf1, tmp);
	      break;

	    case 'n':		/* push planet armies into buf */
	      l = &planets[dist->tclose_pl];
	      APPEND_INT (pbuf1,
			  ((l->pl_info & sender->p_team) ? l->pl_armies : -1));
              break;
            case 'B':
              cap = 1;
	    case 'b':		/* push planet into buf */
	      l = &planets[dist->close_pl];
	      tmp[0] = l->pl_name[0] - 'A' + 'a';
	      tmp[1] = l->pl_name[1];
              tmp[2] = l->pl_name[2];
	      tmp[3] = '\0';
	      APPEND_CAP (pbuf1, cap, tmp);
	      cap = 0;
	      break;
	    case 'L':
	      cap = 1;
	    case 'l':		/* push planet into buf */
	      l = &planets[dist->tclose_pl];
	      tmp[0] = l->pl_name[0] - 'A' + 'a';
	      tmp[1] = l->pl_name[1];
	      tmp[2] = l->pl_name[2];
	      tmp[3] = '\0';
	      APPEND_CAP (pbuf1, cap, tmp);
	      cap = 0;
	      break;
	    case 'Z':		/* push a 3 character team name into buf */
	      cap = 1;
	    case 'z':		/* push a 3 character team name into buf */
	      l = &planets[dist->tclose_pl];
	      APPEND_CAP (pbuf1, cap, teamshort[l->pl_owner]);
	      cap = 0;
	      break;
	    case 't':		/* push a team character into buf */
	      l = &planets[dist->tclose_pl];
	      tmp[0] = teamlet[l->pl_owner];
	      tmp[1] = '\0';
	      APPEND (pbuf1, tmp);
	      break;
	    case 'T':		/* push my team into buf */
	      tmp[0] = teamlet[sender->p_team];
	      tmp[1] = '\0';
	      APPEND (pbuf1, tmp);
	      break;
	    case 'c':		/* push my id char into buf */
	      tmp[0] = sender->p_mapchars[1];
	      tmp[1] = '\0';
	      APPEND (pbuf1, tmp);
	      break;
	    case 'W':		/* push WTEMP flag into buf */
	      if (dist->wtmpflag)
		tmp[0] = '1';
	      else
		tmp[0] = '0';
	      tmp[1] = '\0';
	      APPEND (pbuf1, tmp);
	      break;
	    case 'E':		/* push ETEMP flag into buf */
	      if (dist->etempflag)
		tmp[0] = '1';
	      else
		tmp[0] = '0';
	      tmp[1] = '\0';
	      APPEND (pbuf1, tmp);
	      break;
            case 'K':
              cap = 1;
            case 'k':
              if (cap)
                j = &players[dist->tclose_en];
              else
                j = sender;
 
              if (j->p_ship.s_type == STARBASE)
#ifdef LTD_STATS
                sprintf (tmp, "%5.2f", (float) ltd_kills(j, LTD_SB));
#else
                sprintf (tmp, "%5.2f", (float) j->p_stats.st_sbkills);
#endif
              else
#ifdef LTD_STATS
                sprintf (tmp, "%5.2f", (float) ltd_kills(j, LTD_TOTAL));
#else
                sprintf (tmp, "%5.2f", (float) j->p_stats.st_kills +
                         j->p_stats.st_tkills);
#endif
              APPEND (pbuf1, tmp);
              break;

	    case 'U':		/* push player name into buf */
	      cap = 1;
	    case 'u':		/* push player name into buf */
	      j = &players[dist->tclose_en];
	      APPEND_CAP (pbuf1, cap, j->p_name);
	      cap = 0;
	      break;
	    case 'I':		/* my player name into buf */
	      cap = 1;
	    case 'i':		/* my player name into buf */
	      APPEND_CAP (pbuf1, cap, sender->p_name);
	      cap = 0;
	      break;
	    case 'S':		/* push ship type into buf */
              APPEND (pbuf1, shiptypes[sender->p_ship.s_type]);
	      break;
                 case 'v':      /* push average ping round trip time into buf */
                 case 'V':      /* push ping stdev into buf */
                 case 'y':      /* push packet loss into buf */
                   APPEND (pbuf1, "0\0");
            case 'M':           /* push capitalized lastMessage into buf */
            case 'm':           /* push lastMessage into buf */
                   break;
	    case '*':		/* push %} into buf */
	      APPEND (pbuf1, "%*\0");
	      break;
	    case '}':		/* push %} into buf */
	      APPEND (pbuf1, "%}\0");
	      break;
	    case '{':		/* push %{ into buf */
	      APPEND (pbuf1, "%{\0");
	      break;
	    case '!':		/* push %! into buf */
	      APPEND (pbuf1, "%!\0");
	      break;
	    case '?':		/* push %? into buf */
	      APPEND (pbuf1, "%?\0");
	      break;
	    case '%':		/* push %% into buf */
	      APPEND (pbuf1, "%%\0");
	      break;
	    default:
/* try to continue
** bad macro character is skipped entirely,
** the message will be parsed without whatever %. has occurred. - jn
*/
	      dist_error("Pass 1",macro,*pm-1);
	      break;     
	    }
	}