#ifndef lint
static char *RCSid = "$Header: /usr/brule/guest/empire/empire/emprcs/lib/subs/radmap.c,v 2.2 1995/10/22 21:31:37 empire Exp $";
#endif

/*
 * radmap.c
 *
 * do a radar map given an x,y location, effic,
 * and other things.
 *
 * Dave Pare, 1989
 */

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

void	radmap2();

radmap(cx, cy, eff, range, seesub)
	int	cx;
	int	cy;
	int	eff;
	int	range;
	double	seesub;
{
	radmap2(cx, cy, eff, range, seesub, 1);
}


radmapnopr(cx, cy, eff, range, seesub)
	int	cx;
	int	cy;
	int	eff;
	int	range;
	double	seesub;
{
	radmap2(cx, cy, eff, range, seesub, 0);
}
#if defined(aix)  /* some buggy aix compiles need this. */ 

	static s_char	rad[WORLD_Y][WORLD_X+1];
	static s_char	vis[WORLD_Y][WORLD_X+1];
#endif 

void
radmap2(cx, cy, eff, range, seesub, pr_flag)
	int	cx;
	int	cy;
	int	eff;
	int	range;
	double	seesub;
	int	pr_flag;
{
#if !defined(aix)  /* see note on aix above */ 
	s_char	rad[WORLD_Y][WORLD_X+1];
	s_char	vis[WORLD_Y][WORLD_X+1];
#endif 
	int	rng;
	struct	sctstr sect;
	struct	shpstr ship;
	struct	plnstr plane;
	struct	nstr_sect ns;
	struct	nstr_item ni;
	int	x, y;
	int	row;
	int	n;
	int	changed = 0;

	bzero((s_char *)vis, sizeof(vis));
	range = (int) (range * (eff / 100.0));
	if (range < 1)
		range = 1;
	if (pr_flag)
	pr("%s efficiency %d%%, max range %d\n",
		xyas(cx, cy, player->cnum), eff, range);
	snxtsct_dist(&ns, cx, cy, range);
	blankfill((s_char *)rad, &ns.range, 1);
	while (nxtsct(&ns, &sect)) {
		if (player->owner ||
		    (sect.sct_type <= SCT_RURAL && sect.sct_type != SCT_SANCT)
		    || ns.curdist <= range/3)
			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 (!pr_flag)
		return;
	snxtitem_dist(&ni, EF_PLANE, cx, cy, range);
	while (nxtitem(&ni, (caddr_t)&plane)) {
		if (plane.pln_own == 0)
			continue;
		/* Used to have 'ghosts' when scanning whole world --ts */
		x = deltx(&ns.range,(int)plane.pln_x);
		y = delty(&ns.range,(int)plane.pln_y);

		if ((plane.pln_flags & PLN_LAUNCHED) &&
		    plane.pln_own != player->cnum) {
			vis[y][x] = (s_char) 100;
			rad[y][x] = '$';
		}
	}
	snxtitem_dist(&ni, EF_SHIP, cx, cy, range);
	while (nxtitem(&ni, (caddr_t)&ship)) {
		if (ship.shp_own == 0)
			continue;
		/* Used to have 'ghosts' when scanning whole world --ts */
		x = deltx(&ns.range,(int)ship.shp_x);
		y = delty(&ns.range,(int)ship.shp_y);

		rng = (int) (range * mchr[ship.shp_type].m_visib / 20.0);
		if (ni.curdist > rng)
			continue;
		if ((mchr[ship.shp_type].m_flags & M_SUB) &&
		    ni.curdist > rng * seesub)
			continue;
		if (mchr[ship.shp_type].m_visib > vis[y][x]) {
			vis[y][x] = mchr[ship.shp_type].m_visib;
			/* &~0x20 makes it a cap letter */
			rad[y][x] = (*mchr[ship.shp_type].m_name) & ~0x20;
		}
	}
	/* 
	 * make the center of the display 0
	 * so ve et al can find it.
	 */
	if (deltay(cy, ns.range.ly) > WORLD_Y ||
	    deltax(cx, ns.range.lx) > WORLD_X+1) {
		pr("CONGRATULATIONS!  You have finally reproduced the radar bug I've been trying\n");
		pr("to track down for months!  Please email me immediately: children@empire.net\n");
		pr("so that I can log in right away and see what's causing the bug.  THANKS!\n");
		return;
	}
	rad[deltay(cy, ns.range.ly)][deltax(cx, ns.range.lx)] = '0';
	/* won't work for radar maps > WORLD_Y/2 */
#ifdef HAY
	/* This is not correct 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");
}

deltx(r, x)
struct range *r;
coord x;
{
        if (r->lx < r->hx)
                return x-r->lx;

        if (x >= r->lx)
                return x-r->lx;

        return x+WORLD_X-r->lx;
}

delty(r,y)
struct range *r;
coord y;
{
        if (r->ly < r->hy)
                return y-r->ly;

        if (y >= r->ly)
                return y-r->ly;

        return y+WORLD_Y-r->ly;
}
