home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume6 / gb / part01 / doplanet.c next >
C/C++ Source or Header  |  1989-07-06  |  16KB  |  476 lines

  1. /*
  2.  * Galactic Bloodshed (Robert Chansky, smq@b)
  3.  *  doplanet.c -- do one turn on a planet.
  4.  */ 
  5.  
  6. #include "vars.h"
  7. #include "ships.h"
  8. #include "races.h"
  9. #include "doturn.h"
  10. #include "power.h"
  11. extern struct power Power[];
  12. #include <math.h>
  13. extern bool Nuked[];
  14.  
  15. extern int Ignore_lockfile;
  16.  
  17. char telegram_buf[AUTO_TELEG_SIZE];
  18.  
  19. int tot_resdep,tot_eff,tot_res,tot_fuel,tot_destruct,tot_captured,tot_mob;
  20. float avg_mob[MAXPLAYERS];
  21.  
  22. char sects_gained[MAXPLAYERS], sects_lost[MAXPLAYERS];
  23. float Compat[MAXPLAYERS];
  24. bool Claims;
  25.  
  26.  
  27. int doplanet(starnum,planet, planetnum, command)
  28. int starnum;
  29. planettype *planet;
  30. int planetnum;
  31. int command;
  32. {
  33. int inhab=0,x,y;
  34. reg int i;
  35. int shipno,o=0,j;
  36. sectortype *p;
  37. shiptype *ship;
  38. double att;
  39. float xadd,yadd,dist,t,madd,fadd;
  40. int sectdata,timer=20;
  41. int oldplanetpopn, oldplanetmaxpopn, allmod=0,allexp=0;
  42. char buf[200]; 
  43.  
  44.  
  45. for (i=1; i<=Num_races; i++) {
  46.     o |= isset(Stars[starnum]->inhabited,i);
  47.     inhab |= planet->info[i-1].numsectsowned;
  48. }
  49. if (!o)
  50.     return 0;    /* no one's explored the star yet */
  51.  
  52. if (inhab) {
  53.     printf(" getting sectmap pos %d\n",planet->sectormappos);
  54.     opensectdata(§data);
  55.     getsmap(sectdata,Smap,planet->sectormappos,planet->Maxx*planet->Maxy);
  56.     close(sectdata);
  57.  
  58.     PermuteSects(planet);
  59.     bzero((char *)Sectinfo, sizeof(Sectinfo) );
  60. }
  61.  
  62.  
  63.  
  64. dist = hypot((double)planet->ypos, (double)planet->xpos);
  65.     /* closer planets orbit faster */
  66. t = atan2((double)planet->ypos, (double)planet->xpos) - SYSTEMGRAVCONST * SYSTEMSIZE / dist;
  67. xadd = planet->xpos - dist * cos(t);
  68. yadd = planet->ypos - dist * sin(t);
  69.  
  70.  
  71. printf("xadd %g yadd %g \n", xadd, yadd);
  72.  
  73.        /* adjust ships in orbit around the planet */
  74.  
  75. for (shipno=0; shipno<MAXPSHIPS; shipno++)
  76.     if (planet->shipnums[shipno] && ((ship=ships[planet->shipnums[shipno]])!=NULL) && !ship->is_dead && !ship->rad) {
  77.        if ( !(ship->is_docked && ship->whatdest==LEVEL_PLAN)) {
  78.         /* adjust fuel, orbit for ships that are not landed */
  79.         ship->xpos += xadd;
  80.         ship->ypos += yadd;
  81.          /* add fuel to ships orbiting gas giants */
  82.         if (planet->type == TYPE_GASGIANT && !is_object(ship)) {
  83.          if (ship->type == STYPE_TANKER) {
  84.             fadd = FUEL_GAS_ADD_TANKER;
  85.             madd = FUEL_GAS_ADD_TANKER*MASS_FUEL;
  86.          } else if (ship->type == STYPE_STATION) {
  87.             fadd = FUEL_GAS_ADD_STATION;
  88.             madd = FUEL_GAS_ADD_STATION*MASS_FUEL;
  89.          } else {
  90.             fadd = FUEL_GAS_ADD;
  91.             madd = FUEL_GAS_ADD*MASS_FUEL;
  92.          }
  93.          if (ship->fuel + fadd > Shipdata[ship->type][ABIL_FUELCAP]) {
  94.             madd -= (Shipdata[ship->type][ABIL_FUELCAP] - (ship->fuel+fadd))*MASS_FUEL;
  95.             fadd = Shipdata[ship->type][ABIL_FUELCAP]-(ship->fuel+fadd);
  96.          }
  97.          ship->fuel += fadd;
  98.          ship->mass += madd;
  99.         }
  100.        }
  101.  
  102.        if ( (is_object(ship) && !ship->orders.object.on) || !is_object(ship)) {
  103.         if (ship->type == OTYPE_VN) {
  104.             /* Von Neumann machine */
  105.          if (ship->is_docked && ship->whatdest==LEVEL_PLAN) {
  106.         if (ship->orders.object.number2) {
  107.             /* we are currently trying to construct another
  108.                machine */
  109.           reg int x,y,a,dum;
  110.           for (i=1; i<253 && i<=ship->orders.object.number; i++) {
  111.             a = round_rand(sqrt((double)ship->orders.object.number));
  112.             x = mod(int_rand((int)(ship->xpos-a),(int)(ship->xpos+a)),(int)planet->xpos,dum);
  113.             y = mod(int_rand((int)(ship->ypos-a),(int)(ship->ypos+a)),(int)planet->ypos,dum);
  114.             Sectinfo[x][y].VN= 1;
  115.           }
  116.           if (ship->resource >= Shipdata[OTYPE_VN][ABIL_COST]) {
  117.            ship->resource -= Shipdata[OTYPE_VN][ABIL_COST];
  118.            ship->mass -= Shipdata[OTYPE_VN][ABIL_COST]*MASS_RESOURCE;
  119.            if (ship->orders.object.number > int_rand(5,50)) {
  120.             /* enough to start a new VN 'herd'. build another
  121.                ship. */
  122.             for (i=0; i<MAXPSHIPS && planet->shipnums[i]; i++) ;
  123.             if (i<MAXPSHIPS) {
  124.             shiptype *s2;
  125.             Num_ships++;
  126.             fprintf(stderr,"VN #%d constructed VN #%d.\n",shipno,Num_ships);
  127.             planet->shipnums[i] = Num_ships;
  128.             ships[Num_ships] = (shiptype *)malloc(sizeof(shiptype));
  129.             s2 = ships[Num_ships];
  130.             bzero((char *)s2,sizeof(shiptype));
  131.             s2->whatorbits = LEVEL_PLAN;
  132.             s2->storbits = ship->storbits;
  133.             s2->pnumorbits = ship->pnumorbits;
  134.             s2->xpos = ((int)ship->xpos + int_rand(-9,9)) % planet->Maxx;
  135.             s2->xpos = abs(s2->xpos);
  136.             s2->ypos = ((int)ship->ypos + int_rand(-4,4)) % planet->Maxy;
  137.             s2->ypos = abs(s2->ypos);
  138.             s2->is_docked = 1;
  139.             s2->whatdest = ship->whatdest;
  140.             s2->deststar = ship->deststar;
  141.             s2->destpnum = ship->destpnum;
  142.             s2->type = OTYPE_VN;
  143.             s2->mass = Shipdata[OTYPE_VN][ABIL_MASS];
  144.             s2->owner = 1;
  145.             s2->orders.object.number = 1;
  146.                 /* is not building any VN's */
  147.                 /* no assignment now */
  148.             ship->orders.object.number2 = 0;
  149.           } else
  150.             fprintf(stderr,"#%d can't slot insert new VN!!\n",shipno);
  151.          } else {
  152.             /* we don't have too many in this herd, so make 
  153.                some more */
  154.             ship->orders.object.number++;
  155.          }
  156.         } else {
  157.             /* if there are no players to steal from, try
  158.                and make some resources by ourselves */
  159.             reg int i,f=0;
  160.             for (i=Num_races-1; !f && i>0; i--)
  161.                 if (planet->info[i-1].resource)
  162.                     f=i;
  163.             if (!f) {
  164.                 /* nobody here */
  165. /*#                ifdef UV_4.3*/
  166.                 sectortype tmp;
  167.                 int tmp2;
  168.                 tmp = Sector(*planet,(int)(ship->xpos), (int)(ship->ypos));
  169.                 tmp2 = tmp.resource /5;
  170.                 ship->resource += tmp2;
  171.                 /*ship->resource += (Sector(*planet,(int)(ship->xpos), (int)(ship->ypos)).resource) / 5;
  172.                 ship->mass += ((Sector(*planet,(int)(ship->xpos), (int)(ship->ypos)).resource) / 5) * MASS_RESOURCE;*/
  173. /*#                else
  174.                 ship->resource += 7;
  175.                 ship->mass += 7 * MASS_RESOURCE;
  176. #                endif*/
  177.             }
  178.         }
  179.            } else {
  180.         /* we have no assignment -- we must launch. taken care of
  181.            in doship */
  182.            }
  183.           } else {    /* orbiting a planet */
  184.         if (ship->orders.object.number2) {
  185.          if (ship->whatdest==LEVEL_PLAN && ship->deststar==starnum && 
  186.             ship->destpnum==planetnum) {
  187.                 /* we just arrived from somewhere */
  188.             if (planet->type==TYPE_GASGIANT) {
  189.               if (ship->fuel >= Shipdata[OTYPE_VN][ABIL_FUELCAP])
  190.             ship->orders.object.number2 = 0;
  191.                 /* gas giants are of no use to us;
  192.                    doship() will head us somewhere else */
  193.             } else {
  194.             /* find a place on the planet to land */
  195.             int x,y; reg int d;        /* auto vars for & */
  196.             printf(" VN finding a place to land\n");
  197.             Getxysect(planet,&x,&y,1);
  198.             while ((d=Getxysect(planet,&x,&y,0)) && 
  199.                     Sector(*planet,x,y).des!=DES_LAND &&
  200.                     Sector(*planet,x,y).des!=DES_MOUNT &&
  201.                     Sector(*planet,x,y).resource==0)
  202.                      ;
  203.             if (d) {
  204.                 printf(" VN landed.\n");
  205.                 ship->is_docked = 1;
  206.                 ship->whatdest = LEVEL_PLAN;
  207.                 ship->deststar = ship->storbits;
  208.                 ship->destpnum = ship->pnumorbits;
  209.                 ship->xpos = x;
  210.                 ship->ypos = y;
  211.                 ship->orders.object.number2 = 1;
  212.                 /* number2 means we are currently
  213.                    busy here */
  214.             } else
  215.                  /* head somewhere else */
  216.                 ship->orders.object.number2 = 0;
  217.                 printf("turning off; can't find place 2land\n");
  218.             }
  219.          } else {
  220.             /* we just launched from this planet -- pick
  221.                someplace to go to (taken care of in doship) */
  222.          }
  223.         } else {
  224.             /* okay, we don't know what the hell we are doing here. 
  225.                wait for doship to give further orders. */
  226.         }
  227.           }
  228.         }
  229.        }
  230.  
  231.             /* bombard the planet */
  232.        if (!is_object(ship) && ship->orders.o.bombard
  233.             && ship->whatorbits==LEVEL_PLAN
  234.             && ship->whatdest==LEVEL_PLAN
  235.             && ship->storbits==ship->deststar
  236.             && ship->pnumorbits==ship->destpnum)
  237.         Bombard(ship,shipno,planet);     /* ship bombards planet */
  238.  
  239.         if (ship==NULL) {
  240.             fprintf(stderr,"null ship #%d slot %d .\n",planet->shipnums[shipno],shipno);
  241.             planet->shipnums[shipno] = 0;
  242.         }
  243.     }
  244. planet->xpos += xadd;
  245. planet->ypos += yadd;
  246. if (planet->xpos>SYSTEMSIZE) planet->xpos *= .5;
  247. else if (planet->xpos< -SYSTEMSIZE) planet->xpos *= .5;
  248. if (planet->ypos>SYSTEMSIZE) planet->ypos *= .5;
  249. else if (planet->ypos< -SYSTEMSIZE) planet->ypos *= .5;
  250.  
  251. if (!inhab && !Stinfo[starnum][planetnum].Thing_add)
  252.     return 0;    /* (no one's explored the planet) */
  253.  
  254.     /* check for space mirrors (among other things) warming the planet */
  255.     /* if a change in any artificial warming/cooling trends */
  256. if (Stinfo[starnum][planetnum].temp_add)
  257.     planet->conditions[TEMP] = planet->conditions[RTEMP] +
  258.             Stinfo[starnum][planetnum].temp_add + int_rand(-2,2);
  259. else
  260.     planet->conditions[TEMP] = planet->conditions[RTEMP] + int_rand(-2,2);
  261.  
  262.  
  263. bzero((char *)avg_mob, sizeof(avg_mob) );
  264. bzero((char *)sects_gained, sizeof(sects_gained) );
  265. bzero((char *)sects_lost, sizeof(sects_lost) );
  266. Claims = 0;
  267.  
  268. if (Stinfo[starnum][planetnum].Thing_add) {
  269.      /* start a meso colony */
  270.     x = int_rand(0,planet->Maxx-1);
  271.     y = int_rand(0,planet->Maxy-1);
  272.     Sector(*planet,x,y).des = DES_LAND;    /* cheating. so what. */
  273.     Sector(*planet,x,y).popn = 1;
  274.     Sector(*planet,x,y).owner = Stinfo[starnum][planetnum].Thing_add;
  275. }
  276. tot_resdep=tot_eff=tot_res=tot_fuel=tot_destruct=tot_mob=tot_captured=0;
  277.  
  278. oldplanetmaxpopn = planet->maxpopn;
  279. planet->maxpopn = 0; 
  280.  
  281. oldplanetpopn = planet->popn;
  282. planet->popn = 0;    /* initialize population for recount */ 
  283. for (i=1; i<=Num_races; i++) {
  284.     Compat[i] = compatibility(planet, races[i]);
  285.     planet->info[i-1].numsectsowned = 0;
  286. }
  287.  
  288. printf(" while %d\n",Getxysect(planet, &x, &y, 1));    /* reset */
  289. while (Getxysect(planet, &x, &y, 0)) {
  290.        p = &Sector(*planet,x,y);
  291.        if (p->owner) {
  292.         /* (all modified; sectors belonging to that player modified) */
  293.         allmod = 1;    
  294.         if (!p->popn ) {
  295.           p->owner=0;    /* make wasted/unowned sects go to player 0 */
  296.         } else {
  297.           planet->info[p->owner-1].numsectsowned++;
  298.           if (!Stars[starnum]->nova_stage) {
  299.                    /* spread excess popn to surrounding sects */
  300.                   spread(planet,p,x,y);    
  301.                   produce(planet,p);    /* produce stuff there */
  302.             planet->popn += p->popn;
  303.                Power[p->owner].popn += p->popn;
  304.                Power[p->owner].sum_eff += p->eff;
  305.                starpopns[starnum][p->owner] += p->popn;
  306.           } else {
  307.             /* damage sector from supernova */
  308.             p->resource++;
  309.             if (p->fert)
  310.                 --p->fert;
  311.             if (Stars[starnum]->nova_stage == 14)
  312.                 p->popn = 0;
  313.             else
  314.                 p->popn *= .80;
  315.           }
  316.         }
  317.        }
  318.  
  319.        planet->maxpopn += maxsupport(p);
  320.  
  321.        if (Sectinfo[x][y].VN)
  322.            p->VN = 1;
  323.        else
  324.            p->VN = 0;
  325.        if (p->is_wasted) {
  326.          if (x>1 && x<planet->Maxx-2) {
  327.             if (p->des==DES_SEA || p->des==DES_GAS) {
  328.                 /* don't reclaim pole sectors */
  329.                   if ( y>1 && y<planet->Maxy-2 && 
  330.                     (!(p-1)->is_wasted || !(p+1)->is_wasted)
  331.                     && !random()%5)
  332.                     p->is_wasted = 0;
  333.                   } else if (p->des==DES_LAND || p->des==DES_MOUNT) {
  334.                 if ( y>1 && y<planet->Maxy-2 && 
  335.                    ((p-1)->popn || (p+1)->popn)
  336.                    && !random()%10)
  337.                     p->is_wasted = 0;
  338.                   }
  339.         }
  340.        }
  341.  
  342.      /* evaporate the oceans on novae */
  343.      if (Stars[starnum]->nova_stage && p->des==DES_SEA)
  344.  
  345.     if ( (x>0 && (p-1)->des==DES_LAND) ||
  346.          (x<planet->Maxx-1 && (p+1)->des==DES_LAND) || 
  347.          (y>0 && (p-planet->Maxx)->des==DES_LAND) ||
  348.          (y<planet->Maxy-1 && (p+planet->Maxx)->des==DES_LAND ) ) {
  349.            p->des = DES_LAND;
  350.            p->popn = p->owner = 0;
  351.            p->resource += 3;
  352.            p->fert = int_rand(1,4);
  353.            printf("sect %d,%d evaporated.\n",x,y);
  354.     }
  355. }
  356.  
  357. if (allmod) {    /* ( >= 1 inhabited sector on the planet) */
  358.  
  359.      if (planet->expltimer >= 1)
  360.         planet->expltimer--;
  361.      if (!Stars[starnum]->nova_stage && !planet->expltimer) {
  362.       if (!planet->expltimer)
  363.         planet->expltimer = 5;
  364.        for (i=1; !Claims && !allexp && i<=Num_races; i++) {
  365.          printf("pl %d numsectsowned %d Claims %d allexp %d compat %f\n",i,planet->info[i-1].numsectsowned,Claims,allexp,Compat[i]);
  366.          /* sectors have been modified for this player*/
  367.          /* & planet is compatible enough */
  368.          if (planet->info[i-1].numsectsowned && Compat[i] > 40.0)
  369.            while (!Claims && !allexp && --timer) {
  370.          printf("exploring ... timer=%d\n",timer);
  371.         /*printf("exploring player %d\n",i);*/
  372.         o = 1;
  373.         Getxysect(planet, &x, &y, 1);
  374.         while (!Claims && Getxysect(planet, &x, &y, 0)) {
  375.               /* find out if all sectors have been explored */
  376.             o &= Sectinfo[x][y].explored[i];
  377.             p = &Sector(*planet,x,y);
  378.             if (!p->owner && !p->is_wasted && p->des==DES_LAND && Sectinfo[x][y].explored[i]) {
  379.                  /* (water) explorations have found an island */
  380.                 printf("found an island @ %d,%d\n",x,y);
  381.                 Claims = i;
  382.                  /* give them some free people there */
  383.                 p->popn = races[i]->number_sexes;
  384.                 tot_captured = 1;
  385.             } else
  386.                 explore(planet, p, x, y, i);
  387.         }
  388.         allexp |= o;    /* all sectors explored for this player */
  389.  
  390.            }
  391.            }
  392.      }
  393.     if (allexp)
  394.         planet->expltimer = 5;
  395.  
  396.  
  397.     for (i=1; i<=Num_races; i++)
  398.      if (planet->info[i-1].autorep) {
  399.  
  400.       planet->info[i-1].autorep--;
  401.       teleg_add("",telegram_buf);    /* clear buf */
  402.       sprintf(buf,"****** Report: Planet /%s/%s ******\n", 
  403.         Stars[starnum]->name, Stars[starnum]->pnames[planetnum] );
  404.       teleg_add(buf,telegram_buf);
  405.       if (Stinfo[starnum][planetnum].temp_add) {
  406.         sprintf(buf,"\nGlobal temperature alteration: %d to %d.\n\n", 
  407.             Temp(planet->conditions[RTEMP]), Temp(planet->conditions[TEMP]));
  408.         teleg_add(buf,telegram_buf);
  409.       }
  410.       teleg_add("resource prod.  fuel prod.  weapons prod. mob.pt prod.\n",telegram_buf);
  411.       sprintf(buf,"%12d%12d%15d%13d\n", tot_res, tot_fuel, tot_destruct,tot_mob);
  412.       teleg_add(buf,telegram_buf);
  413.       sprintf(buf,"resource deposit depletion: %d\n", tot_resdep);
  414.       teleg_add(buf,telegram_buf);
  415.       teleg_add("total births  (%%)    growth of max popn support  (%%)\n",telegram_buf);
  416.       sprintf(buf,"%9d      (%.2f%%)%23d   (%.2f%%)\n", 
  417.             planet->popn - oldplanetpopn, 
  418.             ((float)planet->popn-oldplanetpopn)/oldplanetpopn,
  419.             planet->maxpopn - oldplanetmaxpopn, 
  420.             ((float)planet->maxpopn-oldplanetmaxpopn)/oldplanetmaxpopn);
  421.       teleg_add(buf,telegram_buf);
  422.       sprintf(buf,"sectors owned on this planet: %d.\n", tot_captured);
  423.       teleg_add(buf,telegram_buf);
  424.       if (sects_gained[i] || sects_lost[i]) {
  425.           teleg_add("\nWAR STATUS: ",telegram_buf);
  426.           sprintf(buf,"%d sectors gained, %d sectors lost.\n",
  427.                     sects_gained[i],sects_lost[i]);
  428.           teleg_add(buf,telegram_buf);
  429.       }
  430.       if (Stars[starnum]->nova_stage) {
  431.         sprintf(buf,"\nThis planet's primary is in a Stage %d nova.", Stars[starnum]->nova_stage);
  432.         teleg_add(buf,telegram_buf);
  433.       }
  434.  
  435.       teleg_send(TELEG_PLAYER_AUTO, i, telegram_buf);
  436.  
  437.     }
  438.  
  439.        /* find out who is on this planet, for nova notification */
  440.     if (Stars[starnum]->nova_stage == 1) {
  441.          teleg_add("",telegram_buf);    /* initialize telegram counter */
  442.          sprintf(buf,"BULLETIN from /%s/%s\n", Stars[starnum]->name, Stars[starnum]->pnames[planetnum]);
  443.          teleg_add(buf,telegram_buf);
  444.          sprintf(buf,"\nStar %s is undergoing nova.\n", Stars[starnum]->name);
  445.          teleg_add(buf,telegram_buf);
  446.          if (planet->type==TYPE_EARTH)
  447.         teleg_add("Seas and rivers are boiling!\n",telegram_buf);
  448.          sprintf(buf, "This planet must be evacuated immediately!\n%c", TELEG_DELIM);
  449.               teleg_add(buf,telegram_buf);
  450.               for (i=1; i<=Num_races; i++)
  451.         if (planet->info[i-1].numsectsowned)
  452.                 teleg_send(TELEG_PLAYER_AUTO, i, telegram_buf);
  453.       }
  454.  
  455.  
  456.    for (i=1; i<=Num_races; i++) {
  457.     Power[i].resource += planet->info[i-1].resource;
  458.     Power[i].destruct += planet->info[i-1].destruct;
  459.     Power[i].fuel += planet->info[i-1].fuel;
  460.     Power[i].planets_owned += !!planet->info[i-1].numsectsowned;
  461.     if (planet->info[i-1].numsectsowned) {
  462.         Power[i].sectors_owned += planet->info[i-1].numsectsowned;
  463.         Power[i].sum_mob += avg_mob[i];
  464.       /* combat readiness naturally moves towards the avg mobilization */
  465.         avg_mob[i] /= planet->info[i-1].numsectsowned;
  466.         planet->info[i-1].comread += 
  467.                 sgn(avg_mob[i] - planet->info[i-1].comread);
  468.      }
  469.    }
  470.    planet->conditions[TOXIC] = (planet->conditions[TOXIC]*50 + 
  471.              100.0 * planet->popn / planet->maxpopn) / 51.0;
  472.  
  473.  }
  474.  return allmod;
  475. }
  476.