|
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); }