home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume13 / dominion / part21 / npc.c < prev   
C/C++ Source or Header  |  1992-02-11  |  19KB  |  599 lines

  1.    /* npc.c -- modules involved in NPC movemaking */
  2.  
  3. /*
  4.  * Copyright (C) 1990 Free Software Foundation, Inc.
  5.  * Written by the dominion project.
  6.  *
  7.  * This file is part of dominion.
  8.  *
  9.  * dominion is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License as published
  11.  * by the Free Software Foundation; either version 1, or (at your option)
  12.  * any later version.
  13.  *
  14.  * This software is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this software; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23. #ifdef SYSV
  24. # include <string.h>
  25. #else
  26. # include <strings.h>
  27. #endif /* SYSV */
  28.  
  29. #include "dominion.h"
  30. #include "misc.h"
  31. #include "army.h"
  32. #include <math.h>
  33. #include <curses.h>
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #include <signal.h>
  37.  
  38. extern Sworld world;
  39. extern Suser user;
  40. extern struct s_desig_map desig_map[];
  41. extern int (*wrapx)(), (*wrapy)();
  42. extern Sdiplo **allocate_diplo();
  43. extern int debug;
  44. extern struct army_type *army_types;
  45. extern struct spirit_type *spirit_types;
  46.  
  47. struct desire {
  48.   int base,final;
  49. };
  50.  
  51. float npc_food_need,npc_metal_need,npc_jewel_need,npc_money_need;
  52. int opt_army_size,atwar,npc_specific;
  53.  
  54. /*-----------------------------npc_moves()------------------------------------
  55.     This function makes the moves for an npc
  56. ----------------------------------------------------------------------------*/
  57. npc_moves(np)
  58.      Snation *np;
  59. {
  60.   int i;
  61.   struct desire **des_array;
  62.  
  63.   des_array = (struct desire **) malloc(world.xmax*sizeof(struct desire*));
  64.   for (i = 0; i < world.xmax; ++i)
  65.     des_array[i] = (struct desire *) malloc(world.ymax*sizeof(struct desire));
  66.   if (debug)
  67.     printf("doing init\n");
  68.   init_npc(np);
  69. /*  npc_needs(np); */
  70.   do_npc_draft(np);
  71.   if (debug)
  72.     printf("doing merge\n");
  73.   do_npc_merge(np);
  74.   if (debug)
  75.     printf("doing split\n");
  76.   do_npc_split(np);
  77.   if (debug)
  78.     printf("doing summon\n");
  79.   do_npc_summon(np);
  80.   if (debug)
  81.     printf("doing armies\n");
  82.   do_npc_armies(np,des_array);
  83.   if (debug)
  84.     printf("doing redesig\n");
  85.   do_npc_redesig(np);
  86.  
  87.   for (i = 0; i < world.xmax; i++)    /* free desire array */
  88.     free(des_array[i]);
  89.   free(des_array);
  90.  
  91.   for (i = 0; i < world.xmax; ++i) {    /* free visible sectors array */
  92.     free(user.visible_sectors[i]);
  93.   }
  94.   free(user.visible_sectors);
  95.  
  96.   free_diplo(user.diplo_matrix, world.n_nations);
  97. }
  98.  
  99. /*-------------------------------init_npc()----------------------------------
  100.     This is basically the function init_user, copied from user.c.  There
  101. are some things that init_user does that this does not do.
  102.     Also, this function sets global varibles like needs and race-specific
  103. army types.
  104. ---------------------------------------------------------------------------*/
  105. init_npc(np)
  106.      Snation *np;
  107. {
  108.   int c,i,d;
  109.   FILE *fp, *fopen();
  110.   char line[EXECLEN];
  111.  
  112.     /* find out which army types are available to the user */
  113.   user.avail_armies = NULL;
  114.   get_avail_armies(&user, np->tech_skill);
  115.  
  116.     /*------ set npc_specific to be 1 + the index of the race 
  117.          specific army type, if any.  ---------------*/
  118.   npc_specific = 0;
  119.   if ((fp = fopen(RACES_FILE, "r")) != NULL) {
  120.     while (1) {
  121.       if (fgets(line, EXECLEN, fp) == NULL)
  122.         break;
  123.       if (strncmp(line, np->race.name, strlen(np->race.name)) == 0
  124.       && strncmp(line+strlen(np->race.name), "_armies:",
  125.              strlen("_armies:")) == 0) {
  126.         if (line[strlen(line)-1] == '\n') {
  127.           line[strlen(line)-1] = '\0';
  128.     }
  129.     npc_specific = army_type_index(strchr(line, ':')+1) + 1;
  130.       }
  131.     }
  132.     fclose(fp);
  133.   }
  134.  
  135.   user.spirit_list = NULL;
  136.   get_spirits(&user, np->mag_skill);
  137.     /* now set fields for the ustruct */
  138.   user.underwater = 0;        /* user is not underwater at start */
  139.   if (np->race.pref_alt < 0) {
  140.     user.underwater = 1;    /* merfolk or whatever */
  141.   }
  142.     /* load user's diplomacy statuses, for fast access later;
  143.        also remember the initial values, so users cannot change
  144.        their status by more than one step at a time.
  145.      */
  146.   user.diplo_matrix = allocate_diplo(world.n_nations);
  147. /*  user.init_diplo = allocate_diplo(world.n_nations); */
  148.   read_in_diplo(user.diplo_matrix, world.n_nations);
  149. /*  read_initial_diplo(user.init_diplo, world.n_nations); */
  150.  
  151. /* now do diplomacy and set the atwar variable to 1 if npc is at war */
  152.   do_npc_diplo(np);
  153.  
  154.     /* load hanging spells, and put them in this user's list */
  155.   load_h_spells(&user);
  156.     /* calculate visibility matrix for this user.
  157.        this might depend on spells, so do it after
  158.        loading spells.
  159.      */
  160.   user.visible_sectors = (int **) malloc(world.xmax*sizeof(int *));
  161.   for (i = 0; i < world.xmax; ++i) {
  162.     user.visible_sectors[i] = (int *) malloc(world.ymax*sizeof(int));
  163.   }
  164.   find_visible_sectors(user.visible_sectors);
  165.  
  166.  
  167. /*  npc_money_need =(float)calc_expend(np)/((float)calc_revenue(np)+1.0);
  168.   npc_metal_need =(float)calc_expend_metal(np)/((float)calc_metal(np)+1.0)+.3;
  169. npc_jewel_need =(float)calc_expend_jewels(np)/((float)calc_jewels(np)+1.0)+.3;*/
  170.  
  171.   npc_metal_need = atwar ? 1.3:1.0; /* for now */
  172.   npc_jewel_need = atwar ? 1.3:1.0; /* for now */
  173.   npc_food_need = (float)calc_expend_food(np)/((float)calc_food(np)+1.0);
  174.   if(atwar){
  175.     opt_army_size = get_n_soldiers(np)*2/np->n_sects;
  176.     opt_army_size=max(OCCUPYING_SOLDIERS*3/2,opt_army_size);
  177.   }
  178.   else{
  179.     opt_army_size = OCCUPYING_SOLDIERS;
  180.   }
  181.  
  182.   if(debug)
  183.     printf("opt size = %d.\n",opt_army_size);
  184.  
  185.   if(atwar){
  186.     np->taxes = 20;
  187.     np->tech_r_d_metal = 0;
  188.     if (next_thon_jewels(np) < MAGE_JEWELS_MAINT) {
  189.       np->mag_r_d_jewels = 0;
  190.     } else {
  191.       if (calc_jewels(np) * 2 > np->jewels) {
  192.     np->mag_r_d_jewels = np->jewels * 50 / calc_jewels(np);
  193.       } else {
  194.     np->mag_r_d_jewels = 100;
  195.       }
  196.     }
  197.     np->mag_r_d = 15;
  198.     np->tech_r_d = 15;
  199.   } else {
  200.     np->taxes = 10;
  201.     np->tech_r_d_metal = 30;
  202.     np->mag_r_d_jewels = 0;
  203.     np->mag_r_d = 30;
  204.     np->tech_r_d = 30;
  205.   }
  206. }
  207.  
  208. /*---------------------------do_npc_draft()-----------------------------------
  209.     Draft armies.  This routine has been altered to take technology
  210. level into account.
  211. ----------------------------------------------------------------------------*/
  212. do_npc_draft(np)
  213.      Snation *np;
  214. {
  215.   Sarmy ap, make_army();
  216.   Ssector *sp;
  217.   Savail_army *can_draft;
  218.   struct army_type this_atype;
  219.   int max_sold,cur_sold,ngood,good_armies[MAX_TYPES],i,drafted;
  220.   int cut1,cut2,start,stop,step;
  221.   char type[NAMELEN];
  222.  
  223.     /*-------- Initialize variables for npc drafting -------*/
  224.   if(atwar) max_sold = get_n_civil(np)*np->npc_agg/200;
  225.   else max_sold = get_n_civil(np)*np->npc_agg/300;
  226.  
  227.   cut1 = max_sold*(np->npc_agg/2)/100;        /* -30 bonus cutoff */
  228.   cut2 = max_sold*(np->npc_agg/2 + 25)/100;    /* -1 to -29 bonus cutoff */
  229.   cur_sold = get_n_soldiers(np);
  230.   ngood = get_good_types(good_armies,cur_sold,cut1,cut2);
  231.  
  232.     /*--- now draft from the cheap armies if we are desperate ------*/
  233.   if(cur_sold < cut2 || (cur_sold - cut2 < max_sold - cur_sold)){
  234.     start = 0;
  235.     stop = ngood;
  236.     step = 1;
  237.   } else{
  238.     start = ngood-1;
  239.     stop = -1;
  240.     step = -1;
  241.   }
  242.     /*--- get cut 2 out of the way if we have already passed it ---*/
  243.   if(cur_sold > cut2) cut2 = 2*max_sold;
  244.  
  245.   if(ngood == 0)    /* no armies we want to draft */
  246.     return;
  247.  
  248.         /*------ Now draft armies ---------*/
  249.   while(cur_sold < max_sold){
  250.     drafted = 0;
  251.     for(i = start;(i != stop) && (cur_sold < max_sold);i += step){
  252.       this_atype = army_types[good_armies[i]];
  253.       strcpy(type,this_atype.type);
  254.       sp = &world.map[np->capital.x][np->capital.y];
  255.       ap = make_army(type,type, opt_army_size, A_DEFEND, np->id, sp->loc);
  256.       ap.id = free_army_id(np);
  257.       ap.next = NULL;
  258.       if (ap.n_soldiers > sp->n_people || army_cost(&ap) > np->money ||
  259.             army_cost_metal(&ap) > np->metal) {
  260.         break;
  261.       }
  262.       ++np->n_armies;
  263.       cur_sold += opt_army_size;
  264.       drafted = 1;
  265.       if (debug)
  266.         printf("npc drafted %s\n",type);
  267.  
  268.       if (np->armies == NULL) {
  269.         np->armies = (Sarmy *) malloc(sizeof(Sarmy));
  270.         *(np->armies) = ap;
  271.         np->armies->next = NULL;
  272.       } else {
  273.         insert_army_nation(np, &ap, -1);
  274.       }
  275.       insert_army_sector(sp, &ap);
  276.       sp->n_people -= ap.n_soldiers;
  277.       np->money -= army_cost(&ap);
  278.       np->metal -= army_cost_metal(&ap);
  279.     }
  280.   if(cur_sold > cut2){            /* need to recalc good types */
  281.     cut1 = max_sold*(np->npc_agg/2)/100;    /* -30 bonus cutoff */
  282.     cut2 = max_sold*(np->npc_agg/2 + 25)/100;    /* -1 to -29 bonus cutoff */
  283.     ngood = get_good_types(good_armies,cur_sold,cut1,cut2);
  284.     if(cur_sold > cut1) cut1 = 2*max_sold;
  285.     if(cur_sold > cut2) cut2 = 2*max_sold;
  286.   }
  287.   if(!drafted || !ngood)    /* No armies can be drafted anymore */
  288.     return;
  289.   }
  290. }
  291.  
  292. /*----------------------------do_npc_summon()--------------------------------
  293.     Have the npc draft a mage, if necessary, and summon spirits.
  294. Basically, find the net spell points and draft the biggest spirit you can.
  295. Don't draft caravan spirits.
  296. ---------------------------------------------------------------------------*/
  297. do_npc_summon(np)
  298. Snation *np;
  299. {
  300.   int have_mage = 0,sindex,net_points,badflags;
  301.   Sarmy army,make_army();
  302.   struct spirit_type this_stype;
  303.   Ssector *sp;
  304.   Sspirit *sptr,*tmp_sptr;
  305.  
  306.   if(!atwar || np->spell_pts < 2)
  307.     return;
  308.  
  309.   badflags = AF_INVERSE_ALT & AF_CARGO;
  310.   if (user.underwater)
  311.     badflags |= AF_LAND;
  312.   else
  313.     badflags |= AF_WATER;
  314.  
  315.   sp = &world.map[np->capital.x][np->capital.y];
  316.  
  317.   have_mage = get_first_mage(np);
  318.   if (!have_mage) {
  319.     if (np->jewels >= INITIATION_JEWELS && next_thon_jewels(np) > 6000)
  320.       init_npc_mage(np,sp);
  321.     else
  322.       return;            /* no mage, can't summon */
  323.   }
  324.   
  325.   net_points = new_spell_pts(np) - military_maint_spell_pts(np);
  326.   while(net_points){        /* while we can still summon */
  327.     tmp_sptr = 0;
  328.     for(sptr = user.spirit_list ; sptr ; sptr = sptr->next){
  329.       if (np->spell_pts < sptr->cost) 
  330.     break;
  331.       tmp_sptr = sptr;
  332.     }
  333.     if (!tmp_sptr)
  334.       break;
  335.  
  336.     sindex = spirit_type_index(tmp_sptr->type);
  337.     this_stype = spirit_types[sindex];
  338.     while ((this_stype.flags & badflags) && sptr != user.spirit_list){
  339.       for (sptr = user.spirit_list ;sptr->next != tmp_sptr ;sptr = sptr->next);
  340.       sindex = spirit_type_index(sptr->type);
  341.       this_stype = spirit_types[sindex];
  342.       tmp_sptr = sptr;
  343.       }
  344.  
  345.     if (this_stype.flags & badflags)
  346.       break;
  347.  
  348.     if (debug)
  349.       printf("npc summons %s\n",tmp_sptr->type);
  350.  
  351.     army = make_army(this_stype.type, this_stype.type, this_stype.size,
  352.              A_DEFEND, np->id, sp->loc);
  353.     army.id = free_army_id(np);
  354.     army.next = NULL;
  355.     army.flags = this_stype.flags;
  356.  
  357.   /*============ now insert it into the list ============*/
  358.  
  359.     ++np->n_armies;
  360.     if (np->armies == NULL) {         /* special case:  empty list */
  361.       np->armies = (Sarmy *) malloc(sizeof(Sarmy));
  362.       *(np->armies) = army;
  363.       np->armies->next = NULL;
  364.     } else {
  365.       insert_army_nation(np, &army, -1);
  366.     }
  367.     insert_army_sector(sp, &army);
  368.     np->spell_pts -= spirit_types[sindex].spell_pts_draft;
  369.     net_points = new_spell_pts(np) - military_maint_spell_pts(np);
  370.   }
  371. }
  372.  
  373. /*-----------------------------do_npc_merge()--------------------------------
  374.     merge npc armies together.  If an army has less than an optimal
  375. number of units, check for other armies of the npc that are reachable and
  376. within NPC_VIEW sectors.  Move to the one that will give the greatest
  377. movement left and merge.  Prefer to merge with other armies that have
  378. less than the optimal number.
  379. ---------------------------------------------------------------------------*/
  380. do_npc_merge(np)
  381.   Snation *np;
  382. {
  383.   int i,tx,ty,x,y,finalmv;
  384.   Pt finalpos;
  385.   Sarmy *bestarmy,*ap,*tmpap,*get_army();
  386.   struct armyid *alist;
  387.   struct argument args[N_EXEC_ARGS];
  388.   struct tmp_map {
  389.     int mvcost,mvleft;
  390.   } legal_moves[NPC_SIDE][NPC_SIDE];
  391.  
  392.   for(i = 0;i < NPC_SIDE; i++){            /* fill in border of legal mv */
  393.     legal_moves[0][i].mvleft = -2;
  394.     legal_moves[NPC_SIDE-1][i].mvleft = -2;
  395.     legal_moves[i][0].mvleft = -2;
  396.     legal_moves[i][NPC_SIDE-1].mvleft = -2;
  397.   }
  398.  
  399.   for(ap = np->armies ;ap ;ap = ap->next){    /* for all npcs armies */
  400.     if(ap->n_soldiers >= max(opt_army_size*2/3,OCCUPYING_SOLDIERS))
  401.       continue;                    /* skip loop if army ok. */
  402.     if(is_mage(ap))
  403.       continue;
  404.     bestarmy = 0;
  405.     check_moves(np,ap,legal_moves);        /* new function */
  406.  
  407.     /* now check for armies belonging to this player that can be moved to */
  408.  
  409.  /*   printf("%d needs to merge.\n",ap->id); */
  410.     for (x = ap->pos.x-NPC_VIEW; x <= ap->pos.x+NPC_VIEW; x++) {
  411.       for (y = ap->pos.y-NPC_VIEW; y <= ap->pos.y+NPC_VIEW; y++) {
  412.     alist = world.map[(*wrapx)(x,y)][(*wrapy)(x,y)].alist;
  413.     while(alist){
  414.       if(alist->owner == np->id){        /* if same owner */
  415.         tx = x - ap->pos.x + NPC_VIEW + 1;
  416.         ty = y - ap->pos.y + NPC_VIEW + 1;    /* coords in legal_move */
  417.         if(legal_moves[tx][ty].mvleft >= 0){
  418.           tmpap = get_army(np, alist->id);
  419.         /* printf("looking at army %d\n",tmpap->id); */
  420.           if(tmp_army_better(ap,tmpap,bestarmy) && tmpap != ap){
  421.         /* printf("best is %d\n",tmpap->id); */
  422.             bestarmy = tmpap;
  423.         finalpos.x = x;
  424.         finalpos.y = y;
  425.         finalmv = legal_moves[tx][ty].mvleft;
  426.               }
  427.         }
  428.       }
  429.       alist = alist->next;
  430.     }    /* while alist */
  431.       }        /* for y */
  432.     }        /* for x */
  433.  
  434.   /* now move the army to the correct location and merge.  */
  435.     if(bestarmy){
  436.       if (debug)
  437.         printf("npc army %d merges with %d.\n",ap->id,bestarmy->id);
  438.       args[1].data.num = ap->id;
  439.       alist = world.map[(*wrapx)(x,y)][(*wrapy)(x,y)].alist;
  440.       args[2].data.num = (*wrapx)(finalpos.x,finalpos.y);
  441.       args[3].data.num = (*wrapy)(finalpos.x,finalpos.y);
  442.       args[4].data.num = finalmv;
  443.       cmd_amove(np,args);        /* move army to new location */
  444.       args[1].data.num = ap->id;
  445.       args[2].data.num = bestarmy->id;
  446.       cmd_amerge(np,args);
  447.     }
  448.   }        /* for ap */
  449. }
  450.  
  451. /*--------------------------------do_npc_split()------------------------------
  452.     Split armies that have grown too large into manageable armies
  453. ----------------------------------------------------------------------------*/
  454. do_npc_split(np)
  455. Snation *np;
  456. {
  457.   Sarmy *ap;
  458.   struct argument args[N_EXEC_ARGS];
  459.  
  460.   for(ap = np->armies ;ap ;ap = ap->next){    /* for all npcs armies */
  461.     if(ap->n_soldiers < opt_army_size*2 || is_spirit(ap))
  462.       continue;                    /* skip loop if army ok. */
  463.     while(ap->n_soldiers >= opt_army_size*2){
  464.       if (debug)
  465.     printf ("npc splits %d troops from army %d\n",opt_army_size,ap->id);
  466.       args[1].data.num = ap->id;
  467.       args[2].data.num = opt_army_size;
  468.       cmd_asplit(np,args);
  469.     }
  470.   }
  471. }
  472.  
  473. /*-------------------------------do_npc_armies()------------------------------
  474.     This routine moves npc armies to desirable sectors.  Des_array is
  475. an array containing the desirability of each sector on the map.  legal_moves
  476. is an array containing the sectors that the army can see, with the sectors
  477. that the army can move to marked with the number of movepoints the army will
  478. have left at that point.  The function looks for the most desirable sectors
  479. that the army can move to and puts them in the highlist array.  It then
  480. randomly picks a point from this array and moves the army to it.
  481. ----------------------------------------------------------------------------*/
  482. do_npc_armies(np,des_array)
  483.   Snation *np;
  484.   struct desire **des_array;
  485. {
  486.   int i,x,y,tx,ty,des_here,high_des,nhigh;
  487.   struct pt highlist[NPC_SIDE*NPC_SIDE];
  488.   Sarmy *ap;
  489.   struct argument args[N_EXEC_ARGS];
  490.   struct tmp_map {
  491.     int mvcost,mvleft;
  492.   } legal_moves[NPC_SIDE][NPC_SIDE],final;
  493.  
  494.   find_desire(np,des_array);            /* fill desireability array */
  495.   for(i = 0;i < NPC_SIDE; i++){            /* fill in border of legal mv */
  496.     legal_moves[0][i].mvleft = -2;
  497.     legal_moves[NPC_SIDE-1][i].mvleft = -2;
  498.     legal_moves[i][0].mvleft = -2;
  499.     legal_moves[i][NPC_SIDE-1].mvleft = -2;
  500.   }
  501.  
  502.   /* Have NPC nation take sectors */
  503.   
  504.   if (np->n_armies == 0) {    /* If there are no armies, forget it */
  505.     return;
  506.   }
  507.   for (ap = np->armies; ap; ap = ap->next) {
  508.     if (debug)
  509.       printf("%d\n", ap->id);
  510.     if(is_mage(ap) && ap->n_soldiers == 1)
  511.       continue;
  512.     check_moves(np,ap,legal_moves);        /* new function */
  513.     high_des = -1;
  514.     for (x = ap->pos.x-NPC_VIEW; x <= ap->pos.x+NPC_VIEW; x++) {
  515.       for (y = ap->pos.y-NPC_VIEW; y <= ap->pos.y+NPC_VIEW; y++) {
  516.  
  517. /* Now check if it's the most desireable sector so far */
  518. /* and if it can be moved to. */
  519.  
  520.         if (good_altitude(&world.map[(*wrapx)(x,y)][(*wrapy)(x,y)],np)) {
  521.       des_here = des_array[(*wrapx)(x,y)][(*wrapy)(x,y)].final;
  522.       tx = x - ap->pos.x + NPC_VIEW + 1;
  523.       ty = y - ap->pos.y + NPC_VIEW + 1;
  524.       if (legal_moves[tx][ty].mvleft >= 0){
  525.         if(des_here > high_des) {
  526.           nhigh = 1;
  527.           highlist[0].x = x;
  528.           highlist[0].y = y;
  529.           high_des = des_here;
  530.         }
  531.         if(des_here == high_des) {
  532.           highlist[nhigh].x = x;
  533.           highlist[nhigh++].y = y;
  534.         }
  535.           }
  536.     }
  537.       }        /* end y loop */
  538.     }        /* enc x loop */
  539.  
  540.     /* Move army to one of the desireable sectors and change status to OCCUPY */
  541.     /* Change the desireability of the sector so not all the armies go there */
  542.  
  543.     i = RND() % nhigh;
  544.     tx = highlist[i].x - ap->pos.x + NPC_VIEW + 1;
  545.     ty = highlist[i].y - ap->pos.y + NPC_VIEW + 1;
  546.     x = (*wrapx)(highlist[i].x,highlist[i].y);
  547.     y = (*wrapy)(highlist[i].x,highlist[i].y);
  548.     args[1].data.num = ap->id;
  549.     args[2].data.num = x;
  550.     args[3].data.num = y;
  551.     args[4].data.num = legal_moves[tx][ty].mvleft;
  552.     cmd_amove(np,args);        /* move army to new location */
  553.     if(good_altitude(&world.map[x][y],np) || is_water(ap)){
  554.       args[2].data.num = A_OCCUPY;
  555.       cmd_astat(np,args);
  556.     }
  557.     des_array[x][y].final = des_array[x][y].final * opt_army_size /
  558.             (opt_army_size+ap->n_soldiers);
  559.   }
  560. }
  561.  
  562. /*------------------------------do_npc_redesig()-------------------------------
  563.     Redesignate sectors that the npc owns.
  564. -----------------------------------------------------------------------------*/
  565. do_npc_redesig(np)
  566.      Snation *np;
  567. {
  568.   struct pt_list *Pointer;
  569.   int Loop,x,y;
  570.  
  571.   /* Have NPC nation redesignate sectors */
  572.   
  573.   Pointer = np->ptlist;
  574.   for (Loop = 0; Loop < np->n_sects; Loop++) {
  575.     x = Pointer->pt.x;
  576.     y = Pointer->pt.y;
  577.     if (world.map[x][y].n_people > 0 &&
  578.     world.map[x][y].designation == D_NODESIG) {
  579.       if ((world.map[x][y].metal + world.map[x][y].jewels > 0)
  580.       && ((world.map[x][y].metal > world.map[x][y].soil - 6)
  581.       || (world.map[x][y].jewels > world.map[x][y].soil - 6))) {
  582.     if (world.map[x][y].metal > world.map[x][y].jewels) {
  583.       world.map[x][y].designation = D_METAL_MINE;
  584.       np->money -= desig_map[D_METAL_MINE].price;
  585.     } else {
  586.       world.map[x][y].designation = D_JEWEL_MINE;
  587.       np->money -= desig_map[D_JEWEL_MINE].price;
  588.     }
  589.       } else {
  590.     if (world.map[x][y].soil >= 0) {
  591.       world.map[x][y].designation = D_FARM;
  592.       np->money -= desig_map[D_FARM].price;
  593.     }
  594.       }
  595.     }
  596.   Pointer = Pointer->next;
  597.   }
  598. }
  599.