diff --git a/include/ship.h b/include/ship.h index c3e24a44..ea323c1f 100644 --- a/include/ship.h +++ b/include/ship.h @@ -185,5 +185,6 @@ extern int m_glim(struct mchrstr *, int); extern int shp_dchrg(struct shpstr *); extern int shp_fire(struct shpstr *); +extern int shp_torp(struct shpstr *, int); #endif diff --git a/src/lib/commands/mfir.c b/src/lib/commands/mfir.c index be1ee2dc..19f1885c 100644 --- a/src/lib/commands/mfir.c +++ b/src/lib/commands/mfir.c @@ -708,7 +708,7 @@ quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown, coord ax, coord ay, int *nfiring) { int range; - double erange, hitchance; + double erange; struct shpstr ship; struct lndstr land; struct nstr_item ni; @@ -738,45 +738,25 @@ quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown, if (ship.shp_own == aown) 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, - I_SHELL, SHP_TORP_SHELLS - shell); - if (shell < SHP_TORP_SHELLS) - continue; - if (gun < 1) - continue; -/* - if (ship.shp_mobil <= 0) - continue; -*/ erange = torprange(&ship); range = mapdist(ship.shp_x, ship.shp_y, ax, ay); if (range > roundrange(erange)) continue; if (!line_of_sight(NULL, ship.shp_x, ship.shp_y, ax, ay)) continue; - + dam2 = shp_torp(&ship, 0); + /* no putship(&ship) because ammo is charged in use_ammo() */ + if (dam2 < 0) + continue; (*nfiring)++; fp = malloc(sizeof(struct flist)); memset(fp, 0, sizeof(struct flist)); fp->type = targ_ship; fp->uid = ship.shp_uid; add_to_fired_queue(&fp->queue, list); -/* - nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1); -*/ - hitchance = DTORP_HITCHANCE(range, ship.shp_visib); - if (!chance(hitchance)) + if (!chance(DTORP_HITCHANCE(range, ship.shp_visib))) continue; - - dam += TORP_DAMAGE(); + dam += dam2; } else { erange = effrange(ship.shp_frnge, ship.shp_tech); if (roundrange(erange) < ni.curdist) diff --git a/src/lib/commands/torp.c b/src/lib/commands/torp.c index 207528ec..41490979 100644 --- a/src/lib/commands/torp.c +++ b/src/lib/commands/torp.c @@ -56,7 +56,6 @@ torp(void) natid vshipown; int range; int dam; - int shells; int subno; int victno; int erange; @@ -79,11 +78,8 @@ torp(void) continue; if ((mchr[(int)sub.shp_type].m_flags & M_TORP) == 0) continue; - shells = sub.shp_item[I_SHELL]; - if (shells < SHP_TORP_SHELLS) - shells += supply_commod(sub.shp_own, sub.shp_x, sub.shp_y, - I_SHELL, SHP_TORP_SHELLS - shells); - if (sub.shp_item[I_GUN] == 0 || shells < SHP_TORP_SHELLS) + if (sub.shp_item[I_GUN] == 0 + || sub.shp_item[I_SHELL] < SHP_TORP_SHELLS) continue; if (sub.shp_item[I_MILIT] < 1) continue; @@ -106,11 +102,8 @@ torp(void) sub.shp_uid, mchr[(int)sub.shp_type].m_name); continue; } - shells = sub.shp_item[I_SHELL]; - if (shells < SHP_TORP_SHELLS) - shells += supply_commod(sub.shp_own, sub.shp_x, sub.shp_y, - I_SHELL, SHP_TORP_SHELLS - shells); - if (sub.shp_item[I_GUN] == 0 || shells < SHP_TORP_SHELLS) { + if (sub.shp_item[I_GUN] == 0 + || sub.shp_item[I_SHELL] < SHP_TORP_SHELLS) { pr("Ship #%d has insufficient armament\n", sub.shp_uid); continue; } @@ -149,19 +142,22 @@ torp(void) continue; } } + dam = shp_torp(&sub, 1); + sub.shp_mission = 0; + putship(sub.shp_uid, &sub); + if (CANT_HAPPEN(dam < 0)) { + pr("Ship #%d has insufficient armament\n", sub.shp_uid); + continue; + } + if ((mchr[(int)sub.shp_type].m_flags & M_SUB) == 0) anti_torp(sub.shp_uid, ntorping, vshipown); getship(sub.shp_uid, &sub); - if (sub.shp_own == 0) { + if (sub.shp_own == 0) continue; - } + 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); - /* Mob cost for a torp is equal to the cost of 1/2 sector of movement */ - sub.shp_mobil -= shp_mobcost(&sub) / 2.0; pr("Whooosh... "); getship(victno, &vship); vshipown = vship.shp_own; @@ -183,9 +179,8 @@ torp(void) } } else if (range > erange) { pr("Out of range\n"); - } else if (hitchance >= 1.0 || chance(hitchance)) { + } else if (chance(hitchance)) { pr("BOOM!...\n"); - dam = TORP_DAMAGE(); if (vshipown != 0) wu(0, vshipown, "%s in %s torpedoed %s for %d damage.\n", prsub(&sub), xyas(sub.shp_x, sub.shp_y, vshipown), @@ -210,8 +205,7 @@ torp(void) wu(0, vshipown, "Torpedo sighted @ %s by %s\n", xyas(sub.shp_x, sub.shp_y, vshipown), prship(&vship)); } - sub.shp_mission = 0; - putship(sub.shp_uid, &sub); + if (mchr[(int)sub.shp_type].m_flags & M_SUB) anti_torp(sub.shp_uid, ntorping, vshipown); } @@ -355,55 +349,28 @@ static int fire_torp(struct shpstr *sp, struct shpstr *targ, int ntargets) { int range, erange, dam; - int shells; - double hitchance; erange = roundrange(torprange(sp)); range = mapdist(sp->shp_x, sp->shp_y, targ->shp_x, targ->shp_y); if (range > erange) return 0; - shells = sp->shp_item[I_SHELL]; - - if (shells < SHP_TORP_SHELLS) - shells += supply_commod(sp->shp_own, sp->shp_x, sp->shp_y, - I_SHELL, SHP_TORP_SHELLS - shells); - - if (sp->shp_item[I_GUN] == 0 || shells < SHP_TORP_SHELLS) - return 0; - - if (sp->shp_item[I_MILIT] < 1) - return 0; - - if (sp->shp_effic < 60) - return 0; - - if (sp->shp_mobil <= 0) - return 0; - if (!line_of_sight(NULL, sp->shp_x, sp->shp_y, targ->shp_x, targ->shp_y)) return 0; - - /* All set.. fire! */ - shells -= SHP_TORP_SHELLS; - sp->shp_item[I_SHELL] = shells; + dam = shp_torp(sp, 1); putship(sp->shp_uid, sp); - - /* Mob cost for a torp is equal to the cost of 1/2 sector of movement */ - sp->shp_mobil -= shp_mobcost(sp) / 2.0; - - hitchance = DTORP_HITCHANCE(range, sp->shp_visib); + if (dam < 0) + return 0; pr("Captain! Torpedoes sighted!\n"); - if (chance(hitchance)) { + if (chance(DTORP_HITCHANCE(range, sp->shp_visib))) { pr("BOOM!...\n"); if (sp->shp_own != 0) wu(0, sp->shp_own, "%s @ %s torpedoed %s\n", prship(sp), xyas(sp->shp_x, sp->shp_y, sp->shp_own), prsub(targ)); - dam = TORP_DAMAGE(); if (ntargets > 2) dam /= ntargets / 2; diff --git a/src/lib/subs/landgun.c b/src/lib/subs/landgun.c index 7d463fd4..1cca07cd 100644 --- a/src/lib/subs/landgun.c +++ b/src/lib/subs/landgun.c @@ -33,6 +33,7 @@ #include +#include "damage.h" #include "file.h" #include "nat.h" #include "optlist.h" @@ -151,6 +152,33 @@ shp_dchrg(struct shpstr *sp) return (int)seagun(sp->shp_effic, 3); } +/* + * Fire torpedo from ship SP. + * Use ammo and mobility, resupply if necessary. + * Return damage if the ship fires, else -1. + */ +int +shp_torp(struct shpstr *sp, int usemob) +{ + int shells; + + if (sp->shp_effic < 60 || (mchr[sp->shp_type].m_flags & M_TORP) == 0) + return -1; + if (sp->shp_item[I_MILIT] == 0 || sp->shp_item[I_GUN] == 0) + return -1; + if (usemob && sp->shp_mobil <= 0) + return -1; + shells = sp->shp_item[I_SHELL]; + shells += supply_commod(sp->shp_own, sp->shp_x, sp->shp_y, + I_SHELL, SHP_TORP_SHELLS - shells); + if (shells < SHP_TORP_SHELLS) + return -1; + sp->shp_item[I_SHELL] = shells - SHP_TORP_SHELLS; + if (usemob) + sp->shp_mobil -= (int)shp_mobcost(sp) / 2.0; + return TORP_DAMAGE(); +} + /* * Return effective firing range for range factor RNG at tech TLEV. */ diff --git a/src/lib/subs/mission.c b/src/lib/subs/mission.c index e45e1e2a..1f8e9d73 100644 --- a/src/lib/subs/mission.c +++ b/src/lib/subs/mission.c @@ -507,34 +507,15 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, 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]; - if (gun < 1) - continue; - shell = sp->shp_item[I_SHELL]; - if (shell < SHP_TORP_SHELLS) - shell += supply_commod(sp->shp_own, - sp->shp_x, sp->shp_y, I_SHELL, - SHP_TORP_SHELLS - shell); - if (shell < SHP_TORP_SHELLS) - continue; - range = roundrange(torprange(sp)); if (md > range) continue; - if (!line_of_sight(NULL, x, y, gp->x, gp->y)) continue; - sp->shp_item[I_SHELL] = shell - SHP_TORP_SHELLS; - sp->shp_mobil -= shp_mobcost(sp) / 2.0; + dam2 = shp_torp(sp, 1); putship(sp->shp_uid, sp); + if (dam2 < 0) + continue; hitchance = DTORP_HITCHANCE(md, sp->shp_visib); wu(0, sp->shp_own, @@ -546,7 +527,7 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, "\tWhooosh... Hitchance = %d%%\n", (int)(hitchance * 100)); - if (hitchance < 1.0 && !chance(hitchance)) { + if (!chance(hitchance)) { wu(0, sp->shp_own, "\tMissed\n"); mpr(victim, "Incoming torpedo sighted @ %s missed (whew)!\n", @@ -554,8 +535,6 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, continue; } wu(0, sp->shp_own, "\tBOOM!...\n"); - dam2 = TORP_DAMAGE(); - dam += dam2; nreport(victim, N_TORP_SHIP, 0, 1); wu(0, sp->shp_own,