home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume6
/
gb
/
part01
/
doship.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-06
|
13KB
|
373 lines
/*
* Galactic Bloodshed (Robert Chansky, smq@b)
* doship -- do one ship turn.
*/
#include "vars.h"
#include "ships.h"
#include "races.h"
#include "doturn.h"
#include "power.h"
#include <math.h>
extern struct power Power[];
extern int Ignore_lockfile;
doship(shipno,ship)
int shipno;
shiptype *ship;
{
int j,t;
char buf[200];
if (!ship->is_dead) {
/* add ships, popn to total count to add AP's */
Power[ship->owner].ships_owned++;
Power[ship->owner].resource += ship->resource;
Power[ship->owner].fuel += ship->fuel;
Power[ship->owner].destruct += ship->destruct;
Power[ship->owner].popn += ship->popn;
if (ship->whatorbits==LEVEL_UNIV) {
Sdatanumships[ship->owner]++;
Sdatapopns[ship->owner] += ship->popn;
} else {
starnumships[ship->storbits][ship->owner] += (ship->type==OTYPE_VN) ? ship->orders.object.number : 1;
/* add popn of ships to popn */
starpopns[ship->storbits][ship->owner] += ship->popn;
}
/* repair radiation */
if (ship->rad) {
/* kill off some people */
ship->popn = round_rand(ship->popn * .80);
if (ship->rad > REPAIR_RATE)
ship->rad = 0;
else
ship->rad -= REPAIR_RATE;
} else {
/* irradiated ships are immobile */
Moveship(shipno, ship, Stars[ship->storbits],
Stars[ship->deststar],
planets[ship->storbits][ship->pnumorbits],
planets[ship->deststar][ship->destpnum],
ships[ship->destshipno]);
/* repair ship by the amount of crew it has */
if (ship->damage && ship->popn) { reg int d;
if ((d = ((float)ship->popn /
Shipdata[ship->type][ABIL_MAXCREW]) * REPAIR_RATE)
> ship->damage)
ship->damage = 0;
else
ship->damage -= d;
}
switch (ship->type) {
case OTYPE_CANIST:
if (ship->whatorbits == LEVEL_PLAN && !ship->is_docked) { char *t;
if (--ship->orders.object.number) {
t = &Stinfo[ship->storbits][ship->pnumorbits].temp_add;
if (*t - 10 < -120)
*t = -120;
else
*t -= 10;
} else { /* timer expired; destroy canister */
int fd,j=0;
ship->is_dead = 1;
while (j<MAXPSHIPS && planets[ship->storbits][ship->pnumorbits]->shipnums[j] != shipno)
j++;
if (j<MAXPSHIPS) {
planets[ship->storbits][ship->pnumorbits]->shipnums[j] = 0;
openshfdata(&fd); destroyship(fd,shipno); close(fd);
teleg_add("",telegram_buf);
sprintf(buf,"Notice from /%s/%s\n\n",
Stars[ship->storbits]->name,
Stars[ship->storbits]->pnames[ship->pnumorbits]);
teleg_add(buf,telegram_buf);
teleg_add("Canister of dust previously covering this planet has dissipated.\n",telegram_buf);
for (j=1; j<=Num_races; j++)
if (planets[ship->storbits][ship->pnumorbits]->info[j-1].numsectsowned)
teleg_send(TELEG_PLAYER_AUTO, j, telegram_buf);
} else fprintf(stderr,"can't delete canister #%d!\n",shipno);
}
}
break;
case STYPE_MINE:{ reg int i,rad=0; float xd[MAXSSHIPS],yd[MAXSSHIPS];
int p,shfdata;
/* check around and see if we should explode. */
if (ship->orders.object.on && ship->whatorbits==LEVEL_STAR) {
for (i=0; i<MAXSSHIPS; i++)
if (Stars[ship->storbits]->shipnums[i]) {
xd[i] = ships[Stars[ship->storbits]->shipnums[i]]->xpos- ship->xpos;
yd[i] = ships[Stars[ship->storbits]->shipnums[i]]->ypos- ship->ypos;
if (Stars[ship->storbits]->shipnums[i]==shipno)
p = i;
else
if (isset(races[ship->owner]->atwar,ships[Stars[ship->storbits]->shipnums[i]]->owner) &&
(abs(xd[i])+abs(yd[i])) < ship->orders.object.number)
rad = 1;
if (rad) {
/* we've found someone we don't like,
detonate and irradiate them */
Stars[ship->storbits]->shipnums[p] = 0;
openshfdata(&shfdata);
destroyship(shfdata, shipno);
close(shfdata);
teleg_add("",telegram_buf);
sprintf(buf, "BULLETIN!\n mine #%d triggered at system /%s",shipno,Stars[ship->storbits]->name);
teleg_add(buf, telegram_buf);
teleg_send(TELEG_PLAYER_AUTO,ship->owner,telegram_buf);
for (i=0; i<=MAXSSHIPS; i++)
if (Stars[ship->storbits]->shipnums[i] &&
Stars[ship->storbits]->shipnums[i]!=shipno &&
(abs(xd[i])+abs(yd[i]))<ship->orders.object.number) {
rad = round_rand(((float)Shipdata[STYPE_MINE][ABIL_DESTCAP] / ship->destruct)*.5);
if (ships[Stars[ship->storbits]->shipnums[i]]->rad + rad > 100)
ships[Stars[ship->storbits]->shipnums[i]]->rad = 100;
else
ships[Stars[ship->storbits]->shipnums[i]]->rad += rad;
teleg_add("",telegram_buf);
sprintf(buf, "BULLETIN!\n ship #%d irradiated by mine at system /%s", Stars[ship->storbits]->shipnums[i],
Stars[ship->storbits]->name);
teleg_add(buf, telegram_buf);
teleg_send(TELEG_PLAYER_AUTO,ships[Stars[ship->storbits]->shipnums[i]]->owner,telegram_buf);
}
}
}
}/* else if (ship->whatorbits==LEVEL_PLAN) {}*/
} break;
case STYPE_MIRROR:
switch (ship->orders.aimed_at.level) {
case LEVEL_SHIP: /* ship aimed at is a legal ship now */
/* if in the same system */
if ( (ship->whatorbits==LEVEL_STAR || ship->whatorbits==LEVEL_PLAN)
&& (ships[ship->orders.aimed_at.shipno]!=NULL)
&& (ships[ship->orders.aimed_at.shipno]->whatorbits==LEVEL_STAR ||
ships[ship->orders.aimed_at.shipno]->whatorbits==LEVEL_PLAN)
&& ship->storbits == ships[ship->orders.aimed_at.shipno]->storbits
&& !ships[ship->orders.aimed_at.shipno]->is_dead )
ships[ship->orders.aimed_at.shipno]->damage += 10;
break;
case LEVEL_PLAN: { reg char *t;
t = &Stinfo[ship->storbits][ship->orders.aimed_at.pnum].temp_add;
if (*t + ship->orders.aimed_at.intensity > 120)
*t = 120;
else if (*t + ship->orders.aimed_at.intensity < -120)
*t = -120;
else
*t += ship->orders.aimed_at.intensity;
}
break;
case LEVEL_STAR:
Stars[ship->storbits]->stability += random()&01;
break;
case LEVEL_UNIV:
break;
}
break;
case STYPE_GOD:
/* gods have infinite power.... heh heh heh */
ship->fuel = Shipdata[ship->type][ABIL_FUELCAP];
ship->popn = Shipdata[ship->type][ABIL_MAXCREW];
ship->destruct = Shipdata[ship->type][ABIL_DESTCAP];
ship->resource = Shipdata[ship->type][ABIL_CARGO];
break;
case OTYPE_TERRA: /* terraforming device */
/* if landed on planet, change conditions to be like race */
if (ship->is_docked && ship->whatdest==LEVEL_PLAN && ship->orders.object.on) {
int j,d,a;planettype *p;
p = planets[ship->storbits][ship->pnumorbits];
if (p->info[ship->owner-1].fuel >= 3) {
p->info[ship->owner-1].fuel-= 3;
for (j=RTEMP+1; j<=OTHER; j++) {
d = races[ship->owner]->conditions[j] - p->conditions[j];
a = int_rand(sgn(d)*3,-sgn(d));
if (p->conditions[j] + a < 0)
p->conditions[j] = 0;
else if (p->conditions[j] + a > 100)
p->conditions[j] = 100;
else p->conditions[j] += a;
}
}
}
break;
case OTYPE_VN: /* Von Neumann machine */
do_VN(ship,shipno);
break;
case STYPE_POD:
if (ship->notified) {
/* we just arrived at this system -- explode */
int shfdata;
reg int i,f= -1;
for (i=0; i<MAXSSHIPS && Stars[ship->storbits]->shipnums[i]!=shipno; i++) ;
if (i==MAXSSHIPS)
fprintf(stderr,"cannot del pod #%d!\n",shipno);
else {
Stars[ship->storbits]->shipnums[i] = 0;
ship->is_dead = 1;
openshfdata(&shfdata);
destroyship(shfdata, shipno);
close(shfdata);
for (i=0; f== -1 && i<Stars[ship->storbits]->numplanets; i++)
if (sqrt((double)Distsq(ship->xpos, ship->ypos,
Stars[ship->storbits]->xpos + planets[ship->storbits][i]->xpos,
Stars[ship->storbits]->ypos + planets[ship->storbits][i]->ypos))/SYSTEMSIZE < float_rand()*2)
f = i;
teleg_add("",telegram_buf);
sprintf(buf, "Bulletin\n\nSpore pod #%d has warmed and exploded.\n",shipno);
teleg_add(buf,telegram_buf);
if (f != -1) {
sprintf(buf,"A spore has landed on planet %s.\n",Stars[ship->storbits]->pnames[f]);
Stinfo[ship->storbits][f].Thing_add = ship->owner;
/* so doplanet does not pass over it */
setbit(Stars[ship->storbits]->inhabited,ship->owner);
planets[ship->storbits][f]->info[ship->owner-1].explored = 1;
} else {
sprintf(buf,"No spores have survived.\n");
}
teleg_add(buf,telegram_buf);
teleg_send(TELEG_PLAYER_AUTO, ship->owner, telegram_buf);
teleg_add("",telegram_buf);
sprintf(buf,"BULLETIN!\n\n A spore pod has exploded in system /%s.\n",Stars[ship->storbits]->name);
teleg_add(buf,telegram_buf);
teleg_add("Spores may have drifted to planets here.\n",telegram_buf);
for (i=1; i<=Num_races; i++)
if (i!=ship->owner && isset(Stars[ship->storbits]->inhabited,i))
teleg_send(TELEG_PLAYER_AUTO, i, telegram_buf);
}
}
break;
default:
break;
}
}
}
}
do_VN(ship,shipno)
shiptype *ship;
int shipno;
{
int j,n,r;
planettype *p;
char buf[150];
if (ship->orders.object.on) {
p = planets[ship->storbits][ship->pnumorbits];
if (ship->is_docked && ship->whatdest==LEVEL_PLAN && ship->whatorbits==LEVEL_PLAN) {
/* try to launch it */
if (ship->orders.object.number2 == 0) { /* launch if no assignment */
/* steal some fuel from other players,telegram */
bool f=0;
for (r=Num_races-1; !f && r>0; r--)
if (p->info[r-1].fuel >= Shipdata[OTYPE_VN][ABIL_COST]) {
p->info[ship->owner-1].fuel +=
Shipdata[OTYPE_VN][ABIL_FUELCAP];
p->info[r-1].fuel -= Shipdata[OTYPE_VN][ABIL_FUELCAP];
f = r;
}
if (f) {
/*if (f!=1) {*/
teleg_add("",telegram_buf);
teleg_add("Bulletin!\n\n",telegram_buf);
sprintf(buf,"%d fuel stolen by %s #%d on planet /%s/%s!\n",
Shipdata[OTYPE_VN][ABIL_FUELCAP],
Shipnames[OTYPE_VN],
shipno, Stars[ship->storbits]->name,
Stars[ship->storbits]->pnames[ship->pnumorbits]);
teleg_add(buf,telegram_buf);
teleg_send(TELEG_PLAYER_AUTO, f, telegram_buf);
teleg_send(TELEG_PLAYER_AUTO, 1, telegram_buf);
/*}*/
ship->orders.object.number2 = 0; /* no current assignment */
ship->xpos = Stars[ship->storbits]->xpos + planets[ship->storbits][ship->pnumorbits]->xpos + int_rand(-10,10);
ship->ypos = Stars[ship->storbits]->ypos + planets[ship->storbits][ship->pnumorbits]->ypos + int_rand(-10,10);
ship->is_docked = 0;
ship->whatdest = LEVEL_UNIV;
}
} else {
/* we have an assignment. Since we are landed, this means
we are engaged in building up resources/fuel. */
/* steal resources from other players,telegram */
bool f=0;
for (r=Num_races-1; !f && r>0; r--)
if (p->info[r-1].resource >= Shipdata[OTYPE_VN][ABIL_COST])
f = r;
if (f) {
/*if (f!=1) {*/
ship->resource += Shipdata[OTYPE_VN][ABIL_COST];
ship->mass += Shipdata[OTYPE_VN][ABIL_COST] * MASS_RESOURCE;
p->info[f-1].resource -= Shipdata[OTYPE_VN][ABIL_COST];
teleg_add("",telegram_buf);
teleg_add("Bulletin!\n\n",telegram_buf);
sprintf(buf,"%d resources stolen by %s #%d\non planet ",
Shipdata[OTYPE_VN][ABIL_COST],
Shipnames[OTYPE_VN], shipno);
teleg_add(buf,telegram_buf);
sprintf(buf,"/%s/%s!\n",
Stars[ship->storbits]->name,
Stars[ship->storbits]->pnames[ship->pnumorbits]);
teleg_add(buf,telegram_buf);
teleg_send(TELEG_PLAYER_AUTO, f, telegram_buf);
/* remove */
teleg_send(TELEG_PLAYER_AUTO, 1, telegram_buf);
/*}*/
/* if no resources to steal, more will be produced in doplanet*/
}
}
} else {
/* we are not landed */
if (ship->orders.object.number2) {
/* we've arrived from somewhere -- look for a place to land.
this is done on planet turn */
} else {
/* we were just built & launched */
reg int s,min=0,min2=0;
/* find closest unexplored star */
for (s=1; s<Sdata.numstars; s++)
if (s != ship->storbits &&
Distsq(Stars[s]->xpos,Stars[s]->ypos,ship->xpos,ship->ypos) <
Distsq(Stars[min]->xpos,Stars[min]->ypos,ship->xpos,ship->ypos))
min2 = min,min = s;
/* don't go there if we have a choice,
and we have VN's there already */
if (isset(Stars[min]->inhabited,1))
if (isset(Stars[min2]->inhabited,1))
ship->deststar = int_rand(0,Sdata.numstars-1);
else
ship->deststar = min2; /* 2nd closest star */
else
ship->deststar = min;
if (Stars[ship->deststar]->numplanets) {
ship->destpnum =
int_rand(0,Stars[ship->deststar]->numplanets-1);
ship->whatdest = LEVEL_PLAN;
} else {
ship->whatdest = LEVEL_STAR;
}
fprintf(stderr,"VN #%d headed for star %d, pl %d.\n",shipno,ship->deststar, ship->destpnum);
ship->orders.object.number2 = 1;
/* we are assigned to go */
}
}
}
}