|
|
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: 11612 (0x2d5c)
Types: TextFile
Names: »fire.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Empire.V/V1.1/COMMANDS/fire.c«
#define D_UPDATE
#define D_SECTDES
#define D_SHIPTYP
#define D_NEWSVERBS
#define D_TRTYCLAUSE
#define D_SCTSTR
#define D_SHPSTR
#define D_DCHRSTR
#define D_MCHRSTR
#define D_FILES
#include "empdef.h"
fire()
{
register char *cp;
register i;
char *xytoa(), *splur(), *getstar(), vfleet;
int ax, ay, vx, vy;
int aship, vship, alors, vlors;
int adef, vdef, vnum, dam, nshells;
short dx, dy;
double arng, vrng, agun, vgun, dsq, q, error;
double seagun(), tfact(), landgun(), sqrt();
struct shpstr as, vs;
/* Get victim vlors, vnum, vx, vy, & vdef */
cp = getstar(argp[1], "Firing on ");
vlors = landorsea(cp);
if( vlors == LAND ) {
if( sargs(cp) == -1 ||
getsect(lx, ly, UP_ALL) == -1 ) return(SYN_RETURN);
if( sect.sct_desig == S_SANCT ) {
printf("%d,%d is a %s!!", lx, ly, dchr[sect.sct_desig].d_name);
return(FAIL_RETURN);
}
vnum = sect.sct_owned;
vx = lx;
vy = ly;
vdef = landdef(sect.sct_desig); /* banks=320 all others 160 */
sprintf(fmtbuf,"Firing on sector %d,%d from ", vx, vy);
cp = fmtbuf;
} else {
vship = getshno(cp, "Victim ship? ", &vs);
if( vship == -1 ||
vs.shp_own == 0 ) {
printf("No such ship exists");
return(SYN_RETURN);
}
vnum = vs.shp_own;
vfleet = vs.shp_fleet;
vx = vs.shp_xp;
vy = vs.shp_yp;
vdef = seadef(vs.shp_type); /* m_prdct */
sprintf(fmtbuf,"Firing on ship #%d from ", vship);
cp = fmtbuf;
}
/* Get attacker alors, ax, ay, adef, agun & arng */
cp = getstar(argp[2], cp);
alors = landorsea(cp);
if( alors == LAND ) {
/* Attacking from land */
if( sargs(cp) == -1 ||
getmysect(lx, ly, UP_ALL) == -1 ) return(SYN_RETURN);
if( sect.sct_desig != S_FORTR ) {
printf("Not a fortress");
return(SYN_RETURN);
}
if( sect.sct_guns == 0 ) {
printf("Insufficient arms");
return(SYN_RETURN);
}
if( sect.sct_shell == 0 ) {
printf("Klick! ...");
return(FAIL_RETURN);
}
if( sect.sct_milit < 5 ) {
printf("Not enough military for firing crew");
return(FAIL_RETURN);
}
sect.sct_shell--;
nshells = 1;
arng = (sect.sct_guns < 7) ? sect.sct_guns : 7;
arng = tfact(cnum, arng);
agun = landgun(sect.sct_effic);
adef = landdef(sect.sct_desig);
putsect(lx, ly);
ax = lx;
ay = ly;
} else {
/* Attacking from sea */
if( getmyship(aship = atopi(cp), &as) == -1 ) return(SYN_RETURN);
if( mchr[as.shp_type].m_frnge == 0 ||
as.shp_gun == 0 ) {
printf("Insufficient arms");
return(SYN_RETURN);
}
if( as.shp_shels == 0 ) {
printf("Klick! ...");
return(FAIL_RETURN);
}
if( as.shp_effc < 60 ) {
printf("Ship #%d is crippled (%d%%)", aship, as.shp_effc);
return(FAIL_RETURN);
}
ax = as.shp_xp;
ay = as.shp_yp;
arng = tfact(cnum, mchr[as.shp_type].m_frnge / 2.);
printf("Efficiency %d%% max range %.2f ", as.shp_effc, arng);
i = (as.shp_gun > mchr[as.shp_type].m_gun) ? mchr[as.shp_type].m_gun : as.shp_gun;
if( as.shp_type == S_TEN && i > 1 ) i = 1;
i = (i < as.shp_shels) ? i : as.shp_shels;
sprintf(fmtbuf,"How many guns (%d max) ?", i);
nshells = onearg(argp[3], fmtbuf);
nshells = (i < nshells) ? i : nshells;
if( nshells == 0 ) return(FAIL_RETURN);
as.shp_shels -= nshells;
agun = seagun(as.shp_type, as.shp_effc, nshells);
adef = seadef(as.shp_type);
as.shp_mbl = (as.shp_mbl < 0) ? as.shp_mbl : 0;
putship(aship, &as);
}
/* Calculate range to see if we have a hit or a miss */
dx = xwrap(vx - ax);
dy = ywrap(vy - ay);
dsq = dx*dx + dy*dy;
if( (vlors == SEA) && (dsq > 50.) ) {
printf("Victim ship not sighted");
return(FAIL_RETURN);
}
if( dsq < 50. && vnum != 0 ) {
if( vlors == LAND ) {
if( trechk(cnum, vnum, LANFIR) == -1 ) return(FAIL_RETURN);
} else {
if( trechk(cnum, vnum, SEAFIR) == -1 ) return(FAIL_RETURN);
}
}
printf("Kaboom!!!▶07◀\n");
error = dsq / (arng*arng);
error = error*error;
if( error > (rand() % 32768) / (5. * 32767.) + .9 ) {
/* Missed - treat it like firing on a land sector; change x,y vdef & vnum */
q = arng / sqrt(dsq);
vx = ax + (short)(dx * q);
vy = ay + (short)(dy * q);
printf("Out of range, shell%s short in %d,%d\n", ((nshells == 1) ? " falls" : "s fall"), vx, vy);
vlors = LAND;
if( getsect(vx, vy, UP_ALL) == -1 ) return(SYN_RETURN);
vdef = landdef(sect.sct_desig);
vnum = sect.sct_owned;
} else {
if( error * 32767. > rand() % 32768 ) {
agun *= .5;
printf("Wind deflects shell%s.\n", splur(nshells));
}
}
if( vlors == LAND ) {
getsect(vx, vy, UP_NONE);
if( sect.sct_desig == S_SANCT ) {
printf("Bounce!");
return(FAIL_RETURN);
}
if( sect.sct_desig == S_WATER ) {
printf("SPLASH..");
return(FAIL_RETURN);
}
}
sigsave();
dam = shelldam(agun, vdef);
ntused = agun / 20. + ntused + .5;
vgun = 0;
if( vlors == SEA ) goto X4120;
/* Shell hit land */
nreport(cnum, N_SCT_SHELL, vnum);
if( (vnum != 0) && (vnum != cnum) ) {
sprintf(fmtbuf,"Country #%d shell%s did %d%% damage in %s", cnum, splur(nshells), dam, xytoa(vx, vy, vnum));
wu(0, vnum, fmtbuf);
}
/* Do damage to the sector, then see if it is a fort and can return fire */
getsect(vx, vy, UP_NONE);
sectdam(dam);
printf("%d%% damage done to sector %d,%d\n", dam, vx, vy);
if( vnum == cnum || vnum == 0 ) {
putsect(vx, vy);
return(NORM_RETURN);
}
vrng = tfact(vnum, (double)((sect.sct_guns < 7) ? sect.sct_guns : 7));
vgun = landgun(sect.sct_effic);
if( sect.sct_desig == S_FORTR &&
sect.sct_shell != 0 &&
dsq <= vrng*vrng &&
vgun > 0 ) {
sect.sct_shell--;
putsect(vx, vy);
fireback(alors, vnum, ax, ay, aship, vgun, adef);
sprintf(fmtbuf,"Sector %s returned fire on %s %s", xytoa(vx, vy, vnum), ((alors == LAND) ? "sector" : "ship at"), xytoa(ax, ay, vnum));
wu(0, vnum, fmtbuf);
} else {
putsect(vx, vy);
}
/* See if the sector is defended, and if defending fort can return fire */
getsect(vx, vy, UP_NONE);
if( sect.sct_dfend == 0 ) return(NORM_RETURN);
dx = sect.sct_dfend<<8;
dx = (dx>>12) + vx;
dy = sect.sct_dfend<<12;
dy = (dy>>12) + vy;
getsect(dx, dy, UP_NONE);
if( vnum == sect.sct_owned &&
sect.sct_desig == S_FORTR &&
sect.sct_shell != 0 ) {
q = min(sect.sct_guns, 7);
if( tfact(vnum, q) < idist(dx -ax, dy - ay) ) return(NORM_RETURN);
sect.sct_shell--;
putsect(dx, dy);
vgun = landgun(sect.sct_effic);
fireback(alors, vnum, ax, ay, aship, vgun, adef);
sprintf(fmtbuf,"Defending sector %s returned fire on %s %s", xytoa(dx, dy, vnum), ((alors == LAND) ? "sector" : "ship at"), xytoa(ax, ay, vnum));
wu(0, vnum, fmtbuf);
}
return(NORM_RETURN);
/* Shell hit ship */
X4120:
shipdam(&vs, dam);
nreport(cnum, N_SHP_SHELL, vnum);
sprintf(fmtbuf,"Country #%d shell%s did %d%% damage to %s #%d", cnum, splur(nshells), dam, mchr[vs.shp_type].m_name, vship);
wu(0, vnum, fmtbuf);
putship(vship, &vs);
if( vs.shp_effc > 20 ) { /* if ship still floats */
printf("%d%% damage done to %s #%d\n", dam, mchr[vs.shp_type].m_name, vship);
}
/* See if any ships in the fleet can return fire on attacker */
for( i = 0; getship(i, &ship) != -1; i++ ) {
if( vnum != ship.shp_own ||
vfleet != ship.shp_fleet ||
ship.shp_gun == 0 ||
ship.shp_shels == 0 ||
ship.shp_type == S_FRE ) continue;
if( idist(ax - ship.shp_xp, ay - ship.shp_yp) > tfact(vnum, mchr[ship.shp_type].m_frnge / 2.) ) continue;
nshells = (ship.shp_gun < ship.shp_shels) ? ship.shp_gun : ship.shp_shels;
if( ship.shp_type == S_TEN && nshells > 1 ) nshells = 1;
if( (vgun = seagun(ship.shp_type, ship.shp_effc, nshells)) == 0 ) continue;
ship.shp_shels -= nshells;
putship(i, &ship);
sprintf(fmtbuf,"Ship #%d returned fire on %s %s", i, ((alors == LAND) ? "sector" : "ship at"), xytoa(ax, ay, vnum));
wu(0, vnum, fmtbuf);
if( fireback(alors, vnum, ax, ay, aship, vgun, adef) == -1 ) return(NORM_RETURN);
}
return(NORM_RETURN);
}
/*
Fire back on attacking fort or ship. Return -1 for sinking
attacking ship. Return 0 for everything else.
*/
fireback(alors, vnum, ax, ay, aship, vgun, adef)
int alors, vnum, ax, ay, aship, adef;
double vgun;
{
int dam;
struct shpstr as;
printf("▶07◀Return fire!\n");
nreport(vnum, N_FIRE_BACK, cnum);
dam = shelldam(vgun, adef);
if( alors == LAND ) {
getsect(ax, ay, UP_NONE);
sectdam(dam);
putsect(ax, ay);
} else {
getship(aship, &as);
shipdam(&as, dam);
putship(aship, &as);
if( as.shp_effc <= 20 ) {
sprintf(fmtbuf,"Country #%d %s #%d at %s sunk▶07◀!\n", cnum, mchr[as.shp_type].m_name, aship, xytoa(ax, ay, vnum));
wu(0, vnum, fmtbuf);
return(-1);
}
}
return(0);
}