diff --git a/include/land.h b/include/land.h index f01d58f2..caf73062 100644 --- a/include/land.h +++ b/include/land.h @@ -167,6 +167,8 @@ extern int l_acc(struct lchrstr *, int); 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); diff --git a/include/prototypes.h b/include/prototypes.h index c1b5948f..4a10d416 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -460,7 +460,7 @@ extern int lnd_prewrite(int, void *); /* 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 *); diff --git a/src/lib/commands/mfir.c b/src/lib/commands/mfir.c index 19f1885c..ca52e15a 100644 --- a/src/lib/commands/mfir.c +++ b/src/lib/commands/mfir.c @@ -79,8 +79,6 @@ multifire(void) coord x; coord y; int mil; - int gun; - int shell; int shots; int dam; int totaldefdam = 0; @@ -173,8 +171,6 @@ multifire(void) 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; @@ -361,13 +357,11 @@ multifire(void) 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); @@ -376,21 +370,16 @@ multifire(void) 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; @@ -716,7 +705,6 @@ quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown, struct sctstr firing; struct nstr_sect ns; struct flist *fp; - int gun, shell; if (own == 0) return 0; @@ -779,16 +767,6 @@ quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown, 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; @@ -803,27 +781,17 @@ quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown, 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; } @@ -929,21 +897,17 @@ static void 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); } diff --git a/src/lib/subs/landgun.c b/src/lib/subs/landgun.c index 1cca07cd..fbaed6c5 100644 --- a/src/lib/subs/landgun.c +++ b/src/lib/subs/landgun.c @@ -35,6 +35,7 @@ #include "damage.h" #include "file.h" +#include "land.h" #include "nat.h" #include "optlist.h" #include "prototypes.h" @@ -65,16 +66,14 @@ seagun(int effic, int guns) } 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; } @@ -179,6 +178,45 @@ shp_torp(struct shpstr *sp, int usemob) 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. */ diff --git a/src/lib/subs/lndsub.c b/src/lib/subs/lndsub.c index a3ba6e90..a6b4636e 100644 --- a/src/lib/subs/lndsub.c +++ b/src/lib/subs/lndsub.c @@ -1128,37 +1128,21 @@ lnd_support(natid victim, natid attacker, coord x, coord y, int defending) 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); @@ -1166,31 +1150,26 @@ lnd_support(natid victim, natid attacker, coord x, coord y, int defending) 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) { diff --git a/src/lib/subs/mission.c b/src/lib/subs/mission.c index 1f8e9d73..1e92f77c 100644 --- a/src/lib/subs/mission.c +++ b/src/lib/subs/mission.c @@ -411,7 +411,7 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, 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, §); @@ -430,9 +430,6 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, if (glp->thing->ef_type == EF_LAND) { lp = (struct lndstr *)glp->thing; - if (lp->lnd_effic < LAND_MINFIREEFF) - continue; - if (mission == MI_SINTERDICT) continue; @@ -440,42 +437,30 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, (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;