(shp_nav_one_sector): When shp_interdict() removed the second ship in

a sector, interdiction loop followed dangling pointer and crashed.
Simplify & fix.
(mlist): Member done no longer used, remove.
This commit is contained in:
Markus Armbruster 2005-03-21 21:05:08 +00:00
parent 1c3eead016
commit 19a80f13c4
2 changed files with 19 additions and 23 deletions

View file

@ -191,7 +191,6 @@ struct mlist {
struct mchrstr *mcp; /* pointer to desc of ship */ struct mchrstr *mcp; /* pointer to desc of ship */
struct shpstr ship; /* struct ship */ struct shpstr ship; /* struct ship */
double mobil; /* how much mobility the ship has left */ double mobil; /* how much mobility the ship has left */
int done; /* has this ship been interdicted yet? */
}; };
#define SHP_DEF(b, t) (t ? (b * (logx((double)t, (double)40.0) < 1.0 ? 1.0 : \ #define SHP_DEF(b, t) (t ? (b * (logx((double)t, (double)40.0) < 1.0 ? 1.0 : \

View file

@ -718,10 +718,9 @@ shp_interdict(struct emp_qelem *list, coord newx, coord newy, natid victim)
stopping |= stopping |=
shp_damage(list, shp_damage(list,
unit_interdict(newx, newy, victim, "ships", unit_interdict(newx, newy, victim, "ships",
shp_easiest_target(list, 0, shp_easiest_target(list, 0, M_SUB),
M_SUB), MI_INTERDICT),
MI_INTERDICT), 0, M_SUB, newx, 0, M_SUB, newx, newy);
newy);
if (most_valuable_ship(list)) { if (most_valuable_ship(list)) {
stopping |= stopping |=
shp_missile_interdiction(list, newx, newy, victim); shp_missile_interdiction(list, newx, newy, victim);
@ -805,9 +804,8 @@ shp_nav_one_sector(struct emp_qelem *list, int dir, natid actor,
struct sctstr sect; struct sctstr sect;
struct emp_qelem *qp; struct emp_qelem *qp;
struct emp_qelem *next; struct emp_qelem *next;
struct emp_qelem *nqp;
struct emp_qelem *nnext;
struct mlist *mlp; struct mlist *mlp;
struct emp_qelem done;
coord dx; coord dx;
coord dy; coord dy;
coord newx; coord newx;
@ -867,7 +865,6 @@ shp_nav_one_sector(struct emp_qelem *list, int dir, natid actor,
} }
mlp->ship.shp_mobil = (int)mlp->mobil; mlp->ship.shp_mobil = (int)mlp->mobil;
putship(mlp->ship.shp_uid, &mlp->ship); putship(mlp->ship.shp_uid, &mlp->ship);
mlp->done = 0; /* We haven't interdicted this ship yet */
/* Now update the map for this ship */ /* Now update the map for this ship */
tech = techfact(mlp->ship.shp_tech, (double)mlp->mcp->m_vrnge); tech = techfact(mlp->ship.shp_tech, (double)mlp->mcp->m_vrnge);
@ -887,26 +884,26 @@ shp_nav_one_sector(struct emp_qelem *list, int dir, natid actor,
if (QEMPTY(list)) if (QEMPTY(list))
return stopping; return stopping;
/* Ok, run through each ship and interdict each coordinate */ /* interdict ships sector by sector */
for (qp = list->q_back; qp != list; qp = next) { emp_initque(&done);
next = qp->q_back; while (!QEMPTY(list)) {
mlp = (struct mlist *)qp; mlp = (struct mlist *)list->q_back;
/* Has this ship been interdicted yet? */
if (mlp->done)
continue;
newx = mlp->ship.shp_x; newx = mlp->ship.shp_x;
newy = mlp->ship.shp_y; newy = mlp->ship.shp_y;
stopping |= shp_interdict(list, newx, newy, actor); stopping |= shp_interdict(list, newx, newy, actor);
if (QEMPTY(list)) /* move survivors in this sector to done */
return stopping; for (qp = list->q_back; qp != list; qp = next) {
/* Now, set all ships in this coordinate to done */ next = qp->q_back;
for (nqp = list->q_back; nqp != list; nqp = nnext) { mlp = (struct mlist *)qp;
nnext = nqp->q_back; if (mlp->ship.shp_x == newx && mlp->ship.shp_y == newy) {
mlp = (struct mlist *)nqp; emp_remque(qp);
if (mlp->ship.shp_x == newx && mlp->ship.shp_y == newy) emp_insque(qp, &done);
mlp->done = 1;
} }
} }
}
/* assign surviving ships back to list */
emp_insque(list, &done);
emp_remque(&done);
return stopping; return stopping;
} }