#ifndef lint
static char *RCSid = "$Header: boar.c,v 1.8 90/03/19 11:14:48 mr-frog Exp $";
#endif /* not lint */

/*
 * boar.c
 *
 * board an enemy ship
 *
 * from PSL Empire, 1985
 */

#include "misc.h"
#include "var.h"
#include "nat.h"
#include "ship.h"
#include "news.h"
#include "file.h"
#include "treaty.h"
#ifdef HARBOR_POLICE
#include "sect.h"
#include "xy.h"
#include "item.h"
#include "nsc.h"
#endif /* HARBOR_POLICE */

boar()
{
	extern	char *argp[];
	int	btused;
	int	dshpno;		/* defending shipno */
	int	ashpno;		/* attacking shipno */
	int	amil;		/* # attacking mil */
	int	dmil;		/* # defending mil */
	natid	d_cnum;		/* defender cnum */
	coord	a_x;		/* attacker x */
	coord	a_y;		/* attacker y */
	int	a_mob;		/* attacker mob */
	coord	d_x;		/* defender x */
	coord	d_y;		/* defender y */
	int	acas;		/* attacker casualties */
	int	dcas;		/* defender casualties */
	int	dam;		/* damage from shipdef() */
	struct	shpstr aship;	/* attacking ship */
	struct	shpstr dship;	/* defending ship */
	double	aspeed;
	double	dspeed;
#ifdef HARBOR_POLICE
	struct	sctstr asect;
	int	from_ship=0,from_land=0;
	struct	nstr_item nbst;
#endif /* HARBOR_POLICE */
	char	*ptr;

	if ((ptr = getstarg(argp[1], "Victim ship #? ")) == 0)
		return RET_SYN;
	if ((dshpno = atoi(ptr)) < 0 || !getship(dshpno, &dship)) {
		pr("No such ship\n");
		return RET_FAIL;
	}
	if ((ptr = getstarg(argp[2], "Boarding party from? ")) == 0)
		return RET_SYN;
#ifdef HARBOR_POLICE
	getsect(dship.shp_x,dship.shp_y,&asect);
	if (asect.sct_type == SCT_HARBR){
		if (board_issector(ptr))
			from_land = 1;
		else{
			if ((ashpno = atoi(ptr)) < 0 ||
				!getship(ashpno, &aship) ||
	    			aship.shp_own != cnum)
				return RET_FAIL;
			from_ship = 1;
		}
	}
	else{
		 if ((ashpno = atoi(ptr)) < 0 || !getship(ashpno, &aship) ||
	    		aship.shp_own != cnum)
			return RET_FAIL;
		from_ship=1;
	}
#else
	if ((ashpno = atoi(ptr)) < 0 || !getship(ashpno, &aship) ||
	    aship.shp_own != cnum)
		return RET_FAIL;
#endif /* HARBOR_POLICE */
	getship(ashpno, &aship);
	getship(dshpno, &dship);
	d_cnum = dship.shp_own;
	if (!trechk(cnum, d_cnum, SEAATT))
		return RET_FAIL;
	d_x = dship.shp_x;
	d_y = dship.shp_y;
#ifdef HARBOR_POLICE
	if (from_ship){
		a_x = aship.shp_x;
		a_y = aship.shp_y;
	}else{
		a_x = asect.sct_x;
		a_y = asect.sct_y;
	}
#else
	a_x = aship.shp_x;
	a_y = aship.shp_y;
#endif /* HARBOR_POLICE */
	if (a_x != d_x || a_y != d_y) {
		pr("Not in same sector!\n");
		return RET_FAIL;
	}

#ifdef HARBOR_POLICE
	if (from_ship)
		amil = getvar(V_MILIT, (char *)&aship, EF_SHIP);
	else
		amil = getvar(V_MILIT, (char *)&asect, EF_SECTOR);
#else
	amil = getvar(V_MILIT, (char *)&aship, EF_SHIP);
#endif /* HARBOR_POLICE */
	if (amil == 0) {
#ifdef HARBOR_POLICE
		if (from_ship)
#endif /* HARBOR_POLICE */
#ifdef	SHIPNAMES
		pr(fmt("No military on %s %s(#%d)\n",
		       mchr[aship.shp_type].m_name, aship.shp_name, ashpno));
#else
		pr(fmt("No military on %s #%d\n",
		       mchr[aship.shp_type].m_name, ashpno));
#endif	SHIPNAMES
#ifdef HARBOR_POLICE
		else
			pr(fmt("No mil in %s!\n",xyas(a_x,a_y,cnum)));
#endif /* HARBOR_POLICE */
		return RET_FAIL;
	}

#ifdef HARBOR_POLICE
	if (from_ship)
		a_mob = aship.shp_mobil;
	else
		a_mob = asect.sct_mobil;
#else
	a_mob = aship.shp_mobil;
#endif /* HARBOR_POLICE */
	if (a_mob <= 0) {
#ifdef HARBOR_POLICE
		if (from_ship)
#endif /* HARBOR_POLICE */
#ifdef	SHIPNAMES
		pr(fmt("%s %s(#%d) has no mobility!\n",
			mchr[aship.shp_type].m_name, aship.shp_name, ashpno));
#else
		pr(fmt("%s #%d has no mobility!\n",
			mchr[aship.shp_type].m_name, ashpno));
#endif	SHIPNAMES
#ifdef HARBOR_POLICE
		else
			pr(fmt("Sector %s has no mobility!\n",xyas(a_x,a_y,cnum)));
#endif /* HARBOR_POLICE */
		return RET_FAIL;
	}
	if (mchr[dship.shp_type].m_flags & M_SUB) {
#ifdef HARBOR_POLICE
		if (asect.sct_type != SCT_HARBR){
#endif /* HARBOR_POLICE */
		pr("You can't board a submarine!\n");
		return RET_FAIL;
#ifdef HARBOR_POLICE
		}
#endif /* HARBOR_POLICE */
	}

#ifdef HARBOR_POLICE
	if (from_ship){
#endif /* HARBOR_POLICE */
	if ((dam = shipdef(d_cnum, seadef(aship.shp_type), a_x, a_y)) > 0) {
#ifdef MERC
		if(d_cnum != 0)
#endif
#ifdef	SHIPNAMES
		wu(0, d_cnum, fmt("Return fire did %d%% damage to %s %s(#%d)",
			dam, mchr[aship.shp_type].m_name, aship.shp_name,
			ashpno));
#else
		wu(0, d_cnum, fmt("Return fire did %d%% damage to %s #%d",
			dam, mchr[aship.shp_type].m_name, ashpno));
#endif	SHIPNAMES
		shipdamage(&aship, dam);
		putship(ashpno, &aship);
		if (aship.shp_effic < 20) {
#ifdef MERC
			if(d_cnum != 0)
#endif
			wu(0, d_cnum,
#ifdef	SHIPNAMES
				fmt("Country #%d lost %s %s(#%d) trying to board %s %s(#%d)",
				cnum, mchr[aship.shp_type].m_name,
				aship.shp_name, ashpno,
				mchr[dship.shp_type].m_name, dship.shp_name,
				dshpno));
#else
				fmt("Country #%d lost %s #%d trying to board %s #%d",
				cnum, mchr[aship.shp_type].m_name, ashpno,
				mchr[dship.shp_type].m_name, dshpno));
#endif	SHIPNAMES
			nreport(cnum, N_SHP_LOSE, d_cnum, 1);
			return RET_OK;
		}
	}
#ifdef HARBOR_POLICE
	}else{
	if ((dam = shipdef(d_cnum,
		landdef(asect.sct_type), a_x, a_y)) > 0) {
#ifdef MERC
		if(d_cnum != 0)
#endif
		wu(0, d_cnum, fmt("Return fire did %d%% damage to %s",
			dam, xyas(a_x,a_y, d_cnum)));
		sectdamage(&asect, dam);
		putsect(&asect);
	}
	}
#endif /* HARBOR_POLICE */
#ifdef HARBOR_POLICE
	if (from_ship)
		getship(ashpno, &aship);
	else
		getsect(a_x,a_y, &asect);
#else
	getship(ashpno, &aship);
#endif /* HARBOR_POLICE */
	getship(dshpno, &dship);
#ifdef HARBOR_POLICE
	if (from_ship && (dship.shp_mobil > 0)) {
#else
	if (dship.shp_mobil > 0) {
#endif /* HARBOR_POLICE */
		aspeed = mchr[aship.shp_type].m_speed *
			aship.shp_effic / 100.0;
		dspeed = mchr[dship.shp_type].m_speed * 
			dship.shp_effic / 100.0;
		aspeed = techfact(aship.shp_tech, 1.0) * aspeed;
		dspeed = techfact(dship.shp_tech, 1.0) * dspeed;
		aship.shp_mobil -= (int) (127.0 / aspeed);
		dship.shp_mobil -= (int) (127.0 / aspeed);
		if (aspeed < dspeed) {
			pr("Victim ship moves faster than you do!");
			pr("  You can't catch him!\n");
#ifdef MERC
			if(dship.shp_own != 0)
#endif
			wu(0, dship.shp_own,
#ifdef	SHIPNAMES
				fmt("%s (#%d) %s %s(#%d) failed to catch %s %s(#%d)\n",
				cname(aship.shp_own), aship.shp_own,
				mchr[aship.shp_type].m_name, aship.shp_name,
				ashpno, mchr[dship.shp_type].m_name,
				dship.shp_name, dshpno));
#else
				fmt("%s (#%d) %s #%d failed to catch %s #%d\n",
				cname(aship.shp_own), aship.shp_own,
				mchr[aship.shp_type].m_name, ashpno,
				mchr[dship.shp_type].m_name, dshpno));
#endif	SHIPNAMES
			putship(ashpno, &aship);
			putship(dshpno, &dship);
			return RET_OK;
		}
	}
	dmil = getvar(V_MILIT, (char *)&dship, EF_SHIP);
#ifdef HARBOR_POLICE
	if (from_ship){
		amil = getvar(V_MILIT, (char *)&aship, EF_SHIP);
		pr(fmt("%d attempting to board ship #%d\n", amil, dshpno));
	}else{
		amil = getvar(V_MILIT, (char *)&asect, EF_SECTOR);
		pr(fmt("%s attempting to board ship #%d\n",
			xyas(a_x,a_y,cnum), dshpno));
	}
#else
	amil = getvar(V_MILIT, (char *)&aship, EF_SHIP);
	pr(fmt("%d attempting to board ship #%d\n", amil, dshpno));
#endif /* HARBOR_POLICE */
	acas = amil;
	dcas = dmil;
	while (1) {
		if (chance(0.33) || dmil <= 0) {
			pr("!");
			if (--dmil <= 0)
				break;
		} else { 
			pr("@");
			if (--amil <= 0)
				break;
		}
	}
	acas -= amil;
	dcas -= dmil;
	if (amil > 0) {
		struct mchrstr *vbase;

		pr("Boarding successful!\n");
#ifdef HARBOR_POLICE
		if (from_ship){
#endif /* HARBOR_POLICE */
#ifdef MERC
		if(d_cnum != 0)
#endif
#ifdef	SHIPNAMES
		wu(0, d_cnum,
			fmt("Country #%d %s %s (#%d) boarded %s %s(#%d)\n",
			cnum, mchr[aship.shp_type].m_name, aship.shp_name,
			aship.shp_uid, mchr[dship.shp_type].m_name,
			dship.shp_name, dshpno));
#else
		wu(0, d_cnum, fmt("Country #%d %s (#%d) boarded %s #%d\n", cnum,
			mchr[aship.shp_type].m_name, aship.shp_uid,
			mchr[dship.shp_type].m_name, dshpno));
#endif	SHIPNAMES
#ifdef HARBOR_POLICE
		}else{
#ifdef MERC
		if(d_cnum != 0)
#endif
#ifdef	SHIPNAMES
		wu(0, d_cnum, fmt("Country #%d harbor police boarded %s %s(#%d)\n", cnum,
			mchr[dship.shp_type].m_name, dship.shp_name, dshpno));
#else
		wu(0, d_cnum, fmt("Country #%d harbor police boarded %s #%d\n", cnum,
			mchr[dship.shp_type].m_name, dshpno));
#endif	SHIPNAMES
		}
#endif /* HARBOR_POLICE */
		nreport(cnum, N_BOARD_SHIP, d_cnum, 1);
		takeover_ship(&dship, cnum, 1);
		dship.shp_fleet = ' ';

		vbase = &mchr[dship.shp_type];
		dmil = min(amil / 2, vl_find(V_MILIT, vbase->m_vtype,
			vbase->m_vamt, (int) vbase->m_nv));
		amil -= dmil;
		pr(fmt("%d of your troops hold%s ship %d\n", dmil,
			splur(dmil != 1), dshpno));
#ifdef HARBOR_POLICE
		if (from_ship){
		pr(fmt("%d return%s to ship %d\n", amil, splur(amil != 1),
			ashpno));
		if (getvar(V_PSTAGE, (char *)&dship, EF_SHIP) == PLG_INFECT) {
			if (getvar(V_PSTAGE, (char *)&aship, EF_SHIP) == 0)
				putvar(V_PSTAGE, PLG_EXPOSED, (char *)&aship,
				       EF_SHIP);
		}
		else if (getvar(V_PSTAGE, (char *)&aship, EF_SHIP) ==
			 PLG_INFECT) {
			if (getvar(V_PSTAGE, (char *)&dship, EF_SHIP) == 0)
				putvar(V_PSTAGE, PLG_EXPOSED, (char *)&dship,
				       EF_SHIP);
		}
		}else{
		pr(fmt("%d return%s to sector %s\n", amil, splur(amil != 1),
			xyas(a_x,a_y,cnum)));
		if (getvar(V_PSTAGE, (char *)&dship, EF_SHIP) == PLG_INFECT) {
			if (getvar(V_PSTAGE, (char *)&asect, EF_SECTOR) == 0)
				putvar(V_PSTAGE, PLG_EXPOSED, (char *)&asect,
				       EF_SECTOR);
		}
		}
#else
		pr(fmt("%d return%s to ship %d\n", amil, splur(amil != 1),
			ashpno));
		if (getvar(V_PSTAGE, (char *)&dship, EF_SHIP) == PLG_INFECT) {
			if (getvar(V_PSTAGE, (char *)&aship, EF_SHIP) == 0)
				putvar(V_PSTAGE, PLG_EXPOSED, (char *)&aship,
				       EF_SHIP);
		}
		else if (getvar(V_PSTAGE, (char *)&aship, EF_SHIP) ==
			 PLG_INFECT) {
			if (getvar(V_PSTAGE, (char *)&dship, EF_SHIP) == 0)
				putvar(V_PSTAGE, PLG_EXPOSED, (char *)&dship,
				       EF_SHIP);
		}
#endif /* HARBOR_POLICE */
	} else {
		pr("\nYou have been repelled...\n");
#ifdef MERC
		if(d_cnum != 0)
#endif
#ifdef HARBOR_POLICE
		if (from_ship){
#ifdef	SHIPNAMES
		wu(0, d_cnum, fmt("Country #%d %s %s(#%d) tried to board %s %s(#%d)",
			cnum, mchr[aship.shp_type].m_name, aship.shp_name,
			ashpno, mchr[dship.shp_type].m_name, dship.shp_name,
			dshpno));
#else
		wu(0, d_cnum, fmt("Country #%d %s #%d tried to board %s #%d",
			cnum, mchr[aship.shp_type].m_name, ashpno,
			mchr[dship.shp_type].m_name, dshpno));
#endif	SHIPNAMES
		}else{
#ifdef	SHIPNAMES
		wu(0, d_cnum, fmt("Country #%d tried to board %s %s(#%d)",
			cnum, mchr[dship.shp_type].m_name, dship.shp_name,
			dshpno));
#else
		wu(0, d_cnum, fmt("Country #%d tried to board %s #%d",
			cnum, mchr[dship.shp_type].m_name, dshpno));
#endif	/* SHIPNAMES */
		}
#else
#ifdef	SHIPNAMES
		wu(0, d_cnum, fmt("Country #%d %s %s(#%d) tried to board %s %s(#%d)",
			cnum, mchr[aship.shp_type].m_name, aship.shp_name,
			ashpno, mchr[dship.shp_type].m_name, dship.shp_name,
			dshpno));
#else
		wu(0, d_cnum, fmt("Country #%d %s #%d tried to board %s #%d",
			cnum, mchr[aship.shp_type].m_name, ashpno,
			mchr[dship.shp_type].m_name, dshpno));
#endif	SHIPNAMES
#endif /* HARBOR_POLICE */
		nreport(cnum, N_SHP_LOSE, d_cnum, 1);
	}
#ifdef HARBOR_POLICE
	if (from_ship){
		putvar(V_MILIT, amil, (char *)&aship, EF_SHIP);
		putship(ashpno, &aship);
	}else{
		putvar(V_MILIT, amil, (char *)&asect, EF_SECTOR);
		putsect(&asect);
	}
#else
	putvar(V_MILIT, amil, (char *)&aship, EF_SHIP);
	putship(ashpno, &aship);
#endif /* HARBOR_POLICE */
	putvar(V_MILIT, dmil, (char *)&dship, EF_SHIP);
	putship(dshpno, &dship);
	pr(fmt("Casualties :\nYours ... %d\n", acas));
	pr(fmt("Theirs .. %d\n", dcas));
	btused = roundavg((dcas + acas) * 0.15 + 0.5);
	pr(fmt("Papershuffling ... %d B.T.U\n", btused));
	NAT_DELTA(nat_btu, cnum, -btused);
	return RET_OK;
}

#ifdef HARBOR_POLICE
static int
board_issector(arg)
        char *arg;
{
        char c;

        while (c = *arg++) {
                if (!isdigit(c) && !isspace(c)) return 1;
        }
        return 0;
}
#endif /* HARBOR_POLICE */
