home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume6
/
gb
/
part01
/
doplanet.c
next >
Wrap
C/C++ Source or Header
|
1989-07-06
|
16KB
|
476 lines
/*
* Galactic Bloodshed (Robert Chansky, smq@b)
* doplanet.c -- do one turn on a planet.
*/
#include "vars.h"
#include "ships.h"
#include "races.h"
#include "doturn.h"
#include "power.h"
extern struct power Power[];
#include <math.h>
extern bool Nuked[];
extern int Ignore_lockfile;
char telegram_buf[AUTO_TELEG_SIZE];
int tot_resdep,tot_eff,tot_res,tot_fuel,tot_destruct,tot_captured,tot_mob;
float avg_mob[MAXPLAYERS];
char sects_gained[MAXPLAYERS], sects_lost[MAXPLAYERS];
float Compat[MAXPLAYERS];
bool Claims;
int doplanet(starnum,planet, planetnum, command)
int starnum;
planettype *planet;
int planetnum;
int command;
{
int inhab=0,x,y;
reg int i;
int shipno,o=0,j;
sectortype *p;
shiptype *ship;
double att;
float xadd,yadd,dist,t,madd,fadd;
int sectdata,timer=20;
int oldplanetpopn, oldplanetmaxpopn, allmod=0,allexp=0;
char buf[200];
for (i=1; i<=Num_races; i++) {
o |= isset(Stars[starnum]->inhabited,i);
inhab |= planet->info[i-1].numsectsowned;
}
if (!o)
return 0; /* no one's explored the star yet */
if (inhab) {
printf(" getting sectmap pos %d\n",planet->sectormappos);
opensectdata(§data);
getsmap(sectdata,Smap,planet->sectormappos,planet->Maxx*planet->Maxy);
close(sectdata);
PermuteSects(planet);
bzero((char *)Sectinfo, sizeof(Sectinfo) );
}
dist = hypot((double)planet->ypos, (double)planet->xpos);
/* closer planets orbit faster */
t = atan2((double)planet->ypos, (double)planet->xpos) - SYSTEMGRAVCONST * SYSTEMSIZE / dist;
xadd = planet->xpos - dist * cos(t);
yadd = planet->ypos - dist * sin(t);
printf("xadd %g yadd %g \n", xadd, yadd);
/* adjust ships in orbit around the planet */
for (shipno=0; shipno<MAXPSHIPS; shipno++)
if (planet->shipnums[shipno] && ((ship=ships[planet->shipnums[shipno]])!=NULL) && !ship->is_dead && !ship->rad) {
if ( !(ship->is_docked && ship->whatdest==LEVEL_PLAN)) {
/* adjust fuel, orbit for ships that are not landed */
ship->xpos += xadd;
ship->ypos += yadd;
/* add fuel to ships orbiting gas giants */
if (planet->type == TYPE_GASGIANT && !is_object(ship)) {
if (ship->type == STYPE_TANKER) {
fadd = FUEL_GAS_ADD_TANKER;
madd = FUEL_GAS_ADD_TANKER*MASS_FUEL;
} else if (ship->type == STYPE_STATION) {
fadd = FUEL_GAS_ADD_STATION;
madd = FUEL_GAS_ADD_STATION*MASS_FUEL;
} else {
fadd = FUEL_GAS_ADD;
madd = FUEL_GAS_ADD*MASS_FUEL;
}
if (ship->fuel + fadd > Shipdata[ship->type][ABIL_FUELCAP]) {
madd -= (Shipdata[ship->type][ABIL_FUELCAP] - (ship->fuel+fadd))*MASS_FUEL;
fadd = Shipdata[ship->type][ABIL_FUELCAP]-(ship->fuel+fadd);
}
ship->fuel += fadd;
ship->mass += madd;
}
}
if ( (is_object(ship) && !ship->orders.object.on) || !is_object(ship)) {
if (ship->type == OTYPE_VN) {
/* Von Neumann machine */
if (ship->is_docked && ship->whatdest==LEVEL_PLAN) {
if (ship->orders.object.number2) {
/* we are currently trying to construct another
machine */
reg int x,y,a,dum;
for (i=1; i<253 && i<=ship->orders.object.number; i++) {
a = round_rand(sqrt((double)ship->orders.object.number));
x = mod(int_rand((int)(ship->xpos-a),(int)(ship->xpos+a)),(int)planet->xpos,dum);
y = mod(int_rand((int)(ship->ypos-a),(int)(ship->ypos+a)),(int)planet->ypos,dum);
Sectinfo[x][y].VN= 1;
}
if (ship->resource >= Shipdata[OTYPE_VN][ABIL_COST]) {
ship->resource -= Shipdata[OTYPE_VN][ABIL_COST];
ship->mass -= Shipdata[OTYPE_VN][ABIL_COST]*MASS_RESOURCE;
if (ship->orders.object.number > int_rand(5,50)) {
/* enough to start a new VN 'herd'. build another
ship. */
for (i=0; i<MAXPSHIPS && planet->shipnums[i]; i++) ;
if (i<MAXPSHIPS) {
shiptype *s2;
Num_ships++;
fprintf(stderr,"VN #%d constructed VN #%d.\n",shipno,Num_ships);
planet->shipnums[i] = Num_ships;
ships[Num_ships] = (shiptype *)malloc(sizeof(shiptype));
s2 = ships[Num_ships];
bzero((char *)s2,sizeof(shiptype));
s2->whatorbits = LEVEL_PLAN;
s2->storbits = ship->storbits;
s2->pnumorbits = ship->pnumorbits;
s2->xpos = ((int)ship->xpos + int_rand(-9,9)) % planet->Maxx;
s2->xpos = abs(s2->xpos);
s2->ypos = ((int)ship->ypos + int_rand(-4,4)) % planet->Maxy;
s2->ypos = abs(s2->ypos);
s2->is_docked = 1;
s2->whatdest = ship->whatdest;
s2->deststar = ship->deststar;
s2->destpnum = ship->destpnum;
s2->type = OTYPE_VN;
s2->mass = Shipdata[OTYPE_VN][ABIL_MASS];
s2->owner = 1;
s2->orders.object.number = 1;
/* is not building any VN's */
/* no assignment now */
ship->orders.object.number2 = 0;
} else
fprintf(stderr,"#%d can't slot insert new VN!!\n",shipno);
} else {
/* we don't have too many in this herd, so make
some more */
ship->orders.object.number++;
}
} else {
/* if there are no players to steal from, try
and make some resources by ourselves */
reg int i,f=0;
for (i=Num_races-1; !f && i>0; i--)
if (planet->info[i-1].resource)
f=i;
if (!f) {
/* nobody here */
/*# ifdef UV_4.3*/
sectortype tmp;
int tmp2;
tmp = Sector(*planet,(int)(ship->xpos), (int)(ship->ypos));
tmp2 = tmp.resource /5;
ship->resource += tmp2;
/*ship->resource += (Sector(*planet,(int)(ship->xpos), (int)(ship->ypos)).resource) / 5;
ship->mass += ((Sector(*planet,(int)(ship->xpos), (int)(ship->ypos)).resource) / 5) * MASS_RESOURCE;*/
/*# else
ship->resource += 7;
ship->mass += 7 * MASS_RESOURCE;
# endif*/
}
}
} else {
/* we have no assignment -- we must launch. taken care of
in doship */
}
} else { /* orbiting a planet */
if (ship->orders.object.number2) {
if (ship->whatdest==LEVEL_PLAN && ship->deststar==starnum &&
ship->destpnum==planetnum) {
/* we just arrived from somewhere */
if (planet->type==TYPE_GASGIANT) {
if (ship->fuel >= Shipdata[OTYPE_VN][ABIL_FUELCAP])
ship->orders.object.number2 = 0;
/* gas giants are of no use to us;
doship() will head us somewhere else */
} else {
/* find a place on the planet to land */
int x,y; reg int d; /* auto vars for & */
printf(" VN finding a place to land\n");
Getxysect(planet,&x,&y,1);
while ((d=Getxysect(planet,&x,&y,0)) &&
Sector(*planet,x,y).des!=DES_LAND &&
Sector(*planet,x,y).des!=DES_MOUNT &&
Sector(*planet,x,y).resource==0)
;
if (d) {
printf(" VN landed.\n");
ship->is_docked = 1;
ship->whatdest = LEVEL_PLAN;
ship->deststar = ship->storbits;
ship->destpnum = ship->pnumorbits;
ship->xpos = x;
ship->ypos = y;
ship->orders.object.number2 = 1;
/* number2 means we are currently
busy here */
} else
/* head somewhere else */
ship->orders.object.number2 = 0;
printf("turning off; can't find place 2land\n");
}
} else {
/* we just launched from this planet -- pick
someplace to go to (taken care of in doship) */
}
} else {
/* okay, we don't know what the hell we are doing here.
wait for doship to give further orders. */
}
}
}
}
/* bombard the planet */
if (!is_object(ship) && ship->orders.o.bombard
&& ship->whatorbits==LEVEL_PLAN
&& ship->whatdest==LEVEL_PLAN
&& ship->storbits==ship->deststar
&& ship->pnumorbits==ship->destpnum)
Bombard(ship,shipno,planet); /* ship bombards planet */
if (ship==NULL) {
fprintf(stderr,"null ship #%d slot %d .\n",planet->shipnums[shipno],shipno);
planet->shipnums[shipno] = 0;
}
}
planet->xpos += xadd;
planet->ypos += yadd;
if (planet->xpos>SYSTEMSIZE) planet->xpos *= .5;
else if (planet->xpos< -SYSTEMSIZE) planet->xpos *= .5;
if (planet->ypos>SYSTEMSIZE) planet->ypos *= .5;
else if (planet->ypos< -SYSTEMSIZE) planet->ypos *= .5;
if (!inhab && !Stinfo[starnum][planetnum].Thing_add)
return 0; /* (no one's explored the planet) */
/* check for space mirrors (among other things) warming the planet */
/* if a change in any artificial warming/cooling trends */
if (Stinfo[starnum][planetnum].temp_add)
planet->conditions[TEMP] = planet->conditions[RTEMP] +
Stinfo[starnum][planetnum].temp_add + int_rand(-2,2);
else
planet->conditions[TEMP] = planet->conditions[RTEMP] + int_rand(-2,2);
bzero((char *)avg_mob, sizeof(avg_mob) );
bzero((char *)sects_gained, sizeof(sects_gained) );
bzero((char *)sects_lost, sizeof(sects_lost) );
Claims = 0;
if (Stinfo[starnum][planetnum].Thing_add) {
/* start a meso colony */
x = int_rand(0,planet->Maxx-1);
y = int_rand(0,planet->Maxy-1);
Sector(*planet,x,y).des = DES_LAND; /* cheating. so what. */
Sector(*planet,x,y).popn = 1;
Sector(*planet,x,y).owner = Stinfo[starnum][planetnum].Thing_add;
}
tot_resdep=tot_eff=tot_res=tot_fuel=tot_destruct=tot_mob=tot_captured=0;
oldplanetmaxpopn = planet->maxpopn;
planet->maxpopn = 0;
oldplanetpopn = planet->popn;
planet->popn = 0; /* initialize population for recount */
for (i=1; i<=Num_races; i++) {
Compat[i] = compatibility(planet, races[i]);
planet->info[i-1].numsectsowned = 0;
}
printf(" while %d\n",Getxysect(planet, &x, &y, 1)); /* reset */
while (Getxysect(planet, &x, &y, 0)) {
p = &Sector(*planet,x,y);
if (p->owner) {
/* (all modified; sectors belonging to that player modified) */
allmod = 1;
if (!p->popn ) {
p->owner=0; /* make wasted/unowned sects go to player 0 */
} else {
planet->info[p->owner-1].numsectsowned++;
if (!Stars[starnum]->nova_stage) {
/* spread excess popn to surrounding sects */
spread(planet,p,x,y);
produce(planet,p); /* produce stuff there */
planet->popn += p->popn;
Power[p->owner].popn += p->popn;
Power[p->owner].sum_eff += p->eff;
starpopns[starnum][p->owner] += p->popn;
} else {
/* damage sector from supernova */
p->resource++;
if (p->fert)
--p->fert;
if (Stars[starnum]->nova_stage == 14)
p->popn = 0;
else
p->popn *= .80;
}
}
}
planet->maxpopn += maxsupport(p);
if (Sectinfo[x][y].VN)
p->VN = 1;
else
p->VN = 0;
if (p->is_wasted) {
if (x>1 && x<planet->Maxx-2) {
if (p->des==DES_SEA || p->des==DES_GAS) {
/* don't reclaim pole sectors */
if ( y>1 && y<planet->Maxy-2 &&
(!(p-1)->is_wasted || !(p+1)->is_wasted)
&& !random()%5)
p->is_wasted = 0;
} else if (p->des==DES_LAND || p->des==DES_MOUNT) {
if ( y>1 && y<planet->Maxy-2 &&
((p-1)->popn || (p+1)->popn)
&& !random()%10)
p->is_wasted = 0;
}
}
}
/* evaporate the oceans on novae */
if (Stars[starnum]->nova_stage && p->des==DES_SEA)
if ( (x>0 && (p-1)->des==DES_LAND) ||
(x<planet->Maxx-1 && (p+1)->des==DES_LAND) ||
(y>0 && (p-planet->Maxx)->des==DES_LAND) ||
(y<planet->Maxy-1 && (p+planet->Maxx)->des==DES_LAND ) ) {
p->des = DES_LAND;
p->popn = p->owner = 0;
p->resource += 3;
p->fert = int_rand(1,4);
printf("sect %d,%d evaporated.\n",x,y);
}
}
if (allmod) { /* ( >= 1 inhabited sector on the planet) */
if (planet->expltimer >= 1)
planet->expltimer--;
if (!Stars[starnum]->nova_stage && !planet->expltimer) {
if (!planet->expltimer)
planet->expltimer = 5;
for (i=1; !Claims && !allexp && i<=Num_races; i++) {
printf("pl %d numsectsowned %d Claims %d allexp %d compat %f\n",i,planet->info[i-1].numsectsowned,Claims,allexp,Compat[i]);
/* sectors have been modified for this player*/
/* & planet is compatible enough */
if (planet->info[i-1].numsectsowned && Compat[i] > 40.0)
while (!Claims && !allexp && --timer) {
printf("exploring ... timer=%d\n",timer);
/*printf("exploring player %d\n",i);*/
o = 1;
Getxysect(planet, &x, &y, 1);
while (!Claims && Getxysect(planet, &x, &y, 0)) {
/* find out if all sectors have been explored */
o &= Sectinfo[x][y].explored[i];
p = &Sector(*planet,x,y);
if (!p->owner && !p->is_wasted && p->des==DES_LAND && Sectinfo[x][y].explored[i]) {
/* (water) explorations have found an island */
printf("found an island @ %d,%d\n",x,y);
Claims = i;
/* give them some free people there */
p->popn = races[i]->number_sexes;
tot_captured = 1;
} else
explore(planet, p, x, y, i);
}
allexp |= o; /* all sectors explored for this player */
}
}
}
if (allexp)
planet->expltimer = 5;
for (i=1; i<=Num_races; i++)
if (planet->info[i-1].autorep) {
planet->info[i-1].autorep--;
teleg_add("",telegram_buf); /* clear buf */
sprintf(buf,"****** Report: Planet /%s/%s ******\n",
Stars[starnum]->name, Stars[starnum]->pnames[planetnum] );
teleg_add(buf,telegram_buf);
if (Stinfo[starnum][planetnum].temp_add) {
sprintf(buf,"\nGlobal temperature alteration: %d to %d.\n\n",
Temp(planet->conditions[RTEMP]), Temp(planet->conditions[TEMP]));
teleg_add(buf,telegram_buf);
}
teleg_add("resource prod. fuel prod. weapons prod. mob.pt prod.\n",telegram_buf);
sprintf(buf,"%12d%12d%15d%13d\n", tot_res, tot_fuel, tot_destruct,tot_mob);
teleg_add(buf,telegram_buf);
sprintf(buf,"resource deposit depletion: %d\n", tot_resdep);
teleg_add(buf,telegram_buf);
teleg_add("total births (%%) growth of max popn support (%%)\n",telegram_buf);
sprintf(buf,"%9d (%.2f%%)%23d (%.2f%%)\n",
planet->popn - oldplanetpopn,
((float)planet->popn-oldplanetpopn)/oldplanetpopn,
planet->maxpopn - oldplanetmaxpopn,
((float)planet->maxpopn-oldplanetmaxpopn)/oldplanetmaxpopn);
teleg_add(buf,telegram_buf);
sprintf(buf,"sectors owned on this planet: %d.\n", tot_captured);
teleg_add(buf,telegram_buf);
if (sects_gained[i] || sects_lost[i]) {
teleg_add("\nWAR STATUS: ",telegram_buf);
sprintf(buf,"%d sectors gained, %d sectors lost.\n",
sects_gained[i],sects_lost[i]);
teleg_add(buf,telegram_buf);
}
if (Stars[starnum]->nova_stage) {
sprintf(buf,"\nThis planet's primary is in a Stage %d nova.", Stars[starnum]->nova_stage);
teleg_add(buf,telegram_buf);
}
teleg_send(TELEG_PLAYER_AUTO, i, telegram_buf);
}
/* find out who is on this planet, for nova notification */
if (Stars[starnum]->nova_stage == 1) {
teleg_add("",telegram_buf); /* initialize telegram counter */
sprintf(buf,"BULLETIN from /%s/%s\n", Stars[starnum]->name, Stars[starnum]->pnames[planetnum]);
teleg_add(buf,telegram_buf);
sprintf(buf,"\nStar %s is undergoing nova.\n", Stars[starnum]->name);
teleg_add(buf,telegram_buf);
if (planet->type==TYPE_EARTH)
teleg_add("Seas and rivers are boiling!\n",telegram_buf);
sprintf(buf, "This planet must be evacuated immediately!\n%c", TELEG_DELIM);
teleg_add(buf,telegram_buf);
for (i=1; i<=Num_races; i++)
if (planet->info[i-1].numsectsowned)
teleg_send(TELEG_PLAYER_AUTO, i, telegram_buf);
}
for (i=1; i<=Num_races; i++) {
Power[i].resource += planet->info[i-1].resource;
Power[i].destruct += planet->info[i-1].destruct;
Power[i].fuel += planet->info[i-1].fuel;
Power[i].planets_owned += !!planet->info[i-1].numsectsowned;
if (planet->info[i-1].numsectsowned) {
Power[i].sectors_owned += planet->info[i-1].numsectsowned;
Power[i].sum_mob += avg_mob[i];
/* combat readiness naturally moves towards the avg mobilization */
avg_mob[i] /= planet->info[i-1].numsectsowned;
planet->info[i-1].comread +=
sgn(avg_mob[i] - planet->info[i-1].comread);
}
}
planet->conditions[TOXIC] = (planet->conditions[TOXIC]*50 +
100.0 * planet->popn / planet->maxpopn) / 51.0;
}
return allmod;
}