extern int m_glim(struct mchrstr *, int);
extern int shp_dchrg(struct shpstr *);
+extern int shp_fire(struct shpstr *);
#endif
int gun;
int shell;
int shots;
- double guneff;
int dam;
int totaldefdam = 0;
int fshipno;
pr("Not enough mil on ship #%d\n", item.ship.shp_uid);
continue;
}
- gun = item.ship.shp_item[I_GUN];
- gun = MIN(gun, item.ship.shp_glim);
- if (item.ship.shp_frnge == 0) {
+ if (item.ship.shp_glim == 0) {
pr("Ships %d cannot fire guns!\n", item.ship.shp_uid);
continue;
}
- if (gun == 0) {
+ if (item.ship.shp_item[I_GUN] == 0) {
pr("Not enough guns on ship #%d\n", item.ship.shp_uid);
continue;
}
if (target == targ_sub)
/* Don't tell it's a sub */
range2 = -1;
- gun = fship.shp_item[I_GUN];
- gun = MIN(gun, fship.shp_glim);
- if (fship.shp_frnge == 0 || gun == 0) {
+ if (fship.shp_item[I_GUN] == 0) {
pr("Insufficient arms.\n");
continue;
}
- shell = fship.shp_item[I_SHELL];
- shell += supply_commod(fship.shp_own,
- fship.shp_x, fship.shp_y,
- I_SHELL, 2 - shell);
- if (shell <= 0) {
+ dam = shp_fire(&fship);
+ putship(fship.shp_uid, &fship);
+ if (dam <= 0) {
pr("Klick! ...\n");
continue;
}
- gun = MIN(gun, shell * 2);
- gun = MIN(gun, mil / 2);
- gun = MAX(gun, 1);
- shots = gun;
- guneff = seagun(fship.shp_effic, shots);
- dam = (int)guneff;
- shell -= ldround(shots / 2.0, 1);
- fship.shp_item[I_SHELL] = shell;
- putship(fship.shp_uid, &fship);
}
if (opt_NOMOBCOST == 0) {
fship.shp_mobil = MAX(fship.shp_mobil - 15, -100);
quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown,
coord ax, coord ay, int *nfiring)
{
- int nshot, range;
+ int range;
double erange, hitchance;
struct shpstr ship;
struct lndstr land;
/* Don't shoot yourself */
if (ship.shp_own == aown)
continue;
- if (ship.shp_effic < 60)
- continue;
-
- gun = ship.shp_item[I_GUN];
- shell = ship.shp_item[I_SHELL];
-
- if (ship.shp_item[I_MILIT] < 1)
- continue;
-
if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
+ if (ship.shp_effic < 60)
+ continue;
+ gun = ship.shp_item[I_GUN];
+ shell = ship.shp_item[I_SHELL];
+ if (ship.shp_item[I_MILIT] < 1)
+ continue;
if (shell < SHP_TORP_SHELLS)
shell += supply_commod(ship.shp_own,
ship.shp_x, ship.shp_y,
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)
- shell += supply_commod(ship.shp_own,
- ship.shp_x, ship.shp_y, I_SHELL, 1);
- /* only need 1 shell, so don't check that */
- if (shell < 1)
- continue;
- nshot = MIN(gun, ship.shp_item[I_MILIT]);
- nshot = MIN(nshot, ship.shp_glim);
- if (nshot == 0)
+ dam2 = shp_fire(&ship);
+ /* no putship(&ship) because ammo is charged in use_ammo() */
+ if (dam2 < 0)
continue;
(*nfiring)++;
fp = malloc(sizeof(struct flist));
fp->uid = ship.shp_uid;
add_to_fired_queue(&fp->queue, list);
nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
- dam += seagun(ship.shp_effic, nshot);
+ dam += dam2;
}
}
snxtitem_dist(&ni, EF_LAND, ax, ay, 8);
radius = desired_radius;
if ((mission == MI_INTERDICT) && (type == EF_SHIP))
- if (mchr[(int)gp->type].m_frnge < 1) {
+ if (mchr[(int)gp->type].m_glim == 0) {
pr("%s: cannot fire at range!\n", obj_nameof(gp));
continue;
}
fire_dchrg(struct shpstr *sp, struct shpstr *targ, int ntargets)
{
int dam;
- int shells;
- int gun;
- double guneff;
if ((mchr[(int)targ->shp_type].m_flags & M_SUB) == 0) {
- shells = sp->shp_item[I_SHELL];
- gun = sp->shp_item[I_GUN];
- gun = MIN(gun, sp->shp_glim);
- gun = MIN(gun, sp->shp_item[I_MILIT] / 2);
-
- shells += supply_commod(sp->shp_own, sp->shp_x, sp->shp_y,
- I_SHELL, (gun + 1) / 2 - shells);
-
- gun = MIN(gun, shells * 2);
- if (gun == 0)
- return;
-
- /* ok, all set.. now, we shoot */
- shells -= ldround(gun / 2.0, 1);
- sp->shp_item[I_SHELL] = shells;
+ dam = shp_fire(sp);
putship(sp->shp_uid, sp);
-
- guneff = seagun(sp->shp_effic, gun);
- dam = (int)guneff;
+ if (dam < 0)
+ return;
if (ntargets > 2)
dam /= ntargets / 2;
sd(natid att, natid own, coord x, coord y, int noisy, int defending,
int usesubs)
{
- int nshot;
int range;
double eff;
struct shpstr ship;
struct nstr_item ni;
- int shell;
int dam, rel, rel2;
if (own == 0)
rel2 = getrel(getnatp(ship.shp_own), att);
if ((ship.shp_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
continue;
- if (ship.shp_effic < 60)
- continue;
if ((mchr[(int)ship.shp_type].m_flags & M_SUB) && !usesubs)
continue;
range = roundrange(effrange(ship.shp_frnge, ship.shp_tech));
if (range < ni.curdist)
continue;
- /* must have gun, shell, and milit to fire */
- shell = ship.shp_item[I_SHELL];
- if (shell < ship.shp_glim)
- shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
- I_SHELL, shell - ship.shp_glim);
- nshot = MIN(MIN(ship.shp_item[I_GUN], shell), ship.shp_item[I_MILIT]);
- nshot = MIN(nshot, ship.shp_glim);
- if (nshot <= 0)
- continue;
- ship.shp_item[I_SHELL] = shell - nshot;
+ dam = shp_fire(&ship);
putship(ship.shp_uid, &ship);
+ if (dam < 0)
+ continue;
if (defending)
nreport(ship.shp_own, N_FIRE_BACK, att, 1);
else
nreport(ship.shp_own, N_FIRE_S_ATTACK, att, 1);
- dam = seagun(ship.shp_effic, nshot);
eff *= (1.0 - (0.01 * dam));
if (noisy) {
pr_beep();
- pr("Incoming shell%s %d damage!\n",
- nshot == 1 ? " does" : "s do", dam);
+ pr("Incoming shells do %d damage!\n", dam);
}
if (noisy || (ship.shp_own != own)) {
if (ship.shp_own == own)
return (int)fortgun(sp->sct_effic, guns);
}
+/*
+ * Fire from ship SP.
+ * Use ammo, resupply if necessary.
+ * Return damage if the ship fires, else -1.
+ */
+int
+shp_fire(struct shpstr *sp)
+{
+ int guns, shells;
+
+ if (sp->shp_effic < 60)
+ return -1;
+ guns = sp->shp_glim;
+ guns = MIN(guns, sp->shp_item[I_GUN]);
+ guns = MIN(guns, (sp->shp_item[I_MILIT] + 1) / 2);
+ if (guns == 0)
+ return -1;
+ shells = sp->shp_item[I_SHELL];
+ shells += supply_commod(sp->shp_own, sp->shp_x, sp->shp_y,
+ I_SHELL, (guns + 1) / 2 - shells);
+ guns = MIN(guns, shells * 2);
+ if (guns == 0)
+ return -1;
+ sp->shp_item[I_SHELL] = shells - (guns + 1) / 2;
+ return (int)seagun(sp->shp_effic, guns);
+}
+
/*
* Drop depth-charges from ship SP.
* Use ammo, resupply if necessary.
sp = (struct shpstr *)glp->thing;
mcp = glp->cp;
- if (sp->shp_effic < 60)
- continue;
- if (sp->shp_frnge == 0)
- continue;
if (((mission == MI_INTERDICT) ||
(mission == MI_SINTERDICT)) &&
(md > ship_max_interdiction_range))
continue;
- if (sp->shp_item[I_MILIT] < 1)
- continue;
/*
if ((mcp->m_flags & M_SUB) &&
(sect.sct_type != SCT_WATER))
a sub. */
if (*s != 's')
continue;
+ if (sp->shp_effic < 60)
+ continue;
+ if (sp->shp_frnge == 0)
+ continue;
+ if (sp->shp_item[I_MILIT] < 1)
+ continue;
if (sp->shp_mobil < 0)
continue;
gun = sp->shp_item[I_GUN];
range = roundrange(effrange(sp->shp_frnge, sp->shp_tech));
if (md > range)
continue;
- if (mission == MI_SINTERDICT) {
+ if (mission == MI_SINTERDICT)
dam2 = shp_dchrg(sp);
- putship(sp->shp_uid, sp);
- if (dam2 < 0)
- continue;
- } else {
- gun = sp->shp_item[I_GUN];
- gun = MIN(gun, sp->shp_glim);
- shell = sp->shp_item[I_SHELL];
- if (shell < gun)
- shell += supply_commod(sp->shp_own,
- sp->shp_x, sp->shp_y, I_SHELL,
- gun - shell);
- gun = MIN(gun, shell);
- gun = MIN(gun, sp->shp_item[I_MILIT] / 2.0);
- if (gun == 0)
- continue;
- gun = MAX(gun, 1);
- dam2 = seagun(sp->shp_effic, gun);
- sp->shp_item[I_SHELL] = shell - gun;
- putship(sp->shp_uid, sp);
- }
+ else
+ dam2 = shp_fire(sp);
+ putship(sp->shp_uid, sp);
+ if (dam2 < 0)
+ continue;
if (range == 0.0)
prb = 1.0;
else