extern int l_dam(struct lchrstr *, int);
extern int l_aaf(struct lchrstr *, int);
+extern int lnd_fire(struct lndstr *);
+
/* src/lib/subs/lndsub.c */
extern void lnd_sweep(struct emp_qelem *, int, int, natid);
extern int lnd_interdict(struct emp_qelem *, coord, coord, natid);
/* landgun.c */
extern double seagun(int, int);
extern double fortgun(int, int);
-extern double landunitgun(int, int, int, int, int);
+extern double landunitgun(int, int);
extern double effrange(int, double);
extern double torprange(struct shpstr *);
extern double fortrange(struct sctstr *);
coord x;
coord y;
int mil;
- int gun;
- int shell;
int shots;
int dam;
int totaldefdam = 0;
fland.lnd_uid, LAND_MINFIREEFF);
continue;
}
- resupply_commod(&fland, I_SHELL); /* Get more shells */
- putland(fland.lnd_uid, &fland);
if (fland.lnd_item[I_SHELL] == 0) {
pr("%s -- not enough shells\n", prland(&fland));
continue;
pr("Unit %d cannot fire!\n", fland.lnd_uid);
continue;
}
- if (fland.lnd_item[I_SHELL] == 0) {
- pr("%s -- not enough shells\n", prland(&fland));
+ if (fland.lnd_item[I_GUN] == 0) {
+ pr("%s -- not enough guns\n", prland(&fland));
continue;
}
- shell = fland.lnd_item[I_SHELL];
-
range = effrange(fland.lnd_frg, fland.lnd_tech);
range2 = roundrange(range);
pr("range is %d.00 (%.2f)\n", range2, range);
range2 = -1;
}
- gun = fland.lnd_item[I_GUN];
- if (gun <= 0) {
- pr("%s -- not enough guns\n", prland(&fland));
+ dam = lnd_fire(&fland);
+ putland(fland.lnd_uid, &fland);
+ if (dam < 0) {
+ pr("Klick! ...\n");
continue;
}
-
- dam = (int)landunitgun(fland.lnd_effic, fland.lnd_dam, gun,
- fland.lnd_ammo, shell);
if (target == targ_ship) {
if (chance(fland.lnd_acc / 100.0))
dam = ldround(dam / 2.0, 1);
}
- use_supply(&fland);
- resupply_commod(&fland, I_SHELL); /* Get more shells */
- putland(fland.lnd_uid, &fland);
} else {
fx = fsect.sct_x;
fy = fsect.sct_y;
struct sctstr firing;
struct nstr_sect ns;
struct flist *fp;
- int gun, shell;
if (own == 0)
return 0;
while (nxtitem(&ni, &land)) {
if (land.lnd_own == 0)
continue;
- if (land.lnd_effic < LAND_MINFIREEFF)
- continue;
- /* Can't fire if on a ship */
- if (land.lnd_ship >= 0)
- continue;
- if (land.lnd_land >= 0)
- continue;
- /* Gotta have military */
- if (land.lnd_item[I_MILIT] < 1)
- continue;
/* Don't shoot yourself */
if (land.lnd_own == aown)
continue;
if (roundrange(erange) < ni.curdist)
continue;
- resupply_all(&land);
- if (!has_supply(&land))
+ dam2 = lnd_fire(&land);
+ /* no putland(&land) because ammo is charged in use_ammo() */
+ if (dam2 < 0)
continue;
- gun = land.lnd_item[I_GUN];
- shell = land.lnd_item[I_SHELL];
-
- if (land.lnd_item[I_MILIT] == 0 || shell == 0 || gun == 0)
- continue;
-
- dam2 = (int)landunitgun(land.lnd_effic, land.lnd_dam, gun,
- land.lnd_ammo, shell);
-
(*nfiring)++;
fp = malloc(sizeof(struct flist));
memset(fp, 0, sizeof(struct flist));
fp->type = targ_unit;
fp->uid = land.lnd_uid;
add_to_fired_queue(&fp->queue, list);
- use_supply(&land);
- putland(land.lnd_uid, &land);
nreport(land.lnd_own, N_FIRE_BACK, player->cnum, 1);
dam += dam2;
}
add_to_fired_queue(struct emp_qelem *elem, struct emp_qelem *list)
{
struct emp_qelem *qp;
- struct flist *fp, *ep;
- int bad = 0;
-
- ep = (struct flist *)elem;
+ struct flist *fp;
+ struct flist *ep = (struct flist *)elem;
/* Don't put them on the list if they're already there */
for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
fp = (struct flist *)qp;
- if ((fp->type == targ_ship) && (fp->uid == ep->uid))
- bad = 1;
- if ((fp->type != targ_ship) && (fp->x == ep->x) &&
- (fp->y == ep->y))
- bad = 1;
+ if (fp->type != targ_land && fp->uid == ep->uid)
+ return;
+ if (fp->type != targ_land
+ && fp->x == ep->x && fp->y == ep->y)
+ return;
}
-
- if (!bad)
- emp_insque(elem, list);
+ emp_insque(elem, list);
}
#include "damage.h"
#include "file.h"
+#include "land.h"
#include "nat.h"
#include "optlist.h"
#include "prototypes.h"
}
double
-landunitgun(int effic, int shots, int guns, int ammo, int shells)
+landunitgun(int effic, int guns)
{
- double d = 0.0;
+ double d;
- shots = MIN(shots, guns);
- while (shots-- > 0)
+ d = 0.0;
+ while (guns--)
d += 5.0 + random() % 6;
d *= effic * 0.01;
- if (shells < ammo && ammo != 0)
- d *= (double)shells / (double)ammo;
return d;
}
return TORP_DAMAGE();
}
+/*
+ * Fire from land unit LP.
+ * Use ammo, resupply if necessary.
+ * Return damage if the land unit fires, else -1.
+ */
+int
+lnd_fire(struct lndstr *lp)
+{
+ int guns, shells;
+ double d;
+ int ammo = lchr[lp->lnd_type].l_ammo;
+
+ if (CANT_HAPPEN(ammo == 0))
+ ammo = 1;
+
+ if (lp->lnd_effic < LAND_MINFIREEFF)
+ return -1;
+ if (lp->lnd_ship >= 0 || lp->lnd_land >= 0)
+ return -1;
+ if (lp->lnd_item[I_MILIT] == 0)
+ return -1;
+ guns = lp->lnd_dam;
+ guns = MIN(guns, lp->lnd_item[I_GUN]);
+ if (guns == 0)
+ return -1;
+ shells = lp->lnd_item[I_SHELL];
+ shells += supply_commod(lp->lnd_own, lp->lnd_x, lp->lnd_y,
+ I_SHELL, ammo - shells);
+ if (shells == 0)
+ return -1;
+ d = landunitgun(lp->lnd_effic, guns);
+ if (shells < ammo) {
+ d *= (double)shells / (double)ammo;
+ ammo = shells;
+ }
+ lp->lnd_item[I_SHELL] = shells - ammo;
+ return d;
+}
+
/*
* Return effective firing range for range factor RNG at tech TLEV.
*/
struct nstr_item ni;
struct lndstr land;
int rel, rel2;
- double dam = 0.0;
+ int dam, dam2;
int dist;
- int shell;
- int gun;
int range;
+ dam = 0;
snxtitem_all(&ni, EF_LAND);
while (nxtitem(&ni, &land)) {
- if (land.lnd_dam == 0)
- continue;
if ((land.lnd_x == x) && (land.lnd_y == y))
continue;
- if (land.lnd_ship >= 0)
- continue;
- if (land.lnd_land >= 0)
- continue;
- if (land.lnd_effic < LAND_MINFIREEFF)
- continue;
- /* Do we have mil? */
- if (land.lnd_item[I_MILIT] <= 0)
- continue;
rel = getrel(getnatp(land.lnd_own), attacker);
rel2 = getrel(getnatp(land.lnd_own), victim);
if ((land.lnd_own != attacker) &&
((rel != ALLIED) || (rel2 != AT_WAR)))
continue;
- /* do we have supplies? */
- if (!has_supply(&land))
- continue;
-
/* are we in range? */
dist = mapdist(land.lnd_x, land.lnd_y, x, y);
if (dist > range)
continue;
- shell = land.lnd_item[I_SHELL];
- gun = land.lnd_item[I_GUN];
-
- if (shell == 0 || gun == 0)
+ dam2 = lnd_fire(&land);
+ putland(land.lnd_uid, &land);
+ if (dam2 < 0)
continue;
- use_supply(&land);
if (defending)
nreport(land.lnd_own, N_FIRE_BACK, victim, 1);
else
nreport(land.lnd_own, N_FIRE_L_ATTACK, victim, 1);
- if (roll(100) < land.lnd_acc) {
- dam += landunitgun(land.lnd_effic, land.lnd_dam, gun,
- land.lnd_ammo, shell) / 2;
- } else {
- dam += landunitgun(land.lnd_effic, land.lnd_dam, gun,
- land.lnd_ammo, shell);
- }
+ if (roll(100) < land.lnd_acc)
+ dam2 /= 2;
+ dam += dam2;
if (land.lnd_own != attacker)
wu(0, land.lnd_own,
"%s supported %s at %s\n",
prland(&land), cname(attacker), xyas(x, y, land.lnd_own));
}
- return (int)dam;
+ return dam;
}
+
int
lnd_can_attack(struct lndstr *lp)
{
struct plchrstr *pcp;
int dam = 0, dam2, mission_flags, tech;
natid plane_owner = 0;
- int gun, shell, md, range, air_dam = 0;
+ int md, range, air_dam = 0;
double prb, hitchance, vrange;
getsect(x, y, §);
if (glp->thing->ef_type == EF_LAND) {
lp = (struct lndstr *)glp->thing;
- if (lp->lnd_effic < LAND_MINFIREEFF)
- continue;
-
if (mission == MI_SINTERDICT)
continue;
(md > land_max_interdiction_range))
continue;
- if ((lp->lnd_ship != -1) || (lp->lnd_land != -1))
- continue;
-
- if (lp->lnd_item[I_MILIT] < 1)
- continue;
-
range = roundrange(effrange(lp->lnd_frg, lp->lnd_tech));
if (md > range)
continue;
- shell = lp->lnd_item[I_SHELL];
- gun = lp->lnd_item[I_GUN];
- if (shell == 0 || gun == 0)
+ dam2 = lnd_fire(lp);
+ putland(lp->lnd_uid, lp);
+ if (dam2 < 0)
continue;
- if (has_supply(lp)) {
- use_supply(lp);
- putland(lp->lnd_uid, lp);
- dam2 = ldround(landunitgun(lp->lnd_effic, lp->lnd_dam, gun,
- lp->lnd_ammo, shell), 1);
- if (sect.sct_type == SCT_WATER) {
- if (chance(lp->lnd_acc / 100.0))
- dam2 = ldround(dam2 / 2.0, 1);
- }
- dam += dam2;
- if (sect.sct_type == SCT_WATER)
- nreport(lp->lnd_own, N_SHP_SHELL, victim, 1);
- else
- nreport(lp->lnd_own, N_SCT_SHELL, victim, 1);
- wu(0, lp->lnd_own,
- "%s fires at %s %s at %s\n",
- prland(lp), cname(victim), s, xyas(x, y, lp->lnd_own));
-
- mpr(victim, "%s %s fires at you at %s\n",
- cname(lp->lnd_own), prland(lp), xyas(x, y, victim));
+ if (sect.sct_type == SCT_WATER) {
+ if (chance(lp->lnd_acc / 100.0))
+ dam2 = ldround(dam2 / 2.0, 1);
}
+ dam += dam2;
+ if (sect.sct_type == SCT_WATER)
+ nreport(lp->lnd_own, N_SHP_SHELL, victim, 1);
+ else
+ nreport(lp->lnd_own, N_SCT_SHELL, victim, 1);
+ wu(0, lp->lnd_own,
+ "%s fires at %s %s at %s\n",
+ prland(lp), cname(victim), s, xyas(x, y, lp->lnd_own));
+
+ mpr(victim, "%s %s fires at you at %s\n",
+ cname(lp->lnd_own), prland(lp), xyas(x, y, victim));
} else if (glp->thing->ef_type == EF_SHIP) {
sp = (struct shpstr *)glp->thing;
mcp = glp->cp;