Units no longer die from lack of maintenance

Damage due to lack of maintenance is now limited by the unit's minimum
efficiency.

Before, units could die.  Unfortunately, the update left any embarked
units on their dead carrier.  Should have seen this when I fixed a
related bug in commit c2c0d1ff, v4.3.22.  Broken for ships and land
units when Empire 2 added their maintenance cost, and for planes when
commit 2e40a4bb (v4.3.4) replaced nuclear stockpiles by nuke units.
The common root cause of these bugs is the update bypassing pre-write
functions (bug#1010856).

If another unit with the same number got built, it picked up the stuck
cargo, triggering the oops from commit 6fb5caf6, which see.

In "stuck on dead carrier" state, units pretty much behave as if their
carrier was still alive, with additional protection from the fact that
a dead carrier can't be damaged or boarded.

The server detects this state on startup since commit 7da9aab5, and
refuses to start.

Only a deity can take units off a dead carrier.
This commit is contained in:
Markus Armbruster 2011-07-05 21:29:03 +02:00
parent 8621911b4d
commit 8ccad0d779
Notes: Markus Armbruster 2011-07-13 19:47:10 +02:00
Correction: commit 2e40a4bb is in v4.3.3.
4 changed files with 31 additions and 50 deletions

View file

@ -30,7 +30,7 @@
* Dave Pare, 1986
* Steve McClure, 1996
* Ron Koenderink, 2004
* Markus Armbruster, 2006-2010
* Markus Armbruster, 2006-2011
*/
#include <config.h>
@ -104,10 +104,7 @@ upd_ship(struct shpstr *sp, int etus,
struct pchrstr *product;
unsigned char *resource;
int dep;
int n;
int mult;
int cost;
int eff;
int n, mult, cost, eff_lost;
mp = &mchr[(int)sp->shp_type];
if (build == 1) {
@ -121,18 +118,14 @@ upd_ship(struct shpstr *sp, int etus,
mult = 2;
cost = -(mult * etus * MIN(0.0, money_ship * mp->m_cost));
if (np->nat_money < cost && !player->simulation) {
if ((eff = sp->shp_effic - etus / 5) < SHIP_MINEFF) {
wu(0, sp->shp_own,
"%s lost to lack of maintenance\n", prship(sp));
makelost(EF_SHIP, sp->shp_own, sp->shp_uid,
sp->shp_x, sp->shp_y);
sp->shp_own = 0;
return;
eff_lost = etus / 5;
if (sp->shp_effic - eff_lost < SHIP_MINEFF)
eff_lost = sp->shp_effic - SHIP_MINEFF;
if (eff_lost > 0) {
wu(0, sp->shp_own, "%s lost %d%% to lack of maintenance\n",
prship(sp), eff_lost);
sp->shp_effic -= eff_lost;
}
wu(0, sp->shp_own,
"%s lost %d%% to lack of maintenance\n",
prship(sp), sp->shp_effic - eff);
sp->shp_effic = eff;
} else {
np->nat_money -= cost;
}