]> git.pond.sub.org Git - empserver/commitdiff
Factor out common torpedo fire code into shp_torp()
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 2 Mar 2008 14:45:41 +0000 (15:45 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Fri, 14 Mar 2008 19:25:38 +0000 (20:25 +0100)
This takes care of a number of bugs / inconsistencies:

* Submarines with zero mobility could interdict.  Change to require
  positive mobility.

* Submarines with zero firing range could not interdict.  Fix by
  dropping the test from perform_mission().  No ships in the stock
  game are affected.

* Submarines without capability torp could fire return torpedoes and
  interdict.  Stock sbc, nm and msb were affected by the return fire
  bug.  Closes bug#950936.

* Shell resupply bugs: quiet_bigdef(), fire_torp() and
  perform_mission() resupplied before checking all other requirements
  and could thus get more shells than actually needed.

torp() no longer resupplies shells.  It's hardly worth the bother, and
fire doesn't do it either.

include/ship.h
src/lib/commands/mfir.c
src/lib/commands/torp.c
src/lib/subs/landgun.c
src/lib/subs/mission.c

index c3e24a44ecfc9af059711e85d30141a7b61e3fd9..ea323c1f742535de35276aea04f660c99af0518b 100644 (file)
@@ -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
index be1ee2dc6ae3186f05d4ff761573882f5eec2e79..19f1885c5bd9997cfeaef1b8258be2da84244713 100644 (file)
@@ -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)
index 207528ec89e8e325f7f3e22d433d714cb502043b..41490979135a092975508a703d60d40f283e19d6 100644 (file)
@@ -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;
 
index 7d463fd450d40ca79e7962237f231951afd81fc0..1cca07cd5a1692da7839d5479e5fc6fb86694382 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <config.h>
 
+#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.
  */
index e45e1e2a545401e6e974d261ef6082fbce4c6636..1f8e9d7366acbc6654f50a248a244c4dd13fe460 100644 (file)
@@ -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,