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

/*
 * $Log: planets.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:28:33  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 "options.h"

extern player *players;
extern planet *planets;
extern char buf[];
extern char buf2[];
extern sorted *sorted_planets;
extern int nplanets;

#ifdef KCMD
extern planetdefense *defender;

#endif

#ifdef FORECAST
extern int seenlist[];

#endif


int canseeall = 0;


void report_planets_rcsid (void);

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


int
canseeplanet (player * P, planet * p, int flag)
{                               /* Flag = 1 -> Attempt to use lookup table, 0 == don't */
  group *g;

#if SPEED&8
  static player *P2;            /* Track for whom the list is set up */
  static int *seensystems;      /* Shortcut list itself.... */

#endif

  if (canseeall)
    return 1;                   /* gm Cheat mode */
  if (p->owner == P)
    return 1;

#if SPEED&8
  if (flag && (seensystems == NULL))
    seensystems = alloc (sizeof (int) * nplanets);

  if (flag && (P2 != P))
  {
    memset (seensystems, 0, nplanets * sizeof (int));

    P2 = P;
    for (g = P->groups; g; g = g->next)
      if (g->dist == 0.0)
      {
        seensystems[atoi (g->where->num)] = 1;
      }
  }

  if (flag)
    return (seensystems[atoi (p->num)]);
#endif

  for (g = P->groups; g; g = g->next)
    if (g->dist == 0.0 && g->where == p)
      return 1;
  return 0;
}

#ifndef NEWGAME
void
printplanet (planet * p, player * P)
{
  static char *productname[] =
  {
    "CAP",
    "MAT",
    0,
    "Drive",
    "Weapons",
    "Shields",
    "Cargo",
  };

  fs (p->name);
  fs (p->num);
  ff (wrap (p->x - P->homex));  /* GE - relative coordinate fix */
  ff (cartesian(wrap (p->y - P->homey)));
  ff (p->size);
  ff (p->pop);
  ff (p->ind);
  ff (p->resources);

#ifdef FORECAST
  if (p->owner == P)
  {
#endif

    if (p->producing == PR_SHIP)
      fs (p->producingshiptype->name);
    else
      fs (productname[p->producing]);

#ifdef FORECAST
  }
  else
    fs ("?");                   /* Don't really know, do we? */
#endif

  ff (p->col);
  ff (p->cap);
  ff (p->mat);
}

#ifndef EDIT
void
in_production (planet * p, int flag)
{
  double pmass;
  double smass;
  double inprog;

  fs (p->name);
  fs (p->num);
  ff (effective_ind (p));
  ff (produce_mat (p));
  ff (produce_cap (p));
  ff (Ftrunc (produce_mass (p)));
  if (p->producing == PR_SHIP)
  {
    fs (p->producingshiptype->name);
#ifdef PARTTECH
    if (flag==TECHPROD)
    {
      ff (p->drive);
      ff (p->guns);
      ff (p->shields);
      ff (p->cargo);
    }
#endif
    smass = typemass (p->producingshiptype);
    pmass = smass * INDPERSHIP;
    inprog = p->inprogress;
    if (smass > p->mat)
      pmass += (smass - p->mat) / p->resources;
    ff (pmass);
    ff (inprog);
  }
  else
  {
    fs ("-");
#ifdef PARTTECH
    if (flag==TECHPROD)
    {
      ff (0.0);
      ff (0.0);
      ff (0.0);
      ff (0.0);
    }
#endif
    ff (0.0);
    ff (0.0);
  }
}

/* Print unowned systems (normally), or if in forecast mode, ones
   you don't own, but could see at the begining of the turn. */

void
print_unowned_planets (player * P)
{
  planet *p;
  char buf3[MAXTEXT];

  for (p = planets; p; p = p->next)

#ifdef FORECAST
    if ((seenlist[ptonum (planets, p)]) && (p->owner == NULL))
#else
    if ((p->owner == NULL) && canseeplanet (P, p, 1))
#endif

    {
      /* print the planet */

      strcpy (buf3, p->name);
      ckunderscores (buf3);
      sprintf (buf, "\nFull Report on System %s\n", buf3);

      fbegin (buf, "xxffff");
      fhead ("N#XYSR");
      fs (p->name);
      fs (p->num);
      ff (wrap (p->x - P->homex));      /* GE: relative coordinate fix */
      ff (cartesian(wrap (p->y - P->homey)));
      ff (p->size);
      ff (p->resources);
      fend ();

      if (P->opts2 & SYSMASS)
      {
        print_sys_mass (P,p);
      }
      print_groups_at_planet (P, p);
    }
}

void
print_partial_reports (player * P)
{
  /* planets you can't see but are on the way to */
  int lost;
  int *lostg;
  group *g;
  planet *p;

  lostg = alloc ((1 + nplanets) * sizeof (int));
  memset (lostg, 0, (((unsigned int) nplanets + 1) * sizeof (int)));

  lost = 0;

  for (g = P->groups; g; g = g->next)   /* Find MIA groups */

#ifdef FORECAST
    if (!(seenlist[ptonum (planets, g->where)]))
#else
    if ((g->dist > 0.0) && !(canseeplanet (P, g->where, 1)))
#endif

    {
      lostg[ptonum (planets, g->where)]++;
      lost++;
    }
  if (lost)                     /* Are there MIA Groups? */
  {
    for (p = planets; (p && lost); p = p->next)
      if (lostg[ptonum (planets, p)])   /* print the planet */
      {
        sprintf (buf, "\nPartial Report on System %s\n", p->num);
        fbegin (buf, "xff");
        fhead ("#XY");
        fs (p->num);
        ff (wrap (p->x - P->homex));
        ff (cartesian(wrap (p->y - P->homey)));
        fend ();

        /* print all groups at the planet */
        sprintf (buf, "Your groups approaching %s", p->num);
        if ((P->opts2 & TECHS) && (P->opts2 & UPCOST))
        {
          fbegin (buf, "iixffffxffffxxf");
          fhead ("G#TDWSCTQMSIDLR");
        }
        else if (P->opts2 & UPCOST)
        {
          fbegin (buf, "iixfifffxffffxxf");
          fhead ("G#TDAWSCTQMSIDLR");
        }
        else if (P->opts2 & TECHS)
        {
          fbegin (buf, "iixffffxfffxxf");
          fhead ("G#TDWSCTQMSDLR");
        }
        else
        {
          fbegin (buf, "iixfifffxfffxxf");
          fhead ("G#TDAWSCTQMSDLR");
        }

        for (g = P->groups; g; g = g->next)
          if (g->where == p)
          {
            printgroup (P, g, PG_FULL, 0);
            lost--;
          }
        fend ();

        print_fleets_at_planet (P, p);
      }
  }
  free (lostg);
}

#ifdef KCMD
void
print_selective_defenses (player * P)
{
  planetdefense *df;

  fbegin ("Selective Planet Defenses", "xxxx");
  fhead ("N#PS");
  for (df = defender; df; df = df->next)
    if (df->planet)
      if (df->planet->owner == P)
      {
        fs (df->planet->name);
        fs (df->planet->num);
        fs (df->defender->name);
        switch (df->dipstat)
        {
        case PEACE:
          fs ("Peace");
          break;
        case WAR:
          fs ("War");
          break;
        default:
          assert (0);
        }
      }
  fend ();
}

void
print_selective_def_at_p (player * P, planet * p)
{
  planetdefense *df;

  fbegin ("Selective Planet Defense", "xxxx");
  fhead ("N#PS");
  for (df = defender; df; df = df->next)
    if (df->planet)
      if ((df->planet->owner == P) && (df->planet == p))
      {
        fs (df->planet->name);
        fs (df->planet->num);
        fs (df->defender->name);
        switch (df->dipstat)
        {
        case PEACE:
          fs ("Peace");
          break;
        case WAR:
          fs ("War");
          break;
        default:
          assert (0);
        }
      }
  fend ();
}
#endif

void
print_routes (player * P)
{
  planet *p;
  int i;

  fbegin ("Your Routes", "xxxxx");
  fhead ("NC$ME");
  for (p = planets; p; p = p->next)
    if (p->owner == P && !zeromem (p->routes, sizeof (p->routes)))
    {
      fs (p->name);
      for (i = 0; i < MAXCARGO; i++)
      {
        if (p->routes[i])
        {
          if (p->routes[i]->owner == P)
            fs (p->routes[i]->name);
          else
            fs (p->routes[i]->num);
        }
        else
          fs ("-");
      }
    }
  if (P->opts2 & AUTOUNLOAD)
  {
    fs ("AUTO");
    fs ("UNLOAD");
    fs ("IS");
    fs ("CURRENTLY");
    fs ("SET");
  }
  fend ();
}

void
print_alien_planets (player * P)
{
  planet *p;
  player *P2;

  /* alien planets you can see */

  for (P2 = players; P2; P2 = P2->next)
    if (P2 != P)
    {
      strcpy (buf2, P2->name);
      ckunderscores (buf2);
      sprintf (buf, "%s Systems", buf2);
      fbegin (buf, "xxffffffxfff");
      fhead ("N#XYSPIRPC$M");
      for (p = planets; p; p = p->next)

#ifdef FORECAST
        if ((p->owner == P2) && seenlist[ptonum (planets, p)])
#else
        if ((p->owner == P2) && canseeplanet (P, p, 1))
#endif

          printplanet (p, P);
      fend ();
    }
}

void
print_full_planet (player * P, planet * p)
{
  int i;
  char buf1[MAXTEXT];
  char buf3[MAXTEXT];

  strcpy (buf1, p->name);
  ckunderscores (buf1);
  assert (p->owner !=NULL);            /* Crash here, if planet unowned. */
  strcpy (buf3, p->owner->name);
  ckunderscores (buf3);
  if (p->owner == P)
    sprintf (buf, "\nFull Report on System %s\n", buf1);
  else
    sprintf (buf, "\nFull Report on System %s (%s)\n", buf1, buf3);

  fbegin (buf, "xxffffffxfff");
  fhead ("N#XYSPIRPC$M");
  printplanet (p, P);
  fend ();
  if (p->owner == P)
  {
    if (P->opts1 & PROD)
    {
      /* Print production info */
#ifdef PARTTECH
    if (P->opts1 & TECHPROD)
    {
      fbegin ("Ship in production", "xxffffxffffff");
      fhead ("N#IM$STDWSCCU");
    }
    else
    {
      fbegin ("Ship in Production", "xxffffxff");
      fhead ("N#IM$STCU");
    }
#else
      fbegin ("Ship in production", "xxffffxff");
      fhead ("N#IM$STCU");
#endif
      in_production (p,P->opts1 & TECHPROD);
      fend ();
    }

    fbegin ("Routes", "xxxxx");
    fhead ("NC$ME");
    if (!zeromem (p->routes, sizeof (p->routes)))
    {
      fs (p->name);
      for (i = 0; i < MAXCARGO; i++)
        if (p->routes[i])
        {
          if (p->routes[i]->owner == P)
            fs (p->routes[i]->name);
          else
            fs (p->routes[i]->num);
        }
        else
          fs ("-");
    }
    fend ();

#ifdef KCMD
    print_selective_def_at_p (P, p);
#endif

#ifndef FORECAST
    print_incoming (P, p);      /* print all incoming groups to the planet */
#endif
  }
  if (P->opts2 & SYSMASS)
  {
    print_sys_mass (P,p);
  }
  print_groups_at_planet (P, p);
}

void
print_full_your_planets (player * P)
{
  sorted *s;
  planet *p;

  if (P->opts2 & SORTPLANETS)
    for (s = sorted_planets, p = s->p; s; s = s->next)
    {
      p = s->p;
      if (p->owner == P)
        print_full_planet (P, p);
    }
  else
    for (p = planets; p; p = p->next)
      if (p->owner == P)
        print_full_planet (P, p);
}

void
print_full_alien_planets (player * P)
{
  player *P2;
  sorted *s;
  planet *p;

  /* alien planets you can see (full reports with groups) */

  for (P2 = players; P2; P2 = P2->next)
    if (P2 != P)
    {
      if (P->opts2 & SORTPLANETS)
        for (s = sorted_planets, p = s->p; s; s = s->next)
        {
          p = s->p;

#ifdef FORECAST
          if ((p->owner == P2) && seenlist[ptonum (planets, p)])
#else
          if ((p->owner == P2) && canseeplanet (P, p, 1))
#endif

            print_full_planet (P, p);
        }
      else
        for (p = planets; p; p = p->next)

#ifdef FORECAST
          if ((p->owner == P2) && seenlist[ptonum (planets, p)])
#else
          if ((p->owner == P2) && canseeplanet (P, p, 1))
#endif

            print_full_planet (P, p);
      }
}

void
print_uninhabited_planets (player * P)
{
  planet *p;

  fbegin ("Uninhabited Systems", "xxffff");
  fhead ("N#XYSR");
  for (p = planets; p; p = p->next)
    if (!p->owner && canseeplanet (P, p, 1))
    {
      fs (p->name);
      fs (p->num);
      ff (wrap (p->x - P->homex));      /* GE: relative coordinate fix */
      ff (cartesian(wrap (p->y - P->homey)));
      ff (p->size);
      ff (p->resources);
    }
  fend ();
}

void
print_unknown_planets (player * P)
{
  planet *p;

  fbegin ("Unknown Systems", "xff");
  fhead ("#XY");
  for (p = planets; p; p = p->next)
    if ((p->owner != P) && !canseeplanet (P, p, 1) &&
        (fabs (wrap (p->x - P->homex) - P->x) < ((double) P->size / 2.0)) &&
        (fabs (wrap (p->y - P->homey) - P->y) < ((double) P->size / 2.0)))
    {
      fs (p->num);
      ff (wrap (p->x - P->homex));      /* GE: relative coordinate fix */
      ff (cartesian(wrap (p->y - P->homey)));
    }
  fend ();
}
#endif

#endif
