]> git.pond.sub.org Git - empserver/commitdiff
Fix tracking of planes flying a sortie
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 23 Mar 2008 18:21:19 +0000 (19:21 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Wed, 26 Mar 2008 21:10:13 +0000 (22:10 +0100)
Planes normally sit in their base (sector or carrier), where they can
be spied, damaged, captured, loaded, unloaded, upgraded and so forth.
All this must not be possible while they fly.  There are two kinds of
flying planes: satellites in orbit, and planes flying a sortie.

Satellites in orbit have always been marked with flag PLN_LAUNCHED.
Works.  What didn't work was tracking planes flying a sortie.

If you look at one sortie in isolation, up to three groups of planes
can be flying at any point of time: the primary group, which carries
out the sortie's mission (bomb, transport, ...), their escorts, and a
group of hostile planes flying interception or air defense.

The old code attempted to track these planes by passing those groups
to the places that need to know whether a plane is flying.  This was
complex and incomplete, and broke down completely for the pin-bombing
command.

It was complex, because the plane code needs to keep track of all the
call chains that can lead to a place that needs to know whether a
plane flies, and pass the groups down the call chains.  This leads to
a rather ugly passing of plane groups all over the place.

It was incomplete, because it generally failed to pass the escorts.

And the whole scheme broke down for the pin-bombing command.  That's
because pin-bombing asks the player for targets while his planes are
loitering above the target sector.  This yields the processor and lets
other code run.  Which does not get the flying planes passed.

The new code marks planes and SAMs (but not other missiles) flying a
sortie with flag PLN_LAUNCHED (the previous commit laid the groundwork
for that), and does away with passing around groups of flying planes.

This fixes the following bugs:

* Many commands could interact with foreign planes flying for a
  pin-bombing command as if they were sitting in their base.  This
  includes spying, damaging, capturing, loading, or upgrading them,
  and even getting intercepted by them.  Any changes to those planes
  were wiped out when they landed.  Abusable.

* The bomb command could bomb its own escorts, directly (pin-bomb
  planes) or through collateral damage, strategic sector damage,
  collapsing bridges or nuke damage.  The damage to the escorts was
  wiped out when they landed.

* If you asked for a plane to fly both in the primary group and the
  escort group, you got charged fuel for two sorties instead of one.

* pln_put1() and pln_put() now recognize planes that didn't take off,
  and refrain from making them land.  Intercept (since commit
  c64e2149) and air defense can do that.  Making them land had no
  ill-effects, but it was still wrong.

There's one new problem: if PLN_LAUNCHED doesn't get reset properly,
due to game crash during flight or some other bug, the plane gets
stuck in the air.  Catch and fix that on game start in ef_verify().

24 files changed:
include/plane.h
include/prototypes.h
src/lib/commands/bomb.c
src/lib/commands/desi.c
src/lib/commands/drop.c
src/lib/commands/fly.c
src/lib/commands/laun.c
src/lib/commands/mfir.c
src/lib/commands/para.c
src/lib/commands/reco.c
src/lib/commands/sabo.c
src/lib/common/ef_verify.c
src/lib/subs/aircombat.c
src/lib/subs/attsub.c
src/lib/subs/bridgefall.c
src/lib/subs/detonate.c
src/lib/subs/list.c
src/lib/subs/lndsub.c
src/lib/subs/mission.c
src/lib/subs/mslsub.c
src/lib/subs/plnsub.c
src/lib/subs/sect.c
src/lib/subs/sectdamage.c
src/lib/update/revolt.c

index 7b1936a639d4c8a26b1695c6157dc334f5dc528d..2133f3628097b3d099240a46d634a46af350d7d8 100644 (file)
@@ -73,7 +73,7 @@ struct plnstr {
     float pln_theta;           /* position in orbital sine wave */
 };
 
-#define        PLN_LAUNCHED    bit(0)  /* A satellite that's in orbit */
+#define        PLN_LAUNCHED    bit(0)  /* Flying (satellite: in orbit) */
 #define        PLN_SYNCHRONOUS bit(1)  /* A satellite in geo-synchronous orbit */
 #define        PLN_AIRBURST    bit(2)  /* Airburst the nuke we're armed with */
 
@@ -160,9 +160,7 @@ extern void ac_combat_headers(natid, natid);
 extern void ac_airtoair(struct emp_qelem *, struct emp_qelem *);
 extern int ac_flak_dam(int, int, int);
 extern void ac_encounter(struct emp_qelem *, struct emp_qelem *, coord,
-                        coord, char *, int, int,
-                        struct emp_qelem *, struct emp_qelem *);
-extern int ac_isflying(struct plnstr *, struct emp_qelem *);
+                        coord, char *, int, int);
 extern void sam_intercept(struct emp_qelem *, struct emp_qelem *,
                          natid, natid, coord, coord, int);
 
index 5fa5cb37a6ad1637529b7b05bfa7101b514d3676..1a127da7ead3fb3242c3cb701b9492ce6af5b5ad 100644 (file)
@@ -402,8 +402,8 @@ extern void stop_service(void);
 extern int confirm(char *);
 extern int askyn(char *);
 /* bridgefall.c */
-extern void bridge_damaged(struct sctstr *, struct emp_qelem *);
-extern void bridgefall(struct sctstr *, struct emp_qelem *);
+extern void bridge_damaged(struct sctstr *);
+extern void bridgefall(struct sctstr *);
 /* bsanct.c */
 extern void bsanct(void);
 /* caploss.c */
@@ -468,7 +468,7 @@ extern int roundrange(double);
 extern int shipsatxy(coord, coord, int, int);
 extern int carriersatxy(coord, coord, natid);
 extern int unitsatxy(coord, coord, int, int);
-extern int planesatxy(coord, coord, int, int, struct emp_qelem *);
+extern int planesatxy(coord, coord, int, int);
 extern int asw_shipsatxy(coord, coord, int, int, struct plnstr *,
                         struct shiplist **);
 extern int num_shipsatxy(coord, coord, int, int);
@@ -484,7 +484,7 @@ extern int bmaps_intersect(natid, natid);
 extern int share_bmap(natid, natid, struct nstr_sect *, char, char *);
 /* mission.c */
 extern char *mission_name(short);
-extern int collateral_damage(coord, coord, int, struct emp_qelem *);
+extern int collateral_damage(coord, coord, int);
 extern int mission_pln_equip(struct plist *, struct ichrstr *, int, char);
 extern int ground_interdict(coord, coord, natid, char *);
 extern int unit_interdict(coord, coord, natid, char *, int, int);
@@ -559,7 +559,6 @@ extern int pln_arm(struct emp_qelem *, int, char, struct ichrstr *,
 extern int pln_mobcost(int, struct plnstr *, int);
 extern void pln_put(struct emp_qelem *);
 extern void pln_put1(struct plist *);
-extern void pln_removedupes(struct emp_qelem *, struct emp_qelem *);
 extern void take_plane_off_ship(struct plnstr *, struct shpstr *);
 extern void take_plane_off_land(struct plnstr *, struct lndstr *);
 extern void plane_sweep(struct emp_qelem *, coord, coord);
@@ -630,8 +629,8 @@ extern int sct_prewrite(int, void *);
 extern void item_prewrite(short *);
 extern int issector(char *);
 /* sectdamage.c */
-extern int sect_damage(struct sctstr *, int, struct emp_qelem *);
-extern int sectdamage(struct sctstr *, int, struct emp_qelem *);
+extern int sect_damage(struct sctstr *, int);
+extern int sectdamage(struct sctstr *, int);
 /* ship.c */
 extern char *prship(struct shpstr *);
 extern int shp_postread(int, void *);
index f475d47df4b9eb9cb43abfa3fa4b3d6abb251768..b645a1388ab19560b9cc1000797d742c5c0dbd98 100644 (file)
@@ -147,8 +147,8 @@ bomb(void)
     }
     mission_flags = pln_arm(&esc_list, 2 * ap_to_target, mission,
                            ip, P_F | P_ESC, mission_flags);
-    ac_encounter(&bomb_list, &esc_list, ax, ay, flightpath, mission_flags,
-                0, 0, 0);
+    ac_encounter(&bomb_list, &esc_list, ax, ay,
+                flightpath, mission_flags, 0);
     if (QEMPTY(&bomb_list)) {
        pr("No planes got through fighter defenses\n");
     } else if (target.sct_type == SCT_SANCT) {
@@ -218,7 +218,7 @@ pin_bomb(struct emp_qelem *list, struct sctstr *target)
     } else {
        nships = shipsatxy(target->sct_x, target->sct_y, 0, M_SUB);
     }
-    nplanes = planesatxy(target->sct_x, target->sct_y, 0, 0, list);
+    nplanes = planesatxy(target->sct_x, target->sct_y, 0, 0);
     nunits = unitsatxy(target->sct_x, target->sct_y, 0, 0);
   retry:
     p = getstring("Bomb what? (ship, plane, land unit, efficiency, commodities) ",
@@ -369,9 +369,9 @@ eff_bomb(struct emp_qelem *list, struct sctstr *target)
           "%s bombing raid did %d%% damage in %s\n",
           cname(player->cnum), oldeff - target->sct_effic,
           xyas(target->sct_x, target->sct_y, target->sct_own));
-    bridge_damaged(target, list);
+    bridge_damaged(target);
     putsect(&sect);
-    collateral_damage(target->sct_x, target->sct_y, dam, list);
+    collateral_damage(target->sct_x, target->sct_y, dam);
 }
 
 static void
@@ -447,7 +447,7 @@ comm_bomb(struct emp_qelem *list, struct sctstr *target)
           cname(player->cnum), b, ip->i_name,
           xyas(target->sct_x, target->sct_y, target->sct_own));
     putsect(&sect);
-    collateral_damage(target->sct_x, target->sct_y, dam, list);
+    collateral_damage(target->sct_x, target->sct_y, dam);
 }
 
 static void
@@ -559,7 +559,7 @@ ship_bomb(struct emp_qelem *list, struct sctstr *target)
            /* Bombs that miss have to land somewhere! */
            dam = pln_damage(&plp->plane, target->sct_x, target->sct_y,
                             'p', &nukedam, 0);
-           collateral_damage(target->sct_x, target->sct_y, dam, list);
+           collateral_damage(target->sct_x, target->sct_y, dam);
            dam = 0;
        }
        if (dam <= 0)           /* dam == 0 if only nukes were delivered */
@@ -586,7 +586,7 @@ ship_bomb(struct emp_qelem *list, struct sctstr *target)
               prship(&ship),
               xyas(target->sct_x, target->sct_y, player->cnum));
        }
-       collateral_damage(target->sct_x, target->sct_y, dam / 2, list);
+       collateral_damage(target->sct_x, target->sct_y, dam / 2);
       next:
        ;
     }
@@ -615,7 +615,7 @@ plane_bomb(struct emp_qelem *list, struct sctstr *target)
        plp = (struct plist *)qp;
        if ((plp->pcp->pl_flags & P_C) && (!(plp->pcp->pl_flags & P_T)))
            continue;
-       nplanes = planesatxy(target->sct_x, target->sct_y, 0, 0, list);
+       nplanes = planesatxy(target->sct_x, target->sct_y, 0, 0);
        if (nplanes == 0) {
            pr("%s could not find any planes!\n", prplane(&plp->plane));
            continue;
@@ -632,7 +632,7 @@ plane_bomb(struct emp_qelem *list, struct sctstr *target)
                continue;
            }
            if (*q == '?') {
-               planesatxy(target->sct_x, target->sct_y, 0, 0, list);
+               planesatxy(target->sct_x, target->sct_y, 0, 0);
                continue;
            }
            if (*q == 'd')
@@ -643,8 +643,7 @@ plane_bomb(struct emp_qelem *list, struct sctstr *target)
            if (getplane(n, &plane) &&
                plane.pln_x == target->sct_x &&
                plane.pln_y == target->sct_y &&
-               ((plane.pln_flags & PLN_LAUNCHED) == 0) &&
-               (!ac_isflying(&plane, list)))
+               !(plane.pln_flags & PLN_LAUNCHED))
                planeno = n;
            else
                pr("Plane #%d not spotted\n", n);
@@ -667,7 +666,7 @@ plane_bomb(struct emp_qelem *list, struct sctstr *target)
            /* Bombs that miss have to land somewhere! */
            dam = pln_damage(&plp->plane, target->sct_x, target->sct_y,
                             'p', &nukedam, 0);
-           collateral_damage(target->sct_x, target->sct_y, dam, list);
+           collateral_damage(target->sct_x, target->sct_y, dam);
            dam = 0;
        }
        if (dam <= 0)           /* dam == 0 if only nukes were delivered */
@@ -694,7 +693,7 @@ plane_bomb(struct emp_qelem *list, struct sctstr *target)
               cname(player->cnum), dam, prplane(&plane),
               xyas(target->sct_x, target->sct_y, own));
        putplane(plane.pln_uid, &plane);
-       collateral_damage(target->sct_x, target->sct_y, dam, list);
+       collateral_damage(target->sct_x, target->sct_y, dam);
       next:
        ;
     }
@@ -781,7 +780,7 @@ land_bomb(struct emp_qelem *list, struct sctstr *target)
            /* Bombs that miss have to land somewhere! */
            dam = pln_damage(&plp->plane, target->sct_x, target->sct_y,
                             'p', &nukedam, 0);
-           collateral_damage(target->sct_x, target->sct_y, dam, list);
+           collateral_damage(target->sct_x, target->sct_y, dam);
            dam = 0;
        }
        if (dam <= 0)           /* dam == 0 if only nukes were delivered */
@@ -798,7 +797,7 @@ land_bomb(struct emp_qelem *list, struct sctstr *target)
                retreat_land(&land, 'b');
        nreport(player->cnum, N_UNIT_BOMB, own, 1);
        putland(land.lnd_uid, &land);
-       collateral_damage(target->sct_x, target->sct_y, dam, list);
+       collateral_damage(target->sct_x, target->sct_y, dam);
       next:
        ;
     }
@@ -830,7 +829,7 @@ strat_bomb(struct emp_qelem *list, struct sctstr *target)
           cname(player->cnum), PERCENT_DAMAGE(dam),
           xyas(target->sct_x, target->sct_y, target->sct_own));
 
-    sectdamage(target, dam, list);
+    sectdamage(target, dam);
 
     pr("did %d damage in %s\n", PERCENT_DAMAGE(dam),
        xyas(target->sct_x, target->sct_y, player->cnum));
index 54be06886c51f07967c384b64bf9367b3e6bf2b2..07f33ae0a6ad4be17f07727ba475037e0625f8fa 100644 (file)
@@ -132,7 +132,7 @@ desi(void)
        if (opt_EASY_BRIDGES == 0) {    /* may cause a bridge fall */
            if (n != SCT_BHEAD)
                continue;
-           bridgefall(&sect, 0);
+           bridgefall(&sect);
        }
     }
     if (changed)
index 4b32a14e2fbe4d0fe42d9d654863c640dec00926..fbfffcfebe7336323fbd237abbf49f6dc9a11fbf 100644 (file)
@@ -124,8 +124,8 @@ drop(void)
     }
     mission_flags = pln_arm(&esc_list, 2 * ap_to_target, 'd',
                            ip, P_ESC | P_F, mission_flags);
-    ac_encounter(&bomb_list, &esc_list, ax, ay, flightpath, mission_flags,
-                0, 0, 0);
+    ac_encounter(&bomb_list, &esc_list, ax, ay,
+                flightpath, mission_flags, 0);
     if (QEMPTY(&bomb_list)) {
        pr("No planes got through fighter defenses\n");
     } else {
index 598fef08304270774d3c3bdedf718455db063f1a..ed55fbca0d53851b79c673deba41c796df3f330d 100644 (file)
@@ -136,8 +136,8 @@ fly(void)
     }
     mission_flags = pln_arm(&esc_list, ap_to_target, 't',
                            ip, P_ESC | P_F, mission_flags);
-    ac_encounter(&bomb_list, &esc_list, ax, ay, flightpath, mission_flags,
-                0, 0, 0);
+    ac_encounter(&bomb_list, &esc_list, ax, ay,
+                flightpath, mission_flags, 0);
     if (QEMPTY(&bomb_list)) {
        pr("No planes got through fighter defenses\n");
     } else {
index 3913196863ab619608c4676d846e1388f4d615f6..996188b88792587f27f9110ea75d0ae041b65cef 100644 (file)
@@ -321,7 +321,7 @@ launch_missile(struct plnstr *pp, int sublaunch)
                       cname(player->cnum), dam,
                       xyas(sx, sy, sect.sct_own));
            }
-           sectdamage(&sect, dam, 0);
+           sectdamage(&sect, dam);
            putsect(&sect);
        }
     } /* end PINPOINTMISSILE conditional */
@@ -414,6 +414,7 @@ launch_sat(struct plnstr *pp, int sublaunch)
     }
     pp->pln_x = sx;
     pp->pln_y = sy;
+    CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED);
     pp->pln_flags |= PLN_LAUNCHED;
     pp->pln_mobil = pp->pln_mobil > dist ? pp->pln_mobil - dist : 0;
     putplane(pp->pln_uid, pp);
index 58e2cb41b414cb080429ebfe3a8e175c994bbece..4d3fd893bf2efd9145b0aa88c9bfb8e7572fb537 100644 (file)
@@ -467,7 +467,7 @@ multifire(void)
            pr("Shells hit sector %s for %d damage.\n",
               xyas(x, y, player->cnum), dam);
            if (target != targ_bogus)
-               sectdamage(&vsect, dam, 0);
+               sectdamage(&vsect, dam);
            break;
        case targ_ship:
            nreport(player->cnum, N_SHP_SHELL, vict, 1);
@@ -600,7 +600,7 @@ do_defdam(struct emp_qelem *list, double odds)
            vict = fp->victim;
            pr("Return fire hit sector %s for %d damage.\n",
               xyas(fp->x, fp->y, player->cnum), dam);
-           sectdamage(&sect, dam, 0);
+           sectdamage(&sect, dam);
            putsect(&sect);
            if (vict)
                wu(0, vict, "Return fire hit sector %s for %d damage.\n",
index e11c20e0c4c96d3c775df5ba00a84a66fe23b634..9c976b2b2459c568d4097ce1178b4708c90e3b62 100644 (file)
@@ -105,8 +105,8 @@ para(void)
     }
     mission_flags = pln_arm(&esc_list, 2 * ap_to_target, 'a',
                            &ichr[I_MILIT], P_ESC | P_F, mission_flags);
-    ac_encounter(&bomb_list, &esc_list, ax, ay, flightpath, mission_flags,
-                0, 0, 0);
+    ac_encounter(&bomb_list, &esc_list, ax, ay,
+                flightpath, mission_flags, 0);
     if (QEMPTY(&bomb_list)) {
        pr("No planes got through fighter defenses\n");
     } else {
index ebcf597f96ab5f4c052cf44f83a7e204a1795f64..fcd4d1359e0768aacd41a68131455c711d5c4868 100644 (file)
@@ -118,8 +118,8 @@ reco(void)
     if (*player->argp[0] == 's')
        mission_flags |= PM_S;
 
-    ac_encounter(&bomb_list, &esc_list, ax, ay, flightpath, mission_flags,
-                0, 0, 0);
+    ac_encounter(&bomb_list, &esc_list, ax, ay,
+                flightpath, mission_flags, 0);
     if (QEMPTY(&bomb_list)) {
        pr("No planes got through fighter defenses\n");
     } else {
index c12c6ad90a221889477b9660d52e6b76e1a63dbf..7911dfc8ea1d9178912fdc3f4fc63138f073a792 100644 (file)
@@ -103,7 +103,7 @@ sabo(void)
        land.lnd_own = 0;
        putland(land.lnd_uid, &land);
 
-       sectdamage(&sect, dam, 0);
+       sectdamage(&sect, dam);
        putsect(&sect);
 
        land.lnd_own = player->cnum;
index fac431035f098ae31d1112ab743aed601c40d0da..fb677145fb54d9d98009695612a23d5b90b01124 100644 (file)
@@ -40,6 +40,7 @@
 #include "file.h"
 #include "misc.h"
 #include "nsc.h"
+#include "plane.h"
 #include "product.h"
 
 static void verify_fail(int, int, struct castr *, int, char *, ...)
@@ -163,6 +164,26 @@ verify_row(int type, int row)
     return ret_val;
 }
 
+static void
+pln_zap_transient_flags(void)
+{
+    int i;
+    struct plnstr *pp;
+
+    /* laziness: assumes plane file is EFF_MEM */
+    for (i = 0; (pp = getplanep(i)) != NULL; i++) {
+       if (pp->pln_flags & PLN_LAUNCHED
+           && (plchr[pp->pln_type].pl_flags & (P_M | P_O)) != P_O) {
+           pp->pln_flags &= ~PLN_LAUNCHED;
+           verify_fail(EF_PLANE, i, NULL, 0, "stuck in the air (patched)");
+           /*
+            * Can't putplane() here, because pln_prewrite() crashes
+            * without a valid player.
+            */
+       }
+    }
+}
+
 int
 ef_verify()
 {
@@ -188,5 +209,6 @@ ef_verify()
        }
     }
 
+    pln_zap_transient_flags();
     return retval;
 }
index 9c833d9b71182553a7049ec49c2802ca503ab0b9..3b87878fa77ba4836f3d82fc63a97321d3c0742d 100644 (file)
@@ -64,16 +64,13 @@ static void ac_doflak(struct emp_qelem *, struct sctstr *);
 static void ac_landflak(struct emp_qelem *, coord, coord);
 static void ac_shipflak(struct emp_qelem *, coord, coord);
 static void ac_fireflak(struct emp_qelem *, natid, int);
-static void getilist(struct emp_qelem *, natid,
-                    struct emp_qelem *, struct emp_qelem *,
-                    struct emp_qelem *, struct emp_qelem *);
+static void getilist(struct emp_qelem *, natid);
 static int do_evade(struct emp_qelem *, struct emp_qelem *);
 
 void
 ac_encounter(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
             coord x, coord y, char *path, int mission_flags,
-            int no_air_defense, struct emp_qelem *obomb,
-            struct emp_qelem *oesc)
+            int no_air_defense)
 {
     int val, non_missiles;
     int rel;
@@ -135,7 +132,6 @@ ac_encounter(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
        }
     }
 
-    pln_removedupes(bomb_list, esc_list);
     while ((dir = mypath[myp++]) && !QEMPTY(bomb_list)) {
        if ((val = diridx(dir)) == DIR_STOP)
            break;
@@ -247,8 +243,7 @@ ac_encounter(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
            continue;
 
        if (unfriendly[sect.sct_own] && !gotilist[sect.sct_own]) {
-           getilist(&ilist[sect.sct_own], sect.sct_own,
-                    bomb_list, esc_list, obomb, oesc);
+           getilist(&ilist[sect.sct_own], sect.sct_own);
            gotilist[sect.sct_own]++;
        }
        if (rel > HOSTILE)
@@ -307,8 +302,7 @@ ac_encounter(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
            if (unfriendly[cn]) {
                /* They are unfriendly too */
                if (!gotilist[cn]) {
-                   getilist(&ilist[cn], cn, bomb_list, esc_list, obomb,
-                            oesc);
+                   getilist(&ilist[cn], cn);
                    gotilist[cn]++;
                }
                PR(plane_owner, "Flying over %s ships in %s\n",
@@ -336,8 +330,7 @@ ac_encounter(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
            if (unfriendly[cn]) {
                /* They are unfriendly too */
                if (!gotilist[cn]) {
-                   getilist(&ilist[cn], cn, bomb_list, esc_list, obomb,
-                            oesc);
+                   getilist(&ilist[cn], cn);
                    gotilist[cn]++;
                }
                PR(plane_owner, "Flying over %s land units in %s\n",
@@ -416,6 +409,8 @@ sam_intercept(struct emp_qelem *att_list, struct emp_qelem *def_list,
                free(dqp);
                continue;
            }
+           CANT_HAPPEN(dplp->plane.pln_flags & PLN_LAUNCHED);
+           dplp->plane.pln_flags |= PLN_LAUNCHED;
            if (first) {
                first = 0;
                PR(plane_owner, "%s launches SAMs!\n", cname(def_own));
@@ -481,7 +476,8 @@ ac_intercept(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
        dist = mapdist(x, y, pp->pln_x, pp->pln_y) * 2;
        if (pp->pln_range < dist)
            continue;
-       if (mission_pln_equip(plp, 0, P_F, 0) < 0) {
+       if (CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED)
+           || mission_pln_equip(plp, 0, P_F, 0) < 0) {
            emp_remque(qp);
            free(qp);
            continue;
@@ -489,6 +485,7 @@ ac_intercept(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
        /* got one; delete from def_list, add to int_list */
        emp_remque(qp);
        emp_insque(qp, &int_list);
+       pp->pln_flags |= PLN_LAUNCHED;
        pp->pln_mobil -= pln_mobcost(dist, pp, P_F);
        putplane(pp->pln_uid, pp);
        icount++;
@@ -983,36 +980,11 @@ ac_flak_dam(int guns, int def, int pl_flags)
     return dam;
 }
 
-/*
- * See if this plane is flying in this list
- */
-int
-ac_isflying(struct plnstr *plane, struct emp_qelem *list)
-{
-    struct emp_qelem *qp;
-    struct emp_qelem *next;
-    struct plnstr *pp;
-    struct plist *plp;
-
-    if (!list)
-       return 0;
-    for (qp = list->q_forw; qp != list; qp = next) {
-       next = qp->q_forw;
-       plp = (struct plist *)qp;
-       pp = &plp->plane;
-       if (plane->pln_uid == pp->pln_uid)
-           return 1;
-    }
-    return 0;
-}
-
-
 /*
  * Get a list of planes available for interception duties.
  */
 static void
-getilist(struct emp_qelem *list, natid own, struct emp_qelem *a,
-        struct emp_qelem *b, struct emp_qelem *c, struct emp_qelem *d)
+getilist(struct emp_qelem *list, natid own)
 {
     struct plchrstr *pcp;
     struct plnstr plane;
@@ -1027,6 +999,8 @@ getilist(struct emp_qelem *list, natid own, struct emp_qelem *a,
        pcp = &plchr[(int)plane.pln_type];
        if ((pcp->pl_flags & P_F) == 0)
            continue;
+       if (plane.pln_flags & PLN_LAUNCHED)
+           continue;
        if (plane.pln_mission != 0)
            continue;
        if (plane.pln_mobil <= 0)
@@ -1035,16 +1009,6 @@ getilist(struct emp_qelem *list, natid own, struct emp_qelem *a,
            continue;
        if (!pln_airbase_ok(&plane, 0, 0))
            continue;
-       /* Finally, is it in the list of planes already in
-          flight? */
-       if (ac_isflying(&plane, a))
-           continue;
-       if (ac_isflying(&plane, b))
-           continue;
-       if (ac_isflying(&plane, c))
-           continue;
-       if (ac_isflying(&plane, d))
-           continue;
        /* got one! */
        ip = malloc(sizeof(*ip));
        ip->bombs = 0;
index 4c9decae06d74dd2ced7a95cda6399cf92bf88df..5183b2a5a7f0d3b668c325cc3fd0d1cbd33a8b75 100644 (file)
@@ -650,7 +650,7 @@ att_approach(struct combat *off, struct combat *def)
     }
     if (off->type == EF_SECTOR) {
        getsect(off->x, off->y, &sect);
-       sectdamage(&sect, dam, 0);
+       sectdamage(&sect, dam);
        putsect(&sect);
        pr("Enemy fleet at %s does %d damage to %s\n",
           xyas(def->x, def->y, player->cnum), dam, prcom(0, off));
index edf0e7f73f32ecce8ddffb8704209ed3912daa5d..f407f32f06c8607a716eb8c46eb96a728a78d866 100644 (file)
@@ -49,7 +49,7 @@
 #include "sect.h"
 #include "xy.h"
 
-static void knockdown(struct sctstr *, struct emp_qelem *);
+static void knockdown(struct sctstr *);
 
 /*
  * Check bridges at and around SP after damage to SP.
@@ -60,7 +60,7 @@ static void knockdown(struct sctstr *, struct emp_qelem *);
  * left to the caller.
  */
 void
-bridge_damaged(struct sctstr *sp, struct emp_qelem *list)
+bridge_damaged(struct sctstr *sp)
 {
     int des;
 
@@ -69,13 +69,13 @@ bridge_damaged(struct sctstr *sp, struct emp_qelem *list)
 
     des = sp->sct_type;
     if (des == SCT_BSPAN || des == SCT_BTOWER)
-       knockdown(sp, list);
+       knockdown(sp);
     if ((des == SCT_BHEAD || des == SCT_BTOWER) && !opt_EASY_BRIDGES)
-       bridgefall(sp, list);
+       bridgefall(sp);
 }
 
 void
-bridgefall(struct sctstr *sp, struct emp_qelem *list)
+bridgefall(struct sctstr *sp)
 {
     int i;
     int j;
@@ -112,7 +112,7 @@ bridgefall(struct sctstr *sp, struct emp_qelem *list)
            }
        }
        if (j > 6) {
-           knockdown(&sect, list);
+           knockdown(&sect);
            putsect(&sect);
        }
     }
@@ -121,7 +121,7 @@ bridgefall(struct sctstr *sp, struct emp_qelem *list)
 /* Knock down a bridge span.  Note that this does NOT write the
  * sector out to the database, it's up to the caller to do that. */
 static void
-knockdown(struct sctstr *sp, struct emp_qelem *list)
+knockdown(struct sctstr *sp)
 {
     struct lndstr land;
     struct plnstr plane;
@@ -165,9 +165,6 @@ knockdown(struct sctstr *sp, struct emp_qelem *list)
            continue;
        if (plane.pln_ship >= 0)
            continue;
-       /* Is this plane flying in this list? */
-       if (ac_isflying(&plane, list))
-           continue;
        np = getnatp(plane.pln_own);
        if (np->nat_flags & NF_BEEP)
            mpr(plane.pln_own, "\07");
index e027eb4a3a3f29a66a703654272889c177c3f583..f92ac6a19b76b1121ed3d668dffbfc0c424f6555 100644 (file)
@@ -105,7 +105,7 @@ detonate(struct nukstr *np, coord x, coord y, int airburst)
        }
        if (opt_FALLOUT)
            fallout = sect.sct_fallout;
-       sect_damage(&sect, damage, 0);
+       sect_damage(&sect, damage);
        if (sect.sct_x == x && sect.sct_y == y)
            retval = damage;
        if (opt_FALLOUT) {
index 96ce5d2da91e2f9f33a80e5c60d715ae6fb5f3ff..3c9574c151644ae8eba8c83e6fbfe95574522feb 100644 (file)
@@ -162,8 +162,7 @@ unitsatxy(coord x, coord y, int wantflags, int nowantflags)
 }
 
 int
-planesatxy(coord x, coord y, int wantflags, int nowantflags,
-          struct emp_qelem *list)
+planesatxy(coord x, coord y, int wantflags, int nowantflags)
 {
     int first;
     int planes;
@@ -179,9 +178,6 @@ planesatxy(coord x, coord y, int wantflags, int nowantflags,
            continue;
        if (plane.pln_flags & PLN_LAUNCHED)
            continue;
-       /* Is this plane one of the ones flying somewhere? */
-       if (ac_isflying(&plane, list))
-           continue;
        plp = &plchr[(int)plane.pln_type];
        if (first) {
            pr(" #          owner           eff       type\n");
index 1029adeea8007585f07dce5259967ad1e700cfc9..395ffcf2fdbb63422f2ab5ea26686ae353669c6f 100644 (file)
@@ -799,7 +799,7 @@ lnd_missile_interdiction(struct emp_qelem *list, coord newx, coord newy,
                            MI_INTERDICT);
     if (dam) {
        mpr(victim, "missile interdiction mission does %d damage!\n", dam);
-       collateral_damage(newx, newy, dam, 0);
+       collateral_damage(newx, newy, dam);
     }
     qp = msl_list.q_forw;
     while (qp != msl_list.q_forw) {
index c8ee9cfd0cb7560b037d58d24819b8be1b2ecce6..580cdea98cdf616ad95fa6648024a809a89e3818 100644 (file)
@@ -108,13 +108,13 @@ ground_interdict(coord x, coord y, natid victim, char *s)
                cname(cn), newdam);
     }
     if (dam) {
-       collateral_damage(x, y, dam, 0);
+       collateral_damage(x, y, dam);
     }
     return dam;
 }
 
 int
-collateral_damage(coord x, coord y, int dam, struct emp_qelem *list)
+collateral_damage(coord x, coord y, int dam)
 {
     int coll;
     struct sctstr sect;
@@ -129,7 +129,7 @@ collateral_damage(coord x, coord y, int dam, struct emp_qelem *list)
            return 0;
        mpr(sect.sct_own, "%s takes %d%% collateral damage\n",
            xyas(x, y, sect.sct_own), coll);
-       sectdamage(&sect, coll, list);
+       sectdamage(&sect, coll);
        putsect(&sect);
        return coll;
     }
@@ -201,7 +201,7 @@ unit_interdict(coord x, coord y, natid victim, char *s, int hardtarget,
        }
     }
     if (dam) {
-       collateral_damage(x, y, dam, 0);
+       collateral_damage(x, y, dam);
     }
     return dam;
 }
@@ -668,7 +668,7 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list,
               xyas(air->x, air->y, air->own));
        }
 
-       ac_encounter(&b, &e, air->x, air->y, pp, mission_flags, 0, 0, 0);
+       ac_encounter(&b, &e, air->x, air->y, pp, mission_flags, 0);
 
        if (!QEMPTY(&b))
            air_dam +=
@@ -930,17 +930,20 @@ mission_pln_arm(struct emp_qelem *list, coord x, coord y, int dist,
     struct emp_qelem *qp;
     struct emp_qelem *next;
     struct plist *plp;
+    struct plnstr *pp;
 
     for (qp = list->q_forw; qp != list; qp = next) {
        next = qp->q_forw;
        plp = (struct plist *)qp;
+       pp = &plp->plane;
 
-       if (plp->plane.pln_x != x)
+       if (pp->pln_x != x)
            continue;
-       if (plp->plane.pln_y != y)
+       if (pp->pln_y != y)
            continue;
 
-       if (mission_pln_equip(plp, ip, flags, mission) < 0) {
+       if (CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED)
+           || mission_pln_equip(plp, ip, flags, mission) < 0) {
            emp_remque(qp);
            free(qp);
            continue;
@@ -966,13 +969,9 @@ mission_pln_arm(struct emp_qelem *list, coord x, coord y, int dist,
            mission_flags &= ~P_MINE;
        }
 
-       /*
-        *      Mob costs for missions are 1/2 normal
-        *       Not anymore. :)
-        */
-/*     plp->plane.pln_mobil -= pln_mobcost(dist,&plp->plane,flags)/2;*/
-       plp->plane.pln_mobil -= pln_mobcost(dist, &plp->plane, flags);
-
+       CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED);
+       pp->pln_flags |= PLN_LAUNCHED;
+       pp->pln_mobil -= pln_mobcost(dist, pp, flags);
     }
     return mission_flags;
 }
@@ -1217,7 +1216,7 @@ air_damage(struct emp_qelem *bombers, coord x, coord y, int mission,
            }
            /* Now, even though we missed, the bombs
               land somewhere. */
-           collateral_damage(x, y, newdam, bombers);
+           collateral_damage(x, y, newdam);
        }
 
        /* use up missiles */
@@ -1396,7 +1395,7 @@ air_defense(coord x, coord y, natid victim, struct emp_qelem *bomb_list,
            /* Now, fly the planes to the sector */
            emp_initque(&empty);
            ac_encounter(&i, &empty, air->x, air->y,
-                        path, mission_flags, 1, bomb_list, esc_list);
+                        path, mission_flags, 1);
 
            /* If none made it, continue */
            if (QEMPTY(&i))
index 3f4bb5e45bd3906d47684763098a6891dd2f9341..4b1a0cdd55daa765b8212fa9ad97d34abb4c7ced 100644 (file)
@@ -116,7 +116,7 @@ msl_hit(struct plnstr *pp, int hardtarget, int type, int news_item,
                    pr("Explosion damages %s %d%%",
                       xyas(pp->pln_x, pp->pln_y, pp->pln_own), dam);
                    getsect(pp->pln_x, pp->pln_y, &sect);
-                   sectdamage(&sect, dam, 0);
+                   sectdamage(&sect, dam);
                    putsect(&sect);
                }
            }
@@ -406,7 +406,7 @@ msl_launch_mindam(struct emp_qelem *list, coord x, coord y, int hardtarget,
            } else {
                /* Missiles that miss have to hit somewhere! */
                newdam = pln_damage(&plp->plane, x, y, 'p', &nukedam, 0);
-               collateral_damage(x, y, newdam, 0);
+               collateral_damage(x, y, newdam);
            }
            plp->plane.pln_effic = 0;
            putplane(plp->plane.pln_uid, &plp->plane);
index d54643fce3706ff30fb45a3cbdbea0dfb32576ff..1c5c8ad5f10e9555f1f90b6a15d5a1f40d371be1 100644 (file)
@@ -553,11 +553,14 @@ pln_arm(struct emp_qelem *list, int dist, char mission, struct ichrstr *ip,
     struct emp_qelem *qp;
     struct emp_qelem *next;
     struct plist *plp;
+    struct plnstr *pp;
 
     for (qp = list->q_forw; qp != list; qp = next) {
        next = qp->q_forw;
        plp = (struct plist *)qp;
-       if (pln_equip(plp, ip, flags, mission) < 0) {
+       pp = &plp->plane;
+       if ((pp->pln_flags & PLN_LAUNCHED)
+           || pln_equip(plp, ip, flags, mission) < 0) {
            emp_remque(qp);
            free(qp);
            continue;
@@ -584,8 +587,11 @@ pln_arm(struct emp_qelem *list, int dist, char mission, struct ichrstr *ip,
            mission_flags &= ~P_MINE;
            /* FIXME no effect */
        }
-       plp->plane.pln_mobil -= pln_mobcost(dist, &plp->plane, flags);
-       pr("%s equipped\n", prplane(&plp->plane));
+       CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED);
+       pp->pln_flags |= PLN_LAUNCHED;
+       pp->pln_mobil -= pln_mobcost(dist, pp, flags);
+       putplane(pp->pln_uid, pp);
+       pr("%s equipped\n", prplane(pp));
     }
     return mission_flags;
 }
@@ -742,8 +748,16 @@ pln_put1(struct plist *plp)
     struct sctstr sect;
 
     pp = &plp->plane;
-    if (!pp->pln_own) {
-       /* crashed */
+
+    if (CANT_HAPPEN((pp->pln_flags & PLN_LAUNCHED)
+                   && (plchr[pp->pln_type].pl_flags & P_M)
+                   && pp->pln_effic >= PLANE_MINEFF))
+       pp->pln_effic = 0;   /* bug: missile launched but not used up */
+
+    if (!(pp->pln_flags & PLN_LAUNCHED))
+       ;                       /* never took off */
+    else if (pp->pln_effic < PLANE_MINEFF) {
+       /* destroyed */
        if (pp->pln_ship >= 0) {
            getship(pp->pln_ship, &ship);
            take_plane_off_ship(pp, &ship);
@@ -775,42 +789,12 @@ pln_put1(struct plist *plp)
            pp->pln_effic = 0;
        }
     }
+    pp->pln_flags &= ~PLN_LAUNCHED;
     putplane(pp->pln_uid, pp);
     emp_remque(&plp->queue);
     free(plp);
 }
 
-void
-pln_removedupes(struct emp_qelem *bomb_list, struct emp_qelem *esc_list)
-{
-    struct emp_qelem *bomb;
-    struct emp_qelem *esc;
-    struct plist *bombp;
-    struct plist *escp;
-
-    if (QEMPTY(bomb_list) || QEMPTY(esc_list))
-       return;
-    bomb = bomb_list->q_forw;
-    while (bomb != bomb_list) {
-       if (QEMPTY(esc_list)) {
-           bomb = bomb_list;
-           continue;
-       }
-       esc = esc_list->q_forw;
-       bombp = (struct plist *)bomb;
-       while (esc != esc_list) {
-           escp = (struct plist *)esc;
-           if (escp->plane.pln_uid == bombp->plane.pln_uid) {
-               emp_remque(esc);
-               free(esc);
-               esc = esc_list;
-           } else
-               esc = esc->q_forw;
-       }
-       bomb = bomb->q_forw;
-    }
-}
-
 /*
  * Fit a plane of PP's type on ship SP.
  * Adjust SP's plane counters.
index 1b90c03c6f0cc6cb1c4475df84656047412d875c..541b9b9babfd31712b0f516f69e0fa5de0616662 100644 (file)
@@ -68,7 +68,7 @@ sct_prewrite(int id, void *ptr)
     struct sctstr *sp = ptr;
     struct sctstr sect;
 
-    bridge_damaged(sp, NULL);
+    bridge_damaged(sp);
     checksect(sp);
     getsect(sp->sct_x, sp->sct_y, &sect);
     return 1;
index a14dad48b79c8f1e8d7683487243d07a6538cd6a..920f45aa28a690661459b8eb94de62161a1d6c27 100644 (file)
@@ -49,7 +49,7 @@
 #include "xy.h"
 
 int
-sect_damage(struct sctstr *sp, int dam, struct emp_qelem *list)
+sect_damage(struct sctstr *sp, int dam)
 {
     int eff;
 
@@ -69,13 +69,13 @@ sect_damage(struct sctstr *sp, int dam, struct emp_qelem *list)
     if (sp->sct_mobil > 0)
        sp->sct_mobil = damage(sp->sct_mobil, dam);
     item_damage(dam, sp->sct_item);
-    bridge_damaged(sp, list);
+    bridge_damaged(sp);
     putsect(sp);
     return eff;
 }
 
 int
-sectdamage(struct sctstr *sp, int dam, struct emp_qelem *list)
+sectdamage(struct sctstr *sp, int dam)
 {
     struct nstr_item ni;
     struct lndstr land;
@@ -87,7 +87,7 @@ sectdamage(struct sctstr *sp, int dam, struct emp_qelem *list)
     /* the damage accordingly. Makes forts a pain */
     dam = ldround(dam / sector_strength(sp), 1);
 
-    eff = sect_damage(sp, PERCENT_DAMAGE(dam), list);
+    eff = sect_damage(sp, PERCENT_DAMAGE(dam));
 
     /* Damage all the land units in the sector */
     /* Units don't take full damage */
@@ -114,9 +114,6 @@ sectdamage(struct sctstr *sp, int dam, struct emp_qelem *list)
            continue;
        if (plane.pln_ship >= 0)
            continue;
-       /* Is this plane flying in this list? */
-       if (ac_isflying(&plane, list))
-           continue;
        planedamage(&plane, dam);
        putplane(plane.pln_uid, &plane);
     }
index 8684eaa2a00d8d07823056adfb5270ef461fa0d1..e9ef4e463e7a22ed8a79d5cc98d53d21f47ecede 100644 (file)
@@ -271,7 +271,7 @@ guerrilla(struct sctstr *sp)
        wu(0, sp->sct_own,
           "Production %s disrupted by terrorists in %s\n",
           effadv(n), ownxy(sp));
-       sect_damage(sp, n / 10, 0);
+       sect_damage(sp, n / 10);
        /*logerror("(#%d) che blew up %s for %d", sp->sct_own, */
        /*ownxy(sp), n); */
        recruit++;