/* fortdef.c */
extern int sd(natid, natid, coord, coord, int, int, int);
extern int dd(natid, natid, coord, coord, int, int);
-extern int sb(natid, natid, struct sctstr *, coord, coord, int, int);
extern int shipdef(natid, natid, coord, coord);
/* getbit.c */
extern int emp_getbit(int, int, unsigned char *);
extern double seagun(int, int);
extern double landgun(int, int);
extern double landunitgun(int, int, int, int, int);
+extern double effrange(int, double);
+extern double torprange(struct shpstr *);
+extern double fortrange(struct sctstr *);
extern int roundrange(double);
/* list.c */
extern int shipsatxy(coord, coord, int, int);
static int ef_with_guns[] = { EF_SECTOR, EF_SHIP, EF_LAND, EF_BAD };
char vbuf[20];
char *ptr;
- double range2, range;
- int trange;
+ double range;
+ int trange, range2;
coord fx;
coord fy;
coord x;
fship.shp_effic);
continue;
}
- range = techfact(fship.shp_tech,
- (double)fship.shp_frnge / 2.0);
- range2 = (double)roundrange(range);
- pr("range is %.2f (%.2f)\n", range2, range);
+ range = effrange(fship.shp_frnge, fship.shp_tech);
+ range2 = roundrange(range);
+ pr("range is %d.00 (%.2f)\n", range2, range);
if (target == targ_sub) {
if ((mchr[(int)fship.shp_type].m_flags & M_DCH) == 0) {
/* Don't tell it's a sub */
shell = fland.lnd_item[I_SHELL];
- range = techfact((int)fland.lnd_tech,
- (double)fland.lnd_frg / 2.0);
- range2 = (double)roundrange(range);
- pr("range is %.2f (%.2f)\n", range2, range);
+ range = effrange(fland.lnd_frg, fland.lnd_tech);
+ range2 = roundrange(range);
+ pr("range is %d.00 (%.2f)\n", range2, range);
if (target == targ_sub) {
/* Don't tell it's a sub */
range2 = -1;
}
if (gun > 7)
gun = 7;
- range = tfactfire(player->cnum, 7.0);
- if (fsect.sct_effic > 59)
- range++;
- range2 = (double)roundrange(range);
- pr("range is %.2f (%.2f)\n", range2, range);
+ range = fortrange(&fsect);
+ range2 = roundrange(range);
+ pr("range is %d.00 (%.2f)\n", range2, range);
if (target == targ_sub) {
/* Don't tell it's a sub */
range2 = -1;
default:
pr_beep();
pr("Kaboom!!!\n");
- prb = (double)(range2 ? (trange / range2) : 1.0);
+ prb = range2 ? (double)trange / range2 : 1.0;
prb *= prb;
if (chance(prb)) {
pr("Wind deflects shell%s.\n", splur(shots));
/* dam = (int)((double)dam / 2.0);*/
- dam =
- (int)((double)dam *
- (double)((double)(90 - (random() % 11)) /
- 100.0));
+ dam *= (90 - (random() % 11)) / 100.0;
if (dam < 0)
dam = 0;
}
quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown,
coord ax, coord ay, int *nfiring)
{
- int nshot;
- double range, erange, hitchance;
+ int nshot, range;
+ double erange, hitchance;
struct shpstr ship;
struct lndstr land;
struct nstr_item ni;
int dam, dam2, rel, rel2;
- double tech;
struct sctstr firing;
struct nstr_sect ns;
struct flist *fp;
if (ship.shp_mobil <= 0)
continue;
*/
- erange = ship.shp_effic
- * techfact(ship.shp_tech, ship.shp_frnge) / 100.0;
- erange = (double)roundrange(erange);
+ erange = torprange(&ship);
range = mapdist(ship.shp_x, ship.shp_y, ax, ay);
- if (range > erange)
+ if (range > roundrange(erange))
continue;
if (!line_of_sight(NULL, ship.shp_x, ship.shp_y, ax, ay))
continue;
dam += TORP_DAMAGE();
} else {
- range = techfact(ship.shp_tech,
- ship.shp_frnge * ship.shp_effic / 200.0);
- range = (double)roundrange(range);
- if (range < ni.curdist)
+ erange = effrange(ship.shp_frnge, ship.shp_tech);
+ if (roundrange(erange) < ni.curdist)
continue;
/* must have gun, shell, and milit to fire */
if (shell < 1)
if ((land.lnd_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
continue;
-
- range = techfact((int)land.lnd_tech, (double)land.lnd_frg / 2.0);
- range = (double)roundrange(range);
- if (range < ni.curdist)
+ erange = effrange(land.lnd_frg, land.lnd_tech);
+ if (roundrange(erange) < ni.curdist)
continue;
resupply_all(&land);
if (!opt_NO_FORT_FIRE) {
snxtsct_dist(&ns, ax, ay, 8);
while (nxtsct(&ns, &firing)) {
-
- if (firing.sct_type != SCT_FORTR)
- continue;
if (firing.sct_own == 0)
continue;
rel = getrel(getnatp(firing.sct_own), own);
/* Don't shoot yourself */
if (firing.sct_own == aown)
continue;
- tech = tfactfire(firing.sct_own, 1.0);
- range = tech * 7.0;
- if (firing.sct_effic > 59) /* fort bonus */
- range++;
- range = (double)roundrange(range);
- if (range < ns.curdist)
+ erange = fortrange(&firing);
+ if (roundrange(erange) < ns.curdist)
continue;
gun = firing.sct_item[I_GUN];
int shells;
int subno;
int victno;
- double erange;
+ int erange;
double hitchance;
struct shpstr vship;
struct shpstr sub;
if (sub.shp_own == 0) {
continue;
}
- erange = ((double)sub.shp_effic / 100.0) *
- techfact(sub.shp_tech, sub.shp_frnge);
- erange = (double)roundrange(erange);
- pr("Effective torpedo range is %.1f\n", erange);
+ erange = roundrange(torprange(&sub));
+ pr("Effective torpedo range is %d.0\n", erange);
shells -= SHP_TORP_SHELLS;
sub.shp_item[I_SHELL] = shells;
putship(sub.shp_uid, &sub);
static void
anti_torp(int f, int ntorping, int vshipown)
{
- int range;
- double erange;
+ int range, erange;
struct shpstr sub;
struct shpstr dd;
int x;
if (!canshoot(&dd, &sub))
continue;
- erange = techfact(dd.shp_tech, dd.shp_frnge) / 2.0;
-
- erange = (double)roundrange(erange);
-
+ erange = roundrange(effrange(dd.shp_frnge, dd.shp_tech));
range = mapdist(sub.shp_x, sub.shp_y, dd.shp_x, dd.shp_y);
-
if (range > erange)
continue;
#define NOISY 1
+static int sb(natid, natid, struct sctstr *, coord, coord, int, int);
+
/*
* See if any nearby ships will open up on the attacker
* Return damage done to attacker, if any.
int usesubs)
{
int nshot;
- double range;
+ int range;
double eff;
struct shpstr ship;
struct nstr_item ni;
continue;
if ((mchr[(int)ship.shp_type].m_flags & M_SUB) && !usesubs)
continue;
- range = techfact(ship.shp_tech,
- ship.shp_frnge * ship.shp_effic / 200.0);
- range = (double)roundrange(range);
+ range = roundrange(effrange(ship.shp_frnge, ship.shp_tech));
if (range < ni.curdist)
continue;
/* must have gun, shell, and milit to fire */
dd(natid att, natid def_own, coord ax, coord ay, int noisy, int defending)
{
int dam, rel, rel2;
- double tech;
- double range;
struct sctstr firing;
struct nstr_sect ns;
return 0;
if (att == def_own)
return 0;
- tech = tfactfire(def_own, 1.0);
dam = 0;
snxtsct_dist(&ns, ax, ay, 8);
while (nxtsct(&ns, &firing) && dam < 80) {
continue;
if (firing.sct_own == 0)
continue;
- if (firing.sct_effic < FORTEFF)
- continue;
rel = getrel(getnatp(firing.sct_own), def_own);
rel2 = getrel(getnatp(firing.sct_own), att);
- if ((firing.sct_own != def_own) &&
- ((rel != ALLIED) || (rel2 != AT_WAR)))
- continue;
-
- range = tfactfire(def_own, 7.0);
- if (firing.sct_effic > 59)
- range++;
- /* Here we round down the range, and then add 1 to it
- to determine if we could possibly hit the sector. If
- we do, we call sb where the range is re-calculated and
- the percentages are checked. */
- range = (double)((int)(range) + 1);
- if (range < ns.curdist)
+ if (firing.sct_own != def_own && (rel != ALLIED || rel2 != AT_WAR))
continue;
/* XXX defdef damage is additive, but ship or land unit damage isn't */
dam += sb(att, def_own, &firing, ax, ay, noisy, defending);
*
* See if the sector being fired at will defend itself.
*/
-int
+static int
sb(natid att, natid def, struct sctstr *sp, coord tx, coord ty, int noisy,
int defending)
{
int damage;
natid own;
int shell;
- double range;
+ int range;
int range2, gun;
- if (sp->sct_type != SCT_FORTR) {
- /* XXX I don't like this restriction */
- return 0;
- }
-
- if (sp->sct_effic < FORTEFF)
- return 0;
-
own = sp->sct_own;
if (own == 0)
return 0;
if (att == own)
return 0;
- range = tfactfire(own, 7.0);
- if (sp->sct_effic > 59)
- range++;
- range = (double)roundrange(range);
- range2 = mapdist((int)sp->sct_x, (int)sp->sct_y, tx, ty);
+ range = roundrange(fortrange(sp));
+ range2 = mapdist(sp->sct_x, sp->sct_y, tx, ty);
if (range < range2)
return 0;
gun = sp->sct_item[I_GUN];
#include <config.h>
#include "misc.h"
+#include "file.h"
+#include "nat.h"
+#include "optlist.h"
#include "prototypes.h"
double
return d;
}
+/*
+ * Return effective firing range for range factor RNG at tech TLEV.
+ */
+double
+effrange(int rng, double tlev)
+{
+ /* FIXME don't truncate TLEV */
+ return techfact((int)tlev, rng / 2.0);
+}
+
+/*
+ * Return torpedo range for ship SP.
+ */
+double
+torprange(struct shpstr *sp)
+{
+ return effrange(sp->shp_frnge * 2, sp->shp_tech)
+ * sp->shp_effic / 100.0;
+}
+
+/*
+ * Return firing range for sector SP.
+ */
+double
+fortrange(struct sctstr *sp)
+{
+ struct natstr *np = getnatp(sp->sct_own);
+ double rng;
+
+ if (sp->sct_type != SCT_FORTR || sp->sct_effic < FORTEFF)
+ return -1.0;
+
+ rng = effrange(14.0 * fire_range_factor, np->nat_level[NAT_TLEV]);
+ if (sp->sct_effic > 59)
+ rng++;
+ return rng;
+}
+
int
roundrange(double r)
{
{
struct nstr_sect ns;
struct sctstr fsect;
- int trange;
- double range, range2, guneff;
+ int trange, range;
+ double guneff;
int shell, gun;
int dam;
int totdam = 0;
continue;
if (fsect.sct_own == victim)
continue;
- if (fsect.sct_type != SCT_FORTR)
- continue;
if (getrel(getnatp(fsect.sct_own), victim) >= NEUTRAL)
continue;
gun = fsect.sct_item[I_GUN];
if (gun < 1)
continue;
- range = tfactfire(fsect.sct_own, MIN(gun, 7));
- if (fsect.sct_effic > 59)
- range++;
- range2 = roundrange(range);
+ range = roundrange(fortrange(&fsect));
trange = mapdist(newx, newy, fsect.sct_x, fsect.sct_y);
- if (trange > range2)
+ if (trange > range)
continue;
if (fsect.sct_item[I_MILIT] < 5)
continue;
int dist;
int shell;
int gun;
- double range, range2;
+ int range;
snxtitem_all(&ni, EF_LAND);
while (nxtitem(&ni, &land)) {
/* are we in range? */
dist = mapdist(land.lnd_x, land.lnd_y, x, y);
- range = techfact((int)land.lnd_tech, (double)land.lnd_frg / 2.0);
-
- range2 = roundrange(range);
- if (dist > range2)
+ range = roundrange(effrange(land.lnd_frg, land.lnd_tech));
+ if (dist > range)
continue;
shell = land.lnd_item[I_SHELL];
struct plchrstr *pcp;
int dam = 0, dam2, mission_flags, tech;
natid plane_owner = 0;
- int gun, shell, md, air_dam = 0;
- double range2, prb, range, mobcost, hitchance;
+ int gun, shell, md, range, air_dam = 0;
+ double prb, mobcost, hitchance, vrange;
getsect(x, y, §);
(md > land_max_interdiction_range))
continue;
- if (md > (lp->lnd_frg / 2))
- continue;
-
if ((lp->lnd_ship != -1) || (lp->lnd_land != -1))
continue;
if (lnd_getmil(lp) < 1)
continue;
- range = techfact((int)lp->lnd_tech, (double)lp->lnd_frg / 2.0);
- range2 = (double)roundrange(range);
-
- if (md > range2)
+ range = roundrange(effrange(lp->lnd_frg, lp->lnd_tech));
+ if (md > range)
continue;
shell = lp->lnd_item[I_SHELL];
continue;
if (!(mcp->m_flags & M_DCH) && !(mcp->m_flags & M_SUBT))
continue;
- range2 = techfact(sp->shp_tech, mcp->m_vrnge);
- range2 *= (double)sp->shp_effic / 200.0;
- if (md > range2)
+ vrange = techfact(sp->shp_tech, mcp->m_vrnge);
+ vrange *= (double)sp->shp_effic / 200.0;
+ if (md > vrange)
continue;
/* can't look all the time */
if (chance(0.5))
if (shell < SHP_TORP_SHELLS)
continue;
- range = sp->shp_effic
- * techfact(sp->shp_tech, sp->shp_frnge) / 100.0;
-
- range2 = (double)roundrange(range);
+ range = roundrange(torprange(sp));
if (md > range)
continue;
"%s locking on %s %s in %s\n",
prship(sp), cname(victim), s, xyas(x, y, sp->shp_own));
wu(0, sp->shp_own,
- "\tEffective torpedo range is %.1f\n", range);
+ "\tEffective torpedo range is %d.0\n", range);
wu(0, sp->shp_own,
"\tWhooosh... Hitchance = %d%%\n",
(int)(hitchance * 100));
"Incoming torpedo sighted @ %s hits and does %d damage!\n",
xyas(x, y, victim), dam2);
} else {
- range = techfact(sp->shp_tech, (double)mcp->m_frnge / 2.0);
- range2 = (double)roundrange(range);
- if (md > range2)
+ range = roundrange(effrange(sp->shp_frnge, sp->shp_tech));
+ if (md > range)
continue;
gun = sp->shp_item[I_GUN];
gun = MIN(gun, sp->shp_glim);
continue;
gun = MAX(gun, 1);
dam2 = seagun(sp->shp_effic, gun);
- if (range2 == 0.0)
+ if (range == 0.0)
prb = 1.0;
else
- prb = ((double)md) / range2;
+ prb = (double)md / range;
prb *= prb;
if (chance(prb))
dam2 /= 2;
switch (type) {
case EF_SHIP:
getship(gp->uid, &ship);
- range = ldround(techfact(gp->tech,
- (double)ship.shp_frnge / 2.0), 1);
+ range = ldround(effrange(ship.shp_frnge, ship.shp_tech), 1);
break;
case EF_LAND:
getland(gp->uid, &land);
- range = ldround(techfact((int)land.lnd_tech,
- (double)land.lnd_frg / 2.0), 1);
+ range = ldround(effrange(land.lnd_frg, land.lnd_tech), 1);
break;
case EF_PLANE:
getplane(gp->uid, &plane);
{
struct nstr_sect ns;
struct sctstr fsect;
- int trange;
- double range, range2, guneff;
+ int trange, range;
+ double guneff;
int shell, gun;
int dam;
int totdam = 0;
while (nxtsct(&ns, &fsect)) {
if (!notified[fsect.sct_own])
continue;
- if (fsect.sct_type != SCT_FORTR)
- continue;
gun = fsect.sct_item[I_GUN];
if (gun < 1)
continue;
- range = tfactfire(fsect.sct_own, MIN(gun, 7));
- if (fsect.sct_effic > 59)
- range++;
- range2 = roundrange(range);
+ range = roundrange(fortrange(&fsect));
trange = mapdist(newx, newy, fsect.sct_x, fsect.sct_y);
- if (trange > range2)
+ if (trange > range)
continue;
if (fsect.sct_item[I_MILIT] < 5)
continue;