[comp.sources.games] v06i086: conquer4 - middle earth multi-player game

billr@saab.CNA.TEK.COM (Bill Randle) (06/24/89)

Submitted-by: adb@bu-it.bu.edu (Adam Bryant)
Posting-number: Volume 6, Issue 86
Archive-name: conquer4/Part04
Superseeds: conquer3; Volume 4, Issue 42-49



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 14)."
# Contents:  combat.c io.c run
# Wrapped by billr@saab on Thu Jun 15 15:20:12 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'combat.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'combat.c'\"
else
echo shar: Extracting \"'combat.c'\" \(39440 characters\)
sed "s/^X//" >'combat.c' <<'END_OF_FILE'
X/*conquer : Copyright (c) 1988 by Ed Barlow.
X *  I spent a long time writing this code & I hope that you respect this.
X *  I give permission to alter the code, but not to copy or redistribute
X *  it without my explicit permission.  If you alter the code,
X *  please document changes and send me a copy, so all can have it.
X *  This code, to the best of my knowledge works well,  but it is my first
X *  'C' program and should be treated as such.  I disclaim any
X *  responsibility for the codes actions (use at your own risk).  I guess
X *  I am saying "Happy gaming", and am trying not to get sued in the process.
X *                                                Ed
X */
X
X#include <math.h>
X#include "header.h"
X#include "data.h"
X
X#define	MGKNUM	32		/* number of units possible in battle */
X#define	ATKR	2
X#define	DFND	1
X#define	NTRL	0
X#define	WIMP	3
X
Xextern	FILE	*fpmsg;
Xextern	FILE	*fnews;
Xextern	short	country;
X
Xshort	retreatside;	/* ATKR, DFND, or none (0) */
Xshort	retreatx;	/* retreat x square */
Xshort	retreaty;	/* retreat y square */
X
Xint	unit[MGKNUM];		/*armynum*/
Xint	owner[MGKNUM];		/*owner*/
Xint	side[MGKNUM];		/*see definitions->1=units 2=unit*/
Xlong	troops[MGKNUM];		/*starting troops in army */
Xint	xspot,yspot;		/*location of battles*/
Xint	anation;		/*nation attacking in this fight*/
Xint	dnation;		/*one nation defending in this fight*/
X
X/************************************************************************/
X/*	COMBAT()	run all combat on the map			*/
X/*  	for each sector, determine if armies in with attack mode	*/
X/************************************************************************/
Xvoid
Xcombat()
X{
X	register int i,j;
X	char	**fought; 		/* TRUE if already fought in sctr */
X	int	temp,ctry;
X	short	armynum,nvynum;
X	int	valid;
X	int	count=0;
X
X	fought = (char **) m2alloc(MAPX,MAPY,sizeof(char));
X
X	printf("Run Combat Routines\n");
X	fprintf(fnews,"4\tBATTLE SUMMARY STATISTICS\n");
X	/*for each nation, if in attack mode run a check*/
X
X	/* no sectors have been fought in yet */
X	for(i=0;i<MAPX;i++) for(j=0;j<MAPY;j++) fought[i][j]=FALSE;
X
X	for(ctry=NTOTAL-1;ctry>0;ctry--) if(isactive(ntn[ctry].active)) {
X
X		/*army combat*/
X		for(j=0;j<MAXARM;j++)
X			if((ntn[ctry].arm[j].sold>0)
X			&&(ntn[ctry].arm[j].stat>=ATTACK)
X			&&(ntn[ctry].arm[j].stat<=SORTIE
X			  ||ntn[ctry].arm[j].stat>=NUMSTATUS)
X			&&(fought[ntn[ctry].arm[j].xloc][ntn[ctry].arm[j].yloc]==0)){
X
X			/* someone can initiate combat in xspot,yspot */
X			xspot=ntn[ctry].arm[j].xloc;
X			yspot=ntn[ctry].arm[j].yloc;
X			fought[xspot][yspot]=TRUE;
X
X			/*initialize matrix*/
X			for(temp=0;temp<MGKNUM;temp++){
X				unit[temp]=(-1);
X				owner[temp]=(-1);
X				side[temp]=NTRL;
X				troops[temp]=0;
X			}
X
X			/*check all armies in sector and add to matrix*/
X			count=0;
X			valid=FALSE;
X			/*is valid,set matrix*/
X			for(country=0;country<NTOTAL;country++)
X			if(isactive(ntn[country].active))
X			for(armynum=0;armynum<MAXARM;armynum++)
X			if((ASOLD>0)
X			&&(ASTAT!=SCOUT)
X			&&(AXLOC==xspot)
X			&&(AYLOC==yspot)
X			&&(count<MGKNUM)) {
X				if((country!=ctry)
X				&&(ntn[ctry].dstatus[country]>HOSTILE)) {
X					valid=TRUE;
X					if( sct[xspot][yspot].owner==ctry ) {
X						dnation=ctry;
X						anation=country;
X					} else if(( rand()%2==0 )
X					||( sct[xspot][yspot].owner==country )){
X						anation=ctry;
X						dnation=country;
X					} else {
X						dnation=ctry;
X						anation=country;
X					}
X				}
X				unit[count]=armynum;
X				owner[count]=country;
X				count++;
X			}
X
X			if(valid==TRUE) fight();
X		}
X
X		/*navy combat*/
X		for(j=0;j<MAXNAVY;j++)
X		if((ntn[ctry].nvy[j].warships!=0)
X&&(fought[ntn[ctry].nvy[j].xloc][ntn[ctry].nvy[j].yloc]==0)
X&&(sct[ntn[ctry].nvy[j].xloc][ntn[ctry].nvy[j].yloc].altitude==WATER)){
X
X			xspot=ntn[ctry].nvy[j].xloc;
X			yspot=ntn[ctry].nvy[j].yloc;
X			fought[xspot][yspot]=1;
X
X			/*initialize matrix*/
X			for(temp=0;temp<MGKNUM;temp++){
X				unit[temp]=(-1);
X				owner[temp]=(-1);
X				side[temp]=NTRL;
X				troops[temp]=0;
X			}
X
X			/*check all fleets in 2 sector range and add to matrix*/
X			count=0;
X			valid=FALSE;
X			/*is valid,set matrix*/
X			for(country=0;country<NTOTAL;country++)
X			if(isactive(ntn[country].active))
X			for(nvynum=0;nvynum<MAXNAVY;nvynum++)
X			if((NWSHP+NMSHP+NGSHP!=0)
X			&&(abs(NXLOC-xspot)<=2)
X			&&(abs(NYLOC-yspot)<=2)
X			&&(sct[NXLOC][NYLOC].altitude==WATER)
X			&&(count<MGKNUM)) {
X				fought[NXLOC][NYLOC]=1;
X				if((country!=ctry)
X				&&(ntn[ctry].dstatus[country]>HOSTILE)){
X					valid=TRUE;
X					anation=ctry;
X					dnation=country;
X				}
X				unit[count]=nvynum;
X				owner[count]=country;
X				count++;
X			}
X			if(valid==TRUE) navalcbt();
X		}
X	}
X	free(fought);
X	printf("\nall army and navy attacks completed\n");
X}
X
X/* macro for owner, accounts for runaway indicator */
X#define UOWNER(x) ((owner[(x)]<(-1))?(-owner[(x)]-1):(owner[(x)]))
X/************************************************************************/
X/*	FIGHT()	-	fight an individual battle given the three	*/
X/*	matricies global to this module					*/
X/************************************************************************/
Xvoid
Xfight()
X{
X	int	roll,strength,fortdam=FALSE;
X	int	odds;			/* odds (asold/dsold) times 100 */
X	int	done;
X	int	i,j,k;
X	long	asold=0,dsold=0;	/*a's and d's total soldiers*/
X	long	astr=0,dstr=0;		/*a's and d's relative strength*/
X	long	Aloss,Dloss;    	/*a's and d's total losses*/
X	int	PAloss,PDloss;		/*percent a and d loss*/
X	long	loss;
X	int	abonus=0,dbonus=0;	/* bonus aggregate */
X	long	vampire=0;		/* # non vamps deaded */
X	short	nvamps=0;		/* number of vampire armies */
X
X	/* determine who is attacker & who is on defenders side?*/
X	for(j=0;j<MGKNUM;j++) if(owner[j]!=(-1)){
X		if(owner[j]==anation) side[j]=ATKR;
X		else if(owner[j]==dnation) side[j]=DFND;
X		else if(ntn[anation].dstatus[owner[j]]==JIHAD) side[j]=DFND;
X		else if(ntn[owner[j]].dstatus[anation]==JIHAD) side[j]=DFND;
X		else if(ntn[anation].dstatus[owner[j]]==WAR)   side[j]=DFND;
X		else if(ntn[owner[j]].dstatus[anation]==WAR)   side[j]=DFND;
X		else if((ntn[owner[j]].dstatus[anation]==TREATY)&&(ntn[owner[j]].dstatus[dnation]>HOSTILE)) side[j]=ATKR;
X		else if((ntn[owner[j]].dstatus[anation]==ALLIED)&&(ntn[owner[j]].dstatus[dnation]>HOSTILE)) side[j]=ATKR;
X	}
X
X	/*calculate number of troops and assign statuses */
X	asold=0;
X	dsold=0;
X	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)) {
X		/* record troops for all units in sector */
X		troops[i]=ntn[owner[i]].arm[unit[i]].sold;
X
X		if(((ntn[owner[i]].arm[unit[i]].unittyp == A_MERCENARY)
X		||(ntn[owner[i]].arm[unit[i]].unittyp == A_ORC)
X		||(ntn[owner[i]].arm[unit[i]].unittyp == A_GOBLIN))
X		&&( ntn[owner[i]].arm[unit[i]].stat < NUMSTATUS )
X		&&( rand()%100<15 )) {
X			if( ispc(ntn[owner[i]].active)) {
X				mailopen( owner[i] );
X				fprintf(fm,"Message to %s from Conquer\n",ntn[owner[i]].name);
X				fprintf(fm,"\n  Your %s Army %d Refuses to Fight\n",
X				  unittype[ntn[owner[i]].arm[unit[i]].unittyp],
X				  unit[i]);
X				mailclose();
X			}
X			retreatside = side[i];
X			fdxyretreat();
X			if((retreatx==xspot)&&(retreaty==yspot)){
X				/* move to capitol & kill 30% */
X				ntn[owner[i]].arm[unit[i]].xloc=ntn[owner[i]].capx;
X				ntn[owner[i]].arm[unit[i]].yloc=ntn[owner[i]].capy;
X				ntn[owner[i]].arm[unit[i]].sold*=7;
X				ntn[owner[i]].arm[unit[i]].sold/=10;
X			} else {
X				/* retreat normally and kill 20% */
X				ntn[owner[i]].arm[unit[i]].sold*=8;
X				ntn[owner[i]].arm[unit[i]].sold/=10;
X				retreat( i );
X			}
X			owner[i]=(-1-owner[i]);
X			continue;
X		}
X		else if(side[i]==ATKR){
X			if((ntn[owner[i]].arm[unit[i]].stat!=RULE)
X			&&( ntn[owner[i]].arm[unit[i]].stat!=TRADED)
X			&&( ntn[owner[i]].arm[unit[i]].stat!=SCOUT)) {
X				asold += ntn[owner[i]].arm[unit[i]].sold;
X			} else {
X				side[i]=NTRL;
X			}
X			/* sortie 20% bonus in odds */
X			if(ntn[owner[i]].arm[unit[i]].stat==SORTIE)
X				asold += ntn[owner[i]].arm[unit[i]].sold/5;
X		} else if(side[i]==DFND){
X			if(ntn[owner[i]].arm[unit[i]].stat!=RULE) {
X				dsold += ntn[owner[i]].arm[unit[i]].sold;
X			}
X		}
X		if((magic(owner[i],VAMPIRE)==TRUE) &&
X		(ntn[owner[i]].arm[unit[i]].unittyp==A_ZOMBIE)) nvamps++;
X	}
X
X	if(asold<=0) {
X		printf("\nCombat aborted due to lack of attackers.\n");
X		return;
X	}
X	if( asold > dsold*100)		odds=10000;
X	else if( dsold > asold*100 )	odds=1;
X	else	odds = (asold*100)/dsold;
X
X	/* mercenaries/orcs/goblins might run away */
X	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)) {
X		if(((( odds > 200 )&&(side[i]==DFND))
X		||(( odds < 100 )&&(side[i]==ATKR)))
X		&&((ntn[owner[i]].arm[unit[i]].unittyp == A_MERCENARY)
X		  ||(ntn[owner[i]].arm[unit[i]].unittyp == A_ORC)
X		  ||(ntn[owner[i]].arm[unit[i]].unittyp == A_GOBLIN))
X		&&(ntn[owner[i]].arm[unit[i]].stat < NUMSTATUS)
X		&&( rand()%100<30 )) {
X			if( ispc(ntn[owner[i]].active)) {
X				mailopen( owner[i] );
X				fprintf(fm,"Message to %s from Conquer\n",ntn[owner[i]].name);
X				fprintf(fm,"  Your %s Army %d Runs Away\n",
X				  unittype[ntn[owner[i]].arm[unit[i]].unittyp],
X				  unit[i]);
X				mailclose();
X			}
X			retreatside = side[i];
X			if( side[i] == ATKR ) asold-= troops[i];
X			if( side[i] == DFND ) dsold-= troops[i];
X			fdxyretreat();
X			if((retreatx==xspot)&&(retreaty==yspot)){
X				/* move to capitol & kill 75% */
X				ntn[owner[i]].arm[unit[i]].xloc=ntn[owner[i]].capx;
X				ntn[owner[i]].arm[unit[i]].yloc=ntn[owner[i]].capy;
X				ntn[owner[i]].arm[unit[i]].sold/=4;
X			} else {
X				/* retreat normally and kill 50% */
X				ntn[owner[i]].arm[unit[i]].sold/=2;
X				retreat( i );
X			}
X			owner[i]=(-1-owner[i]);
X			continue;
X		}
X	}
X	retreatside=0;
X	if( asold<=0 ) {
X		printf("Exit from battle due to lack of attackers\n");
X		return;
X	}
X
X	/* CALCULATE AVERAGE COMBAT BONUS */
X	abonus=0;
X	dbonus=0;
X	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)) {
X		if(side[i]==ATKR)
X			abonus += cbonus(i)*troops[i];
X		else if(side[i]==DFND && ntn[owner[i]].arm[unit[i]].stat!=RULE)
X			dbonus += cbonus(i)*troops[i];
X	}
X
X	/*archer bonus if not in fort vs knights/cavalry*/
X	j=0;
X	k=0;
X	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1))
X	if(ISCITY(sct[xspot][yspot].designation)){
X		if((ntn[owner[i]].arm[unit[i]].unittyp == A_CAVALRY)
X		||(ntn[owner[i]].arm[unit[i]].unittyp == A_KNIGHT))
X		if(side[i]==ATKR) j+=troops[i];
X		else if(side[i]==DFND) k+=troops[i];
X	}
X
X	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)) {
X		if(j>0) abonus += (15 * j * troops[i]) / asold;
X		if(k>0 && dsold>0) dbonus += (15 * k * troops[i]) / dsold;
X	}
X
X	abonus/=asold;
X	if (dsold>0) dbonus/=dsold;
X
X	/*CALCULATED BONUSES TO WHOLE COMBAT*/
X	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)) {
X		if(fort_val(&sct[xspot][yspot]) != 0){
X			/*Catapults add +1%/20 men defending castle (max +10%)*/
X			if((ntn[owner[i]].arm[unit[i]].unittyp == A_CATAPULT)
X			&&(side[i]==DFND))
X				dbonus += max((troops[i]/20),10);
X			/*Catapults add +1%/40 men attacking castle (max +10%)*/
X			else if((ntn[owner[i]].arm[unit[i]].unittyp == A_CATAPULT)
X			&&(side[i]==ATKR)) {
X				strength = max((troops[i]/40),10);
X				abonus += strength;
X				/* possible damage 20% chance */
X				if(rand()%100<2*strength) {
X					fortdam=TRUE;
X					sct[xspot][yspot].fortress--;
X					if(sct[xspot][yspot].fortress == 0)
X					sct[xspot][yspot].designation = DRUIN;
X				}
X			}
X			/*Siege_engines add +1%/20 men when attacking fortress*/
X			else if((ntn[owner[i]].arm[unit[i]].unittyp == A_SIEGE)
X			&&(side[i]==ATKR)) {
X				strength = max((troops[i]/20),30);
X				abonus += strength;
X				/* possible damage 15% chance */
X				if(rand()%100<strength/2) {
X					fortdam=TRUE;
X					sct[xspot][yspot].fortress--;
X					if(sct[xspot][yspot].fortress == 0)
X						sct[xspot][yspot].designation = DRUIN;
X				}
X			}
X		} else {
X			/*Catapults add +1%/40 men normal combat (max +10%)*/
X			if(ntn[owner[i]].arm[unit[i]].unittyp == A_CATAPULT)
X				abonus+=max((troops[i]/40),10);
X		}
X	}
X
X	/*RUN COMBAT */
X	/*FIRST GIVE RANDOM ROLL FROM 0 to 100 */
X	/*WITH A PROBABILITY BELL CURVE */
X	/* high roll favors attacker [ 5 d21 - 5 ] */
X	roll = 0;
X	for(i=0;i<5;i++) {
X		roll += rand()%21+1;
X	}
X	roll -= 5;
X
X	/*find relative strength of troops*/
X	astr = asold * (100 + abonus);
X	dstr = dsold * (100 + dbonus);
X
X	/*Recalculate odds based on quality of troops*/
X	if( astr > dstr*100)		odds=10000;
X	else if( dstr > astr*100 )	odds=1;
X	else	odds = (astr*100)/dstr;
X
X	/* calculate loss for an even battle */
X	PDloss = MAXLOSS * roll / 100;
X	PAloss = MAXLOSS * (100 - roll) / 100;
X
X	/* adjust for odds */
X	if( odds == 1 ) {
X		PDloss=0;
X		PAloss=200;
X	} else if( odds == 10000 ) {
X		PAloss=0;
X		PDloss=200;
X	} else if(odds > 100) {
X		PDloss += (odds / 12 - 8);	/* 8.33% for higher odds */
X		PAloss -= (odds / 16 - 6);	/* 6.25% for lower odds */
X		if(PAloss<(100-roll)/20)
X			PAloss=(100-roll)/20;	/* can't get too small */
X	} else {
X		PAloss += ( 800 / odds - 8);	/* 8% for higher odds */
X		PDloss -= ( 600 / odds - 6);	/* 6% for lower odds */
X		if(PDloss<roll/20)
X			PDloss = roll/20;	/* can't get too small */
X	}
X
X	if( fort_val(&sct[xspot][yspot]) > 0 ){
X		PDloss *= 120;
X		PAloss *= 120;
X		PDloss /= 100;
X		PAloss /= 100;
X	}
X
X	retreatside = 0;
X
X	if((PDloss > 2* PAloss)
X	&&(odds>150)
X	&&(((PDloss>=50)&&(rand()%4==0))
X	  ||(rand()%8)))	retreatside=DFND;
X
X	if((PAloss > 2* PDloss)
X	&&(odds<150)
X	&&(((PAloss>=50)&&(rand()%2==0))
X	  ||(rand()%6)))	retreatside=ATKR;
X
X	if(retreatside!=0) {
X		fdxyretreat();
X		/* no legal retreat route */
X		if((retreatside!=0) && (retreatx== xspot)
X		&& (retreaty== yspot)){
X			if(retreatside==ATKR) PAloss+=15;
X			else if(retreatside==DFND) PDloss+=15;
X#ifdef DEBUG
X			printf("side %d (%d %d) can't retreat...+15%% loss\n",retreatside,retreatx,retreaty);
X#endif DEBUG
X			retreatside = 0;
X		}
X#ifdef DEBUG
X		else printf("retreat side %d to %d %d\n",retreatside,retreatx,retreaty);
X#endif DEBUG
X	}
X
X	if(PAloss>100) PAloss = 100;
X	if(PDloss>100) PDloss = 100;
X
X	Aloss = Dloss = 0;
X	for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)){
X		if(side[i]==ATKR){
X			if( ntn[owner[i]].arm[unit[i]].unittyp >= MINLEADER) {
X				if((rand()%100) < PAloss){ /* kill it */
X					for(j=0;j<MAXARM;j++)
X					if(ntn[owner[i]].arm[j].stat==unit[i]+NUMSTATUS)
X					ntn[owner[i]].arm[j].stat=ATTACK;
X					Aloss += troops[i];
X					ntn[owner[i]].arm[unit[i]].sold=0;
X				}
X			} else {
X				loss=(troops[i]*PAloss)/100;
X				/*archers/catapults on sortie take 1/4 damage*/
X				if((ntn[owner[i]].arm[unit[i]].stat==SORTIE)
X				&&(fort_val(&sct[xspot][yspot]) > 0)
X				&&(sct[xspot][yspot].owner==country)
X				&&((ntn[owner[i]].arm[unit[i]].unittyp==A_ARCHER)
X				||(ntn[owner[i]].arm[unit[i]].unittyp==A_CATAPULT)))
X					loss /= 4;
X				/*army can't have less than 25 men in it*/
X				if(troops[i]-loss<25)
X					loss=troops[i];
Xif( loss>troops[i] ) {
Xprintf("I AM VERY CONFUSED - PLEASE HELP... combat.c\n");
X}
X				Aloss+=loss;
X				ntn[owner[i]].arm[unit[i]].sold-=loss;
X				if((ntn[owner[i]].arm[unit[i]].unittyp==A_MILITIA)&&(retreatside==ATKR)) {
X				sct[ntn[owner[i]].arm[unit[i]].xloc][ntn[owner[i]].arm[unit[i]].yloc].people += ntn[owner[i]].arm[unit[i]].sold;
X				ntn[owner[i]].arm[unit[i]].sold-=0;
X				}
X			}
X		} else if(side[i]==DFND){
X			if( ntn[owner[i]].arm[unit[i]].unittyp >= MINLEADER) {
X				if((ntn[owner[i]].arm[unit[i]].stat!=RULE
X				||PDloss>=80)&&((rand()%100) < PDloss)){ /* kill it */
X					for(j=0;j<MAXARM;j++)
X					if(ntn[owner[i]].arm[j].stat==unit[i]+NUMSTATUS)
X					ntn[owner[i]].arm[j].stat=ATTACK;
X					Dloss +=troops[i];
X					ntn[owner[i]].arm[unit[i]].sold=0;
X				}
X			} else {
X				loss=(troops[i]*PDloss)/100;
X				/*destroy army if < 25 men*/
X				if(troops[i]-loss<25)
X					loss=troops[i];
X				Dloss+=loss;
X				ntn[owner[i]].arm[unit[i]].sold-=loss;
X				if((ntn[owner[i]].arm[unit[i]].unittyp==A_MILITIA)&&(retreatside==DFND)) {
X				sct[ntn[owner[i]].arm[unit[i]].xloc][ntn[owner[i]].arm[unit[i]].yloc].people += ntn[owner[i]].arm[unit[i]].sold;
X				ntn[owner[i]].arm[unit[i]].sold-=0;
X				}
X			}
X		}
X		/* non-vampire troops are sucked in by vampires */
X		if((nvamps>0)&&(magic(owner[i],VAMPIRE)==FALSE)
X		&&(ntn[owner[i]].arm[unit[i]].unittyp!=A_ZOMBIE)
X		&&(ntn[owner[i]].arm[unit[i]].unittyp<MINLEADER))
X			vampire+= loss / 3;
X	}
X	/* use k variable to hold length */
X#ifdef HIDELOC
X	if( isntn( ntn[sct[xspot][yspot].owner].active )) {
X	fprintf(fnews,"4.\tBattle occurs in %s", ntn[sct[xspot][yspot].owner].name);
X	k = 27+strlen(ntn[sct[xspot][yspot].owner].name);
X	} else {
X	fprintf(fnews,"4.\tBattle on unowned land");
X	k = 30;
X	}
X#else
X	fprintf(fnews,"4.\tBattle in %d,%d",xspot,yspot);
X	k = 25;
X#endif
X	for(j=0;j<MGKNUM;j++) if(UOWNER(j)>(-1)){
X		done=FALSE;
X		for(i=0;i<j;i++) if(UOWNER(j)==UOWNER(i)) done=TRUE;
X		if(done==FALSE) {
X			loss=NTRL;
X			for(i=j;(loss==NTRL||loss==WIMP) && i<MGKNUM;i++)
X				if(UOWNER(i)==UOWNER(j)) {
X					if(owner[i]<(-1)) loss=WIMP;
X					else loss=side[i];
X				}
X			if(loss!=NTRL) {
X				k += 11 + strlen(ntn[UOWNER(j)].name);
X				if(loss==WIMP) k++;
X				if(k>79) {
X					k = 30;
X					fprintf(fnews,",\n4.\t  ");
X				} else fprintf(fnews,", ");
X				if(loss==ATKR)
X					fprintf(fnews,"attacker %s",ntn[UOWNER(j)].name);
X				else if(loss==DFND)
X					fprintf(fnews,"defender %s",ntn[UOWNER(j)].name);
X				else if(loss==WIMP)
X					fprintf(fnews,"retreater %s",ntn[UOWNER(j)].name);
X			}
X		}
X	}
X	fprintf(fnews,"\n");
X	if(nvamps>0){
X		for(i=0;i<MGKNUM;i++) if(owner[i]>(-1)){
X			if((magic(owner[i],VAMPIRE)==TRUE)
X			&&(ntn[owner[i]].arm[unit[i]].unittyp==A_ZOMBIE)
X			&&(ntn[owner[i]].arm[unit[i]].sold > 0))
X				ntn[owner[i]].arm[unit[i]].sold+=vampire/nvamps;
X		}
X	}
X
X	/*who is in the battle; but don't send to scared armies */
X	for(j=0;j<MGKNUM;j++) if(owner[j]>(-1)){
X		done=FALSE;
X
X		/*first time your nation appears done=FALSE*/
X		for(i=0;i<j;i++) if(owner[j]==owner[i]) done=TRUE;
X
X		if((done==FALSE)&&(ispc(ntn[owner[j]].active))) {
X
X			loss=NTRL;
X			for(i=j;loss==NTRL && i<MGKNUM;i++)
X				loss=side[i];
X			mailopen( owner[j] );
X
X			fprintf(fm,"BATTLE SUMMARY for sector %d, %d\n",xspot,yspot);
X			fprintf(fm,"Battle occured during %s of Year %d\n",PSEASON(TURN),YEAR(TURN));
X
X			if(loss==ATKR)
X				fprintf(fm,"You are on the Attacking Side\n");
X			else if(loss==DFND)
X				fprintf(fm,"You are on the Defending Side\n");
X			else	fprintf(fm,"You are Neutral\n");
X
X			/*detail all participants in battle*/
X			for(k=0;k<MGKNUM;k++) if(owner[k]!=(-1)){
X				fprintf(fm," %s ",ntn[UOWNER(k)].name);
X				if(owner[k]<(-1))
X					fprintf(fm,"chickens out: ");
X				else if(side[k]==DFND
X				&& ntn[UOWNER(k)].arm[unit[k]].stat!=RULE)
X					fprintf(fm,"defending: ");
X				else if(side[k]==ATKR)
X					fprintf(fm,"attacking: ");
X				else fprintf(fm,"neutral: ");
X				fprintf(fm,"army %d (%s, men %d, bonus=%d, loss=%d)",
X					unit[k],
X					unittype[ntn[UOWNER(k)].arm[unit[k]].unittyp%UTYPE],
X					troops[k],
X					cbonus(k),
X					troops[k]-ntn[UOWNER(k)].arm[unit[k]].sold);
X				if((ntn[UOWNER(k)].arm[unit[k]].unittyp >= MINLEADER)
X				&&( ntn[UOWNER(k)].arm[unit[k]].sold == 0))
X					fprintf(fm," (killed)\n");
X				else if((ntn[owner[k]].arm[unit[k]].unittyp == A_MILITIA)
X				&&( ntn[owner[k]].arm[unit[k]].sold == 0))
X				fprintf(fm," (disbanded)\n");
X				else fputc('\n',fm);
X			}
X
X			fprintf(fm,"attacking soldiers=%ld -> percent loss %d%%\n",asold,PAloss);
X			fprintf(fm,"defending soldiers=%ld -> percent loss %d%%\n",dsold,PDloss);
X			fprintf(fm,"ODDS=%d => adjusted to %d to 100; Die Roll is %d\n",odds*(100+dbonus)/(100+abonus),odds,roll);
X			fprintf(fm,"RESULT: Attackers lose %ld men, Defenders lose %ld men\n",Aloss, Dloss);
X			if(fortdam==TRUE) fprintf(fm,"Fortifications damaged during the attack\n");
X			if(retreatside==ATKR){
X			if(Aloss<asold)
X			fprintf(fm,"Additionally, All attackers retreat to %d %d\n",retreatx,retreaty);
X			} else if(retreatside==DFND){
X			if(Dloss<dsold)
X			fprintf(fm,"Additionally, All defenders retreat to %d %d\n",retreatx,retreaty);
X			}
X			mailclose();
X		}
X	}
X	retreat( -1 );
X}
X
X/************************************************************************/
X/*	CBONUS() - return combat bonuses for unit i			*/
X/************************************************************************/
Xint
Xcbonus(num)
X{
X	short	armynum;
X	int	armbonus;
X
X	armbonus=0;
X	armynum=unit[num];
X	country=UOWNER(num);
X
X	/*Racial combat bonus due to terrain (the faster you move the better)*/
X	armbonus+=5*(9-movecost[xspot][yspot]);	/* this line always has */
X				/* the same result... must fix -- ADB */
X
X	if(((magic(country,DESTROYER)==1)
X	||(magic(country,DERVISH)==1))
X	&&((sct[xspot][yspot].vegetation==ICE)
X	||(sct[xspot][yspot].vegetation==DESERT)))
X		armbonus+=30;
X
X	if(ASTAT>=NUMSTATUS) armbonus+=20;	/* army group */
X	if(side[num]==DFND){
X
X		if(sct[xspot][yspot].altitude==MOUNTAIN) armbonus+=20;
X		else if(sct[xspot][yspot].altitude==HILL) armbonus+=10;
X
X		if(sct[xspot][yspot].vegetation==JUNGLE) armbonus+=20;
X		else if(sct[xspot][yspot].vegetation==FOREST) armbonus+=15;
X		else if(sct[xspot][yspot].vegetation==WOOD) armbonus+=10;
X
X		if(ATYPE==A_MERCENARY) armbonus += MERCDEF;
X		else armbonus += ntn[UOWNER(num)].dplus;
X
X		if(ASTAT==MAGDEF) armbonus+=30;
X		else if(ASTAT==SORTIE) armbonus-=30;
X		else if(ASTAT==SIEGED) armbonus-=20;
X
X		if((sct[xspot][yspot].owner==country)
X		&&(ASTAT==GARRISON||ASTAT==MILITIA||ASTAT==SIEGED)){
X			if(ATYPE == A_ZOMBIE) /* don't utilize walls well */
X				armbonus += fort_val(&sct[xspot][yspot])/2;
X			else armbonus += fort_val(&sct[xspot][yspot]);
X		}
X	}
X	else if(side[num]==ATKR) {
X		if( (fort_val(&sct[xspot][yspot]) > 0)
X		&&( magic(country,SAPPER)==TRUE)) armbonus += 10;
X
X		if(ATYPE == A_MERCENARY) armbonus += MERCATT;
X		else armbonus += ntn[UOWNER(num)].aplus;
X		if(ASTAT==MAGATT) armbonus += 30;
X		if(ASTAT==SORTIE && (fort_val(&sct[xspot][yspot]) > 0)
X		&& sct[xspot][yspot].owner==country) {
X			armbonus += 10;
X			if((ATYPE==A_DRAGOON)||(ATYPE==A_LEGION)
X			||(ATYPE==A_PHALANX)) {
X				/* bonus for organization or riding cavalry */
X				armbonus += 5;
X			} else if ((ATYPE==A_LT_CAV)||(ATYPE==A_CAVALRY)) {
X				/* bonus for mounted sortie */
X				armbonus += 10;
X			} else if (avian(ATYPE)||ATYPE==A_ELEPHANT||ATYPE==A_KNIGHT) {
X				/* bonus for mounted or flying sortie */
X				armbonus += 15;
X			}
X			if ((ATYPE>=MINMONSTER)||(ATYPE<=MAXMONSTER)) {
X				/* bonus for monsters (scare factor) */
X				armbonus += 5;
X			}
X		}
X	}
X
X	/*army status is important*/
X	if(ASTAT==MARCH) armbonus-=40;
X
X	/*if a fortress*/
X	if(fort_val(&sct[xspot][yspot]) > 0){
X		/*Cavalry and Knights get -20%*/
X		if((ATYPE == A_CAVALRY) ||(ATYPE == A_KNIGHT)) armbonus -= 20;
X		/*Archers gain pluses*/
X		else if((ATYPE == A_ARCHER)&&(sct[xspot][yspot].owner==country))
X			armbonus += 15;
X		else if(ATYPE == A_ARCHER) armbonus += 5;
X	}
X
X	if(side[num]==ATKR) armbonus+= *(unitattack+(ATYPE%UTYPE));
X	else armbonus+= *(unitdefend+(ATYPE%UTYPE));
X
X	/*Phalanx and Legionaires need certain numbers of troops*/
X	if((ATYPE==A_PHALANX)||(ATYPE==A_LEGION)) {
X 		if(ASOLD>1000){	armbonus+=20;
X 		} else if(ASOLD>500) armbonus+=10;
X	}
X
X	return(armbonus);
X}
X
Xvoid
Xfdxyretreat()	/* finds retreat location */
X{
X	int	x,y,nation=(-1);
X	int	xsctr= xspot;
X	int	ysctr= yspot;
X
X	retreatx=xsctr;
X	retreaty=ysctr;
X
X	if((sct[xsctr][ysctr].designation==DTOWN)
X	||(sct[xsctr][ysctr].designation==DCAPITOL)
X	||(sct[xsctr][ysctr].designation==DCITY)){
X		retreatside=0;
X		return;
X	}
X
X	if(retreatside == ATKR) nation=anation;
X	else nation=dnation;
X
X	for(x= xsctr-1; x<=xsctr+1; x++)
X	for(y= ysctr-1; y<=ysctr+1; y++) if(ONMAP(x,y)){
X		if(tofood( &sct[x][y],
X			sct[x][y].owner == country ? country : 0)==0) continue;
X		if(((sct[x][y].owner == nation)
X		   ||(ntn[sct[x][y].owner].dstatus[nation] < NEUTRAL))
X		||(solds_in_sector( x, y, sct[x][y].owner) == 0)){
X			retreatx=x;
X			retreaty=y;
X#ifdef DEBUG
X			printf("armies in %d %d retreat to %d %d\n",xsctr,ysctr,x,y);
X#endif DEBUG
X			return;
X		}
X	}
X}
X
Xvoid
Xretreat(unitnum)
Xint	unitnum;	/* if -1 then normal, else retreat only unit ismerc */
X{
X	int cnum;
X
X	if(retreatside == 0) return;
X
X	for(cnum=0;cnum<MGKNUM;cnum++) if(owner[cnum]>(-1)){
X		if( unitnum != (-1) ) cnum=unitnum;
X		if((side[cnum]==ATKR)&&(retreatside==ATKR)){
X			ntn[owner[cnum]].arm[unit[cnum]].xloc = retreatx;
X			ntn[owner[cnum]].arm[unit[cnum]].yloc = retreaty;
X		}
X		else if((side[cnum]==DFND)&&(retreatside==DFND)){
X			ntn[owner[cnum]].arm[unit[cnum]].xloc = retreatx;
X			ntn[owner[cnum]].arm[unit[cnum]].yloc = retreaty;
X		}
X		if( unitnum != (-1) ) return;
X	}
X}
X
X
X/*SUBROUTINE TO RUN NAVAL COMBAT ON ALL SHIPS */
X/* quick define for easier reading */
X#define QWAR 1
X#define QGAL 2
X#define QMER 3
X/* just like fight, this takes array of owner,side,unit and calculates */
X/* a random battle based on the strengths of the combatants.           */
Xvoid
Xnavalcbt()
X{
X	int acrew=0,dcrew=0;	/*a's and d's crew and soldier strength*/
X	int ahold=0,dhold=0;	/*a's and d's warship strength*/
X	int awsunk=0,dwsunk=0;	/*a's and d's warship losses for the round*/
X	int agsunk=0,dgsunk=0;	/*a's and d's galley losses for the round*/
X	int amsunk=0,dmsunk=0;	/*a's and d's merchent losses for the round*/
X	int awcapt=0,dwcapt=0;	/*a's and d's warship captures for the round*/
X	int agcapt=0,dgcapt=0;	/*a's and d's galley captures for the round*/
X	int amcapt=0,dmcapt=0;	/*a's and d's merchant captures for the round*/
X	int akcrew=0,dkcrew=0;	/*a's and d's crew losses for the round*/
X	char wnum[MGKNUM],gnum[MGKNUM],mnum[MGKNUM];
X	register int done,i,j,k;
X	int roll,odds,savecntry=country;
X	int PAloss, PDloss, Ploss, which, shipsize;
X	int thold, ghold, nvynum, armynum;
X	int dcptpct, acptpct, cptpct;
X	struct s_nation *saventn=curntn;
X	void show_ships(),capture();
X
X	printf("In Naval Combat....\n");
X
X	/* determine who is attacker & who is on defenders side?*/
X	for(j=0;j<MGKNUM;j++) if(owner[j]!=(-1)){
X		if(owner[j]==anation) side[j]=ATKR;
X		else if(ntn[anation].dstatus[owner[j]]==JIHAD) side[j]=DFND;
X		else if(ntn[owner[j]].dstatus[anation]==JIHAD) side[j]=DFND;
X		else if(ntn[anation].dstatus[owner[j]]==WAR)   side[j]=DFND;
X		else if(ntn[owner[j]].dstatus[anation]==WAR)   side[j]=DFND;
X		else if((ntn[owner[j]].dstatus[anation]==TREATY)
X		&&(ntn[owner[j]].dstatus[dnation]>HOSTILE)) side[j]=ATKR;
X		else if((ntn[owner[j]].dstatus[anation]==ALLIED)
X		&&(ntn[owner[j]].dstatus[dnation]>HOSTILE)) side[j]=ATKR;
X	}
X
X	/* Loop through all competitors to determine
X	 *  relative combat strengths:
X	 *                              men/unit strength
X	 * crew on ship:
X	 *     warship crew                     1
X	 *     galley crew                      2
X	 *     merchant crew                    4
X	 * soldiers onboard:
X      *     SAILOR/ARCHER                   3/4
X      *     MARINE                          1/3
X	 *     others                          4/3
X	 */
X	for(j=0;j<MGKNUM;j++) if(owner[j]!=(-1)){
X		curntn= &ntn[owner[j]];
X		country= owner[j];
X		wnum[j]=SHIPS(ntn[country].nvy[unit[j]].warships,N_LIGHT)+
X			SHIPS(ntn[country].nvy[unit[j]].warships,N_MEDIUM)+
X			SHIPS(ntn[country].nvy[unit[j]].warships,N_HEAVY);
X		mnum[j]=SHIPS(ntn[country].nvy[unit[j]].merchant,N_LIGHT)+
X			SHIPS(ntn[country].nvy[unit[j]].merchant,N_MEDIUM)+
X			SHIPS(ntn[country].nvy[unit[j]].merchant,N_HEAVY);
X		gnum[j]=SHIPS(ntn[country].nvy[unit[j]].galleys,N_LIGHT)+
X			SHIPS(ntn[country].nvy[unit[j]].galleys,N_MEDIUM)+
X			SHIPS(ntn[country].nvy[unit[j]].galleys,N_HEAVY);
X		if(side[j]==DFND) {
X			if((k=fltwhold(unit[j]))>0) {
X				dhold += k;
X				if (magic(country,SAILOR)==TRUE) {
X					dcrew += 5*k*curntn->nvy[unit[j]].crew/4;
X				} else dcrew += k*curntn->nvy[unit[j]].crew;
X			}
X			if((k=fltmhold(unit[j]))>0) {
X				if (magic(country,SAILOR)==TRUE) {
X					dcrew += 5*k*curntn->nvy[unit[j]].crew/16;
X				} else dcrew += k*curntn->nvy[unit[j]].crew/4;
X			}
X			if((k=fltghold(unit[j]))>0) {
X				if (magic(country,SAILOR)==TRUE) {
X					dcrew += 5*k*curntn->nvy[unit[j]].crew/8;
X				} else dcrew += k*curntn->nvy[unit[j]].crew/2;
X				if(curntn->nvy[unit[j]].armynum!=MAXARM) {
X					k = curntn->nvy[unit[j]].armynum;
X					switch (curntn->arm[k].unittyp) {
X					case A_ARCHER:
X					case A_SAILOR:
X						dcrew += 3*curntn->arm[k].sold/2;
X						break;
X					case A_MARINES:
X						dcrew += 3*curntn->arm[k].sold;
X						break;
X					default:
X						dcrew += 3*curntn->arm[k].sold/4;
X						break;
X					}
X				}
X			}
X		} else if(side[j]==ATKR) {
X			if((k=fltwhold(unit[j]))>0) {
X				ahold += k;
X				if (magic(country,SAILOR)==TRUE) {
X					acrew += 5*k*curntn->nvy[unit[j]].crew/4;
X				} else acrew += k*curntn->nvy[unit[j]].crew;
X			}
X			if((k=fltmhold(unit[j]))>0) {
X				if (magic(country,SAILOR)==TRUE) {
X					acrew += 5*k*curntn->nvy[unit[j]].crew/16;
X				} else acrew += k*curntn->nvy[unit[j]].crew/4;
X			}
X			if((k=fltghold(unit[j]))>0) {
X				if (magic(country,SAILOR)==TRUE) {
X					acrew += 5*k*curntn->nvy[unit[j]].crew/8;
X				} else acrew += k*curntn->nvy[unit[j]].crew/2;
X				if(curntn->nvy[unit[j]].armynum!=MAXARM) {
X					k = curntn->nvy[unit[j]].armynum;
X					switch (curntn->arm[k].unittyp) {
X					case A_ARCHER:
X					case A_SAILOR:
X						acrew += 3*curntn->arm[k].sold/2;
X						break;
X					case A_MARINES:
X						acrew += 3*curntn->arm[k].sold;
X						break;
X					default:
X						acrew += 3*curntn->arm[k].sold/4;
X						break;
X					}
X				}
X			}
X		}
X	}
X
X	/*find battle odds*/
X	if( acrew > dcrew*100 ) odds=10000;
X	else if ( dcrew > acrew*100 ) odds=1;
X	else odds = (acrew*100)/dcrew;
X
X	/* calculate capture percentages */
X	/*
X	 *  This formula produces:
X      *        0% capture for   1:100  odds
X	 *        2% capture for   1:10   odds
X      *       15% capture for   1:1    odds
X	 *       60% capture for  10:1    odds
X	 *      100% capture for >60:1    odds
X	 *      with linear progression between each.
X	 */
X	if (odds>6000) {
X		dcptpct=0;
X		acptpct=100;
X	} else if (odds>1000) {
X		dcptpct= (6000-odds)/2500;
X		acptpct= (odds-1000)/125+60;
X	} else if (odds>100) {
X		dcptpct= (1000-odds)/69+2;
X		acptpct= (odds-100)/20+15;
X	} else if (odds>10) {
X		dcptpct= (100-odds)/2+15;
X		acptpct= (odds-10)/6.9+2;
X	} else if (odds>6) {
X		dcptpct= (10-odds)*14+60;
X		acptpct= (odds-6)/2;
X	} else {
X		dcptpct= 100;
X		acptpct= 0;
X	}
X#ifdef DEBUG
X	printf("capture percentage: attack = %d  defend = %d\n",acptpct,dcptpct);
X#endif DEBUG
X
X	/*figure combat on a one-to-one basis */
X	/* use a bell curve roll */
X	roll = 0;
X	for(i=0;i<5;i++) {
X		roll += rand()%21+1;
X	}
X	roll -= 5;
X	PDloss = MAXLOSS * roll / 100;
X	PAloss = MAXLOSS * (100 - roll) / 100;
X#ifdef DEBUG
X	printf("Pdloss = %d  PAloss = %d\n",PDloss,PAloss);
X#endif DEBUG
X
X	/* adjust based on the odds */
X	if( odds == 1 ) {
X		PDloss = 0;
X		PAloss = 100;
X	} else if ( odds == 10000 ) {
X		PAloss = 0;
X		PDloss = 100;
X	} else if ( odds > 100 ) {
X		PDloss += (odds / 10 - 10);		/* 10% increase */
X		PAloss -= (odds / 25 - 4);		/* 4% decrease */
X		if(PAloss<(100-roll)/5)
X			PAloss=(100-roll)/5;
X	} else {
X		PAloss += ( 1000 / odds - 10);	/* 10% increase */
X		PDloss -= ( 400 / odds - 4);		/* 4% decrease  */
X		if(PDloss<roll/5)
X			PDloss = roll/5;
X	}
X	if (PAloss>100) PAloss=100;
X	if (PDloss>100) PDloss=100;
X
X	/* calculate actual losses */
X	for(j=0;j<MGKNUM;j++) if(owner[j]!=(-1)){
X		curntn= &ntn[owner[j]];
X		country= owner[j];
X
X		/* determine side */
X		which=side[j];
X		/* capturing is by foe so use other percent */
X		if(which==ATKR) {
X			cptpct=dcptpct;
X			Ploss= PAloss;
X		} else if(which==DFND) {
X			cptpct=acptpct;
X			Ploss= PDloss;
X		} else continue;
X
X		/* find all weighting info */
X		nvynum = unit[j];
X		thold = flthold(nvynum);
X		ghold = fltghold(nvynum);
X
X		/* go through all ships in the navy */
X		for(shipsize=N_LIGHT;shipsize<=N_HEAVY;shipsize++) {
X			/* check warships */
X			for(i=0;i<P_NWAR(shipsize);i++)
X			if (rand()%100<Ploss) {
X				if(rand()%100<cptpct/2) {
X					/* capture a ship */
X					if(which==ATKR){
X						if (dhold) {
X							awcapt++;
X							ahold-=(shipsize+1);
X							capture(QWAR,DFND,shipsize,rand()%dhold+1);
X							NSUB_WAR(1);
X						}
X					} else {
X						if (ahold) {
X							dwcapt++;
X							dhold-=(shipsize+1);
X							capture(QWAR,ATKR,shipsize,rand()%ahold+1);
X							NSUB_WAR(1);
X						}
X					}
X					if(which==ATKR) akcrew += P_NCREW;
X					else dkcrew += P_NCREW;
X				} else if (rand()%2==0 || Ploss>90) {
X					/* destroy a ship */
X					NSUB_WAR(1);
X					k = P_NCREW*(shipsize+1);
X					thold -= (shipsize+1);
X					if(which==ATKR) {
X						awsunk++;
X						ahold-=(shipsize+1);
X						akcrew+=k;
X					} else {
X						dwsunk++;
X						dhold-=(shipsize+1);
X						dkcrew+=k;
X					}
X				} else {
X					/* damage a ship */
X					k = (shipsize+1)*Ploss*P_NCREW/100;
X					if(which==ATKR) akcrew += k;
X					else dkcrew += k;
X					P_NCREW -= k/thold;
X				}
X			}
X			/* check galleys */
X			for(i=0;i<P_NGAL(shipsize);i++)
X			if (rand()%100<Ploss) {
X				if(rand()%100<cptpct) {
X					/* capture a ship */
X					if(which==ATKR){
X						if (dhold) {
X							agcapt++;
X							ghold-=(shipsize+1);
X							thold-=(shipsize+1);
X							capture(QGAL,DFND,shipsize,rand()%dhold+1);
X							NSUB_GAL(1);
X						}
X					} else if(which==DFND) {
X						if (ahold) {
X							dgcapt++;
X							ghold-=(shipsize+1);
X							thold-=(shipsize+1);
X							capture(QGAL,ATKR,shipsize,rand()%ahold+1);
X							NSUB_GAL(1);
X						}
X					}
X					if(which==ATKR) akcrew += P_NCREW;
X					else dkcrew += P_NCREW;
X					if (P_NARMY!=MAXARM) {
X						armynum = P_NARMY;
X						k = P_ASOLD*(shipsize+1)/(ghold+shipsize+1);
X						if(P_ATYPE<MINLEADER) {
X						if(which==ATKR) akcrew += k;
X						else dkcrew += k;
X						P_ASOLD -= k;
X						} else if(rand()%100<k*100/P_ASOLD){
X						if(which==ATKR) akcrew += P_ASOLD;
X						else dkcrew += P_ASOLD;
X						P_ASOLD = 0;
X						P_NARMY = MAXARM;
X						}
X					}
X				} else if (rand()%3==0||Ploss>90) {
X					/* ship destroyed */
X					k = (shipsize+1)*SHIPCREW;
X					if(which==ATKR) akcrew += k;
X					else dkcrew += k;
X					NSUB_GAL(1);
X					ghold-=(shipsize+1);
X					thold-=(shipsize+1);
X					/* kill all soldiers onboard */
X					if (P_NARMY!=MAXARM) {
X						armynum = P_NARMY;
X						k = P_ASOLD*(shipsize+1)/(ghold+shipsize+1);
X						if(P_ATYPE<MINLEADER) {
X						if(which==ATKR) akcrew += k;
X						else dkcrew += k;
X						P_ASOLD -= k;
X						} else if(rand()%100<k*100/P_ASOLD){
X						if(which==ATKR) akcrew += P_ASOLD;
X						else dkcrew += P_ASOLD;
X						P_ASOLD = 0;
X						P_NARMY = MAXARM;
X						}
X					}
X					if(which==ATKR) agsunk++;
X					else dgsunk++;
X				} else {
X					/* damage a ship */
X					k = (shipsize+1)*Ploss*P_NCREW/100;
X					if(which==ATKR) akcrew += k;
X					else dkcrew += k;
X					P_NCREW -= k/thold;
X					/* damage any soldiers onboard */
X					if (P_NARMY!=MAXARM) {
X						armynum = P_NARMY;
X						k = P_ASOLD*(shipsize+1)*Ploss/(ghold*100);
X						if(P_ATYPE<MINLEADER) {
X						P_ASOLD -= k;
X						if(which==ATKR) akcrew += k;
X						else dkcrew += k;
X						} else if(rand()%100<k*100/P_ASOLD){
X						if(which==ATKR) akcrew += P_ASOLD;
X						else dkcrew += P_ASOLD;
X						P_ASOLD = 0;
X						P_NARMY = MAXARM;
X						}
X					}
X				}
X			}
X			/* check merchants */
X			for(i=0;i<P_NMER(shipsize);i++)
X			if (rand()%100<Ploss) {
X				if(rand()%100<cptpct) {
X					/* capture a ship */
X					if(which==ATKR){
X						if (dhold) {
X							amcapt++;
X							capture(QMER,DFND,shipsize,rand()%dhold+1);
X							NSUB_MER(1);
X						}
X					} else if(which==DFND) {
X						if (ahold) {
X							dmcapt++;
X							capture(QMER,ATKR,shipsize,rand()%ahold+1);
X							NSUB_MER(1);
X						}
X					}
X					if(which==ATKR) akcrew += P_NCREW;
X					else dkcrew += P_NCREW;
X				} else if (rand()%3==0 || Ploss>90) {
X					/* ship destroyed */
X					k = (shipsize+1)*P_NCREW;
X					if(which==ATKR) akcrew += k;
X					else dkcrew += k;
X					P_NCREW -= k/thold;
X					k = P_NCREW*thold;
X					NSUB_MER(1);
X					if((thold-=(shipsize+1))!=0) P_NCREW = k / thold;
X					else P_NCREW = 0;
X					/* kill all people onboard */
X					k = (shipsize+1)*P_NPEOP;
X					if(which==ATKR) akcrew += k;
X					else dkcrew += k;
X					P_NPEOP -= k/(thold+shipsize+1);
X					k = P_NPEOP*(thold+shipsize+1);
X					if (thold>0) P_NPEOP = k / thold;
X					else P_NPEOP=0;
X					if(which==ATKR) amsunk++;
X					else dmsunk++;
X				} else {
X					/* damage a ship */
X					k = (shipsize+1)*Ploss*P_NCREW/100;
X					if(which==ATKR) akcrew += k;
X					else dkcrew += k;
X					P_NCREW -= k/thold;
X					/* damage any people onboard */
X					k = (shipsize+1)*Ploss*P_NPEOP/100;
X					if(which==ATKR) akcrew += k;
X					else dkcrew += k;
X					P_NPEOP -= k/thold;
X				}
X			}
X		}
X	}
X#ifdef HIDELOC
X	fprintf(fnews,"4.\tNaval Battle occurs");
X#else
X	fprintf(fnews,"4.\t%d,%d: Naval Battle",xspot,yspot);
X#endif
X	for(j=0;j<MGKNUM;j++) if(owner[j]!=(-1)){
X		k=0;
X		for(i=0;i<j;i++) if(owner[j]==owner[i]) k=1;
X		if(k==0) {
X		if(side[i]==DFND)
X			fprintf(fnews,", attacker %s",ntn[owner[j]].name);
X		else if(side[i]==ATKR)
X			fprintf(fnews,", defender %s",ntn[owner[j]].name);
X		}
X	}
X	fprintf(fnews,"\n");
X
X	/*mail results; who is in the battle*/
X	for(j=0;j<MGKNUM;j++) if(owner[j]!=(-1)){
X		done=FALSE;
X
X		/*first time your nation appears done=FALSE*/
X		for(i=0;i<j;i++) if(owner[j]==owner[i]) done=TRUE;
X
X		if((done==FALSE)&&(ispc(ntn[owner[j]].active))) {
X			mailopen( owner[j] );
X
X			fprintf(fm,"NAVAL BATTLE in sector %d %d\n",xspot,yspot);
X			fprintf(fm,"Battle occured during %s of Year %d\n",
X				PSEASON(TURN),YEAR(TURN));
X
X			if(side[j]==ATKR)
X				fprintf(fm,"You are on the Attacking Side\n");
X			else	if(side[j]==DFND)
X				fprintf(fm,"You are on the Defending Side\n");
X			else	fprintf(fm,"You are on the Neutral Side\n");
X
X			/*detail all participants in battle*/
X			for(k=0;k<MGKNUM;k++) if(owner[k]!=(-1)){
X				if(side[k]==DFND)
X				fprintf(fm," %s is defender with navy ",ntn[owner[k]].name);
X				else if(side[k]==ATKR)
X				fprintf(fm," %s is attacker with navy ",ntn[owner[k]].name);
X				else
X				fprintf(fm," %s is neutral with navy ",ntn[owner[k]].name);
X				fprintf(fm,"%d (%d warships %d galleys %d merchants)",
X					unit[k],wnum[k],gnum[k],mnum[k]);
X				putc('\n',fm);
X 
X			}
X
X			fprintf(fm,"attacker strength (%d men) -> percent loss %d%%\n",acrew,PAloss);
X			fprintf(fm,"defender strength (%d men) -> percent loss %d%%\n",dcrew,PDloss);
X			fprintf(fm,"Odds are %d to 100; RANDOM ROLL is %d\n",odds,roll);
X			fprintf(fm,"RESULT:  Attackers lose %d men  Defenders lose %d men\n",akcrew,dkcrew);
X			/* display any other results */
X			show_ships("Attacking","sunk",awsunk,agsunk,amsunk);
X			show_ships("Defending","sunk",dwsunk,dgsunk,dmsunk);
X			show_ships("Attacking","captured",awcapt,agcapt,amcapt);
X			show_ships("Defending","captured",dwcapt,dgcapt,dmcapt);
X			mailclose();
X		}
X	}
X	curntn= saventn;
X	country= savecntry;
X	printf("Out Naval Combat....\n");
X}
X
X/* routine to distribute a captured ship */
Xvoid
Xcapture(type,to,shipsize,holdcount)
X	int type,to,shipsize,holdcount;
X{
X	int i,nvynum;
X	struct s_nation *saventn=curntn;
X#ifdef DEBUG
X	printf("capture: hdcnt==%d typ==%d spsz==%d to==%d\n",holdcount,
X		  type,shipsize,to);
X#endif DEBUG
X	for (i=0;holdcount && i<MGKNUM;i++) {
X		if (owner[i]!=(-1) && side[i]==to) {
X			curntn= &ntn[owner[i]];
X			holdcount -= fltwhold(unit[i]);
X		}
X		if(holdcount<=0) {
X			holdcount=0;
X			i--;
X		}
X	}
X#ifdef DEBUG
X	printf("capture 2: holdcount==%d i==%d\n",holdcount,i);
X#endif DEBUG
X	if (i==MGKNUM) {
X		curntn = saventn;
X		return;
X	}
X	nvynum = unit[i];
X#ifdef DEBUG
X	printf("Should have succesful capture of %d\n",type);
X#endif DEBUG
X	switch(type) {
X	case QWAR:
X		(void) NADD_WAR(1);
X		break;
X	case QGAL:
X		(void) NADD_GAL(1);
X		break;
X	case QMER:
X		(void) NADD_MER(1);
X		break;
X	default:
X		fprintf(stderr,"unknown type in function capture");
X		break;
X	}
X	curntn = saventn;
X}
X
X/* routine to display combat results */
Xvoid
Xshow_ships(who,what,war,gal,mer)
X	char *who,*what;
X	int war, gal, mer;
X{
X	if (war+gal+mer>0) {
X		fprintf(fm,"%s ships %s: ",who,what);
X		if (war) fprintf(fm,"%d Warships ",war);
X		if (gal) fprintf(fm,"%d Galleys ",gal);
X		if (mer) fprintf(fm,"%d Merchants",mer);
X		putc('\n',fm);
X	}
X}
END_OF_FILE
if test 39440 -ne `wc -c <'combat.c'`; then
    echo shar: \"'combat.c'\" unpacked with wrong size!
fi
# end of 'combat.c'
fi
if test -f 'io.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'io.c'\"
else
echo shar: Extracting \"'io.c'\" \(12125 characters\)
sed "s/^X//" >'io.c' <<'END_OF_FILE'
X/*io.c*/
X/*Print and io subroutines for game*/
X
X/*conquer : Copyright (c) 1988 by Ed Barlow.
X *  I spent a long time writing this code & I hope that you respect this.
X *  I give permission to alter the code, but not to copy or redistribute
X *  it without my explicit permission.  If you alter the code,
X *  please document changes and send me a copy, so all can have it.
X *  This code, to the best of my knowledge works well,  but it is my first
X *  'C' program and should be treated as such.  I disclaim any
X *  responsibility for the codes actions (use at your own risk).  I guess
X *  I am saying "Happy gaming", and am trying not to get sued in the process.
X *                                                Ed
X */
X
X#include "header.h"
X#include "data.h"
X#include "patchlevel.h"
X#include <ctype.h>
X
Xextern FILE *fexe;
X/*offset of upper left hand corner*/
Xextern short xoffset, yoffset;
X/*current cursor postion (relative to 00 in upper corner)*/
X/*	position is 2*x,y*/
Xextern short xcurs,ycurs;
Xextern short redraw; 		/*redraw map in this turn if redraw is a 1*/
Xextern short hilmode,dismode;			/*display state*/
Xextern short country;			/* nation id of owner*/
X
X/************************************************************************/
X/*	GETSPACE() - malloc all space needed	 			*/
X/************************************************************************/
Xvoid
Xgetspace()
X{
X	sct = (struct s_sector **) m2alloc(MAPX,MAPY,sizeof(struct s_sector));
X	occ = (char **) m2alloc(MAPX,MAPY,sizeof(char));
X	movecost = (short **) m2alloc(MAPX,MAPY,sizeof(short));
X}
X
X#ifdef ADMIN
X/************************************************************************/
X/*	PRINTELE() - print a sector.altitude map 			*/
X/************************************************************************/
Xvoid
Xprintele()
X{
X	register int X, Y;
X	printf("doing print of altitude\n");
X	for(Y=0;Y<MAPY;Y++) {
X		for(X=0;X<MAPX;X++) putc(sct[X][Y].altitude,stdout);
X		putc('\n',stdout);
X	}
X}
X#endif ADMIN
X#ifdef ADMIN
X/************************************************************************/
X/*	PR_NTNS() - print nation marks					*/
X/************************************************************************/
Xvoid
Xpr_ntns()
X{
X	register int X, Y;
X	printf("doing print of nations\n");
X	for(Y=0;Y<MAPY;Y++) {
X		for(X=0;X<MAPX;X++) {
X			if(sct[X][Y].owner==0)
X				putc(sct[X][Y].altitude,stderr);
X			else putc(ntn[sct[X][Y].owner].mark,stderr);
X		}
X		putc('\n',stderr);
X	}
X}
X#endif ADMIN
X
X/************************************************************************/
X/*	WRITEDATA() - write data to datafile 				*/
X/*	trashes/creates datafile in the process				*/
X/************************************************************************/
Xvoid
Xwritedata()
X{
X	long	bytes;
X	int	fd;
X
X	printf("\ndoing write of data\n");
X	if((fd = creat(datafile,0666))==-1) {
X		printf("cant open data.  check permissions\n");
X		abrt();
X	}
X
X/* write world structure */
X	if((bytes=write(fd,&world,sizeof(struct s_world)))!=sizeof(struct s_world))
X	{
X		printf("error writing world data\n");
X		printf("wrong data format (%ld vs. %d)\n",bytes,sizeof(struct s_world) );
X		abrt();
X	}
X
X	if((bytes=write(fd,*sct,MAPX*MAPY*sizeof(struct s_sector))) == -1)
X	{
X		printf("Wrong number of bytes (%ld) written for sct (should be %d)\n",bytes,MAPX*MAPY*sizeof(struct s_sector));
X		abrt();
X	};
X	printf("writing %ld bytes of sector data\n",bytes);
X	if((bytes=write(fd,ntn,NTOTAL*sizeof(struct s_nation))) == -1)
X	{
X		printf("Wrong number of bytes (%ld) written for ntn (should be %d)\n",bytes,NTOTAL*sizeof(struct s_nation));
X		abrt();
X	}
X	printf("writing %ld bytes of nation data\n",bytes);
X	close(fd);
X}
X
X/************************************************************************/
X/*	READDATA()	-	read data & malloc space		*/
X/************************************************************************/
Xvoid
Xreaddata()
X{
X	int fd;
X	int n_read;
X
X	/*read in existing nation army and navy data*/
X	/*check if file openable*/
X	printf("reading data file\n");
X	if( (fd = open(datafile,0)) < 0 ) {
X		fprintf( stderr, "can not open %s \n", datafile );
X		fprintf( stderr, "for help with conquer, type conquer -h\n");
X		exit(FAIL);
X	}
X
X/* read world structure */
X	if((n_read=read(fd,&world,sizeof(struct s_world)))!=sizeof(struct s_world))
X	{
X		printf("error reading world data\n");
X		printf("wrong data format (%d vs. %d)\n",n_read, sizeof(struct s_world) );
X		abrt();
X	}
X#ifdef DEBUG
X	printf("reading %d bytes of world data\n",sizeof(struct s_world));
X#endif DEBUG
X
X	getspace();
X
X	if((n_read=read(fd,*sct,MAPX*MAPY*sizeof(struct s_sector)))==0)
X		printf("EOF\n");
X	else if(n_read==-1) printf("error reading sector data (sct)\n");
X	if(n_read != (MAPX*MAPY*sizeof(struct s_sector))) {
X		printf("error reading sector data (sct)\n");
X		printf( "wrong data format (%d vs. %d)\n",n_read,  MAPX*MAPY*sizeof(struct s_sector) );
X		abrt();
X	}
X#ifdef DEBUG
X	printf("reading %d bytes of sector data\n",n_read);
X#endif DEBUG
X	if((n_read=read(fd,ntn,NTOTAL*sizeof(struct s_nation))) == -1)
X		printf("error reading s_nation data (ntn)\n");
X	else if(n_read!= NTOTAL*sizeof(struct s_nation)) {
X		printf("error reading s_nation data (ntn)\n");
X		printf( "wrong data format (%d vs. %d)\n",n_read, NTOTAL*sizeof(struct s_nation) );
X		abrt();
X	}
X#ifdef DEBUG
X	printf("reading %d bytes of nation data\n",n_read);
X#endif DEBUG
X	close(fd);
X} /* readdata() */
X
X#ifdef ADMIN
X/************************************************************************/
X/*	PRINTVEG() -	print a vegetation map subroutine		*/
X/************************************************************************/
Xvoid
Xprintveg()
X{
X	register int X, Y;
X	printf("doing print of vegetation\n");
X	for(Y=0;Y<MAPY;Y++) {
X		for(X=0;X<MAPX;X++) putc(sct[X][Y].vegetation,stderr);
X		putc('\n',stderr);
X	}
X}
X#endif ADMIN
X#ifdef CONQUER
X/************************************************************************/
X/*	OFFMAP()	deal if cursor is off the map			*/
X/************************************************************************/
Xvoid
Xoffmap()
X{
X	/*set offset offsets can not be < 0*/
X	if(xcurs<1){
X		if(XREAL<=0) {
X			xoffset=0;
X			xcurs=0;
X		}
X		else {
X			redraw=TRUE;
X			xoffset-=15;
X			xcurs+=15;
X		}
X	}
X	else if(xcurs >= (COLS-23)/2){
X		if(XREAL<MAPX) {
X			redraw=TRUE;
X			xoffset+=15;
X			xcurs-=15;
X		}
X	}
X	if(XREAL>=MAPX) xcurs=MAPX-1-xoffset;
X	if(xoffset<0) {
X		xcurs += xoffset;
X		xoffset=0;
X	}
X	if(xcurs<0) {
X		xoffset += xcurs;
X		xcurs=0;
X	}
X	else if(xcurs >= (COLS-23)/2) {
X		redraw=TRUE;
X		xoffset+=15;
X		xcurs-=15;
X	}
X
X	if(ycurs<1){
X		if(YREAL<=0) {
X			yoffset=0;
X			ycurs=0;
X		}
X		else {
X			redraw=TRUE;
X			ycurs+=15;
X			yoffset-=15;
X		}
X	}
X	else if(ycurs >= SCREEN_Y_SIZE-1){
X		if(YREAL<MAPY) {
X			redraw=TRUE;
X			yoffset+=15;
X			ycurs-=15;
X		}
X	}
X	if(YREAL>=MAPY) ycurs=MAPY-1-yoffset;
X	if(yoffset<0) {
X		ycurs += yoffset;
X		yoffset=0;
X	}
X	if(ycurs<0) {
X		yoffset += ycurs;
X		ycurs=0;
X	}
X	else if(ycurs >= SCREEN_Y_SIZE-1) {
X		redraw=TRUE;
X		yoffset+=15;
X		ycurs-=15;
X	}
X	whatcansee();
X}
X#endif CONQUER
X#ifdef CONQUER
X/************************************************************************/
X/*	PRINTSCORE()	- like it says					*/
X/************************************************************************/
Xvoid
Xprintscore()
X{
X	int i;
X	int nationid; 	/*current nation id */
X
X	printf("Conquer %s.%d: %s of Year %d, Turn %d\n",VERSION,PATCHLEVEL,
X		PSEASON(TURN),YEAR(TURN), TURN);
X	printf("id      name   race    class    align  score    talons military  civilians sect\n");
X	for (nationid=1; nationid<NTOTAL; nationid++) {
X		if(!isntn(ntn[nationid].active)) continue;
X		printf("%2d ",nationid);
X		printf("%9s ",ntn[nationid].name);
X		for(i=1;i<8;i++)
X			if(ntn[nationid].race==*(races+i)[0])
X				printf("%6s ",*(races+i));
X		printf("%8s ",*(Class+ntn[nationid].class));
X 		printf(" %7s ",allignment[npctype(ntn[nationid].active)]);
X   		printf("%6ld  %8ld %8ld   %8ld %4d\n",
X			ntn[nationid].score ,ntn[nationid].tgold
X			,ntn[nationid].tmil ,ntn[nationid].tciv
X			,ntn[nationid].tsctrs );
X	}
X}
X#endif CONQUER
X
X/************************************************************************/
X/*	FLEE() - civilains in x,y flee from somebody			*/
X/*	slaver means 25% of populace stays				*/
X/* 	isupd is TRUE if it is update					*/
X/************************************************************************/
Xvoid
Xflee(x,y,isupd,slaver)
Xint x,y,isupd,slaver;
X{
X	int count=0;	/*count is number of acceptable sectors to go to */
X	int svcountry=country;
X	int slaves=0;
X	int i,j;
X	country=sct[x][y].owner;
X
X	if(slaver==TRUE){
X		slaves= sct[x][y].people/4;
X		sct[x][y].people-=slaves;
X	}
X
X	/*flee*/
X	sct[x][y].people*=6;
X	sct[x][y].people/=10;
X	/*check if next to anybody of the sectors owners race*/
X	for(i=x-2;i<=x+2;i++) for(j=y-2;j<=y+2;j++)
X		if(ONMAP(i,j)
X		&&(ntn[sct[i][j].owner].race==ntn[sct[x][y].owner].race))
X			count++;
X
X	if(count>0) {
X#ifdef CONQUER
X	if(isupd==0) {
X		if(slaver==TRUE){
X			mvprintw(LINES-2,20,"CIVILIANS ABANDON SECTOR (%d slaves)",slaves);
X		}else{
X			mvaddstr(LINES-2,20,"CIVILIANS ABANDON SECTOR");
X		}
X	}
X#endif CONQUER
X	for(i=x-2;i<=x+2;i++) for(j=y-2;j<=y+2;j++)
X		if(ONMAP(i,j)
X		&&(ntn[sct[i][j].owner].race==ntn[sct[x][y].owner].race)) {
X			sct[i][j].people += sct[x][y].people / count;
X			if(isupd==0) SADJCIV2;
X		}
X	} else {
X		sct[x][y].people /= 2;
X		for(i=x-4;i<=x+4;i++) for(j=y-4;j<=y+4;j++)
X			if(ONMAP(i,j)
X			&&(ntn[sct[i][j].owner].race==ntn[sct[x][y].owner].race))
X				count++;
X		if(count>0) {
X#ifdef CONQUER
X		if(isupd==0) mvaddstr(LINES-2,20,"PEOPLE FLEE SECTOR AND HALF DIE");
X#endif CONQUER
X		for(i=x-4;i<=x+4;i++) for(j=y-4;j<=y+4;j++)
X			if(ONMAP(i,j)
X			&&(ntn[sct[i][j].owner].race==ntn[sct[x][y].owner].race)) {
X				sct[i][j].people += sct[x][y].people / count;
X				if(isupd==0) SADJCIV2;
X			}
X		}
X#ifdef CONQUER
X		else if(isupd==0) mvaddstr(LINES-2,20,"PEOPLE IN SECTOR DIE");
X#endif CONQUER
X	}
X
X	sct[x][y].people = slaves;
X	if(isupd==0) SADJCIV;
X	sct[x][y].fortress=0;
X	/*SINFORT;*/
X	if(tofood( &sct[XREAL][YREAL],sct[XREAL][YREAL].owner)!=0) {
X		DEVASTATE(x,y);
X		if(isupd==0) SADJDES2;
X	}
X	country=svcountry;
X}
X#ifdef ADMIN
X/************************************************************************/
X/*	READMAP()	- read a map in from map files 			*/
X/*	returns TRUE for success, FALSE for fail			*/
X/************************************************************************/
Xint
Xreadmap()
X{
X	FILE	*mapfile;
X	char	line[128];
X	register int x,y;
X
X	/* read in ele.map */
X	strcpy(line,scenario);
X	strcat(line,".ele");
X	if ((mapfile=fopen(line,"r"))==NULL) {
X		fprintf(stderr,"error on read of %s file\n",line);
X		return(TRUE);
X	} else fprintf(stderr,"reading elevation map file from %s\n",line );
X
X	y=0;
X	while( TRUE ) {
X		if(fgets( line, 128, mapfile )==NULL) break;
X		for(x=0;x<MAPX;x++) sct[x][y].altitude = line[x];
X		y++;
X		if(y>=MAPY) break;
X	}
X	fprintf(stderr,"done reading %d lines of %d characters\n",y,strlen(line));
X
X	/* read in veg.map */
X	strcpy(line,scenario);
X	strcat(line,".veg");
X	if ((mapfile=fopen(line,"r"))==NULL) {
X		fprintf(stderr,"error on read of %s file\n",line);
X		return(TRUE);
X	} else fprintf(stderr,"reading vegetation map file from %s\n",line );
X	y=0;
X	while( TRUE ) {
X		if(fgets( line, 128, mapfile )==NULL) break;
X		for(x=0;x<MAPX;x++) sct[x][y].vegetation = line[x];
X		y++;
X		if(y>=MAPY) break;
X	}
X	fprintf(stderr,"done reading %d lines of %d characters\n",y,strlen(line));
X
X	return(TRUE);
X}
X#endif ADMIN
X
X/*********************************************************************/
X/* M2ALLOC() - two dimensional array allocator (because C is stupid) */
X/*********************************************************************/
Xchar **m2alloc(nrows, ncols, entrysize)
Xint	nrows;		/* row dimension */
Xint	ncols;		/* column dimension */
Xint	entrysize;	/* # bytes in items to be stored */
X{
X	char	**baseaddr;
X	int	j;
X	entrysize *= ncols;
X	baseaddr = (char **)
X		malloc( (unsigned) (nrows*(sizeof(char *)+entrysize)));
X
X	if( baseaddr == (char **) NULL ) {
X		printf("OOPS - cant allocate %d by %d blocks of %d bytes\n",nrows,ncols,entrysize);
X		abrt();
X	}
X	if(nrows>0){
X		*baseaddr = (char *) (baseaddr + nrows);
X		for(j=1; j<nrows; j++)
X			baseaddr[j] = baseaddr[j-1] + entrysize;
X	}
X	return(baseaddr);
X}
END_OF_FILE
if test 12125 -ne `wc -c <'io.c'`; then
    echo shar: \"'io.c'\" unpacked with wrong size!
fi
# end of 'io.c'
fi
if test -f 'run' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'run'\"
else
echo shar: Extracting \"'run'\" \(1789 characters\)
sed "s/^X//" >'run' <<'END_OF_FILE'
X#below is a shell script that runs updates 3 times a day every day but sunday
X#
X#PLEASE CHANGE TIME* VARIABLES TO APPROPRIATE TIMES, and CHANGE PATH VARIABLES
X#
X#KEEP THE TIMES IN CHRONOLOGICAL ORDER AND THE TIME1H and TIME2H values
X#represent the hours of TIME1 and TIME2
X#########################################################
X# use the command "at -l" to get a list of existing at jobs
X# use the command "at -r <jobname>" to remove existing at jobs
X#########################################################
XTIME1=1000
XTIME1H=10
XTIME2=1700
XTIME2H=17
XTIME3=2300
X#Below is the full command to update a game of conquer 
XPATHTOCONQ="/d7/c7913/smile/oldgame/conquer -x -d/d7/c7913/smile/oldgame/temp"
X#Path to this file
XPATHTORUN=/d7/c7913/smile/oldgame/run
X#LOG is full path name of log file
XLOG=/d7/c7913/smile/oldgame/runlog
X
X/bin/date >> $LOG
X$PATHTOCONQ >> $LOG
X
XDAY=`/bin/date | /usr/bin/awk '{ print $1 }'`
Xecho "day is $DAY" >> $LOG
XHOUR=`/bin/date|/usr/bin/awk '{ print $4 }'|/usr/bin/awk -F: '{ print $1 }'`
Xecho "hour is $HOUR" >> $LOG
X#BELOW IS AN EXAMPLE OF A BSD SCRIPT
X#switch $DAY
X#	case Sat:
X#		set nextday=mon
X#		breaksw
X#	default:
X#		set nextday =
X#		breaksw
X#endsw
Xcase $DAY in
X	Sat)
X 		nextday=mon
X		;;
X	*)
X 		nextday=""
X		;;
Xesac
X#switch $HOUR
X#	case 00:
X#		set nexthour=$TIME1
X#		breaksw
X#	default:
X#		set nexthour=$TIME2
X#		breaksw
X#endsw
Xcase $HOUR in
X$TIME1H)
X 	nexthour=$TIME2
X	echo "nexthour is $nexthour" >> $LOG
X	;;
X$TIME2H)
X 	nexthour=$TIME3
X	echo "nexthour is $nexthour" >> $LOG
X	;;
X*)
X	nexthour=$TIME1
X	echo "nexthour is $nexthour" >> $LOG
X	;;
Xesac
X#below for bsd (i think)
X#/usr/bin/at $nexthour $nextday $PATHTORUN 
X#below for SYSV
Xecho "/usr/bin/at $nexthour $nextday < $PATHTORUN" >> $LOG
Xecho "XXX" >> $LOG
X/usr/bin/at $nexthour $nextday < $PATHTORUN 
END_OF_FILE
if test 1789 -ne `wc -c <'run'`; then
    echo shar: \"'run'\" unpacked with wrong size!
fi
chmod +x 'run'
# end of 'run'
fi
echo shar: End of archive 4 \(of 14\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 14 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0