DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T c

⟦36eda6cbc⟧ TextFile

    Length: 39440 (0x9a10)
    Types: TextFile
    Names: »combat.c.orig«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Conquer/combat.c.orig« 

TextFile

/*conquer : Copyright (c) 1988 by Ed Barlow.
 *  I spent a long time writing this code & I hope that you respect this.
 *  I give permission to alter the code, but not to copy or redistribute
 *  it without my explicit permission.  If you alter the code,
 *  please document changes and send me a copy, so all can have it.
 *  This code, to the best of my knowledge works well,  but it is my first
 *  'C' program and should be treated as such.  I disclaim any
 *  responsibility for the codes actions (use at your own risk).  I guess
 *  I am saying "Happy gaming", and am trying not to get sued in the process.
 *                                                Ed
 */

#include <math.h>
#include "header.h"
#include "data.h"

#define	MGKNUM	32		/* number of units possible in battle */
#define	ATKR	2
#define	DFND	1
#define	NTRL	0
#define	WIMP	3

extern	FILE	*fpmsg;
extern	FILE	*fnews;
extern	short	country;

short	retreatside;	/* ATKR, DFND, or none (0) */
short	retreatx;	/* retreat x square */
short	retreaty;	/* retreat y square */

int	unit[MGKNUM];		/*armynum*/
int	owner[MGKNUM];		/*owner*/
int	side[MGKNUM];		/*see definitions->1=units 2=unit*/
long	troops[MGKNUM];		/*starting troops in army */
int	xspot,yspot;		/*location of battles*/
int	anation;		/*nation attacking in this fight*/
int	dnation;		/*one nation defending in this fight*/

/************************************************************************/
/*	COMBAT()	run all combat on the map			*/
/*  	for each sector, determine if armies in with attack mode	*/
/************************************************************************/
void
combat()
{
	register int i,j;
	char	**fought; 		/* TRUE if already fought in sctr */
	int	temp,ctry;
	short	armynum,nvynum;
	int	valid;
	int	count=0;

	fought = (char **) m2alloc(MAPX,MAPY,sizeof(char));

	printf("Run Combat Routines\n");
	fprintf(fnews,"4\tBATTLE SUMMARY STATISTICS\n");
	/*for each nation, if in attack mode run a check*/

	/* no sectors have been fought in yet */
	for(i=0;i<MAPX;i++) for(j=0;j<MAPY;j++) fought[i][j]=FALSE;

	for(ctry=NTOTAL-1;ctry>0;ctry--) if(isactive(ntn[ctry].active)) {

		/*army combat*/
		for(j=0;j<MAXARM;j++)
			if((ntn[ctry].arm[j].sold>0)
			&&(ntn[ctry].arm[j].stat>=ATTACK)
			&&(ntn[ctry].arm[j].stat<=SORTIE
			  ||ntn[ctry].arm[j].stat>=NUMSTATUS)
			&&(fought[ntn[ctry].arm[j].xloc][ntn[ctry].arm[j].yloc]==0)){

			/* someone can initiate combat in xspot,yspot */
			xspot=ntn[ctry].arm[j].xloc;
			yspot=ntn[ctry].arm[j].yloc;
			fought[xspot][yspot]=TRUE;

			/*initialize matrix*/
			for(temp=0;temp<MGKNUM;temp++){
				unit[temp]=(-1);
				owner[temp]=(-1);
				side[temp]=NTRL;
				troops[temp]=0;
			}

			/*check all armies in sector and add to matrix*/
			count=0;
			valid=FALSE;
			/*is valid,set matrix*/
			for(country=0;country<NTOTAL;country++)
			if(isactive(ntn[country].active))
			for(armynum=0;armynum<MAXARM;armynum++)
			if((ASOLD>0)
			&&(ASTAT!=SCOUT)
			&&(AXLOC==xspot)
			&&(AYLOC==yspot)
			&&(count<MGKNUM)) {
				if((country!=ctry)
				&&(ntn[ctry].dstatus[country]>HOSTILE)) {
					valid=TRUE;
					if( sct[xspot][yspot].owner==ctry ) {
						dnation=ctry;
						anation=country;
					} else if(( rand()%2==0 )
					||( sct[xspot][yspot].owner==country )){
						anation=ctry;
						dnation=country;
					} else {
						dnation=ctry;
						anation=country;
					}
				}
				unit[count]=armynum;
				owner[count]=country;
				count++;
			}

			if(valid==TRUE) fight();
		}

		/*navy combat*/
		for(j=0;j<MAXNAVY;j++)
		if((ntn[ctry].nvy[j].warships!=0)
&&(fought[ntn[ctry].nvy[j].xloc][ntn[ctry].nvy[j].yloc]==0)
&&(sct[ntn[ctry].nvy[j].xloc][ntn[ctry].nvy[j].yloc].altitude==WATER)){

			xspot=ntn[ctry].nvy[j].xloc;
			yspot=ntn[ctry].nvy[j].yloc;
			fought[xspot][yspot]=1;

			/*initialize matrix*/
			for(temp=0;temp<MGKNUM;temp++){
				unit[temp]=(-1);
				owner[temp]=(-1);
				side[temp]=NTRL;
				troops[temp]=0;
			}

			/*check all fleets in 2 sector range and add to matrix*/
			count=0;
			valid=FALSE;
			/*is valid,set matrix*/
			for(country=0;country<NTOTAL;country++)
			if(isactive(ntn[country].active))
			for(nvynum=0;nvynum<MAXNAVY;nvynum++)
			if((NWSHP+NMSHP+NGSHP!=0)
			&&(abs(NXLOC-xspot)<=2)
			&&(abs(NYLOC-yspot)<=2)
			&&(sct[NXLOC][NYLOC].altitude==WATER)
			&&(count<MGKNUM)) {
				fought[NXLOC][NYLOC]=1;
				if((country!=ctry)
				&&(ntn[ctry].dstatus[country]>HOSTILE)){
					valid=TRUE;
					anation=ctry;
					dnation=country;
				}
				unit[count]=nvynum;
				owner[count]=country;
				count++;
			}
			if(valid==TRUE) navalcbt();
		}
	}
	free(fought);
	printf("\nall army and navy attacks completed\n");
}

/* macro for owner, accounts for runaway indicator */
#define UOWNER(x) ((owner[(x)]<(-1))?(-owner[(x)]-1):(owner[(x)]))
/************************************************************************/
/*	FIGHT()	-	fight an individual battle given the three	*/
/*	matricies global to this module					*/
/************************************************************************/
void
fight()
{
	int	roll,strength,fortdam=FALSE;
	int	odds;			/* odds (asold/dsold) times 100 */
	int	done;
	int	i,j,k;
	long	asold=0,dsold=0;	/*a's and d's total soldiers*/
	long	astr=0,dstr=0;		/*a's and d's relative strength*/
	long	Aloss,Dloss;    	/*a's and d's total losses*/
	int	PAloss,PDloss;		/*percent a and d loss*/
	long	loss;
	int	abonus=0,dbonus=0;	/* bonus aggregate */
	long	vampire=0;		/* # non vamps deaded */
	short	nvamps=0;		/* number of vampire armies */

	/* determine who is attacker & who is on defenders side?*/
	for(j=0;j<MGKNUM;j++) if(owner[j]!=(-1)){
		if(owner[j]==anation) side[j]=ATKR;
		else if(owner[j]==dnation) side[j]=DFND;
		else if(ntn[anation].dstatus[owner[j]]==JIHAD) side[j]=DFND;
		else if(ntn[owner[j]].dstatus[anation]==JIHAD) side[j]=DFND;
		else if(ntn[anation].dstatus[owner[j]]==WAR)   side[j]=DFND;
		else if(ntn[owner[j]].dstatus[anation]==WAR)   side[j]=DFND;
		else if((ntn[owner[j]].dstatus[anation]==TREATY)&&(ntn[owner[j]].dstatus[dnation]>HOSTILE)) side[j]=ATKR;
		else if((ntn[owner[j]].dstatus[anation]==ALLIED)&&(ntn[owner[j]].dstatus[dnation]>HOSTILE)) side[j]=ATKR;
	}

	/*calculate number of troops and assign statuses */
	asold=0;
	dsold=0;
	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)) {
		/* record troops for all units in sector */
		troops[i]=ntn[owner[i]].arm[unit[i]].sold;

		if(((ntn[owner[i]].arm[unit[i]].unittyp == A_MERCENARY)
		||(ntn[owner[i]].arm[unit[i]].unittyp == A_ORC)
		||(ntn[owner[i]].arm[unit[i]].unittyp == A_GOBLIN))
		&&( ntn[owner[i]].arm[unit[i]].stat < NUMSTATUS )
		&&( rand()%100<15 )) {
			if( ispc(ntn[owner[i]].active)) {
				mailopen( owner[i] );
				fprintf(fm,"Message to %s from Conquer\n",ntn[owner[i]].name);
				fprintf(fm,"\n  Your %s Army %d Refuses to Fight\n",
				  unittype[ntn[owner[i]].arm[unit[i]].unittyp],
				  unit[i]);
				mailclose();
			}
			retreatside = side[i];
			fdxyretreat();
			if((retreatx==xspot)&&(retreaty==yspot)){
				/* move to capitol & kill 30% */
				ntn[owner[i]].arm[unit[i]].xloc=ntn[owner[i]].capx;
				ntn[owner[i]].arm[unit[i]].yloc=ntn[owner[i]].capy;
				ntn[owner[i]].arm[unit[i]].sold*=7;
				ntn[owner[i]].arm[unit[i]].sold/=10;
			} else {
				/* retreat normally and kill 20% */
				ntn[owner[i]].arm[unit[i]].sold*=8;
				ntn[owner[i]].arm[unit[i]].sold/=10;
				retreat( i );
			}
			owner[i]=(-1-owner[i]);
			continue;
		}
		else if(side[i]==ATKR){
			if((ntn[owner[i]].arm[unit[i]].stat!=RULE)
			&&( ntn[owner[i]].arm[unit[i]].stat!=TRADED)
			&&( ntn[owner[i]].arm[unit[i]].stat!=SCOUT)) {
				asold += ntn[owner[i]].arm[unit[i]].sold;
			} else {
				side[i]=NTRL;
			}
			/* sortie 20% bonus in odds */
			if(ntn[owner[i]].arm[unit[i]].stat==SORTIE)
				asold += ntn[owner[i]].arm[unit[i]].sold/5;
		} else if(side[i]==DFND){
			if(ntn[owner[i]].arm[unit[i]].stat!=RULE) {
				dsold += ntn[owner[i]].arm[unit[i]].sold;
			}
		}
		if((magic(owner[i],VAMPIRE)==TRUE) &&
		(ntn[owner[i]].arm[unit[i]].unittyp==A_ZOMBIE)) nvamps++;
	}

	if(asold<=0) {
		printf("\nCombat aborted due to lack of attackers.\n");
		return;
	}
	if( asold > dsold*100)		odds=10000;
	else if( dsold > asold*100 )	odds=1;
	else	odds = (asold*100)/dsold;

	/* mercenaries/orcs/goblins might run away */
	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)) {
		if(((( odds > 200 )&&(side[i]==DFND))
		||(( odds < 100 )&&(side[i]==ATKR)))
		&&((ntn[owner[i]].arm[unit[i]].unittyp == A_MERCENARY)
		  ||(ntn[owner[i]].arm[unit[i]].unittyp == A_ORC)
		  ||(ntn[owner[i]].arm[unit[i]].unittyp == A_GOBLIN))
		&&(ntn[owner[i]].arm[unit[i]].stat < NUMSTATUS)
		&&( rand()%100<30 )) {
			if( ispc(ntn[owner[i]].active)) {
				mailopen( owner[i] );
				fprintf(fm,"Message to %s from Conquer\n",ntn[owner[i]].name);
				fprintf(fm,"  Your %s Army %d Runs Away\n",
				  unittype[ntn[owner[i]].arm[unit[i]].unittyp],
				  unit[i]);
				mailclose();
			}
			retreatside = side[i];
			if( side[i] == ATKR ) asold-= troops[i];
			if( side[i] == DFND ) dsold-= troops[i];
			fdxyretreat();
			if((retreatx==xspot)&&(retreaty==yspot)){
				/* move to capitol & kill 75% */
				ntn[owner[i]].arm[unit[i]].xloc=ntn[owner[i]].capx;
				ntn[owner[i]].arm[unit[i]].yloc=ntn[owner[i]].capy;
				ntn[owner[i]].arm[unit[i]].sold/=4;
			} else {
				/* retreat normally and kill 50% */
				ntn[owner[i]].arm[unit[i]].sold/=2;
				retreat( i );
			}
			owner[i]=(-1-owner[i]);
			continue;
		}
	}
	retreatside=0;
	if( asold<=0 ) {
		printf("Exit from battle due to lack of attackers\n");
		return;
	}

	/* CALCULATE AVERAGE COMBAT BONUS */
	abonus=0;
	dbonus=0;
	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)) {
		if(side[i]==ATKR)
			abonus += cbonus(i)*troops[i];
		else if(side[i]==DFND && ntn[owner[i]].arm[unit[i]].stat!=RULE)
			dbonus += cbonus(i)*troops[i];
	}

	/*archer bonus if not in fort vs knights/cavalry*/
	j=0;
	k=0;
	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1))
	if(ISCITY(sct[xspot][yspot].designation)){
		if((ntn[owner[i]].arm[unit[i]].unittyp == A_CAVALRY)
		||(ntn[owner[i]].arm[unit[i]].unittyp == A_KNIGHT))
		if(side[i]==ATKR) j+=troops[i];
		else if(side[i]==DFND) k+=troops[i];
	}

	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)) {
		if(j>0) abonus += (15 * j * troops[i]) / asold;
		if(k>0 && dsold>0) dbonus += (15 * k * troops[i]) / dsold;
	}

	abonus/=asold;
	if (dsold>0) dbonus/=dsold;

	/*CALCULATED BONUSES TO WHOLE COMBAT*/
	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)) {
		if(fort_val(&sct[xspot][yspot]) != 0){
			/*Catapults add +1%/20 men defending castle (max +10%)*/
			if((ntn[owner[i]].arm[unit[i]].unittyp == A_CATAPULT)
			&&(side[i]==DFND))
				dbonus += max((troops[i]/20),10);
			/*Catapults add +1%/40 men attacking castle (max +10%)*/
			else if((ntn[owner[i]].arm[unit[i]].unittyp == A_CATAPULT)
			&&(side[i]==ATKR)) {
				strength = max((troops[i]/40),10);
				abonus += strength;
				/* possible damage 20% chance */
				if(rand()%100<2*strength) {
					fortdam=TRUE;
					sct[xspot][yspot].fortress--;
					if(sct[xspot][yspot].fortress == 0)
					sct[xspot][yspot].designation = DRUIN;
				}
			}
			/*Siege_engines add +1%/20 men when attacking fortress*/
			else if((ntn[owner[i]].arm[unit[i]].unittyp == A_SIEGE)
			&&(side[i]==ATKR)) {
				strength = max((troops[i]/20),30);
				abonus += strength;
				/* possible damage 15% chance */
				if(rand()%100<strength/2) {
					fortdam=TRUE;
					sct[xspot][yspot].fortress--;
					if(sct[xspot][yspot].fortress == 0)
						sct[xspot][yspot].designation = DRUIN;
				}
			}
		} else {
			/*Catapults add +1%/40 men normal combat (max +10%)*/
			if(ntn[owner[i]].arm[unit[i]].unittyp == A_CATAPULT)
				abonus+=max((troops[i]/40),10);
		}
	}

	/*RUN COMBAT */
	/*FIRST GIVE RANDOM ROLL FROM 0 to 100 */
	/*WITH A PROBABILITY BELL CURVE */
	/* high roll favors attacker [ 5 d21 - 5 ] */
	roll = 0;
	for(i=0;i<5;i++) {
		roll += rand()%21+1;
	}
	roll -= 5;

	/*find relative strength of troops*/
	astr = asold * (100 + abonus);
	dstr = dsold * (100 + dbonus);

	/*Recalculate odds based on quality of troops*/
	if( astr > dstr*100)		odds=10000;
	else if( dstr > astr*100 )	odds=1;
	else	odds = (astr*100)/dstr;

	/* calculate loss for an even battle */
	PDloss = MAXLOSS * roll / 100;
	PAloss = MAXLOSS * (100 - roll) / 100;

	/* adjust for odds */
	if( odds == 1 ) {
		PDloss=0;
		PAloss=200;
	} else if( odds == 10000 ) {
		PAloss=0;
		PDloss=200;
	} else if(odds > 100) {
		PDloss += (odds / 12 - 8);	/* 8.33% for higher odds */
		PAloss -= (odds / 16 - 6);	/* 6.25% for lower odds */
		if(PAloss<(100-roll)/20)
			PAloss=(100-roll)/20;	/* can't get too small */
	} else {
		PAloss += ( 800 / odds - 8);	/* 8% for higher odds */
		PDloss -= ( 600 / odds - 6);	/* 6% for lower odds */
		if(PDloss<roll/20)
			PDloss = roll/20;	/* can't get too small */
	}

	if( fort_val(&sct[xspot][yspot]) > 0 ){
		PDloss *= 120;
		PAloss *= 120;
		PDloss /= 100;
		PAloss /= 100;
	}

	retreatside = 0;

	if((PDloss > 2* PAloss)
	&&(odds>150)
	&&(((PDloss>=50)&&(rand()%4==0))
	  ||(rand()%8)))	retreatside=DFND;

	if((PAloss > 2* PDloss)
	&&(odds<150)
	&&(((PAloss>=50)&&(rand()%2==0))
	  ||(rand()%6)))	retreatside=ATKR;

	if(retreatside!=0) {
		fdxyretreat();
		/* no legal retreat route */
		if((retreatside!=0) && (retreatx== xspot)
		&& (retreaty== yspot)){
			if(retreatside==ATKR) PAloss+=15;
			else if(retreatside==DFND) PDloss+=15;
#ifdef DEBUG
			printf("side %d (%d %d) can't retreat...+15%% loss\n",retreatside,retreatx,retreaty);
#endif DEBUG
			retreatside = 0;
		}
#ifdef DEBUG
		else printf("retreat side %d to %d %d\n",retreatside,retreatx,retreaty);
#endif DEBUG
	}

	if(PAloss>100) PAloss = 100;
	if(PDloss>100) PDloss = 100;

	Aloss = Dloss = 0;
	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)){
		if(side[i]==ATKR){
			if( ntn[owner[i]].arm[unit[i]].unittyp >= MINLEADER) {
				if((rand()%100) < PAloss){ /* kill it */
					for(j=0;j<MAXARM;j++)
					if(ntn[owner[i]].arm[j].stat==unit[i]+NUMSTATUS)
					ntn[owner[i]].arm[j].stat=ATTACK;
					Aloss += troops[i];
					ntn[owner[i]].arm[unit[i]].sold=0;
				}
			} else {
				loss=(troops[i]*PAloss)/100;
				/*archers/catapults on sortie take 1/4 damage*/
				if((ntn[owner[i]].arm[unit[i]].stat==SORTIE)
				&&(fort_val(&sct[xspot][yspot]) > 0)
				&&(sct[xspot][yspot].owner==country)
				&&((ntn[owner[i]].arm[unit[i]].unittyp==A_ARCHER)
				||(ntn[owner[i]].arm[unit[i]].unittyp==A_CATAPULT)))
					loss /= 4;
				/*army can't have less than 25 men in it*/
				if(troops[i]-loss<25)
					loss=troops[i];
if( loss>troops[i] ) {
printf("I AM VERY CONFUSED - PLEASE HELP... combat.c\n");
}
				Aloss+=loss;
				ntn[owner[i]].arm[unit[i]].sold-=loss;
				if((ntn[owner[i]].arm[unit[i]].unittyp==A_MILITIA)&&(retreatside==ATKR)) {
				sct[ntn[owner[i]].arm[unit[i]].xloc][ntn[owner[i]].arm[unit[i]].yloc].people += ntn[owner[i]].arm[unit[i]].sold;
				ntn[owner[i]].arm[unit[i]].sold-=0;
				}
			}
		} else if(side[i]==DFND){
			if( ntn[owner[i]].arm[unit[i]].unittyp >= MINLEADER) {
				if((ntn[owner[i]].arm[unit[i]].stat!=RULE
				||PDloss>=80)&&((rand()%100) < PDloss)){ /* kill it */
					for(j=0;j<MAXARM;j++)
					if(ntn[owner[i]].arm[j].stat==unit[i]+NUMSTATUS)
					ntn[owner[i]].arm[j].stat=ATTACK;
					Dloss +=troops[i];
					ntn[owner[i]].arm[unit[i]].sold=0;
				}
			} else {
				loss=(troops[i]*PDloss)/100;
				/*destroy army if < 25 men*/
				if(troops[i]-loss<25)
					loss=troops[i];
				Dloss+=loss;
				ntn[owner[i]].arm[unit[i]].sold-=loss;
				if((ntn[owner[i]].arm[unit[i]].unittyp==A_MILITIA)&&(retreatside==DFND)) {
				sct[ntn[owner[i]].arm[unit[i]].xloc][ntn[owner[i]].arm[unit[i]].yloc].people += ntn[owner[i]].arm[unit[i]].sold;
				ntn[owner[i]].arm[unit[i]].sold-=0;
				}
			}
		}
		/* non-vampire troops are sucked in by vampires */
		if((nvamps>0)&&(magic(owner[i],VAMPIRE)==FALSE)
		&&(ntn[owner[i]].arm[unit[i]].unittyp!=A_ZOMBIE)
		&&(ntn[owner[i]].arm[unit[i]].unittyp<MINLEADER))
			vampire+= loss / 3;
	}
	/* use k variable to hold length */
#ifdef HIDELOC
	if( isntn( ntn[sct[xspot][yspot].owner].active )) {
	fprintf(fnews,"4.\tBattle occurs in %s", ntn[sct[xspot][yspot].owner].name);
	k = 27+strlen(ntn[sct[xspot][yspot].owner].name);
	} else {
	fprintf(fnews,"4.\tBattle on unowned land");
	k = 30;
	}
#else
	fprintf(fnews,"4.\tBattle in %d,%d",xspot,yspot);
	k = 25;
#endif
	for(j=0;j<MGKNUM;j++) if(UOWNER(j)>(-1)){
		done=FALSE;
		for(i=0;i<j;i++) if(UOWNER(j)==UOWNER(i)) done=TRUE;
		if(done==FALSE) {
			loss=NTRL;
			for(i=j;(loss==NTRL||loss==WIMP) && i<MGKNUM;i++)
				if(UOWNER(i)==UOWNER(j)) {
					if(owner[i]<(-1)) loss=WIMP;
					else loss=side[i];
				}
			if(loss!=NTRL) {
				k += 11 + strlen(ntn[UOWNER(j)].name);
				if(loss==WIMP) k++;
				if(k>79) {
					k = 30;
					fprintf(fnews,",\n4.\t  ");
				} else fprintf(fnews,", ");
				if(loss==ATKR)
					fprintf(fnews,"attacker %s",ntn[UOWNER(j)].name);
				else if(loss==DFND)
					fprintf(fnews,"defender %s",ntn[UOWNER(j)].name);
				else if(loss==WIMP)
					fprintf(fnews,"retreater %s",ntn[UOWNER(j)].name);
			}
		}
	}
	fprintf(fnews,"\n");
	if(nvamps>0){
		for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)){
			if((magic(owner[i],VAMPIRE)==TRUE)
			&&(ntn[owner[i]].arm[unit[i]].unittyp==A_ZOMBIE)
			&&(ntn[owner[i]].arm[unit[i]].sold > 0))
				ntn[owner[i]].arm[unit[i]].sold+=vampire/nvamps;
		}
	}

	/*who is in the battle; but don't send to scared armies */
	for(j=0;j<MGKNUM;j++) if(owner[j]>(-1)){
		done=FALSE;

		/*first time your nation appears done=FALSE*/
		for(i=0;i<j;i++) if(owner[j]==owner[i]) done=TRUE;

		if((done==FALSE)&&(ispc(ntn[owner[j]].active))) {

			loss=NTRL;
			for(i=j;loss==NTRL && i<MGKNUM;i++)
				loss=side[i];
			mailopen( owner[j] );

			fprintf(fm,"BATTLE SUMMARY for sector %d, %d\n",xspot,yspot);
			fprintf(fm,"Battle occured during %s of Year %d\n",PSEASON(TURN),YEAR(TURN));

			if(loss==ATKR)
				fprintf(fm,"You are on the Attacking Side\n");
			else if(loss==DFND)
				fprintf(fm,"You are on the Defending Side\n");
			else	fprintf(fm,"You are Neutral\n");

			/*detail all participants in battle*/
			for(k=0;k<MGKNUM;k++) if(owner[k]!=(-1)){
				fprintf(fm," %s ",ntn[UOWNER(k)].name);
				if(owner[k]<(-1))
					fprintf(fm,"chickens out: ");
				else if(side[k]==DFND
				&& ntn[UOWNER(k)].arm[unit[k]].stat!=RULE)
					fprintf(fm,"defending: ");
				else if(side[k]==ATKR)
					fprintf(fm,"attacking: ");
				else fprintf(fm,"neutral: ");
				fprintf(fm,"army %d (%s, men %d, bonus=%d, loss=%d)",
					unit[k],
					unittype[ntn[UOWNER(k)].arm[unit[k]].unittyp%UTYPE],
					troops[k],
					cbonus(k),
					troops[k]-ntn[UOWNER(k)].arm[unit[k]].sold);
				if((ntn[UOWNER(k)].arm[unit[k]].unittyp >= MINLEADER)
				&&( ntn[UOWNER(k)].arm[unit[k]].sold == 0))
					fprintf(fm," (killed)\n");
				else if((ntn[owner[k]].arm[unit[k]].unittyp == A_MILITIA)
				&&( ntn[owner[k]].arm[unit[k]].sold == 0))
				fprintf(fm," (disbanded)\n");
				else fputc('\n',fm);
			}

			fprintf(fm,"attacking soldiers=%ld -> percent loss %d%%\n",asold,PAloss);
			fprintf(fm,"defending soldiers=%ld -> percent loss %d%%\n",dsold,PDloss);
			fprintf(fm,"ODDS=%d => adjusted to %d to 100; Die Roll is %d\n",odds*(100+dbonus)/(100+abonus),odds,roll);
			fprintf(fm,"RESULT: Attackers lose %ld men, Defenders lose %ld men\n",Aloss, Dloss);
			if(fortdam==TRUE) fprintf(fm,"Fortifications damaged during the attack\n");
			if(retreatside==ATKR){
			if(Aloss<asold)
			fprintf(fm,"Additionally, All attackers retreat to %d %d\n",retreatx,retreaty);
			} else if(retreatside==DFND){
			if(Dloss<dsold)
			fprintf(fm,"Additionally, All defenders retreat to %d %d\n",retreatx,retreaty);
			}
			mailclose();
		}
	}
	retreat( -1 );
}

/************************************************************************/
/*	CBONUS() - return combat bonuses for unit i			*/
/************************************************************************/
int
cbonus(num)
{
	short	armynum;
	int	armbonus;

	armbonus=0;
	armynum=unit[num];
	country=UOWNER(num);

	/*Racial combat bonus due to terrain (the faster you move the better)*/
	armbonus+=5*(9-movecost[xspot][yspot]);	/* this line always has */
				/* the same result... must fix -- ADB */

	if(((magic(country,DESTROYER)==1)
	||(magic(country,DERVISH)==1))
	&&((sct[xspot][yspot].vegetation==ICE)
	||(sct[xspot][yspot].vegetation==DESERT)))
		armbonus+=30;

	if(ASTAT>=NUMSTATUS) armbonus+=20;	/* army group */
	if(side[num]==DFND){

		if(sct[xspot][yspot].altitude==MOUNTAIN) armbonus+=20;
		else if(sct[xspot][yspot].altitude==HILL) armbonus+=10;

		if(sct[xspot][yspot].vegetation==JUNGLE) armbonus+=20;
		else if(sct[xspot][yspot].vegetation==FOREST) armbonus+=15;
		else if(sct[xspot][yspot].vegetation==WOOD) armbonus+=10;

		if(ATYPE==A_MERCENARY) armbonus += MERCDEF;
		else armbonus += ntn[UOWNER(num)].dplus;

		if(ASTAT==MAGDEF) armbonus+=30;
		else if(ASTAT==SORTIE) armbonus-=30;
		else if(ASTAT==SIEGED) armbonus-=20;

		if((sct[xspot][yspot].owner==country)
		&&(ASTAT==GARRISON||ASTAT==MILITIA||ASTAT==SIEGED)){
			if(ATYPE == A_ZOMBIE) /* don't utilize walls well */
				armbonus += fort_val(&sct[xspot][yspot])/2;
			else armbonus += fort_val(&sct[xspot][yspot]);
		}
	}
	else if(side[num]==ATKR) {
		if( (fort_val(&sct[xspot][yspot]) > 0)
		&&( magic(country,SAPPER)==TRUE)) armbonus += 10;

		if(ATYPE == A_MERCENARY) armbonus += MERCATT;
		else armbonus += ntn[UOWNER(num)].aplus;
		if(ASTAT==MAGATT) armbonus += 30;
		if(ASTAT==SORTIE && (fort_val(&sct[xspot][yspot]) > 0)
		&& sct[xspot][yspot].owner==country) {
			armbonus += 10;
			if((ATYPE==A_DRAGOON)||(ATYPE==A_LEGION)
			||(ATYPE==A_PHALANX)) {
				/* bonus for organization or riding cavalry */
				armbonus += 5;
			} else if ((ATYPE==A_LT_CAV)||(ATYPE==A_CAVALRY)) {
				/* bonus for mounted sortie */
				armbonus += 10;
			} else if (avian(ATYPE)||ATYPE==A_ELEPHANT||ATYPE==A_KNIGHT) {
				/* bonus for mounted or flying sortie */
				armbonus += 15;
			}
			if ((ATYPE>=MINMONSTER)||(ATYPE<=MAXMONSTER)) {
				/* bonus for monsters (scare factor) */
				armbonus += 5;
			}
		}
	}

	/*army status is important*/
	if(ASTAT==MARCH) armbonus-=40;

	/*if a fortress*/
	if(fort_val(&sct[xspot][yspot]) > 0){
		/*Cavalry and Knights get -20%*/
		if((ATYPE == A_CAVALRY) ||(ATYPE == A_KNIGHT)) armbonus -= 20;
		/*Archers gain pluses*/
		else if((ATYPE == A_ARCHER)&&(sct[xspot][yspot].owner==country))
			armbonus += 15;
		else if(ATYPE == A_ARCHER) armbonus += 5;
	}

	if(side[num]==ATKR) armbonus+= *(unitattack+(ATYPE%UTYPE));
	else armbonus+= *(unitdefend+(ATYPE%UTYPE));

	/*Phalanx and Legionaires need certain numbers of troops*/
	if((ATYPE==A_PHALANX)||(ATYPE==A_LEGION)) {
 		if(ASOLD>1000){	armbonus+=20;
 		} else if(ASOLD>500) armbonus+=10;
	}

	return(armbonus);
}

void
fdxyretreat()	/* finds retreat location */
{
	int	x,y,nation=(-1);
	int	xsctr= xspot;
	int	ysctr= yspot;

	retreatx=xsctr;
	retreaty=ysctr;

	if((sct[xsctr][ysctr].designation==DTOWN)
	||(sct[xsctr][ysctr].designation==DCAPITOL)
	||(sct[xsctr][ysctr].designation==DCITY)){
		retreatside=0;
		return;
	}

	if(retreatside == ATKR) nation=anation;
	else nation=dnation;

	for(x= xsctr-1; x<=xsctr+1; x++)
	for(y= ysctr-1; y<=ysctr+1; y++) if(ONMAP(x,y)){
		if(tofood( &sct[x][y],
			sct[x][y].owner == country ? country : 0)==0) continue;
		if(((sct[x][y].owner == nation)
		   ||(ntn[sct[x][y].owner].dstatus[nation] < NEUTRAL))
		||(solds_in_sector( x, y, sct[x][y].owner) == 0)){
			retreatx=x;
			retreaty=y;
#ifdef DEBUG
			printf("armies in %d %d retreat to %d %d\n",xsctr,ysctr,x,y);
#endif DEBUG
			return;
		}
	}
}

void
retreat(unitnum)
int	unitnum;	/* if -1 then normal, else retreat only unit ismerc */
{
	int cnum;

	if(retreatside == 0) return;

	for(cnum=0;cnum<MGKNUM;cnum++) if(owner[cnum]>(-1)){
		if( unitnum != (-1) ) cnum=unitnum;
		if((side[cnum]==ATKR)&&(retreatside==ATKR)){
			ntn[owner[cnum]].arm[unit[cnum]].xloc = retreatx;
			ntn[owner[cnum]].arm[unit[cnum]].yloc = retreaty;
		}
		else if((side[cnum]==DFND)&&(retreatside==DFND)){
			ntn[owner[cnum]].arm[unit[cnum]].xloc = retreatx;
			ntn[owner[cnum]].arm[unit[cnum]].yloc = retreaty;
		}
		if( unitnum != (-1) ) return;
	}
}


/*SUBROUTINE TO RUN NAVAL COMBAT ON ALL SHIPS */
/* quick define for easier reading */
#define QWAR 1
#define QGAL 2
#define QMER 3
/* just like fight, this takes array of owner,side,unit and calculates */
/* a random battle based on the strengths of the combatants.           */
void
navalcbt()
{
	int acrew=0,dcrew=0;	/*a's and d's crew and soldier strength*/
	int ahold=0,dhold=0;	/*a's and d's warship strength*/
	int awsunk=0,dwsunk=0;	/*a's and d's warship losses for the round*/
	int agsunk=0,dgsunk=0;	/*a's and d's galley losses for the round*/
	int amsunk=0,dmsunk=0;	/*a's and d's merchent losses for the round*/
	int awcapt=0,dwcapt=0;	/*a's and d's warship captures for the round*/
	int agcapt=0,dgcapt=0;	/*a's and d's galley captures for the round*/
	int amcapt=0,dmcapt=0;	/*a's and d's merchant captures for the round*/
	int akcrew=0,dkcrew=0;	/*a's and d's crew losses for the round*/
	char wnum[MGKNUM],gnum[MGKNUM],mnum[MGKNUM];
	register int done,i,j,k;
	int roll,odds,savecntry=country;
	int PAloss, PDloss, Ploss, which, shipsize;
	int thold, ghold, nvynum, armynum;
	int dcptpct, acptpct, cptpct;
	struct s_nation *saventn=curntn;
	void show_ships(),capture();

	printf("In Naval Combat....\n");

	/* determine who is attacker & who is on defenders side?*/
	for(j=0;j<MGKNUM;j++) if(owner[j]!=(-1)){
		if(owner[j]==anation) side[j]=ATKR;
		else if(ntn[anation].dstatus[owner[j]]==JIHAD) side[j]=DFND;
		else if(ntn[owner[j]].dstatus[anation]==JIHAD) side[j]=DFND;
		else if(ntn[anation].dstatus[owner[j]]==WAR)   side[j]=DFND;
		else if(ntn[owner[j]].dstatus[anation]==WAR)   side[j]=DFND;
		else if((ntn[owner[j]].dstatus[anation]==TREATY)
		&&(ntn[owner[j]].dstatus[dnation]>HOSTILE)) side[j]=ATKR;
		else if((ntn[owner[j]].dstatus[anation]==ALLIED)
		&&(ntn[owner[j]].dstatus[dnation]>HOSTILE)) side[j]=ATKR;
	}

	/* Loop through all competitors to determine
	 *  relative combat strengths:
	 *                              men/unit strength
	 * crew on ship:
	 *     warship crew                     1
	 *     galley crew                      2
	 *     merchant crew                    4
	 * soldiers onboard:
      *     SAILOR/ARCHER                   3/4
      *     MARINE                          1/3
	 *     others                          4/3
	 */
	for(j=0;j<MGKNUM;j++) if(owner[j]!=(-1)){
		curntn= &ntn[owner[j]];
		country= owner[j];
		wnum[j]=SHIPS(ntn[country].nvy[unit[j]].warships,N_LIGHT)+
			SHIPS(ntn[country].nvy[unit[j]].warships,N_MEDIUM)+
			SHIPS(ntn[country].nvy[unit[j]].warships,N_HEAVY);
		mnum[j]=SHIPS(ntn[country].nvy[unit[j]].merchant,N_LIGHT)+
			SHIPS(ntn[country].nvy[unit[j]].merchant,N_MEDIUM)+
			SHIPS(ntn[country].nvy[unit[j]].merchant,N_HEAVY);
		gnum[j]=SHIPS(ntn[country].nvy[unit[j]].galleys,N_LIGHT)+
			SHIPS(ntn[country].nvy[unit[j]].galleys,N_MEDIUM)+
			SHIPS(ntn[country].nvy[unit[j]].galleys,N_HEAVY);
		if(side[j]==DFND) {
			if((k=fltwhold(unit[j]))>0) {
				dhold += k;
				if (magic(country,SAILOR)==TRUE) {
					dcrew += 5*k*curntn->nvy[unit[j]].crew/4;
				} else dcrew += k*curntn->nvy[unit[j]].crew;
			}
			if((k=fltmhold(unit[j]))>0) {
				if (magic(country,SAILOR)==TRUE) {
					dcrew += 5*k*curntn->nvy[unit[j]].crew/16;
				} else dcrew += k*curntn->nvy[unit[j]].crew/4;
			}
			if((k=fltghold(unit[j]))>0) {
				if (magic(country,SAILOR)==TRUE) {
					dcrew += 5*k*curntn->nvy[unit[j]].crew/8;
				} else dcrew += k*curntn->nvy[unit[j]].crew/2;
				if(curntn->nvy[unit[j]].armynum!=MAXARM) {
					k = curntn->nvy[unit[j]].armynum;
					switch (curntn->arm[k].unittyp) {
					case A_ARCHER:
					case A_SAILOR:
						dcrew += 3*curntn->arm[k].sold/2;
						break;
					case A_MARINES:
						dcrew += 3*curntn->arm[k].sold;
						break;
					default:
						dcrew += 3*curntn->arm[k].sold/4;
						break;
					}
				}
			}
		} else if(side[j]==ATKR) {
			if((k=fltwhold(unit[j]))>0) {
				ahold += k;
				if (magic(country,SAILOR)==TRUE) {
					acrew += 5*k*curntn->nvy[unit[j]].crew/4;
				} else acrew += k*curntn->nvy[unit[j]].crew;
			}
			if((k=fltmhold(unit[j]))>0) {
				if (magic(country,SAILOR)==TRUE) {
					acrew += 5*k*curntn->nvy[unit[j]].crew/16;
				} else acrew += k*curntn->nvy[unit[j]].crew/4;
			}
			if((k=fltghold(unit[j]))>0) {
				if (magic(country,SAILOR)==TRUE) {
					acrew += 5*k*curntn->nvy[unit[j]].crew/8;
				} else acrew += k*curntn->nvy[unit[j]].crew/2;
				if(curntn->nvy[unit[j]].armynum!=MAXARM) {
					k = curntn->nvy[unit[j]].armynum;
					switch (curntn->arm[k].unittyp) {
					case A_ARCHER:
					case A_SAILOR:
						acrew += 3*curntn->arm[k].sold/2;
						break;
					case A_MARINES:
						acrew += 3*curntn->arm[k].sold;
						break;
					default:
						acrew += 3*curntn->arm[k].sold/4;
						break;
					}
				}
			}
		}
	}

	/*find battle odds*/
	if( acrew > dcrew*100 ) odds=10000;
	else if ( dcrew > acrew*100 ) odds=1;
	else odds = (acrew*100)/dcrew;

	/* calculate capture percentages */
	/*
	 *  This formula produces:
      *        0% capture for   1:100  odds
	 *        2% capture for   1:10   odds
      *       15% capture for   1:1    odds
	 *       60% capture for  10:1    odds
	 *      100% capture for >60:1    odds
	 *      with linear progression between each.
	 */
	if (odds>6000) {
		dcptpct=0;
		acptpct=100;
	} else if (odds>1000) {
		dcptpct= (6000-odds)/2500;
		acptpct= (odds-1000)/125+60;
	} else if (odds>100) {
		dcptpct= (1000-odds)/69+2;
		acptpct= (odds-100)/20+15;
	} else if (odds>10) {
		dcptpct= (100-odds)/2+15;
		acptpct= (odds-10)/6.9+2;
	} else if (odds>6) {
		dcptpct= (10-odds)*14+60;
		acptpct= (odds-6)/2;
	} else {
		dcptpct= 100;
		acptpct= 0;
	}
#ifdef DEBUG
	printf("capture percentage: attack = %d  defend = %d\n",acptpct,dcptpct);
#endif DEBUG

	/*figure combat on a one-to-one basis */
	/* use a bell curve roll */
	roll = 0;
	for(i=0;i<5;i++) {
		roll += rand()%21+1;
	}
	roll -= 5;
	PDloss = MAXLOSS * roll / 100;
	PAloss = MAXLOSS * (100 - roll) / 100;
#ifdef DEBUG
	printf("Pdloss = %d  PAloss = %d\n",PDloss,PAloss);
#endif DEBUG

	/* adjust based on the odds */
	if( odds == 1 ) {
		PDloss = 0;
		PAloss = 100;
	} else if ( odds == 10000 ) {
		PAloss = 0;
		PDloss = 100;
	} else if ( odds > 100 ) {
		PDloss += (odds / 10 - 10);		/* 10% increase */
		PAloss -= (odds / 25 - 4);		/* 4% decrease */
		if(PAloss<(100-roll)/5)
			PAloss=(100-roll)/5;
	} else {
		PAloss += ( 1000 / odds - 10);	/* 10% increase */
		PDloss -= ( 400 / odds - 4);		/* 4% decrease  */
		if(PDloss<roll/5)
			PDloss = roll/5;
	}
	if (PAloss>100) PAloss=100;
	if (PDloss>100) PDloss=100;

	/* calculate actual losses */
	for(j=0;j<MGKNUM;j++) if(owner[j]!=(-1)){
		curntn= &ntn[owner[j]];
		country= owner[j];

		/* determine side */
		which=side[j];
		/* capturing is by foe so use other percent */
		if(which==ATKR) {
			cptpct=dcptpct;
			Ploss= PAloss;
		} else if(which==DFND) {
			cptpct=acptpct;
			Ploss= PDloss;
		} else continue;

		/* find all weighting info */
		nvynum = unit[j];
		thold = flthold(nvynum);
		ghold = fltghold(nvynum);

		/* go through all ships in the navy */
		for(shipsize=N_LIGHT;shipsize<=N_HEAVY;shipsize++) {
			/* check warships */
			for(i=0;i<P_NWAR(shipsize);i++)
			if (rand()%100<Ploss) {
				if(rand()%100<cptpct/2) {
					/* capture a ship */
					if(which==ATKR){
						if (dhold) {
							awcapt++;
							ahold-=(shipsize+1);
							capture(QWAR,DFND,shipsize,rand()%dhold+1);
							NSUB_WAR(1);
						}
					} else {
						if (ahold) {
							dwcapt++;
							dhold-=(shipsize+1);
							capture(QWAR,ATKR,shipsize,rand()%ahold+1);
							NSUB_WAR(1);
						}
					}
					if(which==ATKR) akcrew += P_NCREW;
					else dkcrew += P_NCREW;
				} else if (rand()%2==0 || Ploss>90) {
					/* destroy a ship */
					NSUB_WAR(1);
					k = P_NCREW*(shipsize+1);
					thold -= (shipsize+1);
					if(which==ATKR) {
						awsunk++;
						ahold-=(shipsize+1);
						akcrew+=k;
					} else {
						dwsunk++;
						dhold-=(shipsize+1);
						dkcrew+=k;
					}
				} else {
					/* damage a ship */
					k = (shipsize+1)*Ploss*P_NCREW/100;
					if(which==ATKR) akcrew += k;
					else dkcrew += k;
					P_NCREW -= k/thold;
				}
			}
			/* check galleys */
			for(i=0;i<P_NGAL(shipsize);i++)
			if (rand()%100<Ploss) {
				if(rand()%100<cptpct) {
					/* capture a ship */
					if(which==ATKR){
						if (dhold) {
							agcapt++;
							ghold-=(shipsize+1);
							thold-=(shipsize+1);
							capture(QGAL,DFND,shipsize,rand()%dhold+1);
							NSUB_GAL(1);
						}
					} else if(which==DFND) {
						if (ahold) {
							dgcapt++;
							ghold-=(shipsize+1);
							thold-=(shipsize+1);
							capture(QGAL,ATKR,shipsize,rand()%ahold+1);
							NSUB_GAL(1);
						}
					}
					if(which==ATKR) akcrew += P_NCREW;
					else dkcrew += P_NCREW;
					if (P_NARMY!=MAXARM) {
						armynum = P_NARMY;
						k = P_ASOLD*(shipsize+1)/(ghold+shipsize+1);
						if(P_ATYPE<MINLEADER) {
						if(which==ATKR) akcrew += k;
						else dkcrew += k;
						P_ASOLD -= k;
						} else if(rand()%100<k*100/P_ASOLD){
						if(which==ATKR) akcrew += P_ASOLD;
						else dkcrew += P_ASOLD;
						P_ASOLD = 0;
						P_NARMY = MAXARM;
						}
					}
				} else if (rand()%3==0||Ploss>90) {
					/* ship destroyed */
					k = (shipsize+1)*SHIPCREW;
					if(which==ATKR) akcrew += k;
					else dkcrew += k;
					NSUB_GAL(1);
					ghold-=(shipsize+1);
					thold-=(shipsize+1);
					/* kill all soldiers onboard */
					if (P_NARMY!=MAXARM) {
						armynum = P_NARMY;
						k = P_ASOLD*(shipsize+1)/(ghold+shipsize+1);
						if(P_ATYPE<MINLEADER) {
						if(which==ATKR) akcrew += k;
						else dkcrew += k;
						P_ASOLD -= k;
						} else if(rand()%100<k*100/P_ASOLD){
						if(which==ATKR) akcrew += P_ASOLD;
						else dkcrew += P_ASOLD;
						P_ASOLD = 0;
						P_NARMY = MAXARM;
						}
					}
					if(which==ATKR) agsunk++;
					else dgsunk++;
				} else {
					/* damage a ship */
					k = (shipsize+1)*Ploss*P_NCREW/100;
					if(which==ATKR) akcrew += k;
					else dkcrew += k;
					P_NCREW -= k/thold;
					/* damage any soldiers onboard */
					if (P_NARMY!=MAXARM) {
						armynum = P_NARMY;
						k = P_ASOLD*(shipsize+1)*Ploss/(ghold*100);
						if(P_ATYPE<MINLEADER) {
						P_ASOLD -= k;
						if(which==ATKR) akcrew += k;
						else dkcrew += k;
						} else if(rand()%100<k*100/P_ASOLD){
						if(which==ATKR) akcrew += P_ASOLD;
						else dkcrew += P_ASOLD;
						P_ASOLD = 0;
						P_NARMY = MAXARM;
						}
					}
				}
			}
			/* check merchants */
			for(i=0;i<P_NMER(shipsize);i++)
			if (rand()%100<Ploss) {
				if(rand()%100<cptpct) {
					/* capture a ship */
					if(which==ATKR){
						if (dhold) {
							amcapt++;
							capture(QMER,DFND,shipsize,rand()%dhold+1);
							NSUB_MER(1);
						}
					} else if(which==DFND) {
						if (ahold) {
							dmcapt++;
							capture(QMER,ATKR,shipsize,rand()%ahold+1);
							NSUB_MER(1);
						}
					}
					if(which==ATKR) akcrew += P_NCREW;
					else dkcrew += P_NCREW;
				} else if (rand()%3==0 || Ploss>90) {
					/* ship destroyed */
					k = (shipsize+1)*P_NCREW;
					if(which==ATKR) akcrew += k;
					else dkcrew += k;
					P_NCREW -= k/thold;
					k = P_NCREW*thold;
					NSUB_MER(1);
					if((thold-=(shipsize+1))!=0) P_NCREW = k / thold;
					else P_NCREW = 0;
					/* kill all people onboard */
					k = (shipsize+1)*P_NPEOP;
					if(which==ATKR) akcrew += k;
					else dkcrew += k;
					P_NPEOP -= k/(thold+shipsize+1);
					k = P_NPEOP*(thold+shipsize+1);
					if (thold>0) P_NPEOP = k / thold;
					else P_NPEOP=0;
					if(which==ATKR) amsunk++;
					else dmsunk++;
				} else {
					/* damage a ship */
					k = (shipsize+1)*Ploss*P_NCREW/100;
					if(which==ATKR) akcrew += k;
					else dkcrew += k;
					P_NCREW -= k/thold;
					/* damage any people onboard */
					k = (shipsize+1)*Ploss*P_NPEOP/100;
					if(which==ATKR) akcrew += k;
					else dkcrew += k;
					P_NPEOP -= k/thold;
				}
			}
		}
	}
#ifdef HIDELOC
	fprintf(fnews,"4.\tNaval Battle occurs");
#else
	fprintf(fnews,"4.\t%d,%d: Naval Battle",xspot,yspot);
#endif
	for(j=0;j<MGKNUM;j++) if(owner[j]!=(-1)){
		k=0;
		for(i=0;i<j;i++) if(owner[j]==owner[i]) k=1;
		if(k==0) {
		if(side[i]==DFND)
			fprintf(fnews,", attacker %s",ntn[owner[j]].name);
		else if(side[i]==ATKR)
			fprintf(fnews,", defender %s",ntn[owner[j]].name);
		}
	}
	fprintf(fnews,"\n");

	/*mail results; who is in the battle*/
	for(j=0;j<MGKNUM;j++) if(owner[j]!=(-1)){
		done=FALSE;

		/*first time your nation appears done=FALSE*/
		for(i=0;i<j;i++) if(owner[j]==owner[i]) done=TRUE;

		if((done==FALSE)&&(ispc(ntn[owner[j]].active))) {
			mailopen( owner[j] );

			fprintf(fm,"NAVAL BATTLE in sector %d %d\n",xspot,yspot);
			fprintf(fm,"Battle occured during %s of Year %d\n",
				PSEASON(TURN),YEAR(TURN));

			if(side[j]==ATKR)
				fprintf(fm,"You are on the Attacking Side\n");
			else	if(side[j]==DFND)
				fprintf(fm,"You are on the Defending Side\n");
			else	fprintf(fm,"You are on the Neutral Side\n");

			/*detail all participants in battle*/
			for(k=0;k<MGKNUM;k++) if(owner[k]!=(-1)){
				if(side[k]==DFND)
				fprintf(fm," %s is defender with navy ",ntn[owner[k]].name);
				else if(side[k]==ATKR)
				fprintf(fm," %s is attacker with navy ",ntn[owner[k]].name);
				else
				fprintf(fm," %s is neutral with navy ",ntn[owner[k]].name);
				fprintf(fm,"%d (%d warships %d galleys %d merchants)",
					unit[k],wnum[k],gnum[k],mnum[k]);
				putc('\n',fm);
 
			}

			fprintf(fm,"attacker strength (%d men) -> percent loss %d%%\n",acrew,PAloss);
			fprintf(fm,"defender strength (%d men) -> percent loss %d%%\n",dcrew,PDloss);
			fprintf(fm,"Odds are %d to 100; RANDOM ROLL is %d\n",odds,roll);
			fprintf(fm,"RESULT:  Attackers lose %d men  Defenders lose %d men\n",akcrew,dkcrew);
			/* display any other results */
			show_ships("Attacking","sunk",awsunk,agsunk,amsunk);
			show_ships("Defending","sunk",dwsunk,dgsunk,dmsunk);
			show_ships("Attacking","captured",awcapt,agcapt,amcapt);
			show_ships("Defending","captured",dwcapt,dgcapt,dmcapt);
			mailclose();
		}
	}
	curntn= saventn;
	country= savecntry;
	printf("Out Naval Combat....\n");
}

/* routine to distribute a captured ship */
void
capture(type,to,shipsize,holdcount)
	int type,to,shipsize,holdcount;
{
	int i,nvynum;
	struct s_nation *saventn=curntn;
#ifdef DEBUG
	printf("capture: hdcnt==%d typ==%d spsz==%d to==%d\n",holdcount,
		  type,shipsize,to);
#endif DEBUG
	for (i=0;holdcount && i<MGKNUM;i++) {
		if (owner[i]!=(-1) && side[i]==to) {
			curntn= &ntn[owner[i]];
			holdcount -= fltwhold(unit[i]);
		}
		if(holdcount<=0) {
			holdcount=0;
			i--;
		}
	}
#ifdef DEBUG
	printf("capture 2: holdcount==%d i==%d\n",holdcount,i);
#endif DEBUG
	if (i==MGKNUM) {
		curntn = saventn;
		return;
	}
	nvynum = unit[i];
#ifdef DEBUG
	printf("Should have succesful capture of %d\n",type);
#endif DEBUG
	switch(type) {
	case QWAR:
		(void) NADD_WAR(1);
		break;
	case QGAL:
		(void) NADD_GAL(1);
		break;
	case QMER:
		(void) NADD_MER(1);
		break;
	default:
		fprintf(stderr,"unknown type in function capture");
		break;
	}
	curntn = saventn;
}

/* routine to display combat results */
void
show_ships(who,what,war,gal,mer)
	char *who,*what;
	int war, gal, mer;
{
	if (war+gal+mer>0) {
		fprintf(fm,"%s ships %s: ",who,what);
		if (war) fprintf(fm,"%d Warships ",war);
		if (gal) fprintf(fm,"%d Galleys ",gal);
		if (mer) fprintf(fm,"%d Merchants",mer);
		putc('\n',fm);
	}
}