static char *rcsid = "$Header: /plaid/homes/zeus/Blind-2.47/report/RCS/Battle.c,v 2.47 1998/04/15 21:37:54 zeus Exp zeus $";

/*
 * $Log: Battle.c,v $
 * Revision 2.47  1998/04/15 21:37:54  zeus
 * *** empty log message ***
 *
 * Revision 2.46  1997/04/18 12:25:12  zeus
 * *** empty log message ***
 *
 * Revision 2.45  1997/01/01  00:20:45  zeus
 * Revision 2.44  1995/12/31  19:45:18  zeus
 * Revision 2.43  1995/03/20  01:43:09  zeus
 *
 */

#define NOTIMEB
#include "common.h"
#include "prototypes.h"
#include "report-g.h"
#include "report.h"
#include "misc-g.h"
#include "i-o.h"
#include "options.h"

void report_battle_rcsid (void);

void
report_battle_rcsid (void)
{
  printf ("%s\n", rcsid);
}

extern char buf[];
extern battle *battles;
extern bombing *bombings;
extern player *players;
extern FILE *pr;



void
print_player_groups_in_battle (player * P, participant * PA)
{
  group *g;

  if (P->opts1 & BATTLESUM)
  {
    if (P->opts2 & TECHS)
    {
      fbegin (buf, "iixffffxfff");
      fhead ("R#TDWSCTQMS");
    }
    else
    {
      fbegin (buf, "iixfifffxfff");
      fhead ("R#TDAWSCTQMS");
    }
    for (g = PA->groups; g; g = g->next)
      printgroup (P, g, PG_BATSUM, 1);
    fend ();
  }
  else
  {
    if (P->opts2 & TECHS)
    {
      fbegin (buf, "ixffffxfff");
      fhead ("#TDWSCTQMS");
    }
    else
    {
      fbegin (buf, "ixfifffxfff");
      fhead ("#TDAWSCTQMS");
    }
    for (g = PA->groups; g; g = g->next)
      printgroup (P, g, PG_SIMP_BATTLE, 1);
    fend ();
  }
}

void
print_battles (player * P)
{
  player *P2;
  shot *S;
  battle *B;
  viewer *V;
  participant *PA;
  group *g;
  int i1 = 0, i2 = 0;

  for (B = battles; B; B = B->next)
  {
    for (V = B->viewers; V; V = V->next)
      if (V->who == P)
	break;
    if (V)
    {
      strcpy (buf, B->where->name);
      ckunderscores (buf);
      if (canseeplanet (P, B->where, 1))
	fprintf (pr, "\t\tBattle at %s (%s)\n\n", B->where->num, buf);
      else
	fprintf (pr, "\t\tBattle at %s\n\n", B->where->num);
      for (PA = B->participants; PA; PA = PA->next)
      {
	if (PA->who == P)
	{
	  sprintf (buf, "Your Groups");
	  print_player_groups_in_battle (P, PA);
	  break;
	}
      }
      for (PA = B->participants; PA; PA = PA->next)
      {
	P2 = PA->who;
	if (i1 < strlen (P2->name))
	  i1 = strlen (P2->name);
	for (g = PA->groups; g; g = g->next)
	{
	  if (i2 < strlen (g->type->name))
	    i2 = strlen (g->type->name);
	}
	if (P2 != P)
	{
	  strcpy (buf, P2->name);
	  ckunderscores (buf);
	  strcat (buf, " Groups");
	  print_player_groups_in_battle (P, PA);
	}
      }

      if (P->opts1 & BATTLEMASS)
      {
	group *g;
	double bm, fm, btm, ftm;
	double m;
	int b, f;

	sprintf (buf, "Battle masses");
	fbegin (buf, "xiffifff");
	fhead ("W#MT#MT ");
	for (PA = B->participants; PA; PA = PA->next)
	  if (PA->who == P)
	  {
	    b = f = 0;
	    bm = fm = btm = ftm = 0.0;
	    for (g = PA->groups; g; g = g->next)
	    {
	      b += g->ships;
	      m = (typemass (g->type));
	      f += g->left;
	      fm += m * (double) g->left;
	      ftm += (double) g->left * ttechmass (g);
	      bm += m * (double) g->ships;
	      btm += (double) g->ships * ttechmass (g);
	    }
	    if (bm > 0.0)
	    {
	      fs (P->name);
	      fi (f);
	      ff (fm);
	      ff (ftm);
	      fi (b);
	      ff (bm);
	      ff (btm);
	      ff (100.0 * fm / bm);
	    }
	    break;
	  }
	for (PA = B->participants; PA; PA = PA->next)
	  if (PA->who != P)
	  {
	    b = f = 0;
	    bm = fm = btm = ftm = 0.0;
	    for (g = PA->groups; g; g = g->next)
	    {
	      b += g->ships;
	      f += g->left;
	      m = (typemass (g->type));
	      fm += m * (double) g->left;
	      ftm += (double) g->left * ttechmass (g);
	      bm += m * (double) g->ships;
	      btm += (double) g->ships * ttechmass (g);
	    }
	    if (bm > 0.0)
	    {
	      fs (PA->who->name);
	      fi (f);
	      ff (fm);
	      ff (ftm);
	      fi (b);
	      ff (bm);
	      ff (btm);
	      ff (100.0 * fm / bm);
	    }
	  }
	fend ();
      }

      if (!(P->opts1 & LONGBATTLE))
	/* print the blow-by-blow, but only for those that care... */
      {
	int i;
	char *a1, *a2, *a3, *a4;
	a1 = (char *) alloc (sizeof (char) * (i1 + 1));
	a2 = (char *) alloc (sizeof (char) * (i2 + 1));
	a3 = (char *) alloc (sizeof (char) * (i1 + 1));
	a4 = (char *) alloc (sizeof (char) * (i2 + 1));

	for (S = B->shots; S; S = S->next)
	{
	  strcpy (a1, S->attacker->owner->name);
	  for (i = strlen (a1); i < i1; i++)
	    a1[i] = ' ';
	  strcpy (a2, S->attacker->name);
	  for (i = strlen (a2); i < i2; i++)
	    a2[i] = ' ';
	  strcpy (a3, S->target->owner->name);
	  for (i = strlen (a3); i < i1; i++)
	    a3[i] = ' ';
	  strcpy (a4, S->target->name);
	  for (i = strlen (a4); i < i2; i++)
	    a4[i] = ' ';
	  fprintf (pr, "%s %s fires on %s %s %s\n", a1, a2, a3, a4, S->kill ? ":  Destroyed" : ":  Shields");
	}
	fprintf (pr, "\n");
      }
    }
  }
}

void
print_battle_sum (player * P)
{
  player *P2;
  battle *B;
  participant *PA;
  int numb, pnum, nump;
  group *g;
  int *b, *f;
  double *bm, *fm, *btm, *ftm;
  double ms;
  int m;



  nump = listlen (players) + 2;
  bm = alloc (nump * sizeof (double));
  fm = alloc (nump * sizeof (double));
  btm = alloc (nump * sizeof (double));
  ftm = alloc (nump * sizeof (double));
  b = alloc (nump * sizeof (int));
  f = alloc (nump * sizeof (int));
  memset (bm, 0, sizeof (double) * nump);
  memset (fm, 0, sizeof (double) * nump);
  memset (btm, 0, sizeof (double) * nump);
  memset (ftm, 0, sizeof (double) * nump);
  memset (b, 0, sizeof (int) * nump);
  memset (f, 0, sizeof (int) * nump);

  PA = NULL;

  numb = 0;			/* No battles yet */

  for (B = battles; B; B = B->next)
  {
    if (P)
      for (PA = B->participants; PA; PA = PA->next)
	if (PA->who == P)
	  break;
    if (PA || !P)		/* We participated, or are GM */
    {
      numb++;
      for (PA = B->participants; PA; PA = PA->next)
      {
	pnum = ptonum (players, PA->who);
	for (g = PA->groups; g; g = g->next)
	{
	  b[pnum] += g->ships;
	  ms = (typemass (g->type));
	  f[pnum] += g->left;
	  fm[pnum] += ms * (double) g->left;
	  ftm[pnum] += (double) g->left * ttechmass (g);
	  bm[pnum] += ms * (double) g->ships;
	  btm[pnum] += (double) g->ships * ttechmass (g);

	  /* GM Summary */
	  if (!P)
	  {
	    b[nump - 1] += g->ships;
	    f[nump - 1] += g->left;
	    fm[nump - 1] += ms * (double) g->left;
	    ftm[nump - 1] += (double) g->left * ttechmass (g);
	    bm[nump - 1] += ms * (double) g->ships;
	    btm[nump - 1] += (double) g->ships * ttechmass (g);
	  }
	}
      }
    }
  }
  if (numb)
  {
    sprintf (buf, "Battle Summary for %d battles\n", numb);
    fbegin (buf, "xiffifff");
    fhead ("W#MT#MT ");

    for (m = 0; m < nump; m++)
    {
      if (bm[m] > 0)
      {
	for (P2 = players, pnum = 0; P2; pnum++, P2 = P2->next)
	{
	  if (pnum == m - 1)
	  {
	    fs (P2->name);
	    break;
	  }
	}
	/* GM mode, and not matched and last record, print, else check */
	if ((!P) && (!P2) && (m + 1 == nump))
	{
	  fs ("Total");
	}
	else
	{
	  assert (P2 != NULL);
	}
	fi (f[m]);
	ff (fm[m]);
	ff (ftm[m]);
	fi (b[m]);
	ff (bm[m]);
	ff (btm[m]);
	ff (100.0 * fm[m] / bm[m]);
      }
    }
    fend ();
  }
  free (bm);
  free (btm);
  free (fm);
  free (ftm);
  free (b);
  free (f);
}


void
print_bombings (player * P)
{
  bombing *b;
  battle *B;
  viewer *V;

  fbegin ("Bombings", "xxxxfffff");
  fhead ("WO#NPIC$M");
  for (b = bombings; b; b = b->next)
  {
    for (V = b->viewers; V; V = V->next)
    {
      if (V->who == P)
	break;
    }
    if (V)			/* Saw the bombing */
    {
      for (B = battles; B; B = B->next)
      {
	if (B->where == b->where)
	  break;
      }
      if (B)			/* Was a battle */
      {
	for (V = B->viewers; V; V = V->next)
	  if (V->who == P)
	    break;
	if (V)			/* Saw the battle */
	{			/* So print bomber info */
	  fs (b->who->name);
	}
	else
	  fs ("?");		/* Didn't see battle */
      }
      else
      {
	if (canseeplanet (P, b->where, 1))	/* No battle, but you can see it */
	  fs (b->who->name);
	else
	  fs ("?");		/* Was no battle */
      }
      fs (b->whoose->name);
      fs (b->where->num);
      fs (b->where->name);
      ff (b->pop);
      ff (b->ind);
      ff (b->col);
      ff (b->cap);
      ff (b->mat);
    }
  }
  fend ();
}


void
print_bombing_summary (player * P)
{
  bombing *b;
  battle *B;
  viewer *V;
  bombsum *br, *br2;


  br = alloc (sizeof (bombsum));
  br->next = NULL;
  br->owner = NULL;
  br->bomber = NULL;
  fbegin ("Bombing Summary", "xxifffff");
  fhead ("WO#PIC$M");

  for (b = bombings; b; b = b->next)
  {
    for (V = b->viewers; V; V = V->next)
    {
      if (V->who == P)
	break;
    }
    if (V)			/* Saw the bombing */
    {
      for (B = battles; B; B = B->next)
      {
	if (B->where == b->where)
	  break;
      }
      if (B)			/* Was a battle */
      {
	for (V = B->viewers; V; V = V->next)
	  if (V->who == P)
	    break;
	if (V)			/* Saw the battle */
	{			/* So print bomber info */
	  add_bomb_rec (b, br, SAW_IT);
	}
	else
	  add_bomb_rec (b, br, NOT_SEEN);	/* Didn't see battle */
      }
      else
      {
	if (canseeplanet (P, b->where, 1))	/* No battle, but you can see it */
	  add_bomb_rec (b, br, SAW_IT);
	else
	  add_bomb_rec (b, br, NOT_SEEN);	/* Was no battle */
      }
    }				/* Saw the bombing */
  }				/* bombings */
  for (br2 = br->next; br2; br2 = br2->next)
  {
    if (br2->bomber)
      fs (br2->bomber->name);
    else
      fs ("?");			/* The unknown bomber */
    fs (br2->owner->name);
    fi (br2->num_bombed);
    ff (br2->pop);
    ff (br2->ind);
    ff (br2->col);
    ff (br2->cap);
    ff (br2->mat);
  }
  freelist (br);
  fend ();
}

void
add_bomb_rec (bombing * b, bombsum * br, int flag)
{
  bombsum *b2;

  for (b2 = br; b2; b2 = b2->next)
  {
    if (((b2->bomber == b->who) && (b2->owner == b->whoose) && (flag==SAW_IT))
        || ((flag == NOT_SEEN) && (b2->bomber == NULL) && 
        (b2->owner == b->whoose)))
    {
      b2->num_bombed++;
      b2->pop += b->pop;
      b2->ind += b->ind;
      b2->col += b->col;
      b2->cap += b->cap;
      b2->mat += b->mat;
      return;
    }
  }
  /* No current record, so add one */
  b2 = alloc (sizeof (bombsum));
  addlist (&br, b2);
  if (flag == SAW_IT)
    b2->bomber = b->who;
  else
    b2->bomber = NULL;
  b2->owner = b->whoose;
  b2->num_bombed = 1;
  b2->pop = b->pop;
  b2->ind = b->ind;
  b2->col = b->col;
  b2->cap = b->cap;
  b2->mat = b->mat;
  b2->next = NULL;
}
