#ifndef lint
static char *RCSid = "$Header: sona.c,v 1.10 89/09/26 20:03:02 mr-frog Exp $";
#endif

/*
 * sona.c
 *
 * sonar from a sub (or other sonar-equipped ship)
 *
 * Jim Griffith, 1989
 */

#include "misc.h"
#include "var.h"
#include "xy.h"
#include "sect.h"
#include "ship.h"
#include "nsc.h"
#include "nat.h"
#include "path.h"
#include "file.h"
#ifdef ASW_PLANES
#include "queue.h"
#include "plane.h"
#endif /* ASW_PLANES */
#include <fcntl.h>
#include <ctype.h>

sona()
{
	extern	char *argp[];
	register int i;
	struct	nstr_item ni;
	struct	shpstr ship;
	struct	shpstr *targ;
	struct	mchrstr *tmcp;
	int	range;
	int	pingrange;
	int	vrange;
	int	dist;
	char	*name;
	char	*p;

	if (!snxtitem(&ni, EF_SHIP, argp[1]))
		return RET_SYN;

	/* ick */
	ef_close(EF_SHIP);
	ef_open(EF_SHIP, O_RDWR, EFF_MEM);

	while (nxtitem(&ni, (char *)&ship)) {
		if (!owner)
			continue;
		tmcp = &mchr[ship.shp_type];
		if (!(tmcp->m_flags & M_SONAR))
			continue;
		range = (int) techfact(ship.shp_tech,
			(double) mchr[ship.shp_type].m_vrnge);
		for (i=0; targ = getshipp(i); i++) {
			if (targ->shp_own == cnum || targ->shp_own == 0)
				continue;
			tmcp = &mchr[targ->shp_type];
			pingrange = max(tmcp->m_visib, 10) * range / 10;
			vrange = pingrange * ship.shp_effic / 200;
			dist = mapdist(targ->shp_x, targ->shp_y,
				ship.shp_x, ship.shp_y);
			pingrange = (max(pingrange, 2) * targ->shp_effic)/100; 
			if (dist > pingrange)
				continue;
			if (tmcp->m_flags & M_SONAR) {
#ifdef	SHIPNAMES
			    p = fmt("Sonar ping from %s detected by %s %s(#%d)!\n",
#else
			    p = fmt("Sonar ping from %s detected by %s #%d!\n",
#endif	SHIPNAMES
					xyas(ship.shp_x, ship.shp_y,
						targ->shp_own),
#ifdef	SHIPNAMES
					tmcp->m_name, targ->shp_name,
					targ->shp_uid);
#else
					tmcp->m_name, targ->shp_uid);
#endif	SHIPNAMES
#ifdef MERC
				if(targ->shp_own != 0)
#endif
				wu(0, targ->shp_own, p);
#ifdef RETREAT
				if (targ->shp_rflags & RET_SONARED){
					retreat(targ, 's');
					putship(targ->shp_uid,targ);
				}
#endif /* RETREAT */
			}
			if ((dist > vrange))
				continue;
			if ((tmcp->m_flags & M_FOOD) && dist > 0)
				name = "fishing vessel";
			else
				name = tmcp->m_name;
			pr(fmt("%s (#%d) %s #%d @%s\n", cname(targ->shp_own),
				targ->shp_own, name, i,
				xyas(targ->shp_x, targ->shp_y, cnum)));
		}
	}
	ef_close(EF_SHIP);
	ef_open(EF_SHIP, O_RDWR, 0);
	return RET_OK;
}

#ifdef ASW_PLANES
plane_sona(plane_list,x,y,head)
struct  qelem *plane_list;
int	x,y;
struct	shiplook *head;
{
	struct	plnstr	*pp;
	struct	plchrstr *pcp;
	struct	mchrstr *tmcp;
	struct	shpstr *targ,s;
	struct  qelem   *qp;
	struct  qelem   *next;
	struct  plist   *ip;
	struct  sctstr  sect;
	int	found=0;
	int	range,i;
	int	pingrange;
	int	vrange;
	int	dist;
	double	detect;
	char	*name;
	char	*p;

	getsect(x,y,&sect);

	if ((sect.sct_type != SCT_WATER) && (sect.sct_type != SCT_HARBR))
		return;

	/* ick */
/*
	ef_close(EF_SHIP);
	ef_open(EF_SHIP, O_RDONLY, EFF_MEM);
*/

        for (qp = plane_list->q_forw; qp != plane_list; qp = next) {
                next = qp->q_forw;
                ip = (struct plist *) qp;
                pp = &ip->plane;
                pcp = ip->pcp;
		if (!(pcp->pl_flags & P_A)) /* if it isn't an ASW plane */
			continue;
		range = (int) techfact(pp->pln_tech, (double) ((100-pcp->pl_acc)/10));
/*
		for (i=0; targ = getshipp(i); i++) {
*/
		for (i=0; getship(i,&s) ; i++) {
			targ = &s;
			if (targ->shp_own == cnum || targ->shp_own == 0)
				continue;
/*
			if (have_looked(targ->shp_uid,head))
				continue;
*/
			if (have_found(targ->shp_uid,head))
				continue;
			set_have_looked(targ->shp_uid,head);
			tmcp = &mchr[targ->shp_type];
			if (!(tmcp->m_flags & M_SUB))
				continue;
			detect = (100.0 - (double)pcp->pl_acc);
			detect -= (5.0 - (double)mchr[targ->shp_type].m_visib)*10.0;
			detect /= 100.0;
			srandom(random());
			if (!chance(detect))
				continue;
			pingrange = max(tmcp->m_visib, 10) * range / 10;

			vrange = ((float)pingrange) * ((float)pp->pln_effic / 200.0);
			dist = mapdist(targ->shp_x, targ->shp_y, x, y);
			pingrange = (max(pingrange, 2) * targ->shp_effic);
			pingrange = roundavg(pingrange/100.0); 
			if (dist > pingrange)
				continue;
			if (tmcp->m_flags & M_SONAR) {
#ifdef	SHIPNAMES
				p = fmt("Sonar ping from %s detected by %s %s(#%d)!\n",
#else
				p = fmt("Sonar ping from %s detected by %s #%d!\n",
#endif	SHIPNAMES
					xyas(x, y, targ->shp_own),
#ifdef	SHIPNAMES
					tmcp->m_name, targ->shp_name, targ->shp_uid);
#else
					tmcp->m_name, targ->shp_uid);
#endif	SHIPNAMES
#ifdef MERC
				if(targ->shp_own != 0)
#endif
					wu(0, targ->shp_own, p);
			}
			if ((dist > vrange))
				continue;
			set_have_found(targ->shp_uid,head);
			if ((tmcp->m_flags & M_FOOD) && dist > 0)
				name = "fishing vessel";
			else
				name = tmcp->m_name;
			if (!found){
				pr(fmt("\nSonar contact in %s\n",xyas(x,y,cnum)));
				found=1;
			}
			pr(fmt("%s (#%d) %s #%d @%s\n", cname(targ->shp_own),
				targ->shp_own, name, i,
				xyas(targ->shp_x, targ->shp_y, cnum)));
		}
	}
}
#endif /* ASW_PLANES */
