|
|
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 f
Length: 12027 (0x2efb)
Types: TextFile
Names: »fire.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Gb/fire.c«
/*
* Galactic Bloodshed (Robert Chansky, smq@ucscb.ucsc.edu)
* fire.c -- fire at ship or planet from ship or planet
*/
#include "vars.h"
#include "ships.h"
#include "races.h"
#include <signal.h>
#include <setjmp.h>
#include <curses.h>
extern char telegram_buf[AUTO_TELEG_SIZE];
extern jmp_buf main_jenv;
extern int Shipdata[NUMSTYPES][NUMABILS];
extern int Ignore_filelocks;
int fire_stardata,fire_fromshdata,fire_toshdata,
fire_frompdata,fire_topdata,fire_sectdata;
extern bool Nuked[MAXPLAYERS];
fire(APcount, argn,args)
int APcount;
int argn;
char args[MAXARGS][COMMANDSIZE];
{
placetype from,to;
planettype *fpl,*tpl;
sectortype *sect;
int dam=0,dam2=0,strength,oldstrength,maxstrength,
i,from_firex= -1,from_firey= -1,firex= -1,firey= -1,Numplayersretaliate=0;
float dist;
char string[PLACENAMESIZE],buf[100];
bool sameplanet = 0, fromplanetmod=0,toplanetmod=0,starmod=0,sdatamod=0;
int mask,APdeductstar;
int fire_handler();
fire_stardata = fire_fromshdata = fire_toshdata = fire_frompdata =
fire_topdata = fire_sectdata = NEUTRAL_FD;
signal(SIGINT, fire_handler);
/***** get place we are firing from *****/
if (argn!=4) {
printf("fire (from) ship or planet ");
scanf("%35s",string);
} else sscanf(args[1],"%35s",string);
from = Getplace(string,0);
if (from.err && from.level!=LEVEL_SHIP) {
printf("usage: fire [ (from path) (to path) [strength] ]\n");
return;
}
if (from.level == LEVEL_UNIV || from.level == LEVEL_STAR) {
printf("You can't shoot from there.\n");
fire_handler();
} else if (from.level == LEVEL_SHIP) {
if (from.err || from.shipptr->owner != Playernum) {
DontOwnErr();
return;
}
free(from.shipptr); /* erase/get ship again to lock ship file */
openshdata(&fire_fromshdata);
getship(fire_fromshdata,&(from.shipptr),from.shipno);
if (from.shipptr->rad) {
printf("%s #%d is inactive.\n", Shipnames[from.shipptr->type], from.shipno);
fire_handler();
}
if (!from.shipptr->popn && Shipdata[from.shipptr->type][ABIL_MAXCREW]) {
printf("%s #%d has no crew.\n", Shipnames[from.shipptr->type], from.shipno);
fire_handler();
}
if (from.shipptr->whatorbits==LEVEL_UNIV) {
printf("There is nothing here to fire upon.\n");
fire_handler();
} else if (from.shipptr->whatorbits==LEVEL_STAR) {
openstardata(&fire_stardata);
getstar(fire_stardata, &Stars[from.snum], from.snum);
if (!enufAP(Stars[from.shipptr->storbits]->AP, APcount) )
fire_handler();
} else if (from.shipptr->whatorbits==LEVEL_PLAN) {
openpdata(&fire_frompdata);
getplanet(fire_frompdata,&fpl,
Stars[from.shipptr->storbits]->planetpos[from.shipptr->pnumorbits]);
if (!enufAP(Stars[from.shipptr->storbits]->AP, APcount) )
fire_handler();
} else {
/* from.shipptr->whatorbits==LEVEL_UNIV) {*/
openstardata(&fire_stardata);
getsdata(fire_stardata,&Sdata);
if (!enufAP(Sdata.AP, APcount) )
fire_handler();
}
} else if (from.level==LEVEL_PLAN) {
openpdata(&fire_frompdata);
getplanet(fire_frompdata,&fpl,Stars[from.snum]->planetpos[from.pnum]);
if (!enufAP(Stars[from.snum]->AP, APcount) )
fire_handler();
if (!(fpl->info[Playernum-1].destruct)) {
printf("No weapons available.\n");
fire_handler();
}
/* get a sector the enemy place can retaliate to. */
do {
printf("Fire from");
GetMapSector(fpl, &from_firex,&from_firey);
opensectdata(&fire_sectdata);
getsector(fire_sectdata, §, fpl->sectormappos+(from_firey*fpl->Maxx+from_firex)*sizeof(sectortype) );
close(fire_sectdata);
if (sect->owner!=Playernum) /* has to be yours */
printf("You don't own that sector.\n");
} while (sect->owner!=Playernum);
free(sect);
} else {
printf("You can't shoot from there.\n");
return;
}
/******* get target *******/
if (argn!=4) {
printf("fire (at) ship or planet ");
scanf("%35s",string);
} else sscanf(args[2],"%35s",string);
Ignore_filelocks = 1;
to = Getplace(string,1);
Ignore_filelocks = 0;
if (to.err)
fire_handler();
if (to.level==LEVEL_SHIP) {
if (from.level==LEVEL_SHIP) {
if (from.shipno == to.shipno) {
printf("You can't do that.\n");
fire_handler();
} else
Ignore_filelocks = 1;
/* ship file will already be locked */
}
openshdata(&fire_toshdata);
free(to.shipptr);
getship(fire_toshdata, &(to.shipptr), to.shipno);
Ignore_filelocks = 0;
if (to.shipptr->whatorbits==LEVEL_PLAN) {
Ignore_filelocks = 1; /* planet file will already be locked */
if ( (from.snum==to.snum && from.pnum==to.pnum)
|| from.level==LEVEL_PLAN ) {
/* this ship orbits the same planet as the firing one */
sameplanet = 1;
tpl = fpl;
} else {
openpdata(&fire_topdata);
getplanet(fire_topdata,&tpl,Stars[to.snum]->planetpos[to.pnum]);
}
Ignore_filelocks = 0;
} else if (to.shipptr->whatorbits==LEVEL_STAR) {
if (from.shipptr->whatorbits!=LEVEL_STAR) {
openstardata(&fire_stardata);
getstar(fire_stardata, &Stars[to.snum], to.snum);
if (!enufAP(Stars[to.shipptr->storbits]->AP, APcount) )
fire_handler();
}
} else {
/*(to.shipptr->whatorbits==LEVEL_UNIV) {*/
if (!(from.level==LEVEL_SHIP && from.shipptr->whatorbits==LEVEL_UNIV) ) {
/* not already gotten in from */
openstardata(&fire_stardata);
getsdata(fire_stardata, &Sdata);
}
}
} else if (to.level==LEVEL_PLAN) {
if (from.level==LEVEL_PLAN) {
Ignore_filelocks = 1;
if (from.snum == to.snum && from.pnum==to.pnum) {
/* same planet as firing one */
sameplanet = 1;
tpl = fpl;
} else {
openpdata(&fire_topdata);
getplanet(fire_topdata,&tpl,Stars[to.snum]->
planetpos[to.pnum]);
}
Ignore_filelocks = 0;
} else if (from.level==LEVEL_SHIP &&
from.shipptr->whatorbits==LEVEL_PLAN) {
Ignore_filelocks = 1; /* planet data file also locked */
if (from.shipptr->storbits==to.snum &&
from.shipptr->pnumorbits==to.pnum) {
sameplanet = 1;
tpl = fpl;
} else {
openpdata(&fire_topdata);
getplanet(fire_topdata,&tpl,Stars[to.snum]->
planetpos[to.pnum]);
}
Ignore_filelocks = 0;
} else {
openpdata(&fire_topdata);
getplanet(fire_topdata,&tpl,Stars[to.snum]->planetpos[to.pnum]);
}
} else {
printf("You can't shoot at that.\n");
fire_handler();
}
/* ask user for sector of planet to shoot at */
if (to.level==LEVEL_PLAN) {
printf("aim at");
GetMapSector(tpl, &firex, &firey);
}
/* prompt if hes your ally */
if ( to.level==LEVEL_SHIP && isset(Race->allied, to.shipptr->owner) ) {
printf("Fire on your ally? (y/n)");
tty_on();
if (getchr()!='y') {
tty_off();
fire_handler();
}
tty_off();
}
maxstrength = (from.level==LEVEL_SHIP) ?
MIN(from.shipptr->destruct,
Shipdata[from.shipptr->type][ABIL_GUNS]) :
MIN(fpl->info[Playernum-1].destruct, PLAN_FIRE_LIM);
if (argn!=4) {
printf("strength (max %d):",maxstrength );
scanf("%d",&strength);
getchr();
} else sscanf(args[3],"%d",&strength);
if (strength>maxstrength) {
printf("Too large.\n");
fire_handler();
} else if (strength<=0) {
printf("wimp.\n");
fire_handler();
}
/* block kill signals to foil cheaters */
mask = sigblock(SIGINT | SIGQUIT | SIGSTOP);
dam = shoot(from,&to,fpl,tpl,firex,firey,strength, &dist, &sdatamod,&starmod, &fromplanetmod);
printf("Distance to target: %.0f, maximum distance: %d.\n",dist, SYSTEMSIZE);
if (dam < 0) {
printf("Target out of range!\n", SYSTEMSIZE);
fire_handler();
}
if (from.level==LEVEL_SHIP) {
from.shipptr->destruct -= strength;
from.shipptr->mass -= strength*MASS_DESTRUCT;
} else if (from.level==LEVEL_PLAN)
fpl->info[Playernum-1].destruct -= strength;
/* enemy retaliates with twice the strength (if he can) */
if ( to.level==LEVEL_SHIP && !to.shipptr->is_dead) {
strength = MIN(to.shipptr->destruct,Shipdata[to.shipptr->type][ABIL_GUNS]);
to.shipptr->destruct -= strength;
to.shipptr->mass -= strength*MASS_DESTRUCT;
} else if (to.level==LEVEL_PLAN) { /* all players owning planet retal */
int strength2;
oldstrength = strength*2;
strength = 0;
for (i=1; i<MAXPLAYERS; i++)
if (tpl->info[i-1].destruct>0 && i!=Playernum && Nuked[i]) {
strength2 = MIN(oldstrength, tpl->info[i-1].destruct);
if (strength2 > PLAN_FIRE_LIM)
strength2 = PLAN_FIRE_LIM;
tpl->info[i-1].destruct -= strength2;
printf("Player %d returns fire, strength %d.\n", i, strength2);
strength += strength2;
Numplayersretaliate++;
}
}
/* enemy fires at shooting sector */
if ( !(to.level==LEVEL_SHIP && to.shipptr->is_dead) )
dam2 = shoot(to,&from,tpl,fpl,from_firex,from_firey,strength, &dist, &sdatamod,&starmod, &toplanetmod);
if (from.level==LEVEL_PLAN) {
putplanet(fire_frompdata,fpl,Stars[from.snum]->planetpos[from.pnum]);
free(fpl);
close(fire_frompdata);
} else if (from.level==LEVEL_SHIP) {
if (from.shipptr->whatorbits == LEVEL_PLAN) {
if (fromplanetmod || (sameplanet && toplanetmod) ) {
/* can only mean that the from ship is dead */
/* and that both ships don't orbit the same planet */
putplanet(fire_frompdata, fpl, Stars[from.shipptr->storbits]->planetpos[from.shipptr->pnumorbits] );
free(fpl);
}
close(fire_frompdata);
}
putship(fire_fromshdata,from.shipptr,from.shipno);
close(fire_fromshdata);
free(from.shipptr);
}
if (to.level==LEVEL_PLAN && !sameplanet) {
putplanet(fire_topdata,tpl,Stars[to.snum]->planetpos[to.pnum]);
free(tpl);
close(fire_topdata);
} else if (to.level==LEVEL_SHIP) {
if (!sameplanet) {
if (toplanetmod)
putplanet(fire_topdata, tpl, Stars[to.shipptr->storbits]->planetpos[to.shipptr->pnumorbits] );
close(fire_topdata);
}
putship(fire_toshdata,to.shipptr,to.shipno);
free(to.shipptr);
close(fire_toshdata);
}
if (starmod) {
/* this means both ships (if from is a ship) orbit same star */
if (from.level==LEVEL_SHIP)
putstar(fire_stardata,Stars[from.shipptr->storbits],from.shipptr->storbits);
else if (to.level==LEVEL_SHIP) /* it should */
putstar(fire_stardata,Stars[to.shipptr->storbits],to.shipptr->storbits);
}
if (sdatamod)
putsdata(fire_stardata);
close(fire_stardata);
printf("BOOM!!\007 %d%s.\n", dam,
to.level==LEVEL_SHIP ?
(to.shipptr->type==OTYPE_VN ? " Von Neumann machines destroyed"
: "% damage done") : " sectors destroyed" );
teleg_add("",telegram_buf);
sprintf(buf," BULLETIN from %s\n\n",Dispplace(&from));
teleg_add(buf,telegram_buf);
sprintf(buf,"%s%s ",from.level==LEVEL_SHIP ? "ship " : "", Dispplace(&from));
teleg_add(buf,telegram_buf);
sprintf(buf,"fired on %s%s; %d%s.",
to.level==LEVEL_SHIP ? "ship " : "", Dispplace(&to),
dam, to.level==LEVEL_SHIP ?
(to.shipptr->type==OTYPE_VN ? " Von Neumann machines destroyed"
: "% damage done") : " sectors destroyed" );
teleg_add(buf,telegram_buf);
if (to.level==LEVEL_SHIP && to.shipptr->is_dead) {
sprintf(buf,"Ship #%d DESTROYED.\n", to.shipno);
teleg_add(buf,telegram_buf);
}
for (i=1; i<MAXPLAYERS; i++)
if (Nuked[i] && i!=Playernum) {
printf("notifying player %d\n",i);
teleg_send(TELEG_PLAYER_AUTO, i, telegram_buf);
}
if (dam2) {
printf("%s retaliates with %sstrength %d!! %d%s.\n", Dispplace(&to),
Numplayersretaliate>1 ? "total " : "",
strength, dam2,
(from.level==LEVEL_SHIP) ?
"% damage done" : " sectors destroyed" );
} else printf("%s cannot retaliate.\n",Dispplace(&to) );
if (from.level==LEVEL_PLAN) {
/* firing from planet -- deduct APs from that star */
APdeductstar = from.snum;
} else if (from.level==LEVEL_SHIP && from.shipptr->whatorbits!=LEVEL_UNIV) {
/* firing from ship -- deduct APs from star ship orbits */
APdeductstar = from.shipptr->storbits;
}
deductAPs(APcount, APdeductstar, 0);
sigsetmask(mask); /* reset mask */
}
fire_handler(sig, code, scp)
int sig,code;
struct sigcontext *scp;
{
close(fire_stardata);
close(fire_fromshdata);
close(fire_toshdata);
close(fire_frompdata);
close(fire_topdata);
close(fire_sectdata);
longjmp(main_jenv,1);
}