update/revolt: Fix land unit casualties

Fix the bug demonstrated by the previous commit:
take_casualties_from_lands() limits total casualties to @each.  It
should limit each land unit's casualties, and only if !may_kill.  This
can lead to fewer casualties than called for; oops in
take_casualties().  Broken in commit 025e9cc25, v4.4.0.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This commit is contained in:
Markus Armbruster 2018-04-10 16:31:11 +02:00
parent d111522fe8
commit 60429028e7
4 changed files with 16 additions and 16 deletions

View file

@ -29,7 +29,7 @@
* Known contributors to this file: * Known contributors to this file:
* Dave Pare, 1986 * Dave Pare, 1986
* Steve McClure, 1997-2000 * Steve McClure, 1997-2000
* Markus Armbruster, 2004-2016 * Markus Armbruster, 2004-2018
*/ */
#include <config.h> #include <config.h>
@ -455,26 +455,26 @@ take_casualties(struct sctstr *sp, int mc)
each = (mc - taken) / nunits + 2; each = (mc - taken) / nunits + 2;
/* kill some security troops */ /* kill some security troops */
taken += take_casualties_from_lands(sp, MIN(each, mc - taken), 1, 0); taken += take_casualties_from_lands(sp, mc - taken, each, 1);
/* kill some normal troops */ /* kill some normal troops */
taken += take_casualties_from_lands(sp, MIN(each, mc - taken), 0, 0); taken += take_casualties_from_lands(sp, mc - taken, each, 0);
/* Hmm.. still some left.. kill off units now */ /* Hmm.. still some left.. kill off units now */
/* kill some normal troops */ /* kill some normal troops */
taken += take_casualties_from_lands(sp, MIN(each, mc - taken), 0, 1); taken += take_casualties_from_lands(sp, mc - taken, -1, 0);
/* Hmm.. still some left.. kill off units now */ /* Hmm.. still some left.. kill off units now */
/* kill some security troops */ /* kill some security troops */
taken += take_casualties_from_lands(sp, MIN(each, mc - taken), 1, 1); taken += take_casualties_from_lands(sp, mc - taken, -1, 1);
CANT_HAPPEN(taken < mc); CANT_HAPPEN(taken < mc);
return taken; return taken;
} }
int int
take_casualties_from_lands(struct sctstr *sp, int cas, take_casualties_from_lands(struct sctstr *sp, int cas, int each,
int security, int may_kill) int security)
{ {
struct nstr_item ni; struct nstr_item ni;
struct lndstr *lp; struct lndstr *lp;
@ -495,9 +495,11 @@ take_casualties_from_lands(struct sctstr *sp, int cas,
eff_per_cas = 100.0 / lchr[lp->lnd_type].l_item[I_MILIT]; eff_per_cas = 100.0 / lchr[lp->lnd_type].l_item[I_MILIT];
cantake = lp->lnd_item[I_MILIT]; cantake = lp->lnd_item[I_MILIT];
if (!may_kill) if (each >= 0) {
cantake = MIN(cantake, each);
cantake = MIN(cantake, cantake = MIN(cantake,
(int)((lp->lnd_effic - 40) / eff_per_cas)); (int)((lp->lnd_effic - 40) / eff_per_cas));
}
deq = MIN(cantake, cas - taken); deq = MIN(cantake, cas - taken);
if (deq <= 0) if (deq <= 0)
continue; continue;
@ -507,7 +509,7 @@ take_casualties_from_lands(struct sctstr *sp, int cas,
lp->lnd_mobil -= deq * eff_per_cas / 2; lp->lnd_mobil -= deq * eff_per_cas / 2;
lnd_submil(lp, deq); lnd_submil(lp, deq);
if (lp->lnd_effic < LAND_MINEFF) { if (lp->lnd_effic < LAND_MINEFF) {
CANT_HAPPEN(!may_kill); CANT_HAPPEN(each >= 0);
taken += lp->lnd_item[I_MILIT]; taken += lp->lnd_item[I_MILIT];
lnd_dies_fighting_che(lp); lnd_dies_fighting_che(lp);
} }

View file

@ -378,9 +378,9 @@ uid owner xloc yloc type effic mobil off tech opx opy mission radius army ship h
22 0 -14 -8 2 0 0 1 50 0 0 none 0 "" -1 0 42 () "" 0 0 0 0 0 0 0 0 10 0 0 0 0 0 healthy 0 -1 0 22 0 -14 -8 2 0 0 1 50 0 0 none 0 "" -1 0 42 () "" 0 0 0 0 0 0 0 0 10 0 0 0 0 0 healthy 0 -1 0
23 0 -14 -8 2 0 0 1 50 0 0 none 0 "" -1 0 42 () "" 0 0 0 0 0 0 0 0 10 0 0 0 0 0 healthy 0 -1 0 23 0 -14 -8 2 0 0 1 50 0 0 none 0 "" -1 0 42 () "" 0 0 0 0 0 0 0 0 10 0 0 0 0 0 healthy 0 -1 0
24 4 -12 -8 8 100 60 0 170 0 0 none 0 "" -1 0 42 () "" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 -1 0 24 4 -12 -8 8 100 60 0 170 0 0 none 0 "" -1 0 42 () "" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 -1 0
25 0 -12 -8 20 0 -44 1 170 0 0 none 0 "" -1 0 42 () "" 0 1 0 0 0 0 0 0 8 0 0 0 0 0 healthy 0 -1 0 25 0 -12 -8 20 0 -45 1 170 0 0 none 0 "" -1 0 42 () "" 0 0 0 0 0 0 0 0 8 0 0 0 0 0 healthy 0 -1 0
26 0 -12 -8 2 0 -2 1 50 0 0 none 0 "" -1 0 42 () "" 0 0 0 0 0 0 0 0 10 0 0 0 0 0 healthy 0 -1 0 26 0 -12 -8 2 0 -2 1 50 0 0 none 0 "" -1 0 42 () "" 0 0 0 0 0 0 0 0 10 0 0 0 0 0 healthy 0 -1 0
27 0 -12 -8 20 0 0 1 170 0 0 none 0 "" -1 0 42 () "" 0 10 0 0 0 0 0 0 10 0 0 0 0 0 healthy 0 -1 0 27 0 -12 -8 20 0 -10 0 170 0 0 none 0 "" -1 0 42 () "" 0 0 0 0 0 0 0 0 10 0 0 0 0 0 healthy 0 -1 0
28 0 -8 -8 1 0 -12 0 50 0 0 none 0 "" -1 0 42 () "" 0 0 0 0 0 0 0 0 9 0 0 0 0 0 healthy 0 -1 0 28 0 -8 -8 1 0 -12 0 50 0 0 none 0 "" -1 0 42 () "" 0 0 0 0 0 0 0 0 9 0 0 0 0 0 healthy 0 -1 0
29 4 -6 -8 2 14 47 0 50 0 0 none 0 "" -1 0 42 () "" 0 24 0 0 0 0 0 0 8 0 0 0 0 0 healthy 0 -1 0 29 4 -6 -8 2 14 47 0 50 0 0 none 0 "" -1 0 42 () "" 0 24 0 0 0 0 0 0 8 0 0 0 0 0 healthy 0 -1 0
30 2 -16 0 2 88 60 0 50 0 0 none 0 "" -1 0 42 () "" 0 100 0 0 0 0 0 0 7 0 0 0 0 0 healthy 0 -1 0 30 2 -16 0 2 88 60 0 50 0 0 none 0 "" -1 0 42 () "" 0 100 0 0 0 0 0 0 7 0 0 0 0 0 healthy 0 -1 0
@ -463,10 +463,10 @@ timestamp owner type id x y
0 4 3 21 -14 -8 0 4 3 21 -14 -8
0 4 3 22 -14 -8 0 4 3 22 -14 -8
0 4 3 23 -14 -8 0 4 3 23 -14 -8
0 4 3 27 -12 -8
0 4 0 0 -12 -8 0 4 0 0 -12 -8
0 4 3 25 -12 -8 0 4 3 25 -12 -8
0 4 3 26 -12 -8 0 4 3 26 -12 -8
0 4 3 27 -12 -8
0 4 3 28 -8 -8 0 4 3 28 -8 -8
0 4 0 0 -16 -6 0 4 0 0 -16 -6
0 4 0 0 -8 -6 0 4 0 0 -8 -6

View file

@ -1364,11 +1364,11 @@
Play#0 output Play#0 1 rebels murder 2 military Play#0 output Play#0 1 rebels murder 2 military
Play#0 output Play#0 1 Partisans take over -14,-8! Play#0 output Play#0 1 Partisans take over -14,-8!
Play#0 output Play#0 1 sec security #25 kills 4 guerrillas in raid at -12,-8! Play#0 output Play#0 1 sec security #25 kills 4 guerrillas in raid at -12,-8!
Play#0 output Play#0 1 sec security #27 dies fighting guerrillas in -12,-8
Play#0 output Play#0 1 sec security #25 blown up by the crew when POGO took -12,-8! Play#0 output Play#0 1 sec security #25 blown up by the crew when POGO took -12,-8!
Play#0 output Play#0 1 inf infantry #26 captured when POGO took -12,-8! Play#0 output Play#0 1 inf infantry #26 captured when POGO took -12,-8!
Play#0 output Play#0 1 sec security #27 blown up by the crew when POGO took -12,-8!
Play#0 output Play#0 1 Guerrilla warfare in -12,-8 Play#0 output Play#0 1 Guerrilla warfare in -12,-8
Play#0 output Play#0 1 rebels murder 59 military Play#0 output Play#0 1 rebels murder 70 military
Play#0 output Play#0 1 Partisans take over -12,-8! Play#0 output Play#0 1 Partisans take over -12,-8!
Play#0 output Play#0 1 Guerrilla warfare in -10,-8 Play#0 output Play#0 1 Guerrilla warfare in -10,-8
Play#0 output Play#0 1 body count: troops: 10, rebels: 5 Play#0 output Play#0 1 body count: troops: 10, rebels: 5

View file

@ -39,8 +39,6 @@ tester@127.0.0.1 logged in as country #0
Triggering unscheduled update Triggering unscheduled update
production update (60 ETUs) production update (60 ETUs)
preparing sectors... preparing sectors...
Oops: taken < mc in ../src/lib/update/revolt.c:471
Crash dump complete
done preparing sectors. done preparing sectors.
producing for countries... producing for countries...
done producing for countries. done producing for countries.