billr@saab.CNA.TEK.COM (Bill Randle) (06/24/89)
Submitted-by: adb@bu-it.bu.edu (Adam Bryant) Posting-number: Volume 6, Issue 85 Archive-name: conquer4/Part03 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 3 (of 14)." # Contents: misc.c navy.c # Wrapped by billr@saab on Thu Jun 15 15:20:10 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'misc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'misc.c'\" else echo shar: Extracting \"'misc.c'\" \(42709 characters\) sed "s/^X//" >'misc.c' <<'END_OF_FILE' X/* Conquer: Copyright (c) 1988 by Edward M Barlow */ X#include <ctype.h> X#include <stdio.h> X#include "header.h" X#include "data.h" X Xextern FILE *fnews; X Xextern char *HVegcost, *OVegcost, *EVegcost, *DVegcost, *FVegcost; Xextern char *HElecost, *OElecost, *EElecost, *DElecost, *FElecost; X X#ifdef SYSV Xchar *memset(); X#endif X X#ifdef CONQUER Xint Xmove_file( from, to ) Xregister char *from; Xregister char *to; X{ X if( unlink( to ) < 0 ) { X fprintf( stderr, "unlink( %s ) failed \n", to ); X sleep( 2 ); X return( -1 ); X } X X if( link( from, to ) < 0 ) { X fprintf( stderr, "link( %s, %s ) failed \n", from, to ); X sleep( 2 ); X return( -1 ); X } X X if( unlink( from ) < 0 ) { X fprintf( stderr, "unlink( %s ) failed \n", from ); X sleep( 2 ); X return( -1 ); X } X X return( 0 ); X} /* move_file() */ X#endif CONQUER X X#ifdef CONQUER Xlong Xget_number() X{ X long sum=0; X char ch; X int done=FALSE,count=0,xpos,ypos; X /* this routine totally redone to allow deleting */ X while(!done) { X ch=getch(); X if(isdigit(ch)) { X /* only print numbers to the screen */ X addch(ch); X refresh(); X sum *= 10L; X count++; X sum += (long)(ch-'0'); X } else if ((ch=='\b' || ch=='\177')&&(count)) { X /* only delete what was printed */ X getyx(stdscr,ypos,xpos); X move(ypos,--xpos); X addch(' '); X move(ypos,xpos); X refresh(); X sum /= 10L; X count--; X } else if((ch=='\n')||(ch=='\r')) { X done=TRUE; X } X if( count >= 12 ) done=TRUE; X } X return( sum ); X} X#endif CONQUER X X#define INFINITE 1000 X Xint bx; /* destination 'x' coordinate */ Xint by; /* destination 'y' coordinate */ Xint moving_country; /* country that is moving */ X X#define MAX_MOVE_UNITS 0x7f Xunsigned char **history_reachp; Xint level; X X/* X * land_2reachp() X */ X Xint Xland_2reachp( ax, ay, move_points ) Xint ax; Xint ay; Xint move_points; X{ X register int i = 0; X int delta_x, delta_y; X int x_abs_delta, y_abs_delta; X int own; X int dx[ 8 ]; X int dy[ 8 ]; X X delta_x = bx - ax; X delta_y = by - ay; X X /* Have we got where we are going? */ X if( delta_x == 0 && delta_y == 0 ) { X return( 1 ); X } X X /* Any move points left? (optimization) */ X if( move_points == 0 ) { X return( 0 ); X } X X x_abs_delta = (delta_x < 0) ? -delta_x : delta_x; X y_abs_delta = (delta_y < 0) ? -delta_y : delta_y; X X /* couldn't reach if all moves cost 1 (optimization) */ X if( max( x_abs_delta, y_abs_delta ) > move_points ) { X return( 0 ); X } X X { X register int inc_x; X register int inc_y; X X inc_x = (delta_x < 0 ) ? -1 : 1; X inc_y = (delta_y < 0 ) ? -1 : 1; X X /*I HAVE CHANGED THIS CODE FROM THE ORIGINAL TO OPTIMIZE IT*/ X /*I think it should work well*/ X if( y_abs_delta == 0) { X /* try 'x' movements first */ X dx[i] = inc_x; dy[i++] = 0; X dx[i] = inc_x; dy[i++] = inc_y; X dx[i] = inc_x; dy[i++] = -inc_y; X dx[i] = 0; dy[i++] = inc_y; X dx[i] = 0; dy[i++] = -inc_y; X dx[i] = -inc_x; dy[i++] = inc_y; X dx[i] = -inc_x; dy[i++] = 0; X dx[i] = -inc_x; dy[i++] = -inc_y; X } else if( x_abs_delta == 0 ) { X /* try 'y' movements first */ X dx[i] = 0; dy[i++] = inc_y; X dx[i] = inc_x; dy[i++] = inc_y; X dx[i] = -inc_x; dy[i++] = inc_y; X dx[i] = inc_x; dy[i++] = 0; X dx[i] = -inc_x; dy[i++] = 0; X dx[i] = inc_x; dy[i++] = -inc_y; X dx[i] = 0; dy[i++] = -inc_y; X dx[i] = -inc_x; dy[i++] = -inc_y; X } else { /* x_abs_delta != 0, 0 != y_abs_delta */ X /* try diagonal movements first */ X dx[i] = inc_x; dy[i++] = inc_y; X X dx[i] = 0; dy[i++] = inc_y; X dx[i] = inc_x; dy[i++] = 0; X X dx[i] = -inc_x; dy[i++] = inc_y; X dx[i] = inc_x; dy[i++] = -inc_y; X X dx[i] = -inc_x; dy[i++] = 0; X dx[i] = 0; dy[i++] = -inc_y; X X dx[i] = -inc_x; dy[i++] = -inc_y; X } /* if */ X } /* block */ X X { X register int x, y; X register int new_mp; X X for( i = 0; i < 8; i++ ) { X if( (x = ax + dx[i]) < 0 || x >= MAPX ) X continue; X if( (y = ay + dy[i]) < 0 || y >= MAPY ) X continue; X X if( sct[x][y].altitude == PEAK) X continue; X if( sct[x][y].altitude == WATER) X continue; X X new_mp = move_points - movecost[ x ][ y ]; X if( new_mp < 0 ) X continue; X X /* X * If we have been to this sector before X * in fewer move points this path is not X * going to do any better. X */ X if( history_reachp[x][y] >= new_mp ) { X continue; X } X history_reachp[x][y] = new_mp; X X /* X * Test for a hostile army X */ X /* BUG: should engage if army is hostile but does not own sector */ X /* BUG: take into account THE_VOID, HIDDEN, and NINJA */ X /* BUG: NEUTRAL does not allow to pass */ X if( (own = sct[x][y].owner) > 0 && X ntn[own].dstatus[moving_country] >= WAR && X x != bx && y != by && X solds_in_sector( x, y, own ) > 0 ) { X continue; /* at war with the owner, may not pass */ X } X X level++; X if( land_2reachp( x, y, new_mp ) ) { X level--; X return( 1 ); X } /* if */ X level--; X } /* for */ X } /* block */ X return( 0 ); X} /* land_2reachp() */ X X/* X * land_reachp() X */ X#ifdef ADMIN Xint Xland_reachp( ax, ay, gx, gy, move_points, movee ) Xint ax; Xint ay; Xint gx; Xint gy; Xint move_points; Xint movee; X{ X int result; X X if( move_points >= MAX_MOVE_UNITS ) { X fprintf( stderr, "land_reachp(): move_points = %d\n", X move_points ); X X abrt(); X } X X /* Are we starting or ending in the water or on a peak? */ X if( sct[ax][ay].altitude == WATER || sct[ax][ay].altitude == PEAK ) X return( 0 ); X if( sct[gx][gy].altitude == WATER || sct[gx][gy].altitude == PEAK ) X return( 0 ); X X history_reachp = (unsigned char **) m2alloc(MAPX,MAPY,sizeof(char)); X#ifdef BSD X bzero((char *) *history_reachp,MAPX*MAPY); X#else X memset((char *) *history_reachp, 0, MAPX*MAPY ); X#endif X X history_reachp[ax][ay] = move_points; X X bx = gx; X by = gy; X moving_country = movee; X X level = 1; X result = land_2reachp( ax, ay, move_points ); X free(history_reachp); X return( result ); X} /* land_reachp() */ X#endif ADMIN X#ifdef ADMIN X/* X * water_2reachp() X */ X Xint Xwater_2reachp( ax, ay, move_points ) Xint ax; Xint ay; Xint move_points; X{ X register int i = 0; X int delta_x; X int delta_y; X int dx[ 8 ]; X int dy[ 8 ]; X X /* this path uses too many move units */ X if( move_points < 0 ) X return( 0 ); X X /* X * If we have been to this sector before in fewer move points X * this path is not going to do any better. X */ X if( history_reachp[ ax ][ ay ] <= move_points ) X return( 0 ); X X history_reachp[ ax ][ ay ] = move_points; X X delta_x = ax - bx; X delta_y = ay - by; X X /* Have we got where we are going? */ X if( delta_x == 0 && delta_y == 0 ) X return( 1 ); X X /* Have we run into ground, but not reached our destination? */ X if( sct[ax][ay].altitude != WATER ) X return( 0 ); X X /* Any move points left? (optimization) */ X if( move_points == 0 ) X return( 0 ); X X /* couldn't reach if all moves cost 1 (optimization) */ X if( max( abs( delta_x ), abs( delta_y ) ) > move_points ) X return( 0 ); X X /* BUG: test for an enemy navy */ X X { X register int inc_x; X register int inc_y; X X inc_x = (delta_x < 0 ) ? -1 : (delta_x > 0) ? 1 : 0; X inc_y = (delta_y < 0 ) ? -1 : (delta_y > 0) ? 1 : 0; X X if( abs(delta_x) > abs(delta_y) ) { X /* try 'x' movements first */ X dx[i] = inc_x; dy[i++] = 0; X dx[i] = inc_x; dy[i++] = inc_y; X dx[i] = inc_x; dy[i++] = -inc_y; X dx[i] = 0; dy[i++] = inc_y; X dx[i] = 0; dy[i++] = -inc_y; X dx[i] = -inc_x; dy[i++] = inc_y; X dx[i] = -inc_x; dy[i++] = 0; X dx[i] = -inc_x; dy[i++] = -inc_y; X } else { /* abs(delta_x) < abs(delta_y) */ X /* try 'y' movements first */ X dx[i] = 0; dy[i++] = inc_y; X dx[i] = inc_x; dy[i++] = inc_y; X dx[i] = -inc_x; dy[i++] = inc_y; X dx[i] = inc_x; dy[i++] = 0; X dx[i] = -inc_x; dy[i++] = 0; X dx[i] = inc_x; dy[i++] = -inc_y; X dx[i] = 0; dy[i++] = -inc_y; X dx[i] = -inc_x; dy[i++] = -inc_y; X } /* if */ X } /* block */ X X { X register int x, y; X register int new_mp; X X for( i = 0; i < 8; i++ ) { X if( (x = ax + dx[i]) < 0 || x >= MAPX ) X continue; X if( (y = ay + dy[i]) < 0 || y >= MAPY ) X continue; X X new_mp = move_points - 1; X if( new_mp < 0 ) X continue; X X if( water_2reachp( x, y, new_mp ) ) X return( 1 ); X } /* for */ X } /* block */ X X return( 0 ); X} /* water_2reachp() */ X#endif ADMIN X#ifdef XYZ /* XYZ never is defined */ X/* X * water_reachp() X */ X Xint Xwater_reachp( ax, ay, gx, gy, move_points, movee ) Xint ax; Xint ay; Xint gx; Xint gy; Xint move_points; Xint movee; X{ X if( move_points >= MAX_MOVE_UNITS ) { X fprintf( stderr, "water_reachp(): move_points = %d\n", X move_points ); X X abrt(); X } X X#ifdef SYSV X memset(history_reachp, MAX_MOVE_UNITS, MAPX*MAPY*sizeof(history_reachp)); X#else X { register int i,j; X for (i=0; i < MAPX ; i++) X for (j=0; j < MAPY ; j++ ) X history_reachp [i] [j] = MAX_MOVE_UNITS ; X }/* eof memset replacement block */ X#endif X X history_reachp[ ax ][ ay ] = 0; X X bx = gx; X by = gy; X moving_country = movee; X X return( water_2reachp( ax, ay, move_points ) ); X} /* water_reachp() */ X#endif 0 X X/* X * solds_in_sector() X */ X Xlong Xsolds_in_sector( x, y, country ) Xint x; Xint y; Xint country; X{ X register struct s_nation *nptr = &ntn[country]; X register int j; X long total = 0; X X for( j = 0; j < MAXARM; j++ ) { X if( nptr->arm[j].sold == 0 ) X continue; X X if( nptr->arm[j].xloc == x && nptr->arm[j].yloc == y ) X total += nptr->arm[j].sold; X } X X return( total ); X} /* solds_in_sector() */ X#ifdef ADMIN X X/* score_one() */ Xstruct wght { X int sectors; X int civilians; X int soldiers; X int gold; X int jewels; X int metal; X int magics; X int ships; X} weights[] = { X/* Per 2 1000 1000 100K 100K 100K Magic 10 */ X/* Races Sector People Soldiers Gold Jewels Iron Power Ship */ X/* NPC */ { 2, 1, 0, 0, 1, 1, 1, 0 }, X/* kingdom */ { 2, 1, 2, 3, 0, 0, 0, 0 }, X/* empire */ { 3, 0, 0, 1, 1, 0, 0, 0 }, X/* wizard */ { 0, 2, 1, 0, 3, 5, 7, 0 }, X/* theocracy */ { 2, 1, 0, 0, 3, 0, 3, 0 }, X/* pirate */ { 0, 0, 5, 0, 10, 10, 1, 5 }, X/* trader */ { 2, 1, 0, 0, 1, 1, 1, 8 }, X/* warlord */ { 2, 1, 2, 0, 1, 1, 1, 0 }, X/* demon */ { 2, 0, 1, 0, 1, 0, 5, 0 }, X/* dragon */ { 0, 0, 0, 10, 20, 0, 0, 0 }, X/* shadow */ { 2, 0, 0, 0, 0, 5, 0, 0 }, X/* miner */ { 0, 0, 5, 0, 10, 10, 1, 5 }, X}; X Xlong Xscore_one( country ) Xint country; X{ X struct s_nation *nptr = &ntn[ country ]; X long total = 0; X int bonus; X struct wght *wght = &weights[ nptr->class ]; X X total += wght->sectors * nptr->tsctrs / 2L; X total += wght->civilians * nptr->tciv / 1000L; X total += wght->soldiers * nptr->tmil / 1000L; X if(nptr->tgold > 0 ) total += wght->gold * nptr->tgold / 100000L; X total += wght->jewels * nptr->jewels / 100000L; X total += wght->metal * nptr->metals / 100000L; X total += wght->magics * num_powers(country,M_MIL); X total += wght->magics * num_powers(country,M_CIV); X total += wght->magics * num_powers(country,M_MGK); X total += wght->ships * nptr->tships / 10L; X switch( nptr->class ) { X case C_KING: X bonus=(curntn->popularity+curntn->prestige-curntn->poverty); X break; X case C_EMPEROR: X bonus=(curntn->power+curntn->prestige-curntn->poverty); X break; X case C_WIZARD: X bonus=(curntn->knowledge+curntn->power-50); X break; X case C_PRIEST: X bonus=(curntn->wealth+curntn->terror-curntn->poverty); X break; X case C_PIRATE: X bonus=(curntn->reputation+curntn->wealth-50); X break; X case C_TRADER: X bonus=(curntn->wealth+curntn->prestige-curntn->tax_rate*5); X break; X case C_WARLORD: X bonus=(curntn->reputation+curntn->prestige-50); X break; X case C_DEMON : X bonus=(curntn->knowledge+curntn->terror-50); X break; X case C_DRAGON: X bonus=(curntn->wealth+curntn->terror-50); X break; X case C_SHADOW: X bonus=(curntn->power+curntn->terror-50); X break; X default: bonus=0; X } X total += bonus/10; X return( total ); X} /* score_one() */ X#endif ADMIN X/* X * print_accum() X */ X X /* max number of print_accum() calls in one printf() */ X#define MAX_BUFFER 4 X#define BUFFER_SIZE 20 X X/* is_habitable() - returns TRUE/FALSE if habitable */ Xint Xis_habitable( x, y ) Xint x; Xint y; X{ X char temp; X X if(( (temp=sct[x][y].altitude)==WATER )||( temp==PEAK )) return(FALSE); X X if(((temp=sct[x][y].vegetation)==BARREN ) X || ( temp==LT_VEG ) X || ( temp==GOOD ) X || ( temp==WOOD ) X || ( temp==FOREST )) return( TRUE ); X X return( FALSE ); X} X X#ifdef CONQUER Xint Xunits_in_sector(x,y,country) Xint x; Xint y; X{ X int count=0, armynum, nvynum; X for(armynum=0;armynum<MAXARM;armynum++) X if((ASOLD>0)&&(AXLOC==x)&&(AYLOC==y)) count++; X for(nvynum=0;nvynum<MAXNAVY;nvynum++) X if(((NWSHP+NMSHP+NGSHP)!=0)&&(NXLOC==x)&&(NYLOC==y)) count++; X return(count); X} X#endif CONQUER X Xint Xnum_powers(country,type) Xint country,type; X{ X int count_magic=0; X int try; X long start, end; X switch(type){ X case M_MGK: X start=S_MGK; X end=E_MGK; X break; X case M_CIV: X start=S_CIV; X end=E_CIV; X break; X case M_MIL: X start=S_MIL; X end=E_MIL; X break; X case M_ALL: X start=S_MIL; X end=E_MGK; X break; X default: X printf("fatal error in num_powers"); X abrt(); X } X for( try = start; try < start+end; try++ ) X if( magic(country, powers[try] ) == 1 ) count_magic++; X return(count_magic); X} X X/* returns food value of sector */ X/* 4 is limit of livable land */ Xint Xtofood(sptr,cntry) Xstruct s_sector *sptr; Xint cntry; X{ X register int i=0; X register int foodvalue; X while( sptr->vegetation != *(veg+i) ) i++; X foodvalue = *(vegfood+i) - '0'; X if( cntry != 0 ) { X if(foodvalue == 0) { X#ifdef DERVDESG X if ((magic(cntry,DERVISH)||magic(cntry,DESTROYER)) X &&(sptr->vegetation==DESERT || sptr->vegetation==ICE)) X return(6); X#endif DERVDESG X return( 0 ); X } X if(ntn[cntry].race == ELF){ X if(sptr->vegetation == FOREST) foodvalue+=3; X else if(sptr->vegetation == BARREN) foodvalue--; X } X } X if(( sptr->tradegood <= END_EATRATE ) X &&( sptr->tradegood > END_COMMUNICATION )) X foodvalue += *(tg_value+sptr->tradegood) - '0'; X return( foodvalue ); X} X X/*jewel cost for civilian power = Base * 2**( #mgk/2 + #civ + #mil/2 ) */ X/*race magical civilian military */ X/* elves - 50K 50K 50K */ X/* dwarves - 80K 40K 40K */ X/* humans - 100K 25K 50K */ X/* orcs - 100K 50K 25K */ X X/* returns cost of magic power - returns -1 if invalid */ Xlong Xgetmgkcost(type,country) Xint type, country; X{ X int i; X long cost; X long base=BASEMAGIC; X int npowers; X switch(type) { X case M_MGK: X if(ntn[country].race==DWARF) base=DWFMAGIC; X else if(ntn[country].race==HUMAN) base=HUMMAGIC; X else if(ntn[country].race==ORC) base=ORCMAGIC; X npowers=num_powers(country,M_CIV)+num_powers(country,M_MIL)+1 X +2*num_powers(country,M_MGK); X npowers/=2; X break; X case M_CIV: X if(ntn[country].race==DWARF) base=DWFCIVIL; X else if(ntn[country].race==HUMAN) base=HUMCIVIL; X else if(ntn[country].race==ORC) base=ORCCIVIL; X npowers=num_powers(country,M_MGK)+num_powers(country,M_MIL)+1 X +2*num_powers(country,M_CIV); X npowers/=2; X break; X case M_MIL: X if(ntn[country].race==DWARF) base=DWFMILIT; X else if(ntn[country].race==ORC) base=ORCMILIT; X npowers=num_powers(country,M_CIV)+num_powers(country,M_MGK)+1 X +2*num_powers(country,M_MIL); X npowers/=2; X break; X default: X return(-1); X } X cost = base; X for (i=1; i<npowers; i++) { X cost <<= 1; X if (cost > BIG) X return(BIG/2L); X } X return(cost); X} X Xint Xtodigit(character) Xregister int character; X{ X if( character >= '0' && character <= '9' ) X return( character - '0' ); X return( -1 ); X} X X/* set up occ[][] for country. X if leader==true, only for leader sectors plus ntn.communicatins range */ Xvoid Xprep(country,leader) Xint country,leader; X{ X short armynum,nvynum; X int save,i,j,x,y,start,end,com; X X /*set occ to 0*/ X for(i=0;i<MAPX;i++) for(j=0;j<MAPY;j++) occ[i][j]=0; X X save=country; X if(leader) { X /* only do the given country */ X start=save; X end=save+1; X } else { X /* go through all countries */ X start=0; X end=NTOTAL; X } X X /*set occ to country of occupant army*/ X for(country=start;country<end;country++) if(ntn[country].active!=INACTIVE) { X curntn = &ntn[country]; X for(armynum=0;armynum<MAXARM;armynum++){ X if( leader ) { X if((P_ATYPE<MINLEADER) X ||(P_ATYPE>=MINMONSTER) X ||(P_ASOLD==0)) continue; X i=P_AXLOC; X j=P_AYLOC; X com = P_NTNCOM; /* do communications radius */ X for(x=i-com;x<=i+com;x++) X for(y=j-com;y<=j+com;y++) X if(ONMAP(x,y)) occ[x][y]=country; X } else if((P_ASOLD>0)&&(P_ASTAT!=SCOUT)){ X i=P_AXLOC; X j=P_AYLOC; X if((occ[i][j]== 0)||(occ[i][j]== country)) X occ[i][j]= country; X else occ[i][j]= NTOTAL; X } X } X if( !leader ) for(nvynum=0;nvynum<MAXNAVY;nvynum++){ X if((P_NWSHP!=0)||(P_NGSHP!=0)||(P_NMSHP!=0)){ X i=P_NXLOC; X j=P_NYLOC; X if((occ[i][j]== 0)||(occ[i][j]== country)) X occ[i][j]= country; X else occ[i][j]= NTOTAL; X } X } X } X X country=save; X curntn = &ntn[country]; X} X X#ifdef ADMIN X/*routine to depelete a nation without a capitol */ Xvoid Xdeplete(country) Xint country; X{ X struct s_nation *saventn=curntn; X int i,j,x,y,armynum,nation; X X x = ntn[country].capx; X y = ntn[country].capy; X if((sct[x][y].designation==DCAPITOL)&&((sct[x][y].owner==country) X ||(sct[x][y].owner==0)||(!isntn(ntn[sct[x][y].owner].active)))) X return; X X curntn = &ntn[country]; X fprintf(fnews,"1.\tNation %s is depleted by the lack of a Capitol\n",ntn[country].name); X X for(armynum=0;armynum<MAXARM;armynum++) if (P_ASOLD>0) { X /* first disband PDEPLETE% of the military */ X if (P_ATYPE<MINLEADER && X (rand()%100<PDEPLETE||P_ATYPE==A_MERCENARY)) { X if(P_ATYPE==A_MERCENARY) { X MERCMEN += P_ASOLD; X } else if(ntn[sct[AXLOC][AYLOC].owner].race==ntn[country].race) { X sct[P_AXLOC][P_AYLOC].people += P_ASOLD; X } X P_ASOLD=0; X if(ispc(curntn->active)) { X mailopen(country); X fprintf(fm,"Message to %s from Conquer\n\n",curntn->name); X fprintf(fm,"\tYour %s Army %d disperses into the population\n",*(unittype+(P_ATYPE%UTYPE)),armynum); X mailclose(); X } X } else if(P_ATYPE>=MINMONSTER) { X /* disbanding of ALL monsters should take place */ X P_ASOLD=0; X if(ispc(curntn->active)) { X mailopen(country); X fprintf(fm,"Message to %s from Conquer\n\n",curntn->name); X fprintf(fm,"\tYour %s (unit %d) leaves due to the loss of your jewels.\n",*(unittype+(P_ATYPE%UTYPE)),armynum); X mailclose(); X } X } X } X X /* check for sectors breaking away -- not capx, capy */ X if(ispc(curntn->active)) { X /* create a summarized mail message of sectors effected */ X mailopen(country); X fprintf(fm,"Message to %s from Conquer\n\n",curntn->name); X fprintf(fm,"Riots and Rebellion flourish:\n"); X } X for(i=0;i<MAPX;i++) for(j=0;j<MAPY;j++) X if(sct[i][j].owner==country && (i!=x || j!=y) ) { X if(rand()%100 < PDEPLETE && sct[x][y].people>0) { X if(rand()%100 < PDEPLETE) { X /* sector riots */ X flee(i,j,TRUE,FALSE); X DEVASTATE(i,j); X if(ispc(curntn->active)) { X /* add to listing */ X fprintf(fm,"\tsector %d, %d has massive riots\n",i,j); X } X } else { X /* sector becomes owned by another nation */ X#ifdef NOTDONE X /* must work on this still */ X giveaway(i,j,&nation); X if(ispc(curntn->active)) { X fprintf(fm,"\tsector %d, %d joins nation %s\n",ntn[nation].name); X } X#endif NOTDONE X } X } X } X if(ispc(curntn->active)) { X mailclose(); X } else if(isnpc(curntn->active)) { X if(sct[curntn->capx][curntn->capy].owner==country) { X /* reset capitol for npcs */ X sct[curntn->capx][curntn->capy].owner=DCAPITOL; X if(sct[curntn->capx][curntn->capy].fortress<1) X sct[curntn->capx][curntn->capy].fortress=1; X } X } X /* restore */ X curntn = saventn; X} X X X/*routine to sack a nation's captiol */ Xvoid Xsackem(country) X int country; X{ X struct s_nation *saventn=curntn; X int x,y,i,j,foundcap,nation; X X /* hail the conquerer */ X curntn = &ntn[country]; X x = curntn->capx; X y = curntn->capy; X nation = sct[x][y].owner; X if(nation==country || nation==0) return; X X /* advertise */ X fprintf(fnews,"1.\tCapitol of %s sacked by %s\n",ntn[country].name,ntn[nation].name); X X /* first give all prizes to the conquerer */ X if(curntn->tgold > 0) { /* all gold */ X ntn[nation].tgold += curntn->tgold; X curntn->tgold=0; X } X ntn[nation].jewels += curntn->jewels; /* all jewels */ X curntn->jewels=0; X ntn[nation].metals += curntn->metals; /* all metals */ X curntn->metals=0; X ntn[nation].tfood += curntn->tfood/5L; /* 20% of food */ X curntn->tfood -= curntn->tfood/5L; X X /* fix the designation */ X if(sct[x][y].designation==DCAPITOL) { X if(isntn(ntn[nation].active)) { X sct[x][y].designation = DCITY; X } else { X DEVASTATE(x,y); X sct[x][y].owner=country; X } X } X X /* set another sector to the capx, capy to make sure that */ X /* sacking does not occur next update for same sacking. */ X foundcap=FALSE; X for(i=0;foundcap==FALSE && i<MAPX;i++) X for(j=0;foundcap==FALSE && j<MAPY;j++) if(sct[i][j].owner==country) { X if(sct[i][j].designation==DCITY) { X x = i; y = j; X foundcap=TRUE; X } else if((sct[i][j].designation==DTOWN) X &&(((x==curntn->capx)&&(y==curntn->capy)) X ||(sct[x][y].designation!=DTOWN))) { X x = i; y = j; X } else if((x==curntn->capx)&&(y==curntn->capy)) { X x = i; y = j; X } X } X X if ((x!=curntn->capx)||(y!=curntn->capy)) { X /* assign new pseudo capitol */ X if(ispc(curntn->active)) { X mailopen(country); X fprintf(fm,"Message to %s from Conquer\n\n",ntn[country].name); X fprintf(fm,"\tYour Capitol at sector location %d,%d\n",curntn->capx,curntn->capy); X fprintf(fm,"\t was overrun by nation %s.\n\n",ntn[nation].name); X fprintf(fm,"\tA temporary headquarters is now in sector %d,%d,\n",x,y); X fprintf(fm,"\t but designation of a new Capitol is recommended.\n"); X mailclose(); X } X curntn->capx=x; X curntn->capy=y; X } else { X /* no new capitol assignment */ X if(ispc(curntn->active)) { X mailopen(country); X fprintf(fm,"Message to %s from Conquer\n\n",ntn[country].name); X fprintf(fm,"\tYour Capitol at sector location %d,%d\n",curntn->capx,curntn->capy); X fprintf(fm,"\t was overrun by nation %s.\n\n",ntn[nation].name); X fprintf(fm,"\tNo other land remains. The destruction\n"); X fprintf(fm,"\t of your nation seems imminent.\n"); X mailclose(); X } X } X /* restore */ X curntn = saventn; X} X#endif ADMIN X X/*destroy nation--special case if capitol not owned by other nation*/ Xvoid Xdestroy(country) Xint country; X{ X short armynum, nvynum; X int i, x, y; X char buf[20]; X struct s_nation *nptr; X X nptr = &ntn[country]; X if( ismonst(nptr->active) ) return; X fprintf(fnews,"1.\tNation %s was destroyed ",nptr->name); X if(country!=sct[nptr->capx][nptr->capy].owner){ X fprintf(fnews,"(their capitol is now owned by %s)\n",ntn[sct[nptr->capx][nptr->capy].owner].name); X /*get +5% to combat skill*/ X ntn[sct[nptr->capx][nptr->capy].owner].aplus+=5; X } X else fprintf(fnews,"(they owned their capitol)\n"); X X nptr->active=INACTIVE; X nptr->score=0; X sprintf(buf,"%s%d",msgfile,country); X unlink(buf); X X for(armynum=0;armynum<MAXARM;armynum++) if(ASOLD>0) { X if(ntn[sct[AXLOC][AYLOC].owner].race==nptr->race) X sct[AXLOC][AYLOC].people+=ASOLD; X ASOLD=0; X } X for(nvynum=0;nvynum<MAXNAVY;nvynum++) { X NMSHP=0; X NWSHP=0; X NGSHP=0; X } X for(i=0;i<NTOTAL;i++) { X ntn[i].dstatus[country]=UNMET; X nptr->dstatus[i]=UNMET; X } X X /*if take them you get their gold*/ X if(country!=sct[nptr->capx][nptr->capy].owner){ X if(nptr->tgold>0) ntn[sct[nptr->capx][nptr->capy].owner].tgold+=nptr->tgold; X if(nptr->jewels>0) ntn[sct[nptr->capx][nptr->capy].owner].jewels+=nptr->jewels; X if(nptr->metals>0) ntn[sct[nptr->capx][nptr->capy].owner].metals+=nptr->metals; X if(nptr->tfood>0) ntn[sct[nptr->capx][nptr->capy].owner].tfood+=nptr->tfood; X sct[nptr->capx][nptr->capy].designation=DCITY; X } X X /*if god destroys then kill all population*/ X if(country==sct[nptr->capx][nptr->capy].owner){ X for(x=0;x<MAPX;x++) for(y=0;y<MAPY;y++) X if(sct[x][y].owner==country) { X sct[x][y].people=0; X sct[x][y].owner=0; X sct[x][y].designation=DNODESIG; X } X } X /*slowly take over and all people flee*/ X else if(ntn[sct[nptr->capx][nptr->capy].owner].race!=nptr->race){ X for(x=0;x<MAPX;x++) for(y=0;y<MAPY;y++) X if(sct[x][y].owner==country) { X /*all kinds of refugees to neighboring countries*/ X flee(x,y,TRUE,FALSE); X sct[x][y].people=0; X sct[x][y].owner=0; X if(tofood( &sct[x][y],0 )<DESFOOD) X sct[x][y].designation=DNODESIG; X else sct[x][y].designation=sct[x][y].vegetation; X } X } X /*else same race, so give all land to conqueror*/ X else { X for(x=0;x<MAPX;x++) for(y=0;y<MAPY;y++) X if(sct[x][y].owner==country){ X sct[x][y].owner=sct[nptr->capx][nptr->capy].owner; X if( !ISCITY( sct[x][y].designation )) { X if(tofood( &sct[x][y],0)<DESFOOD) X sct[x][y].designation=DNODESIG; X else sct[x][y].designation=DFARM; X } X } X } X return; X} X X#define ALPHA_SIZE 128 X X/*movecost contains movement cost unless water -1 or unenterable land (-2)*/ X/* if water and not ajacent to land will cost -4*/ Xvoid Xupdmove(race,country) Xint country; Xchar race; X{ X register struct s_sector *sptr; X register int i,j; X int x,y; X short veg_cost[ ALPHA_SIZE ]; X short ele_cost[ ALPHA_SIZE ]; X X if( race==GOD ) { X for(x=0;x<MAPX;x++) for(y=0;y<MAPY;y++) movecost[x][y] = 0; X return; X } X X for( j = 0; veg[j] != '0'; j++ ) { X switch( race ) { X case ELF: X veg_cost[ veg[j] ] = EVegcost[j] - '0'; X break; X case DWARF: X veg_cost[ veg[j] ] = DVegcost[j] - '0'; X break; X case ORC: X veg_cost[ veg[j] ] = OVegcost[j] - '0'; X break; X case HUMAN: X default: X veg_cost[ veg[j] ] = HVegcost[j] - '0'; X break; X } /* switch */ X } /* for */ X X if((magic(country,DERVISH)==1) ||(magic(country,DESTROYER)==1)) { X veg_cost[ ICE ] = 1; X veg_cost[ DESERT ] = 1; X } X X for( j = 0; ele[j] != '0'; j++ ) { X switch( race ) { X case ELF: X ele_cost[ ele[j] ] = EElecost[j] - '0'; X break; X case DWARF: X ele_cost[ ele[j] ] = DElecost[j] - '0'; X break; X case ORC: X ele_cost[ ele[j] ] = OElecost[j] - '0'; X break; X case HUMAN: X default: X ele_cost[ ele[j] ] = HElecost[j] - '0'; X break; X } /* switch */ X } /* for */ X X for(x=0;x<MAPX;x++) for(y=0;y<MAPY;y++){ X sptr = &sct[x][y]; X X if(sptr->altitude==WATER) { X movecost[x][y] = -4; X for(i=x-1;i<=x+1;i++) for(j=y-1;j<=y+1;j++) X if( ONMAP(i,j) ) X if( sct[i][j].altitude != WATER) { X movecost[x][y] = -1; X i=x+2; X j=y+2; X } X } else { X if( veg_cost[ sptr->vegetation ] == -1 X || ele_cost[ sptr->altitude ] == -1 ) X movecost[x][y] = -2; X else X movecost[x][y] = veg_cost[ sptr->vegetation ] + ele_cost[ sptr->altitude ]; X } /* if */ X if (sptr->designation == DROAD) X movecost[x][y] = (movecost[x][y] + 1) / 2; X } /* for */ X} /* updmove() */ X X#ifdef CONQUER X/* calculations for cost of movement during flight */ Xint Xflightcost(i,j) Xint i,j; X{ X int cnt,hold=(-1),hold2=(-1); X X for (cnt=0; ele[cnt]!='0'; cnt++ ) { X if (sct[i][j].altitude==ele[cnt]) X hold = (FElecost[cnt] - '0'); X } X for (cnt=0; veg[cnt]!='0'; cnt++ ) { X if (sct[i][j].vegetation==veg[cnt]) X hold2 = (FVegcost[cnt] - '0'); X } X if (hold==(-1) || hold2==(-1)) { X hold=(-1); X } X else hold+=hold2; X X return(hold); X} X#endif CONQUER X#ifdef ADMIN X/* determines whether or not a unit has the ability to fly */ Xint Xavian(typ) Xunsigned char typ; X{ X switch(typ) { X case A_ROC: X case A_GRIFFON: X case SPIRIT: X case DJINNI: X case DEMON: X case DRAGON: X return(TRUE); X default: X return(FALSE); X } X} X#endif ADMIN X Xvoid Xspreadsheet(nation) Xint nation; X{ X register struct s_sector *sptr; X register struct s_nation *nptr; X long product; X long city_pop, cap_pop; X int x,y,i,j,foundmill; X X nptr = &ntn[ nation ]; X X spread.revothr = spread.revfood = spread.revjewels = spread.revmetal = spread.revcap = spread.revcity = 0L; X spread.inothr = spread.incity = spread.incap = spread.ingold = spread.infarm = spread.inmetal = 0; X spread.food = nptr->tfood; X spread.gold = nptr->tgold; X spread.metal = nptr->metals; X spread.jewels = nptr->jewels; X spread.sectors = 0; X spread.civilians = 0L; X X for(x=0;x<MAPX;x++) for(y=0;y<MAPY;y++) { X sptr = &sct[x][y]; X if(sptr->owner!=nation) continue; X X /*update nation file for owner*/ X spread.sectors++; X spread.civilians += sptr->people; X X product = 0; X /*PRODUCE*/ X /*increase tmin based on mined stuff...*/ X if(sptr->designation==DMINE) { X if( !tg_ok( nation, sptr )) continue; X spread.inmetal += sptr->people; X if(sptr->people>TOMANYPEOPLE) { X product = sptr->metal * TOMANYPEOPLE; X product += sptr->metal * (sptr->people-TOMANYPEOPLE)/2L; X } else product = sptr->metal * sptr->people; X X if(magic(sptr->owner,MINER)==1) product*=2L; X if(magic(sptr->owner,STEEL)==1) product*=2L; X spread.metal += product; X spread.revmetal += product*TAXMETAL*nptr->tax_rate/100L; X } X /*harvest food*/ X else if(sptr->designation==DFARM) { X spread.infarm += sptr->people; X if(sptr->people>TOMANYPEOPLE) { X product = (long)tofood(sptr,sptr->owner) * TOMANYPEOPLE; X product += (long)tofood(sptr,sptr->owner) * (sptr->people-TOMANYPEOPLE)/2L; X } else product = (long)tofood(sptr,sptr->owner) * sptr->people; X X switch(SEASON(TURN)) { X case SPRING: X product/=2; X break; X case SUMMER: X break; X case FALL: X product*=5; X product/=2; X break; X case WINTER: X product=0; X break; X } X /* search for neighboring mills */ X foundmill=FALSE; X for(i=x-1;foundmill==FALSE && i<=x+1;i++) X for(j=y-1;foundmill==FALSE && j<=y+1;j++) X if((ONMAP(i,j)) X &&(sct[i][j].owner==sptr->owner) X &&(sct[i][j].designation==DMILL) X &&(sct[i][j].people>=MILLSIZE)) { X product *= 12L; X product /= 10L; X /* must break this way... two for() loops */ X foundmill=TRUE; X } X spread.food += product; X spread.revfood += product*TAXFOOD*nptr->tax_rate/100L; X } X /*gold mines produce gold*/ X else if(sptr->designation==DGOLDMINE) { X if( !tg_ok( nation, sptr )) continue; X spread.ingold += sptr->people; X if(sptr->people>TOMANYPEOPLE) { X product = sptr->jewels * TOMANYPEOPLE; X product += sptr->jewels * (sptr->people-TOMANYPEOPLE)/2L; X } else product = sptr->jewels * sptr->people; X X if(magic(sptr->owner,MINER)==1) product*=2; X X spread.jewels += product; X spread.revjewels += product*TAXGOLD*nptr->tax_rate/100L; X } X else if((sptr->designation==DCITY) X ||(sptr->designation==DCAPITOL)) { X cap_pop = sptr->people; X spread.incap += cap_pop; X X if( magic(sptr->owner, ARCHITECT ) ) { X cap_pop *= 2L; X } X X spread.revcap += cap_pop * TAXCITY*nptr->tax_rate / 100L; X } else if(sptr->designation==DTOWN) { X spread.incity += sptr->people; X city_pop = sptr->people; X if( magic(sptr->owner, ARCHITECT ) ) X city_pop *= 2L; X X spread.revcity += city_pop*TAXTOWN*nptr->tax_rate/100L; X } X#ifndef DERVDESG X else if(((magic(sptr->owner,DERVISH)==1) X ||(magic(sptr->owner,DESTROYER)==1)) X &&((sptr->vegetation==ICE) ||(sptr->vegetation==DESERT)) X &&(sptr->people>0)) { X if(sptr->people>TOMANYPEOPLE) { X product = 6L * TOMANYPEOPLE; X product += 3L * (sptr->people-TOMANYPEOPLE); X } else product = 6L * sptr->people; X X spread.food += product; X /* desert food production mostly static */ X if (sptr->vegetation==DESERT) { X /* harsh summer in desert; good winter */ X if (SEASON(TURN)==SUMMER) product/=2; X else if (SEASON(TURN)==WINTER) { X product*=5; X product/=4; X } X } else { X /* opposite in ice */ X if (SEASON(TURN)==WINTER) product/=2; X else if (SEASON(TURN)==SUMMER) { X product*=5; X product/=4; X } X } X spread.revfood += product*TAXFOOD*nptr->tax_rate/100L; X } X#endif DERVDESG X else { /* other sectors */ X spread.inothr += sptr->people; X if(sptr->people>TOMANYPEOPLE) { X product = (long)tofood(sptr,sptr->owner) * TOMANYPEOPLE; X product += (long)tofood(sptr,sptr->owner) * (sptr->people-TOMANYPEOPLE)/2L; X } else product = (long)tofood(sptr,sptr->owner) * sptr->people; X X spread.revothr += product*TAXOTHR*nptr->tax_rate/100L; X } X } X spread.gold += spread.revfood + spread.revjewels + spread.revmetal + spread.revcity + spread.revcap + spread.revothr; X} X X#ifdef CONQUER X X/* string inputing routine to allow deleting */ Xvoid Xget_nname(str) Xchar str[]; X{ X char ch; X int done=0,count=0,xpos,ypos; X X while(!done) { X ch=getch(); X if (isprint(ch)) { X if (count<NAMELTH+1) { X /* only input displayable characters */ X addch(ch); X refresh(); X str[count++] = ch; X } X } X else if ((ch=='\b' || ch=='\177')&&(count)) X { X /* only delete what was printed */ X getyx(stdscr,ypos,xpos); X move(ypos,--xpos); X addch(' '); X move(ypos,xpos); X refresh(); X count--; X } else if((ch=='\n')||(ch=='\r')) { X done=TRUE; X } X } X str[count] = '\0'; X} X X/* routine to find a nation number using name or number */ X/* returns NTOTAL+1 if input is invalid; -1 for no input */ Xint Xget_country() X{ X char name[NAMELTH+1],ch; X int i,l,hold; X X /* get name and check through list */ X get_nname(name); X X /* return on no entry */ X if ((l=strlen(name))==0) { X return(-1); X } X X for(hold=0;hold<NTOTAL;hold++) X if(strcmp(ntn[hold].name,name)==0) break; X X /* check for 'god' */ X if (strcmp("god",name)==0) hold=0; X if (strcmp("news",name)==0) hold= -2; X X /* check for numbers if name too long */ X if (hold==NTOTAL) { X hold=0; X for (i=0;i<l;i++) { X ch=name[i]; X if(ch < '0' || ch > '9' ) { X getyx(stdscr,i,l); X mvprintw(i+1,0,"Invalid Nation <%s> -- hit any key",name); X clrtoeol(); X refresh(); X getch(); X return(NTOTAL); X } else { X hold *= 10; X hold += (ch-'0'); X } X } X if (hold>NTOTAL) hold=NTOTAL; X } X /* send back result */ X return(hold); X} X Xextern short country; X/* finds a nation for god to be, returns 1 on failure */ Xint Xget_god() X{ X clear(); X mvaddstr(0,0,"SUPER USER; FOR WHAT NATION: "); X refresh(); X X /* return on no entry or bad entry */ X if ((country=get_country())==(-1) || country==NTOTAL) { X country = 0; X return(1); X } X X curntn = &ntn[country]; X return(0); X} X X/* quick routine to reassign god and gods nations */ Xvoid Xreset_god() X{ X /* simple routine; but improves readibility */ X country=0; X curntn= &ntn[country]; X} X#endif CONQUER X X#ifdef ADMIN Xint Xgetleader(class) Xint class; X{ X switch(class){ X case C_NPC: X case C_KING: X case C_TRADER: return(L_BARON); X case C_EMPEROR: return(L_PRINCE); X case C_WIZARD: return(L_MAGI); X case C_PRIEST: return(L_BISHOP); X case C_PIRATE: return(L_CAPTAIN); X case C_WARLORD: return(L_LORD); X case C_DEMON: return(L_DEVIL); X case C_DRAGON: return(L_WYRM); X case C_SHADOW: return(L_NAZGUL); X default: X printf("ERROR-national class (%d) undefined\n",class); X exit(0); X } X return(-1); /* shut lint up */ X} X#endif ADMIN X Xvoid Xmailopen(to) X{ X char line[20]; X if(mailok == TRUE) mailclose(); X X if (to != -2) X sprintf(line,"%s%d",msgfile,to); X else X sprintf(line,"news%d",TURN -1); /* -1 so it appears in X the news now */ X if ((fm=fopen(line,"a+"))==NULL) { X printf("error opening %s",line); X return; X } X mailok=TRUE; X} X Xvoid Xmailclose() X{ X if(mailok==FALSE) return; X X fputs("END\n",fm); X fclose(fm); X mailok=FALSE; X} X X#ifdef ADMIN X/* markok returns TRUE if mark is ok as a nation mark */ Xint Xmarkok(mark,prtflag) Xchar mark; Xint prtflag; /* if true printf reason */ X{ X register int i; X X if((isprint(mark)==0)||(isspace(mark)!=0)) { X if(prtflag) printf("%c is white space\n",mark); X return(FALSE); X } X X for(i=0;ele[i]!='0';i++) if(mark==(*(ele+i))) { X if(prtflag) printf("%c is elevation character\n",mark); X return(FALSE); X } X X for(i=0;veg[i]!='0';i++) if(mark==(*(veg+i))) { X if(prtflag) printf("%c is vegetition character\n",mark); X return(FALSE); X } X X for(i=1;i<NTOTAL;i++) if(ntn[i].mark==mark) { X if(prtflag) printf("%c is already used\n",mark); X return(FALSE); X } X X if(mark=='*') { X if(prtflag) printf("%c is *\n",mark); X return(FALSE); X } X X if(!isalpha(mark)) { X if(prtflag) printf("%c is not an alpha character\n",mark); X return(FALSE); X } X return(TRUE); X} X#endif ADMIN X X/*******************************************************************/ X/* DEFAULTUNIT() returns the default army type for a given country */ X/* this is mostly used by npc's to take advantage of their powers */ X/*******************************************************************/ Xlong Xdefaultunit( nation ) Xint nation; X{ X if(magic(nation,VAMPIRE)) return(A_ZOMBIE); X if(magic(nation,AV_MONST)) { X if(magic(nation,BREEDER)) X return(A_OLOG); X else return(A_URUK); X } X if(magic(nation,ARCHER)) return(A_ARCHER); X if(magic(nation,MI_MONST)) return(A_ORC); /* if race = orc */ X if( ntn[nation].active==NPC_NOMAD ) return(A_LT_CAV); X return(A_INFANTRY); X} X X#ifdef ADMIN Xvoid Xgetmetal( sptr ) Xstruct s_sector *sptr; X{ X int randval; X randval = rand()%100; X if((sptr->tradegood != TG_none)&&(sptr->tradegood != 0)) return; X if( randval < 20 ) { X sptr->tradegood = TG_copper; X sptr->metal = rand()%2 + 1; X } else if( randval < 30 ) { X sptr->tradegood = TG_lead; X sptr->metal = rand()%4 + 1; X } else if( randval < 40 ) { X sptr->tradegood = TG_tin; X sptr->metal = rand()%4 + 2; X } else if( randval < 55 ) { X sptr->tradegood = TG_bronze; X sptr->metal = rand()%4 + 2; X } else if( randval < 80 ) { X sptr->tradegood = TG_iron; X sptr->metal = rand()%7 + 2; X } else if( randval < 95 ) { X sptr->tradegood = TG_steel; X sptr->metal = rand()%8 + 3; X } else if( randval < 99 ) { X sptr->tradegood = TG_mithral; X sptr->metal = rand()%11 + 5; X } else { X sptr->tradegood = TG_adamantine; X sptr->metal = rand()%13 + 8; X } X} X Xvoid Xgetjewel( sptr ) Xstruct s_sector *sptr; X{ X int randval; X if((sptr->tradegood != TG_none)&&(sptr->tradegood != 0)) return; X randval = rand()%100; X if( randval < 20 ) { X sptr->tradegood = TG_spice; X sptr->jewels = rand()%2 + 1; X } else if( randval < 40 ) { X sptr->tradegood = TG_silver; X sptr->jewels = rand()%3 + 1; X } else if( randval < 48 ) { X sptr->tradegood = TG_pearls; X sptr->jewels = rand()%3 + 1; X } else if( randval < 56 ) { X sptr->tradegood = TG_dye; X sptr->jewels = rand()%5 + 1; X } else if( randval < 64 ) { X sptr->tradegood = TG_silk; X sptr->jewels = rand()%5 + 1; X } else if( randval < 84 ) { X sptr->tradegood = TG_gold; X sptr->jewels = rand()%6 + 1; X } else if( randval < 91 ) { X sptr->tradegood = TG_rubys; X sptr->jewels = rand()%6 + 1; X } else if( randval < 96 ) { X sptr->tradegood = TG_ivory; X sptr->jewels = rand()%7 + 2; X } else if( randval < 99 ) { X sptr->tradegood = TG_diamonds; X sptr->jewels = rand()%11 + 2; X } else { X sptr->tradegood = TG_platinum; X sptr->jewels = rand()%17 + 4; X } X} X#endif ADMIN X X/* tg_ok returns true if a trade good can be seen by the owner of sector */ Xint Xtg_ok( nation, sptr ) Xint nation; Xstruct s_sector *sptr; X{ X if(( nation == 0)||(nation>=NTOTAL)) return(TRUE); X X switch( sptr->tradegood ) { X case TG_lead: if(ntn[nation].mine_ability < 8) return(0); break; X case TG_tin: if(ntn[nation].mine_ability < 11) return(0); break; X case TG_bronze: if(ntn[nation].mine_ability < 15) return(0); break; X case TG_iron: if(ntn[nation].mine_ability < 25) return(0); break; X case TG_steel: if(ntn[nation].mine_ability < 30) return(0); break; X case TG_mithral: if(ntn[nation].mine_ability < 30) return(0); break; X case TG_adamantine: if(ntn[nation].mine_ability < 40) return(0); break; X case TG_spice: X case TG_silver: X case TG_pearls: break; X case TG_dye: X case TG_silk: X case TG_gold: if(ntn[nation].wealth < 5) return(0); break; X case TG_rubys: X case TG_ivory: if(ntn[nation].wealth < 10) return(0); break; X case TG_diamonds: X case TG_platinum: if(ntn[nation].wealth < 20) return(0); break; X default: break; X }; X X if(tofood(sptr,nation) >= DESFOOD) return(TRUE); X return(FALSE); X} X X/* this routine computes the fortification value of a sector */ Xint Xfort_val(sptr) X struct s_sector *sptr; X{ X if(sptr->designation==DSTOCKADE) { X return(DEF_BASE); X } X if(sptr->designation==DFORT){ X if(magic(sptr->owner,ARCHITECT)==1){ X return(DEF_BASE + 2*FORTSTR * sptr->fortress); X } X else return(DEF_BASE + FORTSTR * sptr->fortress); X } X if (sptr->designation==DTOWN){ X if(magic(sptr->owner,ARCHITECT)==1){ X return(DEF_BASE + 2*TOWNSTR * sptr->fortress); X } else return(DEF_BASE + TOWNSTR * sptr->fortress); X } X if((sptr->designation==DCAPITOL) X ||(sptr->designation==DCITY)){ X if(magic(sptr->owner,ARCHITECT)==1){ X return(2*DEF_BASE + 2*CITYSTR * sptr->fortress); X } X else return(2*DEF_BASE + CITYSTR * sptr->fortress); X } X return(0); X} X X/* routine to determine compass direction of x1,y1 from x0,y0 */ Xint Xcompass(x0,y0,x1,y1) X int x0,y0,x1,y1; X{ X int dx=x1-x0, dy=y1-y0; /* diplacements */ X int hold; X X if(10*abs(dx) > abs(dy)) { X if(10*abs(dy) > abs(dx)) { X /* four off-quadrants */ X if(dx>0) { X if(dy<0) hold=NORTHEAST; X else hold=SOUTHEAST; X } else { X if(dy<0) hold=NORTHWEST; X else hold=SOUTHWEST; X } X } else { X /* east or west */ X if(dx>0) hold=EAST; X else hold=WEST; X } X } else { X /* north or south or same point */ X if(dy==0) hold=CENTERED; X else if(dy<0) hold=NORTH; X else hold=SOUTH; X } X return(hold); X} X X#ifdef CONQUER X#include <sys/types.h> X#include <sys/stat.h> Xextern short xcurs; Xextern short ycurs; Xoff_t conq_mail_size=0; X#ifdef SYSMAIL Xstatic off_t sys_mail_size=0; X#endif SYSMAIL Xvoid Xcheck_mail() X{ X struct stat info; X#ifdef SYSMAIL X int osys_mail=sys_mail_status; X#endif X int oconq_mail=conq_mail_status; X X /* check conquer mail box */ X if (stat(conqmail,&info)==(-1)) { X conq_mail_status=NO_MAIL; X conq_mail_size=0; X } else { X if (info.st_size > conq_mail_size) { X conq_mail_status=NEW_MAIL; X conq_mail_size=info.st_size; X } else if (info.st_size < conq_mail_size) { X conq_mail_status=NO_MAIL; X conq_mail_size=info.st_size; X } X } X X#ifdef SYSMAIL X /* check system mail box */ X if (stat(sysmail,&info)==(-1)) { X sys_mail_status=NO_MAIL; X sys_mail_size=0; X } else { X if(info.st_atime>info.st_mtime) { X sys_mail_status=NO_MAIL; X sys_mail_size=info.st_size; X } else if (info.st_size > sys_mail_size) { X sys_mail_status=NEW_MAIL; X sys_mail_size=info.st_size; X } else if (info.st_size < sys_mail_size) { X sys_mail_status=NO_MAIL; X sys_mail_size=info.st_size; X } X } X X /* display mail information */ X if(sys_mail_status!=osys_mail) { X if (sys_mail_status==NEW_MAIL) { X mvaddstr(LINES-3,COLS/2-6,"You have System Mail"); X } else { X mvaddstr(LINES-3,COLS/2-6," "); X } X move(ycurs,2*xcurs); X refresh(); X } X if (conq_mail_status!=oconq_mail) { X if (conq_mail_status==NEW_MAIL) { X mvaddstr(LINES-2,COLS/2-6,"You have Conquer Mail"); X } else { X mvaddstr(LINES-2,COLS/2-6," "); X } X move(ycurs,2*xcurs); X refresh(); X } X#else X /* display mail information */ X if (conq_mail_status!=oconq_mail) { X if (conq_mail_status==NEW_MAIL) { X mvaddstr(LINES-3,COLS/2-6,"You have Conquer Mail"); X } else { X mvaddstr(LINES-3,COLS/2-6," "); X } X move(ycurs,2*xcurs); X refresh(); X } X#endif SYSMAIL X} X#endif CONQUER END_OF_FILE if test 42709 -ne `wc -c <'misc.c'`; then echo shar: \"'misc.c'\" unpacked with wrong size! fi # end of 'misc.c' fi if test -f 'navy.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'navy.c'\" else echo shar: Extracting \"'navy.c'\" \(10446 characters\) sed "s/^X//" >'navy.c' <<'END_OF_FILE' X/* conquer : Copyright (c) 1988 by Ed Barlow. */ X/* this code was initially written in January, 1989 by Adam Bryant */ X X#include "header.h" X#include "data.h" X X/* increase fleet by nships of given type */ Xint Xaddwships (nvynum, shipsize, nships) X short nvynum, shipsize, nships; X{ X short hold=nships; X X /* return FALSE if fails, TRUE otherwise */ X X /* check for valid input */ X if (nvynum<0 || nvynum>=MAXNAVY || X shipsize<N_LIGHT || shipsize>N_HEAVY) X return(FALSE); X X hold += P_NWAR(shipsize); X if (hold > N_MASK) { X return(FALSE); X } X X /* place new value in proper place */ X hold <<= (N_BITSIZE*shipsize); X X /* set it in variable */ X P_NWSHP |= hold; X X /* form mask so other values won't be changed */ X hold |= ~(N_MASK<<(N_BITSIZE*shipsize)); X X /* now change the variable */ X P_NWSHP &= hold; X return(TRUE); X} X Xint Xaddmships (nvynum, shipsize, nships) X short nvynum, shipsize, nships; X{ X short hold=nships; X X /* return FALSE if fails, TRUE otherwise */ X X /* check for valid input */ X if (nvynum<0 || nvynum>=MAXNAVY || X shipsize<N_LIGHT || shipsize>N_HEAVY) X return(FALSE); X X hold += P_NMER(shipsize); X if (hold > N_MASK) { X return(FALSE); X } X X /* place new value in proper place */ X hold <<= (N_BITSIZE*shipsize); X X /* set it in variable */ X P_NMSHP |= hold; X X /* form mask so other values won't be changed */ X hold |= ~(N_MASK<<(N_BITSIZE*shipsize)); X X /* now change the variable */ X P_NMSHP &= hold; X return(TRUE); X} X Xint Xaddgships (nvynum, shipsize, nships) X short nvynum, shipsize, nships; X{ X short hold=nships; X X /* return FALSE if fails, TRUE otherwise */ X X /* check for valid input */ X if (nvynum<0 || nvynum>=MAXNAVY || X shipsize<N_LIGHT || shipsize>N_HEAVY) X return(FALSE); X X hold += P_NGAL(shipsize); X if (hold > N_MASK) { X return(FALSE); X } X X /* place new value in proper place */ X hold <<= (N_BITSIZE*shipsize); X X /* set it in variable */ X P_NGSHP |= hold; X X /* form mask so other values won't be changed */ X hold |= ~(N_MASK<<(N_BITSIZE*shipsize)); X X /* now change the variable */ X P_NGSHP &= hold; X return(TRUE); X} X X/* remove nships of given shipsize for a given fleet */ Xvoid Xsubwships (nvynum, shipsize, nships) X short nvynum, shipsize, nships; X{ X short hold; X X /* return FALSE if fails, TRUE otherwise */ X X /* check for valid input */ X if (nvynum<0 || nvynum>=MAXNAVY || X shipsize<N_LIGHT || shipsize>N_HEAVY) X return; X X hold = P_NWAR(shipsize) - nships; X if (hold < 0) { X return; X } X X /* place new value in proper place */ X hold <<= (N_BITSIZE*shipsize); X X /* set it in variable */ X P_NWSHP |= hold; X X /* form mask so other values won't be changed */ X hold |= ~(N_MASK<<(N_BITSIZE*shipsize)); X X /* now change the variable */ X P_NWSHP &= hold; X} X Xvoid Xsubmships (nvynum, shipsize, nships) X short nvynum, shipsize, nships; X{ X short hold; X X /* return FALSE if fails, TRUE otherwise */ X X /* check for valid input */ X if (nvynum<0 || nvynum>=MAXNAVY || X shipsize<N_LIGHT || shipsize>N_HEAVY) X return; X X hold = P_NMER(shipsize) - nships; X if (hold < 0) { X return; X } X /* place new value in proper place */ X hold <<= (N_BITSIZE*shipsize); X X /* set it in variable */ X P_NMSHP |= hold; X X /* form mask so other values won't be changed */ X hold |= ~(N_MASK<<(N_BITSIZE*shipsize)); X X /* now change the variable */ X P_NMSHP &= hold; X} X Xvoid Xsubgships (nvynum, shipsize, nships) X short nvynum, shipsize, nships; X{ X short hold; X X /* return FALSE if fails, TRUE otherwise */ X X /* check for valid input */ X if (nvynum<0 || nvynum>=MAXNAVY || X shipsize<N_LIGHT || shipsize>N_HEAVY) X return; X X hold = P_NGAL(shipsize) - nships; X if (hold < 0) { X return; X } X /* place new value in proper place */ X hold <<= (N_BITSIZE*shipsize); X X /* set it in variable */ X P_NGSHP |= hold; X X /* form mask so other values won't be changed */ X hold |= ~(N_MASK<<(N_BITSIZE*shipsize)); X X /* now change the variable */ X P_NGSHP &= hold; X return; X} X X/* this function finds the total number of ships in a given fleet */ Xint Xfltships(country,nvynum) X int country, nvynum; X{ X struct s_nation *savntn=curntn; X int i, hold=0; X X curntn= &ntn[country]; X for(i=N_LIGHT;i<=N_HEAVY;i++) { X hold += (int) P_NWAR(i); X hold += (int) P_NMER(i); X hold += (int) P_NGAL(i); X } X curntn= savntn; X return(hold); X} X X#ifdef ADMIN X/* this function returns the speed of a given fleet */ X/* which is the speed of the slowest member. */ Xunsigned short Xfltspeed(nvynum) X int nvynum; X{ X int i,hold=99; X X /* light ships faster than heavy ships */ X for (i=N_LIGHT;i<=N_HEAVY && hold>N_WSPD;i++) X if (P_NWAR(i)>0) hold=N_WSPD+(2-i)*N_SIZESPD; X X for (i=N_LIGHT;i<=N_HEAVY && hold>N_MSPD;i++) X if (P_NMER(i)>0) hold=N_MSPD+(2-i)*N_SIZESPD; X X for (i=N_LIGHT;i<=N_HEAVY && hold>N_GSPD;i++) X if (P_NGAL(i)>0) hold=N_GSPD+(2-i)*N_SIZESPD; X X if (hold==99) hold=N_NOSPD; X return(hold); X} X#endif ADMIN X X/* this function returns the amount of storage space in a */ X/* given fleet. heavy+=3 medium+=2 light+=1. */ Xint Xflthold(nvynum) X int nvynum; X{ X int i,hold=0; X X /* light ships faster than heavy ships */ X for (i=N_LIGHT;i<=N_HEAVY;i++) X { X hold += (i+1) * (int)P_NWAR(i); X hold += (i+1) * (int)P_NMER(i); X hold += (i+1) * (int)P_NGAL(i); X } X return(hold); X} X X#ifdef ADMIN X/* this function returns the amount of storage space in warships */ Xint Xfltwhold(nvynum) X int nvynum; X{ X int i,hold=0; X X for (i=N_LIGHT;i<=N_HEAVY;i++) X { X hold += (i+1) * (int)P_NWAR(i); X } X return(hold); X} X#endif ADMIN X X/* this function returns the amount of storage space in galleys */ Xint Xfltghold(nvynum) X int nvynum; X{ X int i,hold=0; X X for (i=N_LIGHT;i<=N_HEAVY;i++) X { X hold += (i+1) * (int)P_NGAL(i); X } X return(hold); X} X X/* this function returns the amount of storage space in merchants */ Xint Xfltmhold(nvynum) X int nvynum; X{ X int i,hold=0; X X for (i=N_LIGHT;i<=N_HEAVY;i++) X { X hold += (i+1) * (int)P_NMER(i); X } X return(hold); X} X X#ifdef CONQUER Xextern short country; Xextern short selector, pager; Xextern short xcurs, ycurs, xoffset, yoffset; Xextern FILE *fexe; X X/* function to ask for cargo choice */ Xstatic int Xget_cargo(str) X char *str; X{ X int choice=(-1); X X mvprintw(LINES-3,0,"%s (A)rmy or (P)eople?",str); X clrtoeol(); X refresh(); X switch(getch()) { X case 'a': X case 'A': X choice=TRUE; X break; X case 'p': X case 'P': X choice=FALSE; X break; X default: X break; X } X X return(choice); X} X X/* this function returns false if loading is invalid */ Xint Xloadstat(status) X int status; X{ X switch(status) { X case TRADED: X case GENERAL: X case MILITIA: X case GARRISON: X case ONBOARD: X return(FALSE); X break; X default: X break; X } X return(TRUE); X} X X/* this function loads a fleet with an item */ Xvoid Xloadfleet() X{ X short nvynum; X /* merchant holding unused */ X int ghold, mhold, unload, doarmy; X int gcargo, mcargo, amount, armynum; X X clear_bottom(0); X if((nvynum=getselunit()-MAXARM)>=0){ X if(nvynum>=MAXNAVY){ X errormsg("Invalid Navy"); X return; X } X } else { X errormsg("Invalid Navy"); X return; X } X X if(sct[XREAL][YREAL].altitude==WATER) { X errormsg("Fleet must be landed"); X return; X } X X /* process loading or unloading */ X ghold = fltghold(nvynum); X mhold = fltmhold(nvynum); X if((ghold==0)&&(mhold == 0)) { X errormsg("No storage space available"); X return; X } else if((P_NARMY==MAXARM)&&(P_NPEOP==0)) { X unload=FALSE; X } else { X mvprintw(LINES-4,0,"Cargo: People %d",P_NPEOP*mhold); X if(P_NARMY==MAXARM) mvaddstr(LINES-4,25,"Army (none)"); X else mvprintw(LINES-4,25,"Army (%d)",P_NARMY); X mvaddstr(LINES-3,0,"Do you wish to (L)oad or (U)nload?"); X refresh(); X switch(getch()) { X case 'l': X case 'L': X unload=FALSE; X break; X case 'u': X case 'U': X unload=TRUE; X break; X default: X return; X } X } X X if(unload==TRUE) { X if(P_NARMY==MAXARM) doarmy=FALSE; X else if(P_NPEOP==0) doarmy=TRUE; X else { X doarmy=get_cargo("Unload"); X } X if(doarmy==TRUE) { X armynum=P_NARMY; X if(sct[XREAL][YREAL].owner==0 X && P_ATYPE!=A_MARINES X && P_ATYPE!=A_SAILOR) { X errormsg("Only sailors or marines may disembark in unowned land"); X return; X } else if (sct[XREAL][YREAL].owner!=country X && sct[XREAL][YREAL].owner!=0 X && P_ATYPE!=A_MARINES) { X errormsg("Only marines may disembark in someone else's land"); X return; X } X P_ASTAT=DEFEND; X P_NARMY=MAXARM; X P_NMOVE=0; X NADJMOV; X NADJHLD; X AADJSTAT; X } else if(doarmy==FALSE){ X if (sct[XREAL][YREAL].owner!=country) { X mvaddstr(LINES-3,0,"Unload in a sector you don't own? (y or n)"); X clrtoeol(); X refresh(); X if (getch()!='y') { X return; X } X } X mvaddstr(LINES-2,0,"Unload how many people?"); X refresh(); X amount=get_number(); X if(amount > mhold*P_NPEOP) { X errormsg("There are not that many on board"); X } else { X sct[XREAL][YREAL].people += amount; X P_NPEOP=(unsigned char)((mhold*P_NPEOP-amount)/mhold); X NADJHLD; X P_NMOVE=0; X NADJMOV; X SADJCIV; X } X } X } else { X clear_bottom(0); X mcargo = mhold*(SHIPHOLD-P_NPEOP); X if(P_NARMY==MAXARM) { X gcargo = ghold*SHIPHOLD; X mvprintw(LINES-4,0,"Available Space: %d soldiers %d people", gcargo, mcargo); X } else { X gcargo = 0; X mvprintw(LINES-4,0,"Available Space: 0 soldiers %d people", mcargo); X } X if(gcargo==0) doarmy=FALSE; X else if(mcargo==0) doarmy=TRUE; X else { X doarmy=get_cargo("Load"); X } X if(doarmy==TRUE) { X mvaddstr(LINES-2,0,"Load what army?"); X refresh(); X armynum = get_number(); X if((armynum<0)||(armynum>=MAXARM)||(P_ASOLD<=0) X ||(loadstat(P_ASTAT)==FALSE)) { X errormsg("Invalid Army"); X } else if((P_AXLOC!=XREAL)||(P_AYLOC!=YREAL)) { X errormsg("Army not in sector"); X } else if(P_ASOLD > gcargo && X (P_ATYPE<MINLEADER || P_ATYPE>=MINMONSTER)) { X errormsg("Army too large for fleet"); X } else { X P_ASTAT=ONBOARD; X P_AMOVE=0; X P_NARMY=armynum; X P_NMOVE=0; X NADJMOV; X NADJHLD; X AADJMOV; X AADJSTAT; X } X } else if(doarmy==FALSE && mcargo!=0){ X mvaddstr(LINES-2,0,"Load how many people?"); X refresh(); X amount=get_number(); X if(sct[XREAL][YREAL].owner!=country) { X errormsg("The people refuse to board"); X } else if(amount > mcargo) { X errormsg("Not enough room on fleet"); X } else if(sct[XREAL][YREAL].people < amount) { X errormsg("Not enough people in sector"); X } else { X sct[XREAL][YREAL].people -= amount; X P_NPEOP += (unsigned char)(amount / mhold); X SADJCIV; X P_NMOVE=0; X NADJMOV; X NADJHLD; X } X } else if (mcargo==0) { X errormsg("No more room onboard fleet"); X } X } X} X#endif CONQUER END_OF_FILE if test 10446 -ne `wc -c <'navy.c'`; then echo shar: \"'navy.c'\" unpacked with wrong size! fi # end of 'navy.c' fi echo shar: End of archive 3 \(of 14\). cp /dev/null ark3isdone 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