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