Fix tracking of planes flying a sortie

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().
This commit is contained in:
Markus Armbruster 2008-03-23 19:21:19 +01:00
parent 8006543878
commit 7ca4f412b1
24 changed files with 128 additions and 172 deletions

View 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 *);