#ifndef lint
static char *RCSid = "$Header: /usr/brule/guest/empire/empire/emprcs/lib/subs/missdef.c,v 2.3 1995/07/28 00:57:59 empire Exp $";
#endif /* not lint */

/*
 * missdef.c
 *
 * Launch missiles from land or sea
 * to protect a ship under attack.
 *
 * Jeff Bailey
 */

#include "misc.h"
#include "xy.h"
#include "var.h"
#include "sect.h"
#include "item.h"
#include "plane.h"
#include "nuke.h"
#include "news.h"
#include "ship.h"
#include "nsc.h"
#include "nat.h"
#include "path.h"
#include "file.h"


/*
 * Fire a missile in defense
 */
missdef(target_ship,victim)
struct shpstr	*target_ship;
natid		victim;
{
	struct	nstr_item nstr;
	struct	plnstr plane;	/* current missile we're lauinching */
	struct	plchrstr *pcp;	/* characteristics of this missile */
	int	shiplaunch;	/* launched from a ship? */
	struct	sctstr sect;	/* sector from which we're launching */
	struct	shpstr ship;	/* ship from which we're launching */
	int	done = 0;
	coord	sx, sy;
	int	dam;
	int	shell;
	int	bombs;
	int	needed;
	int	i;
	struct	mchrstr *mcp;
	int	onsea;
	int	acc;
	int	vis;

	if (target_ship->shp_own == victim)
		return RET_FAIL;
	shiplaunch=0;
	if (!snxtitem_all(&nstr, EF_PLANE))
		return RET_SYN;
	while (!done && nxtitem(&nstr, (s_char *)&plane)) {
		if (plane.pln_own != victim)
			continue;
		pcp = &plchr[plane.pln_type];
		if ((pcp->pl_flags & (P_M|P_T)) != (P_M|P_T)) {
			continue;
		}
		if (plane.pln_ship >= 0) {
			getship(plane.pln_ship, &ship);
			shiplaunch = 1;
			if (ship.shp_own != victim){
				continue;
			}
			plane.pln_x = ship.shp_x;
			plane.pln_y = ship.shp_y;
		} else {
			shiplaunch = 0;
			getsect(plane.pln_x, plane.pln_y, &sect);
			if (sect.sct_own && sect.sct_own != victim) {
				continue;
			}
		}
		if (plane.pln_effic < 60) {
			continue;
		}
		if (plane.pln_nuketype == (s_char)-1)
			continue;
		if (shiplaunch) {
			shell = getvar(V_SHELL, (s_char *)&ship, EF_SHIP);
		} else {
			shell = getvar(V_SHELL, (s_char *)&sect, EF_SECTOR);
		}
		needed = pcp->pl_load - 1;
		if (shell < needed)
			shell += supply_commod(plane.pln_own,plane.pln_x,
				plane.pln_y,I_SHELL,needed-shell);

		if (shell < needed)
			continue;
		bombs = pcp->pl_load;
		if (shiplaunch) {
			putvar(V_SHELL, shell - needed, (s_char *)&ship, EF_SHIP);
		} else {
			putvar(V_SHELL, shell - needed, (s_char *)&sect, EF_SECTOR);
		}
		sx = target_ship->shp_x;
		sy = target_ship->shp_y;
		if (mapdist(plane.pln_x, plane.pln_y, sx, sy) > plane.pln_range)
			continue;
		if (chance(0.02 + (100 - plane.pln_effic)/100.0)) {
			if(victim != 0)
			wu(0, victim, "KABOOOOM!  %s (#%d) explodes on launch pad while being launched in self defense\n",
				pcp->pl_name, plane.pln_uid);
			done = 1;
			plane.pln_own = 0;
			continue;
		}
		getsect(sx,sy,&sect);
		onsea = (sect.sct_type == SCT_WATER) ? 1 : 0;
		mcp = &mchr[target_ship->shp_type];
		/*
		 * subs in port are sitting ducks, while subs
		 * at sea are impossible to spot.
		 */
		vis = mcp->m_visib;
		if (mcp->m_flags & M_SUB) {
			if (onsea) {
				done = 1;
				continue;
			}
			vis = 20;
		}
		/*
		 * ships on high seas are harder to hit because they're
		 * moving around so much!
		 */
		acc = pcp->pl_acc - vis + (mcp->m_speed * onsea) / 2;
		dam = 0;
		if (roll(100) > acc) {
			i = bombs;
			while (i--) {
				dam += roll(8)+8;
			}
		}
		plane.pln_own = 0;
		done = 1;
		nreport(victim, N_SHP_MISS, target_ship->shp_own, 1);
		pr("**** Incoming missile did %d%% damage.\n",dam);
		shipdamage(target_ship, dam);
/*
#ifdef	SHIPNAMES
		wu(0, target_ship->shp_own, "%s missile did %d%% damage to %s %s(#%d) at %s\n",
			cname(victim), dam, mcp->m_name, target_ship->shp_name,
			target_ship->shp_uid,
#else
		wu(0, target_ship->shp_own, "%s missile did %d%% damage to %s #%d at %s\n",
			cname(victim), dam, mcp->m_name, target_ship->shp_uid,
#endif	SHIPNAMES
			xyas(target_ship->shp_x,target_ship->shp_y,
				target_ship->shp_own));
*/
		if(victim != 0)
#ifdef	SHIPNAMES
		wu(0, victim, "%s(#%d) launched in defense did %d%% damage to %s %s %s(#%d) at %s\n",
			pcp->pl_name, plane.pln_uid, dam,
			cname(target_ship->shp_own), mcp->m_name,
			target_ship->shp_name, target_ship->shp_uid,
#else
		wu(0, victim, "%s(#%d) launched in defense did %d%% damage to %s %s(#%d) at %s\n",
			pcp->pl_name, plane.pln_uid, dam,
			cname(target_ship->shp_own), mcp->m_name,
			target_ship->shp_uid,
#endif	SHIPNAMES
			xyas(target_ship->shp_x,target_ship->shp_y, victim));
		putship(target_ship->shp_uid, target_ship);
	};

	
	putplane(plane.pln_uid, &plane);
	if (shiplaunch) {
		ship.shp_nplane -= 1;
		if (ship.shp_nplane + 1 == 0)	/* shouldn't happen */
			ship.shp_nplane = 0;
		putship(plane.pln_ship, &ship);
	}

	return RET_OK;
}

