#ifndef lint
static char *RCSid = "$Header: /usr/brule/guest/empire/empire/emprcs/lib/commands/para.c,v 2.6 1995/10/11 03:02:33 empire Exp $";
#endif

/*
 * para.c
 *
 * Drop paratroops onto a sector
 *
 * Dave Pare, 1986
 * Modified to use att subroutines by Ken Stevens, 1995
 */

#include "misc.h"
#include "player.h"
#include "var.h"
#include "sect.h"
#include "ship.h"
#include "item.h"
#include "plane.h"
#include "land.h"
#include "nuke.h"
#include "xy.h"
#include "nsc.h"
#include "news.h"
#include "file.h"
#include "nat.h"
#include "path.h"
#include "treaty.h"
#include "mission.h"
#include "combat.h"

static
paradrop();

para()
{
	s_char	*p;
	int	mission_flags;
	int	tech;
	coord	tx, ty;
	coord	ax, ay;
	int	ap_to_target;
	s_char	flightpath[MAX_PATH_LEN];
	struct	nstr_item ni_bomb;
	struct	nstr_item ni_esc;
	coord	x, y;
	struct	sctstr target;
	struct	qelem bomb_list;
	struct	qelem esc_list;
	int	wantflags;
	struct	sctstr ap_sect;
	s_char	buf[1024];

	wantflags = P_P;
	if (!snxtitem(&ni_bomb, EF_PLANE, player->argp[1]))
		return RET_SYN;
	if (!snxtitem(&ni_esc, EF_PLANE, getstarg(player->argp[2], "escort(s)? ", buf)))
		pr("No escorts...\n");
	if ((p = getstarg(player->argp[3], "assembly point? ", buf)) == 0 || *p == 0)
		return RET_SYN;
	if (!sarg_xy(p, &x, &y) || !getsect(x, y, &ap_sect))
		return RET_SYN;
	if (ap_sect.sct_own && ap_sect.sct_own != player->cnum) {
		pr("Assembly point not owned by you!\n");
		return RET_SYN;
	}
	ax = x;
	ay = y;
	if (getpath(flightpath, player->argp[4], ax, ay, 0,
	    0, 0, P_FLYING) == 0 || *flightpath == 0)
		return RET_SYN;
	tx = ax;
	ty = ay;
	(void) pathtoxy(flightpath, &tx, &ty, fcost);
	getsect(tx, ty, &target);
	pr("LZ is %s\n", xyas(tx, ty, player->cnum));
	ap_to_target = strlen(flightpath);
	if (*(flightpath+strlen(flightpath)-1) == 'h')
		ap_to_target--;
	pr("range to target is %d\n", ap_to_target);
	/*
	 * select planes within range
	 */
	pln_sel(&ni_bomb, &bomb_list, &ap_sect, ap_to_target,
		2, P_C|wantflags, P_M|P_O);
	pln_sel(&ni_esc, &esc_list, &ap_sect, ap_to_target,
		2, P_ESC|P_F, P_M|P_O);
	/*
	 * now arm and equip the bombers, transports, whatever.
	 * tech is stored in high 16 bits of mission_flags.
	 * yuck.
	 */
	tech=0;
	mission_flags = 0;
	mission_flags |= P_X;		/* stealth (shhh) */
	mission_flags |= P_H; /* gets turned off if not all choppers */
	mission_flags = pln_arm(&bomb_list, 2*ap_to_target, 'a', &ichr[I_MILIT],
		0, mission_flags,&tech);
	if (QEMPTY(&bomb_list)) {
		pr("No planes could be equipped for the mission.\n");
		return RET_FAIL;
	}
	mission_flags = pln_arm(&esc_list, 2*ap_to_target, 'a', &ichr[I_MILIT],
		P_ESC|P_F, mission_flags,&tech);
	ac_encounter(&bomb_list,&esc_list,ax,ay,flightpath,mission_flags,0);
	if (QEMPTY(&bomb_list)) {
		pr("No planes got through fighter defenses\n");
	} else {
		getsect(tx, ty, &target);
		if (target.sct_own && !trechk(player->cnum, target.sct_own, LANATT)) {
			pln_put(&bomb_list);
			pln_put(&esc_list);
			return RET_OK;
		}
		paradrop(&bomb_list, tx, ty);
	}
	pln_put(&bomb_list);
	pln_put(&esc_list);
	return RET_OK;
}

static
paradrop(list, x,y)
	struct	qelem *list;
	coord	x,y;
{
	struct	combat off[1];	/* assaulting ship or sector */
	struct	combat def[1];	/* defending ship */
	struct	qelem olist;	/* assaulting units */
	struct	qelem dlist;	/* defending units */
	int	ototal;		/* total assaulting strength */
	int	a_engineer = 0;	/* assaulter engineers are present */
	int	a_spy = 0;	/* the best assaulter scout */
	double	osupport = 1.0; /* assault support */
	double	dsupport = 1.0; /* defense support */
	struct	plist *plp;
	struct	qelem *qp;

	/* Check for valid attack */

	att_combat_init(def, EF_SECTOR);
	def->x = x;
	def->y = y;
	if (att_abort(A_PARA, 0, def))
		return RET_FAIL;

	/* Show what we're air-assaulting */

	att_show(def);

	/* set what we're air-assaulting with */

	initque(&olist);
	att_combat_init(off, EF_PLANE);
	for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
		plp = (struct plist *) qp;
		if (plp->pcp->pl_flags & (P_V|P_C))
			off->troops += plp->misc;
	}
	off->mil = off->troops;
	if (att_abort(A_PARA, off, def)) {
		pr("Air-Assault aborted\n");
		return RET_OK;
	}

	/* Get ototal */

	ototal = att_estimate_defense(A_PARA, off, &olist, def, a_spy);
	if (att_abort(A_PARA, off, def)) {
		pr("Air-assault aborted\n");
		return RET_OK;
	}

	/* Get the defense */

	att_get_defense(&olist, def, &dlist, a_spy, ototal);

	/* Get defender support */

	att_get_support(A_PARA, 0, 0, 0, 0,
			&olist, off, &dlist, def, &osupport, &dsupport,
			a_engineer);
	if (att_abort(A_PARA, off, def)) {
		pr("Air-ssault aborted\n");
		return RET_OK;
	}
	/*
	 * Death, carnage, and destruction.
	 */

	att_fight(A_PARA,off,&olist,osupport,def,&dlist,dsupport);

	return RET_OK;
}
