|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 5198 (0x144e)
Types: TextFile
Names: »shootblast.c.orig«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Gb/shootblast.c.orig«
/*
* Galactic Bloodshed (Robert Chansky, smq@b)
* shoot() -- shoot from ship or planet to ship or planet (does dam acc. to
* range -- does not remove dest cap from firing ship/planet)
* blast() -- generic damaging routine -- saves only smap
*/
#include "vars.h"
#include "ships.h"
#include <math.h>
extern int Shipdata[NUMSTYPES][NUMABILS];
extern int Distmap();
bool Nuked[MAXPLAYERS]; /* who was nuked on the planet/ship */
int shoot(from,to,fpl,tpl,sectorx,sectory,strength, sdatamod,starmod,planetmod)
placetype from,*to;
planettype *fpl,*tpl;
int sectorx,sectory,strength;
/* reported modifications to datafiles */
bool *sdatamod,*starmod, *planetmod;
{
int i;
double dist,xfrom,yfrom,xto,yto;
double str;
float r;
if (from.level==LEVEL_PLAN) {
xfrom = Stars[from.snum]->xpos + fpl->xpos;
yfrom = Stars[from.snum]->ypos + fpl->ypos;
} else if (from.level==LEVEL_SHIP) {
xfrom = from.shipptr->xpos;
yfrom = from.shipptr->ypos;
}
if (to->level==LEVEL_PLAN) {
xto = Stars[to->snum]->xpos + tpl->xpos;
yto = Stars[to->snum]->ypos + tpl->ypos;
} else if (to->level==LEVEL_SHIP) {
xto = to->shipptr->xpos;
yto = to->shipptr->ypos;
}
dist = sqrt( (double)Distsq(xfrom, yfrom, xto, yto)) + 50.0;
/* (adjust for too close) */
if (dist > SYSTEMSIZE) {
/* out of range */
return -1;
} else {
str = (double)strength * FACTOR_DAMAGE / dist;
printf(" str = %f, rad = %f\n",str,str*FACTOR_DESTPLANET);
r = blast(to, tpl, sectorx, sectory, str * FACTOR_DESTPLANET, str);
if (to->level==LEVEL_SHIP && to->shipptr->is_dead) {
if (to->shipptr->whatorbits==LEVEL_UNIV) {
/* not used since ships can't fire in UNIV scope */
for (i=0; i<MAXUSHIPS; i++)
if (Sdata.shipnums[i] == to->shipno) {
Sdata.shipnums[i] = 0;
Sdata.numships--;
*sdatamod |= 1;
}
} else if (to->shipptr->whatorbits==LEVEL_STAR) {
for (i=0; i<MAXSSHIPS; i++)
if (Stars[to->snum]->shipnums[i] == to->shipno) {
Stars[to->snum]->shipnums[i] = 0;
Stars[to->snum]->numships--;
*starmod |= 1;
}
} else { /* LEVEL_PLAN */
for (i=0; i<MAXPSHIPS; i++)
if (tpl->shipnums[i] == to->shipno) {
tpl->shipnums[i] = 0;
tpl->numships--;
*planetmod |= 1; /* don't need this */
}
}
}
return (int)r;
}
}
/* returns amt of damage or # of sectors nuked */
int blast(place, pl, x, y, r, str)
placetype *place; /* place being destroyed */
planettype *pl; /* pointer to planet being destroyed */
int x,y; /* sector x,y of planet */
register float r; /* radius of blast */
double str; /* strength of blast */
{
register int x2,y2;
float d;
int numdest = 0,lowx,lowy,hix,hiy;
register sectortype *s;
register float fac;
int shfdata,sectdata;
bzero( (char *)Nuked, sizeof(Nuked) );
if (place->level==LEVEL_SHIP) {
numdest = round_rand(str / Shipdata[place->shipptr->type][ABIL_ARMOR]);
if (numdest > 100)
numdest = 100;
if (place->shipptr->type!=OTYPE_VN) {
if (place->shipptr->damage+numdest >= 100) {
place->shipptr->is_dead = 1;
openshfdata(&shfdata);
destroyship(shfdata, (short)place->shipno);
close(shfdata);
} else
place->shipptr->damage += numdest;
} else {
if (place->shipptr->orders.object.number - numdest < 1) {
place->shipptr->is_dead = 1;
openshfdata(&shfdata);
destroyship(shfdata, (short)place->shipno);
close(shfdata);
} else
place->shipptr->orders.object.number -= numdest;
}
Nuked[place->shipptr->owner] = 1;
return numdest; /* return amt of dest made */
} else if (place->level==LEVEL_PLAN) {
opensectdata(§data);
getsmap(sectdata,Smap,pl->sectormappos,pl->Maxx*pl->Maxy );
lowx = MAX((x-r-1),0);
lowy = MAX((y-r-1),0);
hix = MIN((x+r+1),pl->Maxx-1);
hiy = MIN((y+r+1),pl->Maxy-1);
for (y2=lowy; y2<=hiy; y2++) {
for (x2=lowx; x2<=hix; x2++) {
if ( (d = Distmap(x,y,x2,y2) ) <= r) {
s = &Smap[y2*pl->Maxx+x2];
fac = ((float)str/10) * logscale(100 - s->mobilization)/(d+1);
/* factor of destruction */
/*printf("%d,%d dist = %.2f,dest fac %.2f",x2,y2,d,fac);*/
if (fac > 0.55) {
Nuked[s->owner] = 1; /* for retaliating */
if (fac > 1.00) {
fac = 1.00; /* really pulverize it */
s->popn = s->owner = 0;
if (s->des==DES_MOUNT)
s->des=DES_LAND;
else if (s->des==DES_LAND &&
(s+1)->des==DES_SEA || (s-1)->des==DES_SEA)
s->des=DES_SEA;
s->is_wasted = 1;
s->fert = 0;
}
numdest++; /* more than 50% destruction on sector */
s->resource += (percent)round_rand(s->resource * fac)/2;
/* add some resources to be fair */
s->fert -= (percent)round_rand(s->fert * fac)/2;
s->mobilization -= (percent)(round_rand(s->mobilization * fac/2) );
/*printf("::%d,%d killed %d.\n",x2,y2,round_rand(s->popn * fac) );*/
s->popn -= (us)(round_rand(s->popn * fac) );
s->eff -= (percent)(round_rand(s->eff * fac) );
}
}
}
}
pl->conditions[TOXIC] += (100-pl->conditions[TOXIC]) *
((float)numdest / (pl->Maxx*pl->Maxy));
putsmap(sectdata,Smap,pl->sectormappos,pl->Maxx*pl->Maxy );
close(sectdata);
return(numdest);
}
}