home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume6 / conquer4 / part03 / misc.c next >
C/C++ Source or Header  |  1989-07-06  |  43KB  |  1,783 lines

  1. /* Conquer: Copyright (c) 1988 by Edward M Barlow */
  2. #include    <ctype.h>
  3. #include    <stdio.h>
  4. #include    "header.h"
  5. #include    "data.h"
  6.  
  7. extern FILE *fnews;
  8.  
  9. extern char *HVegcost, *OVegcost, *EVegcost, *DVegcost, *FVegcost;
  10. extern char *HElecost, *OElecost, *EElecost, *DElecost, *FElecost;
  11.  
  12. #ifdef SYSV
  13. char    *memset();
  14. #endif
  15.  
  16. #ifdef CONQUER
  17. int
  18. move_file( from, to )
  19. register char    *from;
  20. register char    *to;
  21. {
  22.     if( unlink( to ) < 0 ) {
  23.         fprintf( stderr, "unlink( %s ) failed \n", to );
  24.         sleep( 2 );
  25.         return( -1 );
  26.     }
  27.  
  28.     if( link( from, to ) < 0 ) {
  29.         fprintf( stderr, "link( %s, %s ) failed \n", from, to );
  30.         sleep( 2 );
  31.         return( -1 );
  32.     }
  33.  
  34.     if( unlink( from ) < 0 ) {
  35.         fprintf( stderr, "unlink( %s ) failed \n", from );
  36.         sleep( 2 );
  37.         return( -1 );
  38.     }
  39.  
  40.     return( 0 );
  41. } /* move_file() */
  42. #endif CONQUER
  43.  
  44. #ifdef CONQUER
  45. long
  46. get_number()
  47. {
  48.     long sum=0;
  49.     char ch;
  50.     int done=FALSE,count=0,xpos,ypos;
  51.     /* this routine totally redone to allow deleting */
  52.     while(!done) {
  53.         ch=getch();
  54.         if(isdigit(ch)) {
  55.             /* only print numbers to the screen */
  56.             addch(ch);
  57.             refresh();
  58.             sum *= 10L;
  59.             count++;
  60.             sum += (long)(ch-'0');
  61.         } else if ((ch=='\b' || ch=='\177')&&(count)) {
  62.             /* only delete what was printed */
  63.             getyx(stdscr,ypos,xpos);
  64.             move(ypos,--xpos);
  65.             addch(' ');
  66.             move(ypos,xpos);
  67.             refresh();
  68.             sum /= 10L;
  69.             count--;
  70.         } else if((ch=='\n')||(ch=='\r')) {
  71.             done=TRUE;
  72.         }
  73.         if( count >= 12 ) done=TRUE;
  74.     }
  75.     return( sum );
  76. }
  77. #endif CONQUER
  78.  
  79. #define INFINITE    1000
  80.  
  81. int        bx;        /* destination 'x' coordinate */
  82. int        by;        /* destination 'y' coordinate */
  83. int        moving_country;    /* country that is moving */
  84.  
  85. #define MAX_MOVE_UNITS    0x7f
  86. unsigned char    **history_reachp;
  87. int    level;
  88.  
  89. /*
  90.  *    land_2reachp()
  91.  */
  92.  
  93. int
  94. land_2reachp( ax, ay, move_points )
  95. int    ax;
  96. int    ay;
  97. int    move_points;
  98. {
  99.     register int    i = 0;
  100.     int    delta_x, delta_y;
  101.     int    x_abs_delta, y_abs_delta;
  102.     int    own;
  103.     int    dx[ 8 ];
  104.     int    dy[ 8 ];
  105.  
  106.     delta_x = bx - ax;
  107.     delta_y = by - ay;
  108.  
  109.     /* Have we got where we are going? */
  110.     if( delta_x == 0 && delta_y == 0 ) {
  111.         return( 1 );
  112.     }
  113.  
  114.     /* Any move points left? (optimization) */
  115.     if( move_points == 0 ) {
  116.         return( 0 );
  117.     }
  118.  
  119.     x_abs_delta = (delta_x < 0) ? -delta_x : delta_x;
  120.     y_abs_delta = (delta_y < 0) ? -delta_y : delta_y;
  121.  
  122.     /* couldn't reach if all moves cost 1 (optimization) */
  123.     if( max( x_abs_delta, y_abs_delta ) > move_points ) {
  124.         return( 0 );
  125.     }
  126.  
  127.     {
  128.         register int    inc_x;
  129.         register int    inc_y;
  130.  
  131.         inc_x = (delta_x < 0 ) ? -1 : 1;
  132.         inc_y = (delta_y < 0 ) ? -1 : 1;
  133.  
  134.         /*I HAVE CHANGED THIS CODE FROM THE ORIGINAL TO OPTIMIZE IT*/
  135.         /*I think it should work well*/
  136.         if( y_abs_delta == 0) {
  137.             /* try 'x' movements first */
  138.             dx[i] = inc_x; dy[i++] = 0;
  139.             dx[i] = inc_x; dy[i++] = inc_y;
  140.             dx[i] = inc_x; dy[i++] = -inc_y;
  141.             dx[i] = 0; dy[i++] = inc_y;
  142.             dx[i] = 0; dy[i++] = -inc_y;
  143.             dx[i] = -inc_x; dy[i++] = inc_y;
  144.             dx[i] = -inc_x; dy[i++] = 0;
  145.             dx[i] = -inc_x; dy[i++] = -inc_y;
  146.         } else if( x_abs_delta == 0 ) {
  147.             /* try 'y' movements first */
  148.             dx[i] = 0; dy[i++] = inc_y;
  149.             dx[i] = inc_x; dy[i++] = inc_y;
  150.             dx[i] = -inc_x; dy[i++] = inc_y;
  151.             dx[i] = inc_x; dy[i++] = 0;
  152.             dx[i] = -inc_x; dy[i++] = 0;
  153.             dx[i] = inc_x; dy[i++] = -inc_y;
  154.             dx[i] = 0; dy[i++] = -inc_y;
  155.             dx[i] = -inc_x; dy[i++] = -inc_y;
  156.         } else {    /* x_abs_delta != 0, 0 != y_abs_delta */
  157.             /* try diagonal movements first */
  158.             dx[i] = inc_x; dy[i++] = inc_y;
  159.  
  160.             dx[i] = 0; dy[i++] = inc_y;
  161.             dx[i] = inc_x; dy[i++] = 0;
  162.  
  163.             dx[i] = -inc_x; dy[i++] = inc_y;
  164.             dx[i] = inc_x; dy[i++] = -inc_y;
  165.  
  166.             dx[i] = -inc_x; dy[i++] = 0;
  167.             dx[i] = 0; dy[i++] = -inc_y;
  168.  
  169.             dx[i] = -inc_x; dy[i++] = -inc_y;
  170.         } /* if */
  171.     } /* block */
  172.  
  173.     {
  174.         register int    x, y;
  175.         register int    new_mp;
  176.  
  177.         for( i = 0; i < 8; i++ ) {
  178.             if( (x = ax + dx[i]) < 0 || x >= MAPX )
  179.                 continue;
  180.             if( (y = ay + dy[i]) < 0 || y >= MAPY )
  181.                 continue;
  182.  
  183.             if( sct[x][y].altitude == PEAK)
  184.                 continue;
  185.             if( sct[x][y].altitude == WATER)
  186.                 continue;
  187.  
  188.             new_mp = move_points - movecost[ x ][ y ];
  189.             if( new_mp < 0 )
  190.                 continue;
  191.  
  192.             /*
  193.             *    If we have been to this sector before
  194.             *    in fewer move points this path is not
  195.             *    going to do any better.
  196.             */
  197.             if( history_reachp[x][y] >= new_mp ) {
  198.                 continue;
  199.             }
  200.             history_reachp[x][y] = new_mp;
  201.  
  202.             /*
  203.             *    Test for a hostile army
  204.             */
  205.             /* BUG: should engage if army is hostile but does not own sector */
  206.             /* BUG: take into account THE_VOID, HIDDEN, and NINJA */
  207.             /* BUG: NEUTRAL does not allow to pass */
  208.             if( (own = sct[x][y].owner) > 0 &&
  209.             ntn[own].dstatus[moving_country] >= WAR &&
  210.             x != bx && y != by &&
  211.             solds_in_sector( x, y, own ) > 0 ) {
  212.                 continue;    /* at war with the owner, may not pass */
  213.             }
  214.  
  215.             level++;
  216.             if( land_2reachp( x, y, new_mp ) ) {
  217.                 level--;
  218.                 return( 1 );
  219.             } /* if */
  220.             level--;
  221.         } /* for */
  222.     } /* block */
  223.     return( 0 );
  224. } /* land_2reachp() */
  225.  
  226. /*
  227.  *    land_reachp()
  228.  */
  229. #ifdef ADMIN
  230. int
  231. land_reachp( ax, ay, gx, gy, move_points, movee )
  232. int    ax;
  233. int    ay;
  234. int    gx;
  235. int    gy;
  236. int    move_points;
  237. int    movee;
  238. {
  239.     int    result;
  240.  
  241.     if( move_points >= MAX_MOVE_UNITS ) {
  242.         fprintf( stderr, "land_reachp(): move_points = %d\n",
  243.             move_points );
  244.  
  245.         abrt();
  246.     }
  247.  
  248.     /* Are we starting or ending in the water or on a peak? */
  249.     if( sct[ax][ay].altitude == WATER || sct[ax][ay].altitude == PEAK )
  250.         return( 0 );
  251.     if( sct[gx][gy].altitude == WATER || sct[gx][gy].altitude == PEAK )
  252.         return( 0 );
  253.  
  254.     history_reachp = (unsigned char **) m2alloc(MAPX,MAPY,sizeof(char));
  255. #ifdef BSD
  256.     bzero((char *) *history_reachp,MAPX*MAPY);
  257. #else
  258.     memset((char *) *history_reachp, 0, MAPX*MAPY );
  259. #endif
  260.  
  261.     history_reachp[ax][ay] = move_points;
  262.  
  263.     bx = gx;
  264.     by = gy;
  265.     moving_country = movee;
  266.  
  267.     level = 1;
  268.     result = land_2reachp( ax, ay, move_points );
  269.     free(history_reachp);
  270.     return( result );
  271. } /* land_reachp() */
  272. #endif ADMIN
  273. #ifdef ADMIN
  274. /*
  275.  *    water_2reachp()
  276.  */
  277.  
  278. int
  279. water_2reachp( ax, ay, move_points )
  280. int    ax;
  281. int    ay;
  282. int    move_points;
  283. {
  284.     register int    i = 0;
  285.     int    delta_x;
  286.     int    delta_y;
  287.     int    dx[ 8 ];
  288.     int    dy[ 8 ];
  289.  
  290.     /* this path uses too many move units */
  291.     if( move_points < 0 )
  292.         return( 0 );
  293.  
  294.     /*
  295.     *    If we have been to this sector before in fewer move points
  296.     *    this path is not going to do any better.
  297.     */
  298.     if( history_reachp[ ax ][ ay ] <= move_points )
  299.         return( 0 );
  300.  
  301.     history_reachp[ ax ][ ay ] = move_points;
  302.  
  303.     delta_x = ax - bx;
  304.     delta_y = ay - by;
  305.  
  306.     /* Have we got where we are going? */
  307.     if( delta_x == 0 && delta_y == 0 )
  308.         return( 1 );
  309.  
  310.     /* Have we run into ground, but not reached our destination? */
  311.     if( sct[ax][ay].altitude != WATER )
  312.         return( 0 );
  313.  
  314.     /* Any move points left? (optimization) */
  315.     if( move_points == 0 )
  316.         return( 0 );
  317.  
  318.     /* couldn't reach if all moves cost 1 (optimization) */
  319.     if( max( abs( delta_x ), abs( delta_y ) ) > move_points )
  320.         return( 0 );
  321.  
  322.     /* BUG: test for an enemy navy */
  323.  
  324.     {
  325.         register int    inc_x;
  326.         register int    inc_y;
  327.  
  328.         inc_x = (delta_x < 0 ) ? -1 : (delta_x > 0) ? 1 : 0;
  329.         inc_y = (delta_y < 0 ) ? -1 : (delta_y > 0) ? 1 : 0;
  330.  
  331.         if( abs(delta_x) > abs(delta_y) ) {
  332.             /* try 'x' movements first */
  333.             dx[i] = inc_x; dy[i++] = 0;
  334.             dx[i] = inc_x; dy[i++] = inc_y;
  335.             dx[i] = inc_x; dy[i++] = -inc_y;
  336.             dx[i] = 0; dy[i++] = inc_y;
  337.             dx[i] = 0; dy[i++] = -inc_y;
  338.             dx[i] = -inc_x; dy[i++] = inc_y;
  339.             dx[i] = -inc_x; dy[i++] = 0;
  340.             dx[i] = -inc_x; dy[i++] = -inc_y;
  341.         } else {    /* abs(delta_x) < abs(delta_y) */
  342.             /* try 'y' movements first */
  343.             dx[i] = 0; dy[i++] = inc_y;
  344.             dx[i] = inc_x; dy[i++] = inc_y;
  345.             dx[i] = -inc_x; dy[i++] = inc_y;
  346.             dx[i] = inc_x; dy[i++] = 0;
  347.             dx[i] = -inc_x; dy[i++] = 0;
  348.             dx[i] = inc_x; dy[i++] = -inc_y;
  349.             dx[i] = 0; dy[i++] = -inc_y;
  350.             dx[i] = -inc_x; dy[i++] = -inc_y;
  351.         } /* if */
  352.     } /* block */
  353.  
  354.     {
  355.         register int    x, y;
  356.         register int    new_mp;
  357.  
  358.         for( i = 0; i < 8; i++ ) {
  359.             if( (x = ax + dx[i]) < 0 || x >= MAPX )
  360.                 continue;
  361.             if( (y = ay + dy[i]) < 0 || y >= MAPY )
  362.                 continue;
  363.  
  364.             new_mp = move_points - 1;
  365.             if( new_mp < 0 )
  366.                 continue;
  367.  
  368.             if( water_2reachp( x, y, new_mp ) )
  369.                 return( 1 );
  370.         } /* for */
  371.     } /* block */
  372.  
  373.     return( 0 );
  374. } /* water_2reachp() */
  375. #endif ADMIN
  376. #ifdef XYZ    /* XYZ never is defined */
  377. /*
  378.  *    water_reachp()
  379.  */
  380.  
  381. int
  382. water_reachp( ax, ay, gx, gy, move_points, movee )
  383. int    ax;
  384. int    ay;
  385. int    gx;
  386. int    gy;
  387. int    move_points;
  388. int    movee;
  389. {
  390.     if( move_points >= MAX_MOVE_UNITS ) {
  391.         fprintf( stderr, "water_reachp(): move_points = %d\n",
  392.             move_points );
  393.  
  394.         abrt();
  395.     }
  396.  
  397. #ifdef SYSV
  398.     memset(history_reachp, MAX_MOVE_UNITS, MAPX*MAPY*sizeof(history_reachp));
  399. #else
  400.     { register int i,j;
  401.         for (i=0; i < MAPX ; i++)
  402.         for (j=0; j < MAPY ; j++ )
  403.             history_reachp [i] [j] = MAX_MOVE_UNITS ;
  404.     }/* eof memset replacement block */
  405. #endif
  406.  
  407.     history_reachp[ ax ][ ay ] = 0;
  408.  
  409.     bx = gx;
  410.     by = gy;
  411.     moving_country = movee;
  412.  
  413.     return( water_2reachp( ax, ay, move_points ) );
  414. } /* water_reachp() */
  415. #endif 0
  416.  
  417. /*
  418.  *    solds_in_sector()
  419.  */
  420.  
  421. long
  422. solds_in_sector( x, y, country )
  423. int    x;
  424. int    y;
  425. int    country;
  426. {
  427.     register struct s_nation    *nptr = &ntn[country];
  428.     register int    j;
  429.     long    total = 0;
  430.  
  431.     for( j = 0; j < MAXARM; j++ ) {
  432.         if( nptr->arm[j].sold == 0 )
  433.             continue;
  434.  
  435.         if( nptr->arm[j].xloc == x && nptr->arm[j].yloc == y )
  436.             total += nptr->arm[j].sold;
  437.     }
  438.  
  439.     return( total );
  440. } /* solds_in_sector() */
  441. #ifdef ADMIN
  442.  
  443. /* score_one()    */
  444. struct wght {
  445.     int    sectors;
  446.     int    civilians;
  447.     int    soldiers;
  448.     int    gold;
  449.     int    jewels;
  450.     int    metal;
  451.     int    magics;
  452.     int    ships;
  453. } weights[] = {
  454. /*        Per 2  1000    1000      100K 100K   100K   Magic  10 */
  455. /*    Races   Sector People  Soldiers  Gold Jewels Iron   Power Ship */
  456. /* NPC */    { 2,    1,     0,        0,    1,    1,     1,    0 },
  457. /* kingdom */    { 2,    1,     2,        3,    0,    0,     0,    0 },
  458. /* empire */    { 3,    0,     0,        1,    1,    0,     0,    0 },
  459. /* wizard */    { 0,    2,     1,        0,    3,    5,     7,   0 },
  460. /* theocracy */    { 2,    1,     0,        0,    3,    0,     3,    0 },
  461. /* pirate */    { 0,    0,     5,        0,    10,   10,    1,    5 },
  462. /* trader */    { 2,    1,     0,        0,    1,    1,     1,    8 },
  463. /* warlord */    { 2,    1,     2,        0,    1,    1,     1,    0 },
  464. /* demon */    { 2,    0,     1,        0,    1,    0,     5,   0 },
  465. /* dragon */    { 0,    0,     0,        10,   20,   0,     0,    0 },
  466. /* shadow */    { 2,    0,     0,        0,    0,    5,     0,    0 },
  467. /* miner */    { 0,    0,     5,        0,    10,   10,   1,    5 },
  468. };
  469.  
  470. long
  471. score_one( country )
  472. int    country;
  473. {
  474.     struct    s_nation    *nptr = &ntn[ country ];
  475.     long    total = 0;
  476.     int    bonus;
  477.     struct    wght    *wght = &weights[ nptr->class ];
  478.  
  479.     total += wght->sectors * nptr->tsctrs / 2L;
  480.     total += wght->civilians * nptr->tciv / 1000L;
  481.     total += wght->soldiers * nptr->tmil / 1000L;
  482.     if(nptr->tgold > 0 ) total += wght->gold * nptr->tgold / 100000L;
  483.     total += wght->jewels * nptr->jewels / 100000L;
  484.     total += wght->metal * nptr->metals / 100000L;
  485.     total += wght->magics * num_powers(country,M_MIL);
  486.     total += wght->magics * num_powers(country,M_CIV);
  487.     total += wght->magics * num_powers(country,M_MGK);
  488.     total += wght->ships * nptr->tships / 10L;
  489.     switch( nptr->class ) {
  490.     case     C_KING:
  491.             bonus=(curntn->popularity+curntn->prestige-curntn->poverty);
  492.             break;
  493.     case    C_EMPEROR:
  494.             bonus=(curntn->power+curntn->prestige-curntn->poverty);
  495.             break;
  496.     case    C_WIZARD:
  497.             bonus=(curntn->knowledge+curntn->power-50);
  498.             break;
  499.     case    C_PRIEST:
  500.             bonus=(curntn->wealth+curntn->terror-curntn->poverty);
  501.             break;
  502.     case    C_PIRATE:
  503.             bonus=(curntn->reputation+curntn->wealth-50);
  504.             break;
  505.     case    C_TRADER:
  506.             bonus=(curntn->wealth+curntn->prestige-curntn->tax_rate*5);
  507.             break;
  508.     case    C_WARLORD:
  509.             bonus=(curntn->reputation+curntn->prestige-50);
  510.             break;
  511.     case    C_DEMON    :
  512.             bonus=(curntn->knowledge+curntn->terror-50);
  513.             break;
  514.     case    C_DRAGON:
  515.             bonus=(curntn->wealth+curntn->terror-50);
  516.             break;
  517.     case    C_SHADOW:
  518.             bonus=(curntn->power+curntn->terror-50);
  519.             break;
  520.     default:    bonus=0;
  521.     }
  522.     total += bonus/10;
  523.     return( total );
  524. } /* score_one() */
  525. #endif ADMIN
  526. /*
  527.  *    print_accum()
  528.  */
  529.  
  530.     /* max number of print_accum() calls in one printf() */
  531. #define MAX_BUFFER    4
  532. #define BUFFER_SIZE    20
  533.  
  534. /* is_habitable() - returns TRUE/FALSE if habitable */
  535. int
  536. is_habitable( x, y )
  537. int    x;
  538. int    y;
  539. {
  540.     char    temp;
  541.  
  542.     if(( (temp=sct[x][y].altitude)==WATER )||( temp==PEAK )) return(FALSE);
  543.  
  544.     if(((temp=sct[x][y].vegetation)==BARREN )
  545.     || ( temp==LT_VEG )
  546.     || ( temp==GOOD )
  547.     || ( temp==WOOD )
  548.     || ( temp==FOREST )) return( TRUE );
  549.  
  550.     return( FALSE );
  551. }
  552.  
  553. #ifdef CONQUER
  554. int
  555. units_in_sector(x,y,country)
  556. int    x;
  557. int    y;
  558. {
  559.     int count=0, armynum, nvynum;
  560.     for(armynum=0;armynum<MAXARM;armynum++)
  561.         if((ASOLD>0)&&(AXLOC==x)&&(AYLOC==y)) count++;
  562.     for(nvynum=0;nvynum<MAXNAVY;nvynum++)
  563.         if(((NWSHP+NMSHP+NGSHP)!=0)&&(NXLOC==x)&&(NYLOC==y)) count++;
  564.     return(count);
  565. }
  566. #endif CONQUER
  567.  
  568. int
  569. num_powers(country,type)
  570. int country,type;
  571. {
  572.     int    count_magic=0;
  573.     int    try;
  574.     long    start, end;
  575.     switch(type){
  576.         case M_MGK:
  577.             start=S_MGK;
  578.             end=E_MGK;
  579.             break;
  580.         case M_CIV:
  581.             start=S_CIV;
  582.             end=E_CIV;
  583.             break;
  584.         case M_MIL:
  585.             start=S_MIL;
  586.             end=E_MIL;
  587.             break;
  588.         case M_ALL:
  589.             start=S_MIL;
  590.             end=E_MGK;
  591.             break;
  592.         default:
  593.             printf("fatal error in num_powers");
  594.             abrt();
  595.     }
  596.     for( try = start; try < start+end; try++ )
  597.         if( magic(country, powers[try] ) == 1 ) count_magic++;
  598.     return(count_magic);
  599. }
  600.  
  601. /* returns food value of sector */
  602. /* 4 is limit of livable land */
  603. int
  604. tofood(sptr,cntry)
  605. struct s_sector *sptr;
  606. int    cntry;
  607. {
  608.     register int i=0;
  609.     register int foodvalue;
  610.     while( sptr->vegetation != *(veg+i) ) i++;
  611.     foodvalue = *(vegfood+i) - '0';
  612.     if( cntry != 0 ) {
  613.         if(foodvalue == 0) {
  614. #ifdef DERVDESG
  615.             if ((magic(cntry,DERVISH)||magic(cntry,DESTROYER))
  616.             &&(sptr->vegetation==DESERT || sptr->vegetation==ICE))
  617.                 return(6);
  618. #endif DERVDESG
  619.             return( 0 );
  620.         }
  621.         if(ntn[cntry].race == ELF){
  622.             if(sptr->vegetation == FOREST) foodvalue+=3;
  623.             else if(sptr->vegetation == BARREN) foodvalue--;
  624.         }
  625.     }
  626.     if(( sptr->tradegood <= END_EATRATE )
  627.     &&( sptr->tradegood > END_COMMUNICATION ))
  628.         foodvalue += *(tg_value+sptr->tradegood) - '0';
  629.     return( foodvalue );
  630. }
  631.  
  632. /*jewel cost for civilian power = Base * 2**( #mgk/2 + #civ + #mil/2 )    */
  633. /*race            magical        civilian    military    */
  634. /*    elves -        50K        50K        50K        */
  635. /*    dwarves -    80K        40K        40K        */
  636. /*    humans -    100K        25K        50K        */
  637. /*    orcs -        100K        50K        25K        */
  638.  
  639. /* returns cost of magic power - returns -1 if invalid */
  640. long
  641. getmgkcost(type,country)
  642. int type, country;
  643. {
  644.     int i;
  645.     long cost;
  646.     long base=BASEMAGIC;
  647.     int npowers;
  648.     switch(type) {
  649.     case M_MGK:
  650.         if(ntn[country].race==DWARF)        base=DWFMAGIC;
  651.         else if(ntn[country].race==HUMAN)    base=HUMMAGIC;
  652.         else if(ntn[country].race==ORC)        base=ORCMAGIC;
  653.         npowers=num_powers(country,M_CIV)+num_powers(country,M_MIL)+1
  654.         +2*num_powers(country,M_MGK);
  655.         npowers/=2;
  656.         break;
  657.     case M_CIV:
  658.         if(ntn[country].race==DWARF)        base=DWFCIVIL;
  659.         else if(ntn[country].race==HUMAN)    base=HUMCIVIL;
  660.         else if(ntn[country].race==ORC)        base=ORCCIVIL;
  661.         npowers=num_powers(country,M_MGK)+num_powers(country,M_MIL)+1
  662.         +2*num_powers(country,M_CIV);
  663.         npowers/=2;
  664.         break;
  665.     case M_MIL:
  666.         if(ntn[country].race==DWARF)        base=DWFMILIT;
  667.         else if(ntn[country].race==ORC)        base=ORCMILIT;
  668.         npowers=num_powers(country,M_CIV)+num_powers(country,M_MGK)+1
  669.         +2*num_powers(country,M_MIL);
  670.         npowers/=2;
  671.         break;
  672.     default:
  673.         return(-1);
  674.     }
  675.     cost = base;
  676.     for (i=1; i<npowers; i++) {
  677.         cost <<= 1;
  678.         if (cost > BIG)
  679.             return(BIG/2L);
  680.     }
  681.     return(cost);
  682. }
  683.  
  684. int
  685. todigit(character)
  686. register int    character;
  687. {
  688.     if( character >= '0' && character <= '9' )
  689.         return( character - '0' );
  690.     return( -1 );
  691. }
  692.  
  693. /* set up occ[][] for country.
  694.    if leader==true, only for leader sectors plus ntn.communicatins range */
  695. void
  696. prep(country,leader)
  697. int country,leader;
  698. {
  699.     short armynum,nvynum;
  700.     int save,i,j,x,y,start,end,com;
  701.  
  702.     /*set occ to 0*/
  703.     for(i=0;i<MAPX;i++) for(j=0;j<MAPY;j++) occ[i][j]=0;
  704.  
  705.     save=country;
  706.     if(leader) {
  707.         /* only do the given country */
  708.         start=save;
  709.         end=save+1;
  710.     } else {
  711.         /* go through all countries */
  712.         start=0;
  713.         end=NTOTAL;
  714.     }
  715.  
  716.     /*set occ to country of occupant army*/
  717.     for(country=start;country<end;country++) if(ntn[country].active!=INACTIVE) {
  718.         curntn = &ntn[country];
  719.         for(armynum=0;armynum<MAXARM;armynum++){
  720.             if( leader ) {
  721.                 if((P_ATYPE<MINLEADER)
  722.                 ||(P_ATYPE>=MINMONSTER)
  723.                 ||(P_ASOLD==0)) continue;
  724.                 i=P_AXLOC;
  725.                 j=P_AYLOC;
  726.                 com = P_NTNCOM; /* do communications radius */
  727.                 for(x=i-com;x<=i+com;x++)
  728.                 for(y=j-com;y<=j+com;y++)
  729.                     if(ONMAP(x,y)) occ[x][y]=country;
  730.             } else if((P_ASOLD>0)&&(P_ASTAT!=SCOUT)){
  731.                 i=P_AXLOC;
  732.                 j=P_AYLOC;
  733.                 if((occ[i][j]== 0)||(occ[i][j]== country))
  734.                     occ[i][j]= country;
  735.                 else occ[i][j]= NTOTAL;
  736.             }
  737.         }
  738.         if( !leader ) for(nvynum=0;nvynum<MAXNAVY;nvynum++){
  739.             if((P_NWSHP!=0)||(P_NGSHP!=0)||(P_NMSHP!=0)){
  740.                 i=P_NXLOC;
  741.                 j=P_NYLOC;
  742.                 if((occ[i][j]== 0)||(occ[i][j]== country))
  743.                     occ[i][j]= country;
  744.                 else occ[i][j]= NTOTAL;
  745.             }
  746.         }
  747.     }
  748.  
  749.     country=save;
  750.     curntn = &ntn[country];
  751. }
  752.  
  753. #ifdef ADMIN
  754. /*routine to depelete a nation without a capitol */
  755. void
  756. deplete(country)
  757. int country;
  758. {
  759.     struct s_nation *saventn=curntn;
  760.     int i,j,x,y,armynum,nation;
  761.  
  762.     x = ntn[country].capx;
  763.     y = ntn[country].capy;
  764.     if((sct[x][y].designation==DCAPITOL)&&((sct[x][y].owner==country)
  765.     ||(sct[x][y].owner==0)||(!isntn(ntn[sct[x][y].owner].active))))
  766.         return;
  767.  
  768.     curntn = &ntn[country];
  769.     fprintf(fnews,"1.\tNation %s is depleted by the lack of a Capitol\n",ntn[country].name);
  770.  
  771.     for(armynum=0;armynum<MAXARM;armynum++) if (P_ASOLD>0) {
  772.         /* first disband PDEPLETE% of the military */
  773.         if (P_ATYPE<MINLEADER &&
  774.         (rand()%100<PDEPLETE||P_ATYPE==A_MERCENARY)) {
  775.             if(P_ATYPE==A_MERCENARY) {
  776.                 MERCMEN += P_ASOLD;
  777.             } else if(ntn[sct[AXLOC][AYLOC].owner].race==ntn[country].race) {
  778.                 sct[P_AXLOC][P_AYLOC].people += P_ASOLD;
  779.             }
  780.             P_ASOLD=0;
  781.             if(ispc(curntn->active)) {
  782.                 mailopen(country);
  783.                 fprintf(fm,"Message to %s from Conquer\n\n",curntn->name);
  784.                 fprintf(fm,"\tYour %s Army %d disperses into the population\n",*(unittype+(P_ATYPE%UTYPE)),armynum);
  785.                 mailclose();
  786.             }
  787.         } else if(P_ATYPE>=MINMONSTER) {
  788.             /* disbanding of ALL monsters should take place */
  789.             P_ASOLD=0;
  790.             if(ispc(curntn->active)) {
  791.                 mailopen(country);
  792.                 fprintf(fm,"Message to %s from Conquer\n\n",curntn->name);
  793.                 fprintf(fm,"\tYour %s (unit %d) leaves due to the loss of your jewels.\n",*(unittype+(P_ATYPE%UTYPE)),armynum);
  794.                 mailclose();
  795.             }
  796.         }
  797.     }
  798.  
  799.     /* check for sectors breaking away -- not capx, capy */
  800.     if(ispc(curntn->active)) {
  801.         /* create a summarized mail message of sectors effected */
  802.         mailopen(country);
  803.         fprintf(fm,"Message to %s from Conquer\n\n",curntn->name);
  804.         fprintf(fm,"Riots and Rebellion flourish:\n");
  805.     }
  806.     for(i=0;i<MAPX;i++) for(j=0;j<MAPY;j++)
  807.     if(sct[i][j].owner==country && (i!=x || j!=y) ) {
  808.         if(rand()%100 < PDEPLETE && sct[x][y].people>0) {
  809.             if(rand()%100 < PDEPLETE) {
  810.                 /* sector riots */
  811.                 flee(i,j,TRUE,FALSE);
  812.                 DEVASTATE(i,j);
  813.                 if(ispc(curntn->active)) {
  814.                     /* add to listing */
  815.                     fprintf(fm,"\tsector %d, %d has massive riots\n",i,j);
  816.                 }
  817.             } else {
  818.                 /* sector becomes owned by another nation */
  819. #ifdef NOTDONE
  820.                 /* must work on this still */
  821.                 giveaway(i,j,&nation);
  822.                 if(ispc(curntn->active)) {
  823.                     fprintf(fm,"\tsector %d, %d joins nation %s\n",ntn[nation].name);
  824.                 }
  825. #endif NOTDONE
  826.             }
  827.         }
  828.     }
  829.     if(ispc(curntn->active)) {
  830.         mailclose();
  831.     } else if(isnpc(curntn->active)) {
  832.         if(sct[curntn->capx][curntn->capy].owner==country) {
  833.             /* reset capitol for npcs */
  834.             sct[curntn->capx][curntn->capy].owner=DCAPITOL;
  835.             if(sct[curntn->capx][curntn->capy].fortress<1)
  836.                 sct[curntn->capx][curntn->capy].fortress=1;
  837.         }
  838.     }
  839.     /* restore */
  840.     curntn = saventn;
  841. }
  842.  
  843.  
  844. /*routine to sack a nation's captiol */
  845. void
  846. sackem(country)
  847.     int country;
  848. {
  849.     struct s_nation *saventn=curntn;
  850.     int x,y,i,j,foundcap,nation;
  851.  
  852.     /* hail the conquerer */
  853.     curntn = &ntn[country];
  854.     x = curntn->capx;
  855.     y = curntn->capy;
  856.     nation = sct[x][y].owner;
  857.     if(nation==country || nation==0) return;
  858.  
  859.     /* advertise */
  860.     fprintf(fnews,"1.\tCapitol of %s sacked by %s\n",ntn[country].name,ntn[nation].name);
  861.  
  862.     /* first give all prizes to the conquerer */
  863.     if(curntn->tgold > 0) {            /* all gold */
  864.         ntn[nation].tgold += curntn->tgold;
  865.         curntn->tgold=0;
  866.     }
  867.     ntn[nation].jewels += curntn->jewels;    /* all jewels */
  868.     curntn->jewels=0;
  869.     ntn[nation].metals += curntn->metals;    /* all metals */
  870.     curntn->metals=0;
  871.     ntn[nation].tfood += curntn->tfood/5L;    /* 20% of food */
  872.     curntn->tfood -= curntn->tfood/5L;
  873.  
  874.     /* fix the designation */
  875.     if(sct[x][y].designation==DCAPITOL) {
  876.         if(isntn(ntn[nation].active)) {
  877.             sct[x][y].designation = DCITY;
  878.         } else {
  879.             DEVASTATE(x,y);
  880.             sct[x][y].owner=country;
  881.         }
  882.     }
  883.  
  884.     /* set another sector to the capx, capy to make sure that */
  885.     /* sacking does not occur next update for same sacking.   */
  886.     foundcap=FALSE;
  887.     for(i=0;foundcap==FALSE && i<MAPX;i++)
  888.     for(j=0;foundcap==FALSE && j<MAPY;j++) if(sct[i][j].owner==country) {
  889.         if(sct[i][j].designation==DCITY) {
  890.             x = i; y = j;
  891.             foundcap=TRUE;
  892.         } else if((sct[i][j].designation==DTOWN)
  893.         &&(((x==curntn->capx)&&(y==curntn->capy))
  894.           ||(sct[x][y].designation!=DTOWN))) {
  895.             x = i; y = j;
  896.         } else if((x==curntn->capx)&&(y==curntn->capy)) {
  897.             x = i; y = j;
  898.         }
  899.     }
  900.  
  901.     if ((x!=curntn->capx)||(y!=curntn->capy)) {
  902.         /* assign new pseudo capitol */
  903.         if(ispc(curntn->active)) {
  904.             mailopen(country);
  905.             fprintf(fm,"Message to %s from Conquer\n\n",ntn[country].name);
  906.             fprintf(fm,"\tYour Capitol at sector location %d,%d\n",curntn->capx,curntn->capy);
  907.             fprintf(fm,"\t was overrun by nation %s.\n\n",ntn[nation].name);
  908.             fprintf(fm,"\tA temporary headquarters is now in sector %d,%d,\n",x,y);
  909.             fprintf(fm,"\t but designation of a new Capitol is recommended.\n");
  910.             mailclose();
  911.         }
  912.         curntn->capx=x;
  913.         curntn->capy=y;
  914.     } else {
  915.         /* no new capitol assignment */
  916.         if(ispc(curntn->active)) {
  917.             mailopen(country);
  918.             fprintf(fm,"Message to %s from Conquer\n\n",ntn[country].name);
  919.             fprintf(fm,"\tYour Capitol at sector location %d,%d\n",curntn->capx,curntn->capy);
  920.             fprintf(fm,"\t was overrun by nation %s.\n\n",ntn[nation].name);
  921.             fprintf(fm,"\tNo other land remains.  The destruction\n");
  922.             fprintf(fm,"\t of your nation seems imminent.\n");
  923.             mailclose();
  924.         }
  925.     }
  926.     /* restore */
  927.     curntn = saventn;
  928. }
  929. #endif ADMIN
  930.  
  931. /*destroy nation--special case if capitol not owned by other nation*/
  932. void
  933. destroy(country)
  934. int country;
  935. {
  936.     short armynum, nvynum;
  937.     int i, x, y;
  938.     char buf[20];
  939.     struct s_nation    *nptr;
  940.  
  941.     nptr = &ntn[country];
  942.     if( ismonst(nptr->active) ) return;
  943.     fprintf(fnews,"1.\tNation %s was destroyed ",nptr->name);
  944.     if(country!=sct[nptr->capx][nptr->capy].owner){
  945.         fprintf(fnews,"(their capitol is now owned by %s)\n",ntn[sct[nptr->capx][nptr->capy].owner].name);
  946.         /*get +5% to combat skill*/
  947.         ntn[sct[nptr->capx][nptr->capy].owner].aplus+=5;
  948.     }
  949.     else fprintf(fnews,"(they owned their capitol)\n");
  950.  
  951.     nptr->active=INACTIVE;
  952.     nptr->score=0;
  953.     sprintf(buf,"%s%d",msgfile,country);
  954.     unlink(buf);
  955.  
  956.     for(armynum=0;armynum<MAXARM;armynum++) if(ASOLD>0) {
  957.         if(ntn[sct[AXLOC][AYLOC].owner].race==nptr->race)
  958.             sct[AXLOC][AYLOC].people+=ASOLD;
  959.         ASOLD=0;
  960.     }
  961.     for(nvynum=0;nvynum<MAXNAVY;nvynum++) {
  962.         NMSHP=0;
  963.         NWSHP=0;
  964.         NGSHP=0;
  965.     }
  966.     for(i=0;i<NTOTAL;i++) {
  967.         ntn[i].dstatus[country]=UNMET;
  968.         nptr->dstatus[i]=UNMET;
  969.     }
  970.  
  971.     /*if take them you get their gold*/
  972.     if(country!=sct[nptr->capx][nptr->capy].owner){
  973.         if(nptr->tgold>0) ntn[sct[nptr->capx][nptr->capy].owner].tgold+=nptr->tgold;
  974.         if(nptr->jewels>0) ntn[sct[nptr->capx][nptr->capy].owner].jewels+=nptr->jewels;
  975.         if(nptr->metals>0) ntn[sct[nptr->capx][nptr->capy].owner].metals+=nptr->metals;
  976.         if(nptr->tfood>0) ntn[sct[nptr->capx][nptr->capy].owner].tfood+=nptr->tfood;
  977.         sct[nptr->capx][nptr->capy].designation=DCITY;
  978.     }
  979.  
  980.     /*if god destroys then kill all population*/
  981.     if(country==sct[nptr->capx][nptr->capy].owner){
  982.         for(x=0;x<MAPX;x++) for(y=0;y<MAPY;y++)
  983.         if(sct[x][y].owner==country) {
  984.             sct[x][y].people=0;
  985.             sct[x][y].owner=0;
  986.             sct[x][y].designation=DNODESIG;
  987.         }
  988.     }
  989.     /*slowly take over and all people flee*/
  990.     else if(ntn[sct[nptr->capx][nptr->capy].owner].race!=nptr->race){
  991.         for(x=0;x<MAPX;x++) for(y=0;y<MAPY;y++)
  992.         if(sct[x][y].owner==country) {
  993.             /*all kinds of refugees to neighboring countries*/
  994.             flee(x,y,TRUE,FALSE);
  995.             sct[x][y].people=0;
  996.             sct[x][y].owner=0;
  997.             if(tofood( &sct[x][y],0 )<DESFOOD)
  998.                 sct[x][y].designation=DNODESIG;
  999.             else    sct[x][y].designation=sct[x][y].vegetation;
  1000.         }
  1001.     }
  1002.     /*else same race, so give all land to conqueror*/
  1003.     else {
  1004.         for(x=0;x<MAPX;x++) for(y=0;y<MAPY;y++)
  1005.         if(sct[x][y].owner==country){
  1006.             sct[x][y].owner=sct[nptr->capx][nptr->capy].owner;
  1007.             if( !ISCITY( sct[x][y].designation )) {
  1008.             if(tofood( &sct[x][y],0)<DESFOOD)
  1009.                 sct[x][y].designation=DNODESIG;
  1010.             else    sct[x][y].designation=DFARM;
  1011.             }
  1012.         }
  1013.     }
  1014.     return;
  1015. }
  1016.  
  1017. #define ALPHA_SIZE    128
  1018.  
  1019. /*movecost contains movement cost unless water  -1 or unenterable land (-2)*/
  1020. /* if water and not ajacent to land will cost -4*/
  1021. void
  1022. updmove(race,country)
  1023. int country;
  1024. char race;
  1025. {
  1026.     register struct s_sector    *sptr;
  1027.     register int    i,j;
  1028.     int x,y;
  1029.     short    veg_cost[ ALPHA_SIZE ];
  1030.     short    ele_cost[ ALPHA_SIZE ];
  1031.  
  1032.     if( race==GOD ) {
  1033.         for(x=0;x<MAPX;x++) for(y=0;y<MAPY;y++) movecost[x][y] = 0;
  1034.         return;
  1035.     }
  1036.  
  1037.     for( j = 0; veg[j] != '0'; j++ ) {
  1038.         switch( race ) {
  1039.         case ELF:
  1040.             veg_cost[ veg[j] ] = EVegcost[j] - '0';
  1041.             break;
  1042.         case DWARF:
  1043.             veg_cost[ veg[j] ] = DVegcost[j] - '0';
  1044.             break;
  1045.         case ORC:
  1046.             veg_cost[ veg[j] ] = OVegcost[j] - '0';
  1047.             break;
  1048.         case HUMAN:
  1049.         default:
  1050.             veg_cost[ veg[j] ] = HVegcost[j] - '0';
  1051.             break;
  1052.         } /* switch */
  1053.     } /* for */
  1054.  
  1055.     if((magic(country,DERVISH)==1) ||(magic(country,DESTROYER)==1)) {
  1056.         veg_cost[ ICE ] = 1;
  1057.         veg_cost[ DESERT ] = 1;
  1058.     }
  1059.  
  1060.     for( j = 0; ele[j] != '0'; j++ ) {
  1061.         switch( race ) {
  1062.         case ELF:
  1063.             ele_cost[ ele[j] ] = EElecost[j] - '0';
  1064.             break;
  1065.         case DWARF:
  1066.             ele_cost[ ele[j] ] = DElecost[j] - '0';
  1067.             break;
  1068.         case ORC:
  1069.             ele_cost[ ele[j] ] = OElecost[j] - '0';
  1070.             break;
  1071.         case HUMAN:
  1072.         default:
  1073.             ele_cost[ ele[j] ] = HElecost[j] - '0';
  1074.             break;
  1075.         } /* switch */
  1076.     } /* for */
  1077.  
  1078.     for(x=0;x<MAPX;x++) for(y=0;y<MAPY;y++){
  1079.         sptr = &sct[x][y];
  1080.  
  1081.         if(sptr->altitude==WATER) {
  1082.             movecost[x][y] = -4;
  1083.             for(i=x-1;i<=x+1;i++) for(j=y-1;j<=y+1;j++)
  1084.             if( ONMAP(i,j) )
  1085.                 if( sct[i][j].altitude != WATER) {
  1086.                     movecost[x][y] = -1;
  1087.                     i=x+2;
  1088.                     j=y+2;
  1089.                 }
  1090.         } else {
  1091.             if( veg_cost[ sptr->vegetation ] == -1
  1092.             || ele_cost[ sptr->altitude ] == -1 )
  1093.                 movecost[x][y] = -2;
  1094.             else
  1095.                 movecost[x][y] = veg_cost[ sptr->vegetation ] + ele_cost[ sptr->altitude ];
  1096.         } /* if */
  1097.         if (sptr->designation == DROAD)
  1098.             movecost[x][y] = (movecost[x][y] + 1) / 2;
  1099.     } /* for */
  1100. } /* updmove() */
  1101.  
  1102. #ifdef CONQUER
  1103. /* calculations for cost of movement during flight */
  1104. int
  1105. flightcost(i,j)
  1106. int i,j;
  1107. {
  1108.     int cnt,hold=(-1),hold2=(-1);
  1109.  
  1110.     for (cnt=0; ele[cnt]!='0'; cnt++ ) {
  1111.         if (sct[i][j].altitude==ele[cnt])
  1112.             hold = (FElecost[cnt] - '0');
  1113.     }
  1114.     for (cnt=0; veg[cnt]!='0'; cnt++ ) {
  1115.         if (sct[i][j].vegetation==veg[cnt])
  1116.             hold2 = (FVegcost[cnt] - '0');
  1117.     }
  1118.     if (hold==(-1) || hold2==(-1)) {
  1119.         hold=(-1);
  1120.     }
  1121.     else hold+=hold2;
  1122.  
  1123.     return(hold);
  1124. }
  1125. #endif CONQUER
  1126. #ifdef ADMIN
  1127. /* determines whether or not a unit has the ability to fly */
  1128. int
  1129. avian(typ)
  1130. unsigned char typ;
  1131. {
  1132.     switch(typ) {
  1133.     case A_ROC:
  1134.     case A_GRIFFON:
  1135.     case SPIRIT:
  1136.     case DJINNI:
  1137.     case DEMON:
  1138.     case DRAGON:
  1139.         return(TRUE);
  1140.     default:
  1141.         return(FALSE);
  1142.     }
  1143. }
  1144. #endif ADMIN
  1145.  
  1146. void
  1147. spreadsheet(nation)
  1148. int nation;
  1149. {
  1150.     register struct s_sector    *sptr;
  1151.     register struct s_nation    *nptr;
  1152.     long    product;
  1153.     long    city_pop, cap_pop;
  1154.     int x,y,i,j,foundmill;
  1155.  
  1156.     nptr = &ntn[ nation ];
  1157.  
  1158.     spread.revothr = spread.revfood = spread.revjewels = spread.revmetal = spread.revcap = spread.revcity = 0L;
  1159.     spread.inothr = spread.incity = spread.incap = spread.ingold = spread.infarm = spread.inmetal = 0;
  1160.     spread.food = nptr->tfood;
  1161.     spread.gold = nptr->tgold;
  1162.     spread.metal = nptr->metals;
  1163.     spread.jewels = nptr->jewels;
  1164.     spread.sectors = 0;
  1165.     spread.civilians = 0L;
  1166.  
  1167.     for(x=0;x<MAPX;x++) for(y=0;y<MAPY;y++) {
  1168.         sptr = &sct[x][y];
  1169.         if(sptr->owner!=nation) continue;
  1170.  
  1171.         /*update nation file for owner*/
  1172.         spread.sectors++;
  1173.         spread.civilians += sptr->people;
  1174.  
  1175.         product = 0;
  1176.         /*PRODUCE*/
  1177.         /*increase tmin based on mined stuff...*/
  1178.         if(sptr->designation==DMINE) {
  1179.             if( !tg_ok( nation, sptr )) continue;
  1180.             spread.inmetal += sptr->people;
  1181.             if(sptr->people>TOMANYPEOPLE) {
  1182.                 product = sptr->metal * TOMANYPEOPLE;
  1183.                 product += sptr->metal * (sptr->people-TOMANYPEOPLE)/2L;
  1184.             } else product = sptr->metal *  sptr->people;
  1185.  
  1186.             if(magic(sptr->owner,MINER)==1) product*=2L;
  1187.             if(magic(sptr->owner,STEEL)==1) product*=2L;
  1188.             spread.metal += product;
  1189.             spread.revmetal += product*TAXMETAL*nptr->tax_rate/100L;
  1190.         }
  1191.         /*harvest food*/
  1192.         else if(sptr->designation==DFARM) {
  1193.             spread.infarm += sptr->people;
  1194.             if(sptr->people>TOMANYPEOPLE) {
  1195.                 product = (long)tofood(sptr,sptr->owner) * TOMANYPEOPLE;
  1196.                 product += (long)tofood(sptr,sptr->owner) * (sptr->people-TOMANYPEOPLE)/2L;
  1197.             } else product = (long)tofood(sptr,sptr->owner) *  sptr->people;
  1198.  
  1199.             switch(SEASON(TURN)) {
  1200.             case SPRING:
  1201.                 product/=2;
  1202.                 break;
  1203.             case SUMMER:
  1204.                 break;
  1205.             case FALL:
  1206.                 product*=5;
  1207.                 product/=2;
  1208.                 break;
  1209.             case WINTER:
  1210.                 product=0;
  1211.                 break;
  1212.             }
  1213.             /* search for neighboring mills */
  1214.             foundmill=FALSE;
  1215.             for(i=x-1;foundmill==FALSE && i<=x+1;i++)
  1216.             for(j=y-1;foundmill==FALSE && j<=y+1;j++)
  1217.             if((ONMAP(i,j))
  1218.             &&(sct[i][j].owner==sptr->owner)
  1219.             &&(sct[i][j].designation==DMILL)
  1220.             &&(sct[i][j].people>=MILLSIZE)) {
  1221.                 product *= 12L;
  1222.                 product /= 10L;
  1223.                 /* must break this way... two for() loops */
  1224.                 foundmill=TRUE;
  1225.             }
  1226.             spread.food += product;
  1227.             spread.revfood += product*TAXFOOD*nptr->tax_rate/100L;
  1228.         }
  1229.         /*gold mines produce gold*/
  1230.         else if(sptr->designation==DGOLDMINE) {
  1231.             if( !tg_ok( nation, sptr )) continue;
  1232.             spread.ingold += sptr->people;
  1233.             if(sptr->people>TOMANYPEOPLE) {
  1234.                 product = sptr->jewels * TOMANYPEOPLE;
  1235.                 product += sptr->jewels * (sptr->people-TOMANYPEOPLE)/2L;
  1236.             } else product = sptr->jewels *  sptr->people;
  1237.  
  1238.             if(magic(sptr->owner,MINER)==1) product*=2;
  1239.  
  1240.             spread.jewels += product;
  1241.             spread.revjewels += product*TAXGOLD*nptr->tax_rate/100L;
  1242.         }
  1243.         else if((sptr->designation==DCITY)
  1244.         ||(sptr->designation==DCAPITOL)) {
  1245.             cap_pop  = sptr->people;
  1246.             spread.incap += cap_pop;
  1247.  
  1248.             if( magic(sptr->owner, ARCHITECT ) ) {
  1249.                 cap_pop *= 2L;
  1250.             }
  1251.  
  1252.             spread.revcap +=  cap_pop * TAXCITY*nptr->tax_rate / 100L;
  1253.         } else if(sptr->designation==DTOWN) {
  1254.             spread.incity += sptr->people;
  1255.             city_pop = sptr->people;
  1256.             if( magic(sptr->owner, ARCHITECT ) )
  1257.                 city_pop *= 2L;
  1258.  
  1259.             spread.revcity +=  city_pop*TAXTOWN*nptr->tax_rate/100L;
  1260.         }
  1261. #ifndef DERVDESG
  1262.         else if(((magic(sptr->owner,DERVISH)==1)
  1263.             ||(magic(sptr->owner,DESTROYER)==1))
  1264.         &&((sptr->vegetation==ICE) ||(sptr->vegetation==DESERT))
  1265.         &&(sptr->people>0)) {
  1266.             if(sptr->people>TOMANYPEOPLE) {
  1267.                 product = 6L * TOMANYPEOPLE;
  1268.                 product += 3L * (sptr->people-TOMANYPEOPLE);
  1269.             } else product = 6L *  sptr->people;
  1270.  
  1271.             spread.food += product;
  1272.             /* desert food production mostly static */
  1273.             if (sptr->vegetation==DESERT) {
  1274.                 /* harsh summer in desert; good winter */
  1275.                 if (SEASON(TURN)==SUMMER) product/=2;
  1276.                 else if (SEASON(TURN)==WINTER) {
  1277.                     product*=5;
  1278.                     product/=4;
  1279.                 }
  1280.             } else {
  1281.                 /* opposite in ice */
  1282.                 if (SEASON(TURN)==WINTER) product/=2;
  1283.                 else if (SEASON(TURN)==SUMMER) {
  1284.                     product*=5;
  1285.                     product/=4;
  1286.                 }
  1287.             }
  1288.             spread.revfood += product*TAXFOOD*nptr->tax_rate/100L;
  1289.         }
  1290. #endif DERVDESG
  1291.         else {    /* other sectors */
  1292.             spread.inothr += sptr->people;
  1293.             if(sptr->people>TOMANYPEOPLE) {
  1294.                 product = (long)tofood(sptr,sptr->owner) * TOMANYPEOPLE;
  1295.                 product += (long)tofood(sptr,sptr->owner) * (sptr->people-TOMANYPEOPLE)/2L;
  1296.             } else product = (long)tofood(sptr,sptr->owner) *  sptr->people;
  1297.  
  1298.             spread.revothr += product*TAXOTHR*nptr->tax_rate/100L;
  1299.         }
  1300.     }
  1301.     spread.gold += spread.revfood + spread.revjewels + spread.revmetal + spread.revcity + spread.revcap + spread.revothr;
  1302. }
  1303.  
  1304. #ifdef CONQUER
  1305.  
  1306. /* string inputing routine to allow deleting */
  1307. void
  1308. get_nname(str)
  1309. char str[];
  1310. {
  1311.     char ch;
  1312.     int done=0,count=0,xpos,ypos;
  1313.  
  1314.     while(!done) {
  1315.         ch=getch();
  1316.         if (isprint(ch)) {
  1317.             if (count<NAMELTH+1) {
  1318.                 /* only input displayable characters */
  1319.                 addch(ch);
  1320.                 refresh();
  1321.                 str[count++] = ch;
  1322.             }
  1323.         }
  1324.         else if ((ch=='\b' || ch=='\177')&&(count))
  1325.         {
  1326.             /* only delete what was printed */
  1327.             getyx(stdscr,ypos,xpos);
  1328.             move(ypos,--xpos);
  1329.             addch(' ');
  1330.             move(ypos,xpos);
  1331.             refresh();
  1332.             count--;
  1333.         } else if((ch=='\n')||(ch=='\r')) {
  1334.             done=TRUE;
  1335.         }
  1336.     }
  1337.     str[count] = '\0';
  1338. }
  1339.  
  1340. /* routine to find a nation number using name or number  */
  1341. /* returns NTOTAL+1 if input is invalid; -1 for no input */
  1342. int
  1343. get_country()
  1344. {
  1345.     char name[NAMELTH+1],ch;
  1346.     int i,l,hold;
  1347.  
  1348.     /* get name and check through list */
  1349.     get_nname(name);
  1350.  
  1351.     /* return on no entry */
  1352.     if ((l=strlen(name))==0) {
  1353.         return(-1);
  1354.     }
  1355.  
  1356.     for(hold=0;hold<NTOTAL;hold++)
  1357.         if(strcmp(ntn[hold].name,name)==0) break;
  1358.  
  1359.     /* check for 'god' */
  1360.     if (strcmp("god",name)==0) hold=0;
  1361.     if (strcmp("news",name)==0) hold= -2;
  1362.  
  1363.     /* check for numbers if name too long */
  1364.     if (hold==NTOTAL) {
  1365.         hold=0;
  1366.         for (i=0;i<l;i++) {
  1367.             ch=name[i];
  1368.             if(ch < '0' || ch > '9' ) {
  1369.                 getyx(stdscr,i,l);
  1370.                 mvprintw(i+1,0,"Invalid Nation <%s> -- hit any key",name);
  1371.                 clrtoeol();
  1372.                 refresh();
  1373.                 getch();
  1374.                 return(NTOTAL);
  1375.             } else {
  1376.                 hold *= 10;
  1377.                 hold += (ch-'0');
  1378.             }
  1379.         }
  1380.         if (hold>NTOTAL) hold=NTOTAL;
  1381.     }
  1382.     /* send back result */
  1383.     return(hold);
  1384. }
  1385.  
  1386. extern short country;
  1387. /* finds a nation for god to be, returns 1 on failure */
  1388. int
  1389. get_god()
  1390. {
  1391.     clear();
  1392.     mvaddstr(0,0,"SUPER USER; FOR WHAT NATION: ");
  1393.     refresh();
  1394.  
  1395.     /* return on no entry or bad entry */
  1396.     if ((country=get_country())==(-1) || country==NTOTAL) {
  1397.         country = 0;
  1398.         return(1);
  1399.     }
  1400.  
  1401.     curntn = &ntn[country];
  1402.     return(0);
  1403. }
  1404.  
  1405. /* quick routine to reassign god and gods nations */
  1406. void
  1407. reset_god()
  1408. {
  1409.     /* simple routine; but improves readibility */
  1410.     country=0;
  1411.     curntn= &ntn[country];
  1412. }
  1413. #endif CONQUER
  1414.  
  1415. #ifdef ADMIN
  1416. int
  1417. getleader(class)
  1418. int    class;
  1419. {
  1420.     switch(class){
  1421.     case C_NPC:
  1422.     case C_KING:
  1423.     case C_TRADER:    return(L_BARON);
  1424.     case C_EMPEROR:    return(L_PRINCE);
  1425.     case C_WIZARD:    return(L_MAGI);
  1426.     case C_PRIEST:    return(L_BISHOP);
  1427.     case C_PIRATE:    return(L_CAPTAIN);
  1428.     case C_WARLORD:    return(L_LORD);
  1429.     case C_DEMON:    return(L_DEVIL);
  1430.     case C_DRAGON:    return(L_WYRM);
  1431.     case C_SHADOW:    return(L_NAZGUL);
  1432.     default:
  1433.         printf("ERROR-national class (%d) undefined\n",class);
  1434.         exit(0);
  1435.     }
  1436.     return(-1);    /* shut lint up */
  1437. }
  1438. #endif ADMIN
  1439.  
  1440. void
  1441. mailopen(to)
  1442. {
  1443.     char    line[20];
  1444.     if(mailok == TRUE) mailclose();
  1445.  
  1446.     if (to != -2)
  1447.         sprintf(line,"%s%d",msgfile,to);
  1448.     else
  1449.         sprintf(line,"news%d",TURN -1);    /* -1 so it appears in
  1450.                            the news now        */
  1451.     if ((fm=fopen(line,"a+"))==NULL) {
  1452.         printf("error opening %s",line);
  1453.         return;
  1454.     }
  1455.     mailok=TRUE;
  1456. }
  1457.  
  1458. void
  1459. mailclose()
  1460. {
  1461.     if(mailok==FALSE) return;
  1462.  
  1463.     fputs("END\n",fm);
  1464.     fclose(fm);
  1465.     mailok=FALSE;
  1466. }
  1467.  
  1468. #ifdef ADMIN
  1469. /* markok returns TRUE if mark is ok as a nation mark */
  1470. int
  1471. markok(mark,prtflag)
  1472. char mark;
  1473. int prtflag;    /* if true printf reason */
  1474. {
  1475.     register int i;
  1476.  
  1477.     if((isprint(mark)==0)||(isspace(mark)!=0)) {
  1478.         if(prtflag) printf("%c is white space\n",mark);
  1479.         return(FALSE);
  1480.     }
  1481.  
  1482.     for(i=0;ele[i]!='0';i++) if(mark==(*(ele+i))) {
  1483.         if(prtflag) printf("%c is elevation character\n",mark);
  1484.         return(FALSE);
  1485.     }
  1486.  
  1487.     for(i=0;veg[i]!='0';i++) if(mark==(*(veg+i))) {
  1488.         if(prtflag) printf("%c is vegetition character\n",mark);
  1489.         return(FALSE);
  1490.     }
  1491.  
  1492.     for(i=1;i<NTOTAL;i++) if(ntn[i].mark==mark) {
  1493.         if(prtflag) printf("%c is already used\n",mark);
  1494.         return(FALSE);
  1495.     }
  1496.  
  1497.     if(mark=='*') {
  1498.         if(prtflag) printf("%c is *\n",mark);
  1499.         return(FALSE);
  1500.     }
  1501.  
  1502.     if(!isalpha(mark)) {
  1503.         if(prtflag) printf("%c is not an alpha character\n",mark);
  1504.         return(FALSE);
  1505.     }
  1506.     return(TRUE);
  1507. }
  1508. #endif ADMIN
  1509.  
  1510. /*******************************************************************/
  1511. /* DEFAULTUNIT() returns the default army type for a given country */
  1512. /* this is mostly used by npc's to take advantage of their powers  */
  1513. /*******************************************************************/
  1514. long
  1515. defaultunit( nation )
  1516. int    nation;
  1517. {
  1518.     if(magic(nation,VAMPIRE)) return(A_ZOMBIE);
  1519.     if(magic(nation,AV_MONST)) {
  1520.         if(magic(nation,BREEDER))
  1521.             return(A_OLOG);
  1522.         else    return(A_URUK);
  1523.     }
  1524.     if(magic(nation,ARCHER)) return(A_ARCHER);
  1525.     if(magic(nation,MI_MONST)) return(A_ORC);    /* if race = orc */
  1526.     if( ntn[nation].active==NPC_NOMAD ) return(A_LT_CAV);
  1527.     return(A_INFANTRY);
  1528. }
  1529.  
  1530. #ifdef ADMIN
  1531. void
  1532. getmetal( sptr )
  1533. struct s_sector *sptr;
  1534. {
  1535.     int randval;
  1536.     randval = rand()%100;
  1537.     if((sptr->tradegood != TG_none)&&(sptr->tradegood != 0)) return;
  1538.     if( randval < 20 ) {
  1539.         sptr->tradegood = TG_copper;
  1540.         sptr->metal = rand()%2 + 1;
  1541.     } else if( randval < 30 ) {
  1542.         sptr->tradegood = TG_lead;
  1543.         sptr->metal = rand()%4 + 1;
  1544.     } else if( randval < 40 ) {
  1545.         sptr->tradegood = TG_tin;
  1546.         sptr->metal = rand()%4 + 2;
  1547.     } else if( randval < 55 ) {
  1548.         sptr->tradegood = TG_bronze;
  1549.         sptr->metal = rand()%4 + 2;
  1550.     } else if( randval < 80 ) {
  1551.         sptr->tradegood = TG_iron;
  1552.         sptr->metal = rand()%7 + 2;
  1553.     } else if( randval < 95 ) {
  1554.         sptr->tradegood = TG_steel;
  1555.         sptr->metal = rand()%8 + 3;
  1556.     } else if( randval < 99 ) {
  1557.         sptr->tradegood = TG_mithral;
  1558.         sptr->metal = rand()%11 + 5;
  1559.     } else {
  1560.         sptr->tradegood = TG_adamantine;
  1561.         sptr->metal = rand()%13 + 8;
  1562.     }
  1563. }
  1564.  
  1565. void
  1566. getjewel( sptr )
  1567. struct s_sector *sptr;
  1568. {
  1569.     int randval;
  1570.     if((sptr->tradegood != TG_none)&&(sptr->tradegood != 0)) return;
  1571.     randval = rand()%100;
  1572.     if( randval < 20 ) {
  1573.         sptr->tradegood = TG_spice;
  1574.         sptr->jewels = rand()%2 + 1;
  1575.     } else if( randval < 40 ) {
  1576.         sptr->tradegood = TG_silver;
  1577.         sptr->jewels = rand()%3 + 1;
  1578.     } else if( randval < 48 ) {
  1579.         sptr->tradegood = TG_pearls;
  1580.         sptr->jewels = rand()%3 + 1;
  1581.     } else if( randval < 56 ) {
  1582.         sptr->tradegood = TG_dye;
  1583.         sptr->jewels = rand()%5 + 1;
  1584.     } else if( randval < 64 ) {
  1585.         sptr->tradegood = TG_silk;
  1586.         sptr->jewels = rand()%5 + 1;
  1587.     } else if( randval < 84 ) {
  1588.         sptr->tradegood = TG_gold;
  1589.         sptr->jewels = rand()%6 + 1;
  1590.     } else if( randval < 91 ) {
  1591.         sptr->tradegood = TG_rubys;
  1592.         sptr->jewels = rand()%6 + 1;
  1593.     } else if( randval < 96 ) {
  1594.         sptr->tradegood = TG_ivory;
  1595.         sptr->jewels = rand()%7 + 2;
  1596.     } else if( randval < 99 ) {
  1597.         sptr->tradegood = TG_diamonds;
  1598.         sptr->jewels = rand()%11 + 2;
  1599.      } else {
  1600.         sptr->tradegood = TG_platinum;
  1601.         sptr->jewels = rand()%17 + 4;
  1602.     }
  1603. }
  1604. #endif ADMIN
  1605.  
  1606. /* tg_ok returns true if a trade good can be seen by the owner of sector */
  1607. int
  1608. tg_ok( nation, sptr )
  1609. int    nation;
  1610. struct    s_sector    *sptr;
  1611. {
  1612.     if(( nation == 0)||(nation>=NTOTAL)) return(TRUE);
  1613.  
  1614.     switch( sptr->tradegood ) {
  1615.     case TG_lead:    if(ntn[nation].mine_ability < 8) return(0); break;
  1616.     case TG_tin:    if(ntn[nation].mine_ability < 11) return(0); break;
  1617.     case TG_bronze:    if(ntn[nation].mine_ability < 15) return(0); break;
  1618.     case TG_iron:    if(ntn[nation].mine_ability < 25) return(0); break;
  1619.     case TG_steel:    if(ntn[nation].mine_ability < 30) return(0); break;
  1620.     case TG_mithral: if(ntn[nation].mine_ability < 30) return(0); break;
  1621.     case TG_adamantine: if(ntn[nation].mine_ability < 40) return(0); break;
  1622.     case TG_spice:
  1623.     case TG_silver:
  1624.     case TG_pearls:    break;
  1625.     case TG_dye:
  1626.     case TG_silk:
  1627.     case TG_gold:    if(ntn[nation].wealth < 5) return(0); break;
  1628.     case TG_rubys:
  1629.     case TG_ivory:    if(ntn[nation].wealth < 10) return(0); break;
  1630.     case TG_diamonds:
  1631.     case TG_platinum:    if(ntn[nation].wealth < 20) return(0); break;
  1632.     default:        break;
  1633.     };
  1634.  
  1635.     if(tofood(sptr,nation) >= DESFOOD) return(TRUE);
  1636.     return(FALSE);
  1637. }
  1638.  
  1639. /* this routine computes the fortification value of a sector */
  1640. int
  1641. fort_val(sptr)
  1642.     struct s_sector *sptr;
  1643. {
  1644.     if(sptr->designation==DSTOCKADE) {
  1645.         return(DEF_BASE);
  1646.     }
  1647.     if(sptr->designation==DFORT){
  1648.         if(magic(sptr->owner,ARCHITECT)==1){
  1649.             return(DEF_BASE + 2*FORTSTR * sptr->fortress);
  1650.         }
  1651.         else return(DEF_BASE + FORTSTR * sptr->fortress);
  1652.     }
  1653.     if (sptr->designation==DTOWN){
  1654.         if(magic(sptr->owner,ARCHITECT)==1){
  1655.             return(DEF_BASE + 2*TOWNSTR * sptr->fortress);
  1656.         } else return(DEF_BASE + TOWNSTR * sptr->fortress);
  1657.     }
  1658.     if((sptr->designation==DCAPITOL)
  1659.     ||(sptr->designation==DCITY)){
  1660.         if(magic(sptr->owner,ARCHITECT)==1){
  1661.             return(2*DEF_BASE + 2*CITYSTR * sptr->fortress);
  1662.         }
  1663.         else return(2*DEF_BASE + CITYSTR * sptr->fortress);
  1664.     }
  1665.     return(0);
  1666. }
  1667.  
  1668. /* routine to determine compass direction of x1,y1 from x0,y0 */
  1669. int
  1670. compass(x0,y0,x1,y1)
  1671.     int x0,y0,x1,y1;
  1672. {
  1673.     int dx=x1-x0, dy=y1-y0;    /* diplacements */
  1674.     int hold;
  1675.  
  1676.     if(10*abs(dx) > abs(dy)) {
  1677.         if(10*abs(dy) > abs(dx)) {
  1678.             /* four off-quadrants */
  1679.             if(dx>0) {
  1680.                 if(dy<0) hold=NORTHEAST;
  1681.                 else hold=SOUTHEAST;
  1682.             } else {
  1683.                 if(dy<0) hold=NORTHWEST;
  1684.                 else hold=SOUTHWEST;
  1685.             }
  1686.         } else {
  1687.             /* east or west */
  1688.             if(dx>0) hold=EAST;
  1689.             else hold=WEST;
  1690.         }
  1691.     } else {
  1692.         /* north or south or same point */
  1693.         if(dy==0) hold=CENTERED;
  1694.         else if(dy<0) hold=NORTH;
  1695.         else hold=SOUTH;
  1696.     }
  1697.     return(hold);
  1698. }
  1699.  
  1700. #ifdef CONQUER
  1701. #include    <sys/types.h>
  1702. #include    <sys/stat.h>
  1703. extern short xcurs;
  1704. extern short ycurs;
  1705. off_t conq_mail_size=0;
  1706. #ifdef SYSMAIL
  1707. static off_t sys_mail_size=0;
  1708. #endif SYSMAIL
  1709. void
  1710. check_mail()
  1711. {
  1712.     struct stat info;
  1713. #ifdef SYSMAIL
  1714.     int osys_mail=sys_mail_status;
  1715. #endif
  1716.     int oconq_mail=conq_mail_status;
  1717.  
  1718.     /* check conquer mail box */
  1719.     if (stat(conqmail,&info)==(-1)) {
  1720.         conq_mail_status=NO_MAIL;
  1721.         conq_mail_size=0;
  1722.     } else {
  1723.         if (info.st_size > conq_mail_size) {
  1724.             conq_mail_status=NEW_MAIL;
  1725.             conq_mail_size=info.st_size;
  1726.         } else if (info.st_size < conq_mail_size) {
  1727.             conq_mail_status=NO_MAIL;
  1728.             conq_mail_size=info.st_size;
  1729.         }
  1730.     }
  1731.  
  1732. #ifdef SYSMAIL
  1733.     /* check system mail box */
  1734.     if (stat(sysmail,&info)==(-1)) {
  1735.         sys_mail_status=NO_MAIL;
  1736.         sys_mail_size=0;
  1737.     } else {
  1738.         if(info.st_atime>info.st_mtime) {
  1739.             sys_mail_status=NO_MAIL;
  1740.             sys_mail_size=info.st_size;
  1741.         } else if (info.st_size > sys_mail_size) {
  1742.             sys_mail_status=NEW_MAIL;
  1743.             sys_mail_size=info.st_size;
  1744.         } else if (info.st_size < sys_mail_size) {
  1745.             sys_mail_status=NO_MAIL;
  1746.             sys_mail_size=info.st_size;
  1747.         }
  1748.     }
  1749.  
  1750.     /* display mail information */
  1751.     if(sys_mail_status!=osys_mail) {
  1752.         if (sys_mail_status==NEW_MAIL) {
  1753.             mvaddstr(LINES-3,COLS/2-6,"You have System Mail");
  1754.         } else {
  1755.             mvaddstr(LINES-3,COLS/2-6,"                    ");
  1756.         }
  1757.         move(ycurs,2*xcurs);
  1758.         refresh();
  1759.     }
  1760.     if (conq_mail_status!=oconq_mail) {
  1761.         if (conq_mail_status==NEW_MAIL) {
  1762.             mvaddstr(LINES-2,COLS/2-6,"You have Conquer Mail");
  1763.         } else {
  1764.             mvaddstr(LINES-2,COLS/2-6,"                     ");
  1765.         }
  1766.         move(ycurs,2*xcurs);
  1767.         refresh();
  1768.     }
  1769. #else
  1770.     /* display mail information */
  1771.     if (conq_mail_status!=oconq_mail) {
  1772.         if (conq_mail_status==NEW_MAIL) {
  1773.             mvaddstr(LINES-3,COLS/2-6,"You have Conquer Mail");
  1774.         } else {
  1775.             mvaddstr(LINES-3,COLS/2-6,"                     ");
  1776.         }
  1777.         move(ycurs,2*xcurs);
  1778.         refresh();
  1779.     }
  1780. #endif SYSMAIL
  1781. }
  1782. #endif CONQUER
  1783.