Fix bomb not to wipe out plane updates while asking for targets

The commands to fly planes read the planes into a plane list, and
write them back when they land.  If a plane changes in the file while
it is in that plane list, the changes get wiped out when the plane
lands, triggering a seqno oops.

This is not an issue as long as the complete sortie runs
uninterrupted, because that code takes care to update flying planes
only through the appropriate plane list.

However, the bomb command suspends the planes on a pinpoint bombing
run mid-air over the target sector to let the player choose targets.
This lets code run that *can* update flying planes, for instance the
edit command.

Fix by aborting changed planes, taking care not to clobber the
changes.
This commit is contained in:
Markus Armbruster 2009-03-08 18:19:25 +01:00
parent f10af4dea0
commit f07e6901cb

View file

@ -49,15 +49,16 @@
#include "retreat.h" #include "retreat.h"
#include "ship.h" #include "ship.h"
static void pin_bomb(struct emp_qelem *list, struct sctstr *target); static void pin_bomb(struct emp_qelem *, struct sctstr *);
static void strat_bomb(struct emp_qelem *list, struct sctstr *target); static void eff_bomb(struct emp_qelem *, struct sctstr *);
static void comm_bomb(struct emp_qelem *list, struct sctstr *target); static void comm_bomb(struct emp_qelem *, struct sctstr *);
static void eff_bomb(struct emp_qelem *list, struct sctstr *target); static void ship_bomb(struct emp_qelem *, struct sctstr *);
static int pinflak_planedamage(struct plnstr *pp, struct plchrstr *pcp, static void plane_bomb(struct emp_qelem *, struct sctstr *);
natid from, int flak); static void land_bomb(struct emp_qelem *, struct sctstr *);
static void plane_bomb(struct emp_qelem *list, struct sctstr *target); static void strat_bomb(struct emp_qelem *, struct sctstr *);
static void land_bomb(struct emp_qelem *list, struct sctstr *target); static int changed_plane_aborts(struct plist *);
static void ship_bomb(struct emp_qelem *list, struct sctstr *target); static int pinflak_planedamage(struct plnstr *, struct plchrstr *,
natid, int);
static i_type bombcomm[] = { static i_type bombcomm[] = {
I_CIVIL, I_CIVIL,
@ -325,13 +326,16 @@ static void
eff_bomb(struct emp_qelem *list, struct sctstr *target) eff_bomb(struct emp_qelem *list, struct sctstr *target)
{ {
struct plist *plp; struct plist *plp;
struct emp_qelem *qp; struct emp_qelem *qp, *next;
struct sctstr sect; struct sctstr sect;
int oldeff, dam = 0; int oldeff, dam = 0;
int nukedam; int nukedam;
for (qp = list->q_forw; qp != list; qp = qp->q_forw) { for (qp = list->q_forw; qp != list; qp = next) {
next = qp->q_forw;
plp = (struct plist *)qp; plp = (struct plist *)qp;
if (changed_plane_aborts(plp))
continue;
if ((plp->pcp->pl_flags & P_C) && (!(plp->pcp->pl_flags & P_T))) if ((plp->pcp->pl_flags & P_C) && (!(plp->pcp->pl_flags & P_T)))
continue; continue;
if (plp->bombs || nuk_on_plane(&plp->plane) >= 0) if (plp->bombs || nuk_on_plane(&plp->plane) >= 0)
@ -369,7 +373,7 @@ comm_bomb(struct emp_qelem *list, struct sctstr *target)
int i; int i;
int amt, before; int amt, before;
struct ichrstr *ip; struct ichrstr *ip;
struct emp_qelem *qp; struct emp_qelem *qp, *next;
struct sctstr sect; struct sctstr sect;
int dam = 0; int dam = 0;
int nukedam; int nukedam;
@ -407,8 +411,11 @@ comm_bomb(struct emp_qelem *list, struct sctstr *target)
} else } else
break; break;
} }
for (qp = list->q_forw; qp != list; qp = qp->q_forw) { for (qp = list->q_forw; qp != list; qp = next) {
next = qp->q_forw;
plp = (struct plist *)qp; plp = (struct plist *)qp;
if (changed_plane_aborts(plp))
continue;
if ((plp->pcp->pl_flags & P_C) && (!(plp->pcp->pl_flags & P_T))) if ((plp->pcp->pl_flags & P_C) && (!(plp->pcp->pl_flags & P_T)))
continue; continue;
if (plp->bombs || nuk_on_plane(&plp->plane) >= 0) if (plp->bombs || nuk_on_plane(&plp->plane) >= 0)
@ -445,7 +452,7 @@ ship_bomb(struct emp_qelem *list, struct sctstr *target)
int dam; int dam;
char *q; char *q;
int n; int n;
struct emp_qelem *qp; struct emp_qelem *qp, *next;
int shipno; int shipno;
struct shpstr ship; struct shpstr ship;
int nships = 0; int nships = 0;
@ -457,9 +464,12 @@ ship_bomb(struct emp_qelem *list, struct sctstr *target)
int flak; int flak;
int gun; int gun;
for (qp = list->q_forw; qp != list; qp = qp->q_forw) { for (qp = list->q_forw; qp != list; qp = next) {
next = qp->q_forw;
free_shiplist(&head); free_shiplist(&head);
plp = (struct plist *)qp; plp = (struct plist *)qp;
if (changed_plane_aborts(plp))
continue;
if ((plp->pcp->pl_flags & P_C) && (!(plp->pcp->pl_flags & P_T))) if ((plp->pcp->pl_flags & P_C) && (!(plp->pcp->pl_flags & P_T)))
continue; continue;
if (plp->pcp->pl_flags & P_A) if (plp->pcp->pl_flags & P_A)
@ -502,6 +512,8 @@ ship_bomb(struct emp_qelem *list, struct sctstr *target)
continue; continue;
if ((plp->pcp->pl_flags & P_A) && !on_shiplist(shipno, head)) if ((plp->pcp->pl_flags & P_A) && !on_shiplist(shipno, head))
continue; continue;
if (changed_plane_aborts(plp))
continue;
gun = shp_usable_guns(&ship); gun = shp_usable_guns(&ship);
mcp = &mchr[(int)ship.shp_type]; mcp = &mchr[(int)ship.shp_type];
@ -571,7 +583,7 @@ plane_bomb(struct emp_qelem *list, struct sctstr *target)
int n; int n;
natid own; natid own;
struct plnstr plane; struct plnstr plane;
struct emp_qelem *qp; struct emp_qelem *qp, *next;
int planeno; int planeno;
struct plist *plp; struct plist *plp;
char prompt[128]; char prompt[128];
@ -580,8 +592,11 @@ plane_bomb(struct emp_qelem *list, struct sctstr *target)
int nukedam; int nukedam;
int nplanes; int nplanes;
for (qp = list->q_forw; qp != list; qp = qp->q_forw) { for (qp = list->q_forw; qp != list; qp = next) {
next = qp->q_forw;
plp = (struct plist *)qp; plp = (struct plist *)qp;
if (changed_plane_aborts(plp))
continue;
if ((plp->pcp->pl_flags & P_C) && (!(plp->pcp->pl_flags & P_T))) if ((plp->pcp->pl_flags & P_C) && (!(plp->pcp->pl_flags & P_T)))
continue; continue;
nplanes = planesatxy(target->sct_x, target->sct_y, 0, 0); nplanes = planesatxy(target->sct_x, target->sct_y, 0, 0);
@ -617,6 +632,8 @@ plane_bomb(struct emp_qelem *list, struct sctstr *target)
} }
if (planeno < 0) if (planeno < 0)
continue; continue;
if (changed_plane_aborts(plp))
continue;
dam = 0; dam = 0;
if (nuk_on_plane(&plp->plane) >= 0) if (nuk_on_plane(&plp->plane) >= 0)
hitchance = 100; hitchance = 100;
@ -674,15 +691,18 @@ land_bomb(struct emp_qelem *list, struct sctstr *target)
char prompt[128]; char prompt[128];
char buf[1024]; char buf[1024];
struct lndstr land; struct lndstr land;
struct emp_qelem *qp; struct emp_qelem *qp, *next;
int unitno; int unitno;
int aaf, flak, hitchance; int aaf, flak, hitchance;
struct plist *plp; struct plist *plp;
int nukedam; int nukedam;
int nunits; int nunits;
for (qp = list->q_forw; qp != list; qp = qp->q_forw) { for (qp = list->q_forw; qp != list; qp = next) {
next = qp->q_forw;
plp = (struct plist *)qp; plp = (struct plist *)qp;
if (changed_plane_aborts(plp))
continue;
if ((plp->pcp->pl_flags & P_C) && (!(plp->pcp->pl_flags & P_T))) if ((plp->pcp->pl_flags & P_C) && (!(plp->pcp->pl_flags & P_T)))
continue; continue;
nunits = unitsatxy(target->sct_x, target->sct_y, 0, 0); nunits = unitsatxy(target->sct_x, target->sct_y, 0, 0);
@ -716,6 +736,8 @@ land_bomb(struct emp_qelem *list, struct sctstr *target)
} }
if (unitno < 0) if (unitno < 0)
continue; continue;
if (changed_plane_aborts(plp))
continue;
aaf = lnd_aaf(&land); aaf = lnd_aaf(&land);
if (aaf) { if (aaf) {
@ -798,6 +820,16 @@ strat_bomb(struct emp_qelem *list, struct sctstr *target)
putsect(&sect); putsect(&sect);
} }
static int
changed_plane_aborts(struct plist *plp)
{
if (check_plane_ok(&plp->plane))
return 0;
getplane(plp->plane.pln_uid, &plp->plane);
pln_put1(plp);
return 1;
}
static int static int
pinflak_planedamage(struct plnstr *pp, struct plchrstr *pcp, natid from, pinflak_planedamage(struct plnstr *pp, struct plchrstr *pcp, natid from,
int flak) int flak)