#ifndef lint
static char *RCSid = "$Header: /usr/brule/guest/empire/empire/emprcs/lib/subs/show.c,v 2.9 1995/10/01 22:34:29 empire Exp $";
#endif

/*
 * show.c
 *
 * general routines that are callable to give info on things.
 * currently, planes, ships, nukes and bridges. Tanks & regiments one day?
 *
 * Added nuke_flags to be consistent. Jeff Bailey 12/15/90 (bailey@mcs.kent.edu)
 *
 * Julian Onions, 1988
 */

#include "misc.h"
#include "player.h"
#include "nuke.h"
#include "var.h"
#include "ship.h"
#include "land.h"
#include "item.h"
#include "plane.h"
#include "sect.h"
#include "optlist.h"


/*
 * This cruft really belongs in the empglb.c file.
 * Yuck.
 */

struct lookup {
	int     key;
	s_char   *value;
};

struct lookup  ship_flags[] = {
	M_FOOD, "fish",
	M_TORP, "torp",
	M_DCH, "dchrg",
	M_FLY, "plane",
	M_MSL, "miss",
	M_OIL, "oil",
	M_SONAR, "sonar",
	M_MINE, "mine",
	M_SWEEP, "sweep",
	M_SUB, "sub",
	M_SPY, "spy",
	M_LAND, "land",
	M_SUBT, "sub-torp",
#ifdef TRADESHIPS
	M_TRADE, "trade",
#endif /* TRADESHIPS */
	M_SEMILAND, "semi-land",
	M_OILER, "oiler",
	M_SUPPLY, "supply",
	M_ANTIMISSILE, "anti-missile",
	0, 0
};

struct lookup	land_flags[] = {
	L_XLIGHT,	"xlight",
	L_ENGINEER,	"engineer",
	L_SUPPLY,	"supply",
	L_SECURITY,	"security",
	L_LIGHT,	"light",
	L_MARINE,	"marine",
	L_RECON,	"recon",
	L_RADAR,	"radar",
	L_ASSAULT,	"assault",
	L_FLAK,		"flak",
	0,		0,
};


struct lookup  plane_flags[] = {
	P_T, "tactical",
	P_B, "bomber",
	P_F, "intercept",
	P_C, "cargo",
	P_V, "VTOL",
	P_M, "missile",
	P_L, "light",
	P_S, "spy",
	P_I, "image",
	P_O, "satellite",
	P_X, "stealth",
	P_N, "SDI",
	P_H, "half-stealth",
	P_E, "x-light",
	P_K, "helo",
	P_A, "ASW",
	P_P, "para",
	P_ESC, "escort",
	P_MINE, "mine",
	P_SWEEP, "sweep",
	P_MAR, "marine",
	0, 0
};

struct lookup nuke_flags[] = {
	N_NEUT,	"neutron",
	0,	0
};

static
s_char *
lookup(key, table)
	int     key;
	struct lookup *table;
{
	int	match;

	if ((match = intmatch(key, &table->key, sizeof(*table))) < 0)
		return 0;
	return table[match].value;
}

void
show_bridge(tlev)
	int     tlev;
{
	extern double buil_bt, buil_bc;
	extern int buil_bh;

	if (tlev < buil_bt)
		return;
	pr("Bridges require %g tech, %d hcm, %d workers,\n",
	       buil_bt, buil_bh, buil_bh * 2);
	pr("%d available workforce, and cost $%g\n",
		1 + (buil_bh * 40 / 100), buil_bc);
}

show_nuke_stats(tlev)
	int     tlev;
{
	show_nuke_capab(tlev);
}

show_nuke_build(tlev)
	int     tlev;
{
	register struct nchrstr *np;
	register int n;
	register int avail;
	extern float drnuke_const;

	if (opt_DRNUKE)
		pr("%13s lcm hcm  oil  rad avail tech res $\n", "");
	else
		pr("%13s lcm hcm  oil  rad avail tech $\n", "");

	for (np = nchr, n = 0; n < N_MAXNUKE; np++, n++) {
		avail = 1 +
		     (np->n_rad + np->n_oil + np->n_lcm + np->n_hcm * 2);
		if (np->n_tech > tlev) 
			continue;
		if (np->n_name == 0 || np->n_name[0] == '\0')
			continue;
		if (opt_NEUTRON == 0 && (np->n_flags & N_NEUT))
			continue;
		if (opt_DRNUKE)
			pr("%-13.13s %3d %3d %4d %4d %5d %4d %3d $%6d\n",
			   np->n_name, np->n_lcm, np->n_hcm, np->n_oil,
			   np->n_rad, avail, np->n_tech,
			   (int)(np->n_tech*drnuke_const)+1,
			   np->n_cost);
		else		/* not DRNUKE */
			pr("%-13.13s %3d %3d %4d %4d %5d %4d $%6d\n",
			   np->n_name, np->n_lcm, np->n_hcm, np->n_oil,
			   np->n_rad, avail, np->n_tech, np->n_cost);
	}
}

show_nuke_capab(tlev)
	int     tlev;
{
	register struct nchrstr *np;
	register int i,j,n;
	s_char	*p;
	extern float drnuke_const;

	if (opt_DRNUKE)
		pr("%13s blst dam lbs tech res $%7s abilities\n", "","");
	else
		pr("%13s blst dam lbs tech $%7s abilities\n", "","");

	for (np = nchr, n = 0; n < N_MAXNUKE; np++, n++) {
		if (np->n_tech > tlev)
			continue;
		if (opt_NEUTRON == 0 && (np -> n_flags & N_NEUT))
			continue;
		if (np->n_name == 0 || np->n_name[0] == '\0')
			continue;
		if (opt_DRNUKE) 
			pr("%-13.13s %4d %3d %3d %4d %3d $%7d ",
			   np->n_name, np->n_blast, np->n_dam,
			   np->n_weight, np->n_tech, 
			   (int)(np->n_tech * drnuke_const)+1,
			   np->n_cost);
		else /* not DRNUKE */
			pr("%-13.13s %4d %3d %3d %4d $%7d ",
			   np->n_name, np->n_blast, np->n_dam,
			   np->n_weight, np->n_tech, np->n_cost);

		for (i = j = 0; i < 32; i++) {
			if (!(np->n_flags & bit(i)))
				continue;
			if (p = lookup(bit(i), nuke_flags)) {
				if (j++ > 0)
					pr(" ");
				pr(p);
			}
		}
		pr("\n");
	}
}

show_ship_build(tlev)
	int     tlev;
{
	register struct mchrstr *mp;
	register int n;

	pr("%25s lcm hcm avail tech $\n", "");
	for (mp = mchr, n = 0; n < shp_maxno; n++, mp++) {
		if (mp->m_tech > tlev)
			continue;
		if (mp->m_name == 0 || mp->m_name[0] == '\0')
			continue;
		pr("%-25.25s %3d %3d %5d %4d $%d\n",
		       mp->m_name, mp->m_lcm, mp->m_hcm,
		       20 + mp->m_lcm + mp->m_hcm * 2,
		       mp->m_tech, mp->m_cost);
	}
}

show_ship_stats(tlev)
	int     tlev;
{
	register struct mchrstr *mp;
	int     scount;

	pr("%25s      s  v  s  r  f  l  p","");
	pr("  h");
	pr("  x");
	if (opt_FUEL)
		pr("  fuel");
	pr("\n");

	pr("%25s      p  i  p  n  i  n  l","");
	pr("  e");
	pr("  p");
	if (opt_FUEL)
		pr("   c/u");
	pr("\n");

	pr("%25s def  d  s  y  g  r  d  n","");
	pr("  l");
	pr("  l");
	if (opt_FUEL)
		pr("      ");
	pr("\n");


	for (mp = mchr, scount = 0; scount < shp_maxno; scount++, mp++) {
		if (mp->m_tech > tlev)
			continue;
		if (mp->m_name == 0 || mp->m_name[0] == '\0')
			continue;
		pr("%-25.25s %3d %2d %2d %2d %2d %2d ",
		       mp->m_name, mp->m_armor, mp->m_speed,
		       mp->m_visib, mp->m_vrnge, mp->m_frnge,
		       mp->m_glim);

		pr("%2d ", mp->m_nland);
		pr("%2d ", mp->m_nplanes);
		pr("%2d ", mp->m_nchoppers);
		pr("%2d ", mp->m_nxlight);
		if (opt_FUEL)
			pr("%3d/%1d ", mp->m_fuelc,mp->m_fuelu);
		pr("\n");
	}
}

show_ship_capab(tlev)
	int     tlev;
{
	register struct mchrstr *mp;
	register u_short *ap;
	register u_char *type;
	register int i;
	register int it;
	int     scount;
	int     n;
	s_char    c;
	s_char   *p;

	pr("%25s cargos & capabilities\n","");

	for (mp = mchr, scount = 0; scount < shp_maxno; scount++, mp++) {
		if (mp->m_tech > tlev)
			continue;
		if (mp->m_name == 0 || mp->m_name[0] == '\0')
			continue;
		pr("%-25.25s ", mp->m_name);

		/*
		 * should use vector stuff
		 */
		for (ap = mp->m_vamt, type = mp->m_vtype, i = 0;
		     i < mp->m_nv; i++, ap++, type++) {
			it = unitem((int) *type);
			if (it > 0 && it <= I_MAX && ichr[it].i_name != 0)
				c = ichr[it].i_name[0];
			else
				c = '?';
			pr(" %d%c", *ap, c);
		}
		pr(" ");
		for (i = n = 0; i < 32; i++) {
			if (!(mp->m_flags & bit(i)))
				continue;
			if (p = lookup(bit(i), ship_flags)) {
				if (n++ > 0)
					pr(" ");
				pr(p);
			}
		}
		pr("\n");
	}
}

show_plane_stats(tlev)
	int     tlev;
{
	register struct plchrstr *pp;
	int     pcount;

	pr("%25s acc load att def ran fuel stlth\n", "");
	for (pp = plchr, pcount = 0; pcount < pln_maxno; pcount++, pp++) {
		if (pp->pl_tech > tlev)
			continue;
		if (pp->pl_name == 0 || pp->pl_name[0] == '\0')
			continue;
		pr("%-25.25s %3d %4d %3d %3d %3d %4d ",
		       pp->pl_name, pp->pl_acc, pp->pl_load,
		       pp->pl_att, pp->pl_def, pp->pl_range,
		       pp->pl_fuel);
		pr("%4d%% ",pp->pl_stealth);
		pr("\n");
	}
}

show_plane_capab(tlev)
	int     tlev;
{
	register struct plchrstr *pp;
	register int i;
	int     pcount;
	int     n;
	s_char   *p;

	pr("%25s capabilities\n","");
	for (pp = plchr, pcount = 0; pcount < pln_maxno; pcount++, pp++) {
		if (pp->pl_tech > tlev)
			continue;
		if (pp->pl_name == 0 || pp->pl_name[0] == '\0')
			continue;
		pr("%-25.25s ", pp->pl_name);

		for (i = n = 0; i < 32; i++) {
			if (!(pp->pl_flags & bit(i)))
				continue;
			if (p = lookup(bit(i), plane_flags)) {
				if (n++ > 0)
					pr(" ");
				pr(p);
			}
		}
		pr("\n");
	}
}

show_plane_build(tlev)
	int     tlev;
{
	register struct plchrstr *pp;
	register int n;

	pr("%25s lcm hcm crew avail tech  $\n", "");
	for (pp = plchr, n = 0; n < pln_maxno; n++, pp++) {
		if (pp->pl_tech > tlev)
			continue;
		if (pp->pl_name == 0 || pp->pl_name[0] == '\0')
			continue;
		pr("%-25.25s %3d %3d %3d %5d %4d $%d\n",
		   pp->pl_name, pp->pl_lcm,
		   pp->pl_hcm, pp->pl_crew,
		   20 + 2 * pp->pl_hcm + pp->pl_lcm,
		   pp->pl_tech, pp->pl_cost);
	}
}

show_land_build(tlev)
	int     tlev;
{
	register struct lchrstr *lp;
	register int n;

	pr("%25s lcm hcm mil guns shells avail tech  $\n", "");
	for (lp = lchr, n = 0; n < lnd_maxno; n++, lp++) {
		if (lp->l_tech > tlev)
			continue;
		if (lp->l_name == 0 || lp->l_name[0] == '\0')
			continue;
		pr("%-25.25s %3d %3d %3d %4d %6d %5d %4d  $%d\n",
		   lp->l_name, lp->l_lcm,
		   lp->l_hcm, lp->l_mil,
		   lp->l_gun, lp->l_shell,
		   20 + lp->l_lcm + lp->l_hcm * 2,
		   lp->l_tech, lp->l_cost);
	}
}

show_land_capab(tlev)
{
	struct	lchrstr *lcp;
	int	lcount;
        register u_short *ap;
        register u_char *type;
        register int i,n;
        register int it;
	register s_char *p,c;

	pr("%25s capabilities\n","");

	for (lcp = lchr, lcount = 0; lcount < lnd_maxno; lcount++, lcp++) {
		if (lcp->l_tech > tlev)
			continue;
		if (lcp->l_name == 0 || lcp->l_name[0] == '\0')
			continue;

		pr("%-25s ", lcp->l_name);

                /*
                 * should use vector stuff
                 */
                for (ap = lcp->l_vamt, type = lcp->l_vtype, i = 0;
                     i < lcp->l_nv; i++, ap++, type++) {
                        it = unitem((int) *type);
                        if (it > 0 && it <= I_MAX && ichr[it].i_name != 0)
                                c = ichr[it].i_name[0];
                        else
                                c = '?';
                        pr(" %d%c", *ap, c);
                }
                pr(" ");
                for (i = n = 0; i < 32; i++) {
                        if (!(lcp->l_flags & bit(i)))
                                continue;
                        if (p = lookup(bit(i), land_flags)) {
                                if (n++ > 0)
                                        pr(" ");
                                pr(p);
                        }
                }
		pr("\n");
	}
}

show_land_stats(tlev)
{
	struct	lchrstr *lcp;
	int	lcount;

pr("%25s              s  v  s  r  f  a  d  a  a        x\n","");
pr("%25s              p  i  p  a  r  c  a  m  a  f  f  p\n","");
pr("%25s att def vul  d  s  y  d  g  c  m  m  f  c  u  l\n","");

	for (lcp = lchr, lcount = 0; lcount < lnd_maxno; lcount++, lcp++) {
		if (lcp->l_tech > tlev)
			continue;
		if (lcp->l_name == 0 || lcp->l_name[0] == '\0')
			continue;

		pr("%-25s %1.1f %1.1f %3d ",
			lcp->l_name, lcp->l_att, lcp->l_def, lcp->l_vul);
		pr("%2d %2d %2d %2d ",
			lcp->l_spd, lcp->l_vis, lcp->l_spy, lcp->l_rad);
		pr("%2d %2d %2d %2d %2d ",
			lcp->l_frg, lcp->l_acc, lcp->l_dam, lcp->l_ammo,
			lcp->l_aaf);
		pr("%2d %2d %2d ",
			lcp->l_fuelc, lcp->l_fuelu, lcp->l_nxlight);

		pr("\n");
	}
}

show_sect_build()
{
	register int x, first=1;

	for(x=5;x<SCT_MAXDEF+2;x++){
		if (dchr[x].d_mnem == 0)
			continue;
		if ((dchr[x].d_cost>0) || (dchr[x].d_build!=1) ||
			(dchr[x].d_lcms>0) || (dchr[x].d_hcms>0)){
			if (first){
				pr("sector type    cost to des    cost for 1%% eff   lcms for 1%%    hcms for 1%%\n");
				first=0;
			}
			pr("%-14c %-14d %-17d %-14d %d\n",
				dchr[x].d_mnem, dchr[x].d_cost, dchr[x].d_build,
				dchr[x].d_lcms, dchr[x].d_hcms);
		}
	}
}

show_sect_stats()
{
	register int x, first=1;

	for(x=0;x<SCT_MAXDEF+2;x++){
		if (dchr[x].d_mnem == 0)
			continue;
		if (first){
			pr("                                         --  packing bonus  --\n");
			pr("  sector type           mcost  off def   mil  uw civ bar other\n");
			first=0;
		}
		pr("%c %-23s %3d  %3d %3d   %3d %3d %3d %3d %5d\n",
		   dchr[x].d_mnem, dchr[x].d_name,
		   dchr[x].d_mcst, dchr[x].d_ostr,
		   dchr[x].d_dstr,
		   ichr[I_MILIT].i_pkg[dchr[x].d_pkg],
		   ichr[I_UW].i_pkg[dchr[x].d_pkg],
		   ichr[I_CIVIL].i_pkg[dchr[x].d_pkg],
		   ichr[I_BAR].i_pkg[dchr[x].d_pkg],
		   ichr[I_LCM].i_pkg[dchr[x].d_pkg]);
	}
}

show_sect_capab()
{
	pr("There is no information on sector capabilities.\n");
}
