]> git.pond.sub.org Git - empserver/commitdiff
Fix and enable collateral damage for missing missiles
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 11 Oct 2009 16:04:16 +0000 (12:04 -0400)
committerMarkus Armbruster <armbru@pond.sub.org>
Sun, 13 Dec 2009 07:05:26 +0000 (08:05 +0100)
Collateral damage was disabled, because after msl_hit() reported a
miss, the missile may or may not have reached the target.

Fix by splitting msl_launch() off msl_hit().

Drop the disabled collateral damage code for sector targets, because
sectors can't be missed.  Enable it for ships and land units.

Since msl_launch() returns whether the missile is sub-launched, drop
launch_missile() parameter sublaunch, and simplify its caller.

include/prototypes.h
src/lib/commands/laun.c
src/lib/subs/lndsub.c
src/lib/subs/mission.c
src/lib/subs/mslsub.c
src/lib/subs/shpsub.c

index 326cf46c96995b22eb137b64444b0d3489d7563f..94b838333320ac5f65a2f17ff8f1f79077032c53 100644 (file)
@@ -492,8 +492,9 @@ extern int move_ground(struct sctstr *, struct sctstr *,
                       int, int *);
 extern int fly_map(coord, coord);
 /* mslsub.c */
-extern int msl_hit(struct plnstr *, int, int, int, int, char *,
-                  coord, coord, int);
+extern int msl_launch(struct plnstr *, int, char *, coord, coord, natid,
+                     int *);
+extern int msl_hit(struct plnstr *, int, int, int, int, int, natid);
 extern void msl_sel(struct emp_qelem *, coord, coord, natid, int,
                    int, int);
 extern int msl_abm_intercept(struct plnstr *, coord, coord, int);
index b339de8d6afc765f53e787e0a8a8b35719dfa233..1efe0e0e599dca55f0a441accff59d5856315430 100644 (file)
@@ -47,7 +47,7 @@
 #include "ship.h"
 
 static int launch_as(struct plnstr *pp);
-static int launch_missile(struct plnstr *pp, int sublaunch);
+static int launch_missile(struct plnstr *pp);
 static int launch_sat(struct plnstr *pp);
 static int msl_equip(struct plnstr *, char);
 
@@ -59,8 +59,6 @@ laun(void)
 {
     struct nstr_item nstr;
     struct plnstr plane;
-    struct shpstr ship;
-    int sublaunch;
     struct plchrstr *pcp;
     int retval, gone;
 
@@ -101,17 +99,11 @@ laun(void)
        }
        if (!pln_airbase_ok(&plane, 1, 1))
            continue;
-       sublaunch = 0;
-       if (plane.pln_ship >= 0) {
-           getship(plane.pln_ship, &ship);
-           if (mchr[(int)ship.shp_type].m_flags & M_SUB)
-               sublaunch = 1;
-       }
        pr("%s at %s; range %d, eff %d%%\n", prplane(&plane),
           xyas(plane.pln_x, plane.pln_y, player->cnum),
           plane.pln_range, plane.pln_effic);
        if (!(pcp->pl_flags & P_O)) {
-           retval = launch_missile(&plane, sublaunch);
+           retval = launch_missile(&plane);
            gone = 1;
        } else if ((pcp->pl_flags & (P_M | P_O)) == (P_M | P_O)) {
            retval = launch_as(&plane);
@@ -160,8 +152,10 @@ launch_as(struct plnstr *pp)
     }
     if (msl_equip(pp, 'i') < 0)
        return RET_FAIL;
-    if (msl_hit(pp, pln_def(&plane), EF_PLANE, 0, 0,
-               prplane(&plane), plane.pln_x, plane.pln_y, plane.pln_own)) {
+    if (msl_launch(pp, EF_PLANE, prplane(&plane),
+                  plane.pln_x, plane.pln_y, plane.pln_own, NULL) < 0)
+       return RET_OK;
+    if (msl_hit(pp, pln_def(&plane), EF_PLANE, 0, 0, 0, plane.pln_own)) {
        pr("Satellite shot down\n");
        mpr(plane.pln_own, "%s anti-sat destroyed %s over %s\n",
            cname(player->cnum), prplane(&plane),
@@ -175,16 +169,15 @@ launch_as(struct plnstr *pp)
 
 /*
  * Launch missile PP.
- * If SUBLAUNCH, it's sub-launched.
  * Return RET_OK if launched (even when missile explodes),
  * else RET_SYN or RET_FAIL.
  */
 static int
-launch_missile(struct plnstr *pp, int sublaunch)
+launch_missile(struct plnstr *pp)
 {
     struct plchrstr *pcp = plchr + pp->pln_type;
     coord sx, sy;
-    int n, dam;
+    int n, dam, sublaunch;
     char *cp;
     struct mchrstr *mcp;
     struct shpstr target_ship;
@@ -250,18 +243,12 @@ launch_missile(struct plnstr *pp, int sublaunch)
                return RET_OK;
            }
        }
-       if (!msl_hit(pp, SECT_HARDTARGET, EF_SECTOR, N_SCT_MISS,
-                    N_SCT_SMISS, "sector", sx, sy, sect.sct_own)) {
-#if 0
-           /*
-            * FIXME want collateral damage on miss, but we get here
-            * too when launch fails or missile is intercepted
-            */
-           dam = pln_damage(pp, 's', 0);
-           collateral_damage(sect.sct_x, sect.sct_y, dam, 0);
-#endif
+       if (msl_launch(pp, EF_SECTOR, "sector", sx, sy, sect.sct_own,
+                      &sublaunch) < 0)
            return RET_OK;
-       }
+       if (!msl_hit(pp, SECT_HARDTARGET, EF_SECTOR,
+                    N_SCT_MISS, N_SCT_SMISS, sublaunch, sect.sct_own))
+           CANT_REACH();
        if (getnuke(nuk_on_plane(pp), &nuke))
            detonate(&nuke, sx, sy, pp->pln_flags & PLN_AIRBURST);
        else {
@@ -285,15 +272,16 @@ launch_missile(struct plnstr *pp, int sublaunch)
     } else {
        if (msl_equip(pp, 'p') < 0)
            return RET_FAIL;
+       if (msl_launch(pp, EF_SHIP, prship(&target_ship),
+                      target_ship.shp_x, target_ship.shp_y,
+                      target_ship.shp_own, &sublaunch) < 0)
+           return RET_OK;
        if (!msl_hit(pp, shp_hardtarget(&target_ship), EF_SHIP,
-                    N_SHP_MISS, N_SHP_SMISS, prship(&target_ship),
-                    target_ship.shp_x, target_ship.shp_y,
+                    N_SHP_MISS, N_SHP_SMISS, sublaunch,
                     target_ship.shp_own)) {
            pr("splash\n");
-#if 0 /* FIXME see above */
            dam = pln_damage(pp, 'p', 0);
-           collateral_damage(target_ship.shp_x, target_ship.shp_y, dam, 0);
-#endif
+           collateral_damage(target_ship.shp_x, target_ship.shp_y, dam);
            return RET_OK;
        }
        dam = pln_damage(pp, 'p', 1);
index 98fb636cdcf9d8b8a842ecc6898f39dd41e4ccfd..884d5b14d18ba4e0ba3d38a677ac5a6c4f171466 100644 (file)
@@ -720,7 +720,7 @@ lnd_missile_interdiction(struct emp_qelem *list, coord newx, coord newy,
 {
     int mindam = lnd_count(list) * 20;
     int hardtarget = lnd_easiest_target(list);
-    int dam, newdam;
+    int dam, newdam, sublaunch;
     struct plist *plp;
     struct emp_qelem msl_list, *qp, *newqp;
 
@@ -732,22 +732,18 @@ lnd_missile_interdiction(struct emp_qelem *list, coord newx, coord newy,
        plp = (struct plist *)qp;
 
        if (dam < mindam && mission_pln_equip(plp, NULL, 'p') >= 0) {
+           if (msl_launch(&plp->plane, EF_LAND, "troops",
+                          newx, newy, victim, &sublaunch) < 0)
+               goto use_up_msl;
            if (msl_hit(&plp->plane, hardtarget, EF_LAND,
-                       N_LND_MISS, N_LND_SMISS,
-                       "troops", newx, newy, victim)) {
+                       N_LND_MISS, N_LND_SMISS, sublaunch, victim)) {
                newdam = pln_damage(&plp->plane, 'p', 1);
                dam += newdam;
-#if 0
-           /*
-            * FIXME want collateral damage on miss, but we get here
-            * too when launch fails or missile is intercepted
-            */
            } else {
-               /* Missiles that miss have to hit somewhere! */
                newdam = pln_damage(&plp->plane, 'p', 0);
                collateral_damage(newx, newy, newdam);
-#endif
            }
+       use_up_msl:
            plp->plane.pln_effic = 0;
            putplane(plp->plane.pln_uid, &plp->plane);
        }
index 8012db2c00ecd97e18326ad1176678356853639e..d37135f62b6d06193517a5500578a32ce8fb0d03 100644 (file)
@@ -389,7 +389,7 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list,
     struct plchrstr *pcp;
     int dam = 0, dam2;
     natid plane_owner = 0;
-    int md, range, air_dam;
+    int md, range, air_dam, sublaunch;
     double hitchance, vrange;
     int targeting_ships = *s == 's'; /* "subs" or "ships" FIXME gross! */
 
@@ -562,22 +562,15 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list,
            && !CANT_HAPPEN(hardtarget != SECT_HARDTARGET
                            || (plp->pcp->pl_flags & P_MAR))
            && mission_pln_equip(plp, NULL, 'p') >= 0) {
-           if (msl_hit(&plp->plane, SECT_HARDTARGET, EF_SECTOR,
-                       N_SCT_MISS, N_SCT_SMISS,
-                       "sector", x, y, victim)) {
-               dam2 = pln_damage(&plp->plane, 'p', 1);
-               air_dam += dam2;
-#if 0
-           /*
-            * FIXME want collateral damage on miss, but we get here
-            * too when launch fails or missile is intercepted
-            */
-           } else {
-               /* Missiles that miss have to hit somewhere! */
-               dam2 = pln_damage(&plp->plane, 'p', 0);
-               collateral_damage(x, y, dam2);
-#endif
-           }
+           if (msl_launch(&plp->plane, EF_SECTOR, "sector", x, y, victim,
+                          &sublaunch) < 0)
+               goto use_up_msl;
+           if (!msl_hit(&plp->plane, SECT_HARDTARGET, EF_SECTOR,
+                       N_SCT_MISS, N_SCT_SMISS, sublaunch, victim))
+               CANT_REACH();
+           dam2 = pln_damage(&plp->plane, 'p', 1);
+           air_dam += dam2;
+       use_up_msl:
            plp->plane.pln_effic = 0;
            putplane(plp->plane.pln_uid, &plp->plane);
        }
index c2b2d728a07e5e3eac63bf70e8bf5bc06f567cca..30ed82cb206bd4e64bb9bd10a291ae0f45c931ea 100644 (file)
@@ -30,6 +30,7 @@
  *  Known contributors to this file:
  *     Ken Stevens, 1995
  *     Steve McClure, 1996-2000
+ *     Markus Armbruster, 2004-2009
  */
 
 #include <config.h>
 #include "xy.h"
 
 int
-msl_hit(struct plnstr *pp, int hardtarget, int type, int news_item,
-       int snews_item, char *what, coord x, coord y, int victim)
+msl_launch(struct plnstr *pp, int type, char *what, coord x, coord y,
+          natid victim, int *sublaunchp)
 {
-    int hit;
     struct shpstr ship;
     struct sctstr sect;
     int sublaunch = 0;
     struct plchrstr *pcp = plchr + pp->pln_type;
-    int hitchance;
     char *from;
     int dam;
 
@@ -108,7 +107,7 @@ msl_hit(struct plnstr *pp, int hardtarget, int type, int news_item,
                putsect(&sect);
            }
        }
-       return 0;
+       return -1;
     }
 
     CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED);
@@ -123,14 +122,26 @@ msl_hit(struct plnstr *pp, int hardtarget, int type, int news_item,
 
     if ((pcp->pl_flags & P_T && !(pcp->pl_flags & P_MAR))) {
        if (msl_abm_intercept(pp, x, y, sublaunch))
-           return 0;
+           return -1;
     }
     if (pcp->pl_flags & P_MAR) {
        if (shp_missile_defense(x, y, pp->pln_own, pln_def(pp))) {
-           return 0;
+           return -1;
        }
     }
 
+    if (sublaunchp)
+       *sublaunchp = sublaunch;
+    return 0;
+}
+
+int
+msl_hit(struct plnstr *pp, int hardtarget, int type,
+       int news_item, int snews_item, int sublaunch, natid victim)
+{
+    struct plchrstr *pcp = plchr + pp->pln_type;
+    int hitchance, hit;
+
     if (nuk_on_plane(pp) >= 0) {
        mpr(pp->pln_own, "\tArming nuclear warheads...\n");
        hit = 1;
@@ -294,8 +305,9 @@ msl_intercept(struct plnstr *msl, struct sctstr *sp, int sublaunch,
                def_name, who, att_name, cname(sp->sct_own));
        }
 
-       if (msl_hit(pp, pln_def(msl), EF_PLANE, 0, 0,
-                   att_name, sp->sct_x, sp->sct_y, msl->pln_own)) {
+       if (msl_launch(pp, EF_PLANE, att_name, sp->sct_x, sp->sct_y,
+                      msl->pln_own, NULL) >= 0
+           && msl_hit(pp, pln_def(msl), EF_PLANE, 0, 0, 0, msl->pln_own)) {
            mpr(msl->pln_own, "%s destroyed by %s %s!\n",
                att_name, cname(pp->pln_own), def_name);
            mpr(sp->sct_own, "%s %s intercepted!\n", who, att_name);
index c46ea7e794434ea497a0b99e7857836361eeac80..50e942f78f95a32f765dac9348446412a49334d4 100644 (file)
@@ -480,7 +480,7 @@ static int
 shp_missile_interdiction(struct emp_qelem *list, coord newx, coord newy,
                         natid victim)
 {
-    int dam;
+    int dam, sublaunch;
     int stopping = 0;
     struct emp_qelem msl_list, *qp, *newqp;
     struct plist *plp;
@@ -494,11 +494,12 @@ shp_missile_interdiction(struct emp_qelem *list, coord newx, coord newy,
 
        mvs = most_valuable_ship(list, newx, newy);
        if (mvs && mission_pln_equip(plp, NULL, 'p') >= 0) {
+           if (msl_launch(&plp->plane, EF_SHIP, prship(&mvs->unit.ship),
+                          newx, newy, victim, &sublaunch) < 0)
+               goto use_up_msl;
            if (msl_hit(&plp->plane,
-                       shp_hardtarget(&mvs->unit.ship),
-                       EF_SHIP, N_SHP_MISS, N_SHP_SMISS,
-                       prship(&mvs->unit.ship),
-                       newx, newy, victim)) {
+                       shp_hardtarget(&mvs->unit.ship), EF_SHIP,
+                       N_SHP_MISS, N_SHP_SMISS, sublaunch, victim)) {
                dam = pln_damage(&plp->plane, 'p', 1);
                if (dam) {
                    mpr(victim,
@@ -507,17 +508,11 @@ shp_missile_interdiction(struct emp_qelem *list, coord newx, coord newy,
                    shp_damage_one(mvs, dam);
                    stopping = 1;
                }
-#if 0
-           /*
-            * FIXME want collateral damage on miss, but we get here
-            * too when launch fails or missile is intercepted
-            */
            } else {
-               /* Missiles that miss have to hit somewhere! */
                dam = pln_damage(&plp->plane, 'p', 0);
                collateral_damage(newx, newy, dam);
-#endif
            }
+       use_up_msl:
            plp->plane.pln_effic = 0;
            putplane(plp->plane.pln_uid, &plp->plane);
        }