#ifndef lint
static char *RCSid = "$Header: /usr/brule/guest/empire/empire/emprcs/lib/subs/satmap.c,v 2.4 1995/10/11 03:00:05 empire Exp $";
#endif

/*
 * satmap.c
 *
 * do a satellite map given an x,y location, effic,
 * and other things.
 *
 * Author Unknown
 */

#include "misc.h"
#include "player.h"
#include "xy.h"
#include "sect.h"
#include "ship.h"
#include "land.h"
#include "plane.h"
#include "var.h"
#include "nsc.h"
#include "nat.h"
#include "file.h"

void	satdisp();

void
satmap(x, y, eff, range, flags, type)
	int     x;
	int     y;
	int     eff;
	int	range;
	int     flags;
	int	type;
{
	s_char	rad[WORLD_Y][WORLD_X+1];
	int     acc;
	struct	sctstr sect;
	struct	shpstr ship;
	struct	lndstr land;
	int     count;
	struct	nstr_item ni;
	struct	nstr_sect ns;
	int	rx, ry;
	int	row;
	int	n;
	int	changed = 0;
	long	crackle;
	s_char	noise[100];
	s_char	selection[1024];

	if (!eff)
		return;

	range = range * (eff / 100.0);
	pr("%s efficiency %d%%, max range %d\n", xyas(x, y, player->cnum),
		eff, range);
	bzero(noise, sizeof(noise));
	if (eff < 100)
		for (n = 0; n < eff; ++n)
			noise[100 * n / eff] = 1;

	sprintf(selection, "@%d,%d:%d", x, y, range);

	if (type == EF_BAD || type == EF_SECTOR) {
		if (type == EF_SECTOR) /* Use ?conditionals */
			snxtsct(&ns, selection);
		else
			snxtsct_dist(&ns, x, y, range);
			
		blankfill((s_char *)rad, &ns.range, 1);
		if (flags & P_S) {
			pr("Satellite sector report\n");
			prdate();
			sathead();
			acc = (flags & P_I) ? 5 : 50;
		}
		crackle = count = 0;
		while (nxtsct(&ns, &sect)) {
			if (++crackle == 100)
				crackle = 0;
			if (noise[crackle]) {
				pr("\n");
				continue;
			}
			if (flags & P_S) {
				if (sect.sct_type > SCT_RURAL) {
					satdisp(&sect, acc,0);
					++count;
				}
#ifdef HIDDEN
				setcont(player->cnum, sect.sct_own, FOUND_FLY);
#endif /* HIDDEN */
			}
			if ((flags & P_I) ||
			    sect.sct_type == SCT_WATER ||
			    sect.sct_type == SCT_MOUNT) {
				rad[ns.dy][ns.dx] = dchr[sect.sct_type].d_mnem;
			} else
				rad[ns.dy][ns.dx] = '?';
			changed +=map_set(player->cnum, ns.x, ns.y, rad[ns.dy][ns.dx],0);
		}
		if (changed)
			writemap(player->cnum);
		if (flags & P_S)
			pr("  %d sectors\n\n", count);
	}

	if ((type == EF_BAD || type == EF_SHIP) &&
	    (flags & P_S || flags & P_I)) {
		if (type == EF_SHIP)
			snxtitem(&ni, EF_SHIP, selection);
		else
			snxtitem_dist(&ni, EF_SHIP, x, y, range);

		crackle = count = 0;
		if (flags & P_S) {
			pr("Satellite ship report\n");
			prdate();
#ifdef	SHIPNAMES
			pr(" own  shp# ship type                                  sector   eff\n");
#else
			pr(" own  shp# ship type         sector   eff\n");
#endif	/* SHIPNAMES */
		}
		while (nxtitem(&ni, (caddr_t)&ship)) {
			if (ship.shp_own == 0)
				continue;
			if ((mchr[ship.shp_type].m_flags & M_SUB) &&
			    ((flags & (P_S|P_I)) != (P_S|P_I)))
				continue;
			if (++crackle == 100)
				crackle = 0;
			if (noise[crackle]) {
				pr("\n");
				continue;
			}
			if (flags & P_S) {
				pr("%4d %4d %-16.16s ",
				       ship.shp_own, ship.shp_uid,
				       mchr[ship.shp_type].m_name);
#ifdef	SHIPNAMES
				pr("%-25.25s ", ship.shp_name);
#endif
				prxy("%4d,%-4d ", ship.shp_x, ship.shp_y,
					player->cnum);
				pr("%3d%%\n", ship.shp_effic);
				++count;
#ifdef HIDDEN
                                setcont(player->cnum, ship.shp_own, FOUND_FLY);
#endif /* HIDDEN */
			}
			if (flags & P_I) {
				/* &~0x20 makes it a cap letter */
				/* Used to have 'ghosts' when scanning
					whole world --ts */
				if (ni.range.width != WORLD_X)
					rx=deltax((int)ship.shp_x, ni.range.lx);
				else
					rx = WORLD_X/2+((int)ship.shp_x-x);
				if (ni.range.height != WORLD_Y)
					ry=deltay((int)ship.shp_y, ni.range.ly);
				else
					ry = WORLD_Y/2+((int)ship.shp_y-y);
				rad[ry][rx] =
				    (*mchr[ship.shp_type].m_name) & ~0x20;
			}
		}
		if (flags & P_S)
			pr("  %d ships\n\n", count);
	}

	if ((type == EF_BAD || type == EF_LAND) &&
	    (flags & P_S || flags & P_I)) {
		if (type == EF_LAND)
			snxtitem(&ni, EF_LAND, selection);
		else
			snxtitem_dist(&ni, EF_LAND, x, y, range);

		crackle = count = 0;
		if (flags & P_S) {
			pr("Satellite unit report\n");
			prdate();
			pr(" own  lnd# unit type         sector   eff\n");
		}
		while (nxtitem(&ni, (caddr_t)&land)) {
			if (land.lnd_own == 0)
				continue;
			if (!chance((double)land.lnd_effic/20.0))
				continue;
			if (++crackle == 100)
				crackle = 0;
			if (noise[crackle]) {
				pr("\n");
				continue;
			}
			if (flags & P_S) {
				pr("%4d %4d %-16.16s ",
				       land.lnd_own, land.lnd_uid,
				       lchr[land.lnd_type].l_name);
				prxy("%4d,%-4d", land.lnd_x, land.lnd_y,
					player->cnum);
				pr("%3d%%\n", land.lnd_effic);
				++count;
			}
			if (flags & P_I) {
				/* &~0x20 makes it a cap letter */
				/* Used to have 'ghosts' when scanning
					whole world --ts */
				if (ni.range.width != WORLD_X)
					rx=deltax((int)land.lnd_x, ni.range.lx);
				else
					rx = WORLD_X/2+((int)land.lnd_x-x);
				if (ni.range.height != WORLD_Y)
					ry=deltay((int)land.lnd_y, ni.range.ly);
				else
					ry = WORLD_Y/2+((int)land.lnd_y-y);
				rad[ry][rx] =
				    (*lchr[land.lnd_type].l_name) & ~0x20;
			}
		}
		if (flags & P_S)
			pr("  %d units\n\n", count);
	}


	if (type == EF_BAD) {
		/*
		 * print out the map
		 * We have to make the center a '0' for ve
		 * ve needs a garbage line to terminate the map
		 */
		rad[deltay(y, ns.range.ly)][deltax(x, ns.range.lx)] = '0';

		pr("Satellite radar report\n");
#ifdef HAY
		/* This is wrong for small, hitech worlds. */
		n = deltay(ns.range.hy, ns.range.ly);
#else
		/* This is already available, so why not use it. */
		n = ns.range.height;
#endif
		for (row=0; row < n; row++)
			pr("%s\n", rad[row]);
		pr("\n(c) 1989 Imaginative Images Inc.\n");
	}
}


sathead()
{
	pr("   sect   type own  eff  civ  mil  shl  gun  iron  pet  food\n");
}

void
satdisp(sp, acc, showstuff)
	struct sctstr *sp;
	int     acc, showstuff;
{
	int	vec[I_MAX+1], first;
	struct	nstr_item ni;
	struct	shpstr ship;
	struct	lndstr land;

	if (getvec(VT_ITEM, vec, (caddr_t)sp, EF_SECTOR) < 0)
		return;
	prxy("%4d,%-4d   ", sp->sct_x, sp->sct_y, player->cnum),
	pr("%c  %3d  %3d %4d %4d %4d %4d  %4d %4d %5d\n",
	       dchr[sp->sct_type].d_mnem,
	       sp->sct_own, round((int)sp->sct_effic, acc / 2),
	       round(vec[I_CIVIL], acc), round(vec[I_MILIT], acc),
	       round(vec[I_SHELL], acc), round(vec[I_GUN], acc),
	       round(vec[I_IRON], acc), round(vec[I_PETROL], acc),
	       round(vec[I_FOOD], acc));
	map_set(player->cnum, sp->sct_x, sp->sct_y, dchr[sp->sct_type].d_mnem, 0);
	if (!showstuff)
		return;
	snxtitem_xy(&ni, EF_SHIP, sp->sct_x, sp->sct_y);
	first=1;
	while (nxtitem(&ni, (caddr_t)&ship)) {
		if (ship.shp_own == 0)
			continue;
		if (mchr[ship.shp_type].m_flags & M_SUB)
			continue;
		if (first){
#ifdef	SHIPNAMES
pr("\t own  shp# ship type                                  sector   eff\n");
#else
pr("\t own  shp# ship type         sector   eff\n");
#endif	/* SHIPNAMES */
			first=0;
		}
		pr("\t%4d %4d %-16.16s ", ship.shp_own, ship.shp_uid,
		       mchr[ship.shp_type].m_name);
#ifdef	SHIPNAMES
		pr("%-25.25s ", ship.shp_name);
#endif
		prxy("%4d,%-4d ", ship.shp_x, ship.shp_y, player->cnum);
		pr("%3d%%\n", ship.shp_effic);
	}

	if (!first)
		pr("\n");

	snxtitem_xy(&ni, EF_LAND, sp->sct_x, sp->sct_y);
	first=1;

	while (nxtitem(&ni, (caddr_t)&land)) {
		if (land.lnd_own == 0)
			continue;
		if (!chance((double)land.lnd_effic/20.0))
			continue;

		if (first){
			pr("\t own  lnd# unit type         sector   eff\n");
			first=0;
		}

		pr("\t%4d %4d %-16.16s ",land.lnd_own, land.lnd_uid,
			lchr[land.lnd_type].l_name);
		prxy("%4d,%-4d ",land.lnd_x, land.lnd_y, player->cnum);
		pr("%3d%%", land.lnd_effic);
	}

	if (!first)
		pr("\n");
}
