Because supply_commod() updates supply sources it used, the caller
must not cache objects that could be supply sources across a supply
call. This is very easy to get wrong.
ac_doflak() supplies flak shells if the sector hasn't enough for its
guns. It caches the sector that receives them. If the sector has
some shells, but not enough, it supplies them to itself, causing it to
be updated from within supply_commod(). ac_doflak() then adds the
supplied shells to its cached sector, then writes that back. This
doubles shells already there, and triggers a a seqno mismatch oops.
shp_missile_defense() has similar problems, only for ships.
Disable ac_doflak() and shp_missile_defense() for now, to at least
reduce the oopsing to manageable levels.
Most likely other calls of supply_commod() are also wrong. Many of
them can't be just disabled, because supply is too relevant to
gameplay there.
gun = MIN(FLAK_GUN_MAX, from->sct_item[I_GUN]);
shell = from->sct_item[I_SHELL];
+#if 0
+ /*
+ * FIXME can supply from itself, causing seqno mismatch oops
+ * further down
+ */
if (gun > shell * 2) {
shell += supply_commod(from->sct_own, from->sct_x, from->sct_y,
I_SHELL, (gun + 1) / 2 - shell);
from->sct_item[I_SHELL] = shell;
putsect(from);
}
+#endif
if (gun > shell * 2)
gun = shell * 2;
shell = ship.shp_item[I_SHELL];
if (ship.shp_item[I_MILIT] < 1) /* do we have mil? */
continue;
+#if 0
+ /*
+ * FIXME can supply from itself, causing seqno mismatch oops
+ * further down
+ */
if (shell < 2) { /* do we need shells */
shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
I_SHELL, 2);
if (shell < 2)
continue;
}
+#endif
if (ship.shp_item[I_GUN] < 1) /* we need at least 1 gun */
continue;