update/revolt: Fix land unit casualties changeling master
authorMarkus Armbruster <armbru@pond.sub.org>
Tue, 10 Apr 2018 14:31:11 +0000 (16:31 +0200)
committerMarkus Armbruster <armbru@pond.sub.org>
Sun, 29 Apr 2018 08:33:48 +0000 (10:33 +0200)
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>
src/lib/update/revolt.c
tests/update/final.xdump
tests/update/journal.log
tests/update/server.log

index ce947fe..a74c507 100644 (file)
@@ -29,7 +29,7 @@
  *  Known contributors to this file:
  *     Dave Pare, 1986
  *     Steve McClure, 1997-2000
- *     Markus Armbruster, 2004-2016
+ *     Markus Armbruster, 2004-2018
  */
 
 #include <config.h>
@@ -455,26 +455,26 @@ take_casualties(struct sctstr *sp, int mc)
     each = (mc - taken) / nunits + 2;
 
     /* 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 */
-    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 */
     /* 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 */
     /* 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);
     return taken;
 }
 
 int
-take_casualties_from_lands(struct sctstr *sp, int cas,
-                          int security, int may_kill)
+take_casualties_from_lands(struct sctstr *sp, int cas, int each,
+                          int security)
 {
     struct nstr_item ni;
     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];
        cantake = lp->lnd_item[I_MILIT];
-       if (!may_kill)
+       if (each >= 0) {
+           cantake = MIN(cantake, each);
            cantake = MIN(cantake,
                          (int)((lp->lnd_effic - 40) / eff_per_cas));
+       }
        deq = MIN(cantake, cas - taken);
        if (deq <= 0)
            continue;
@@ -507,7 +509,7 @@ take_casualties_from_lands(struct sctstr *sp, int cas,
        lp->lnd_mobil -= deq * eff_per_cas / 2;
        lnd_submil(lp, deq);
        if (lp->lnd_effic < LAND_MINEFF) {
-           CANT_HAPPEN(!may_kill);
+           CANT_HAPPEN(each >= 0);
            taken += lp->lnd_item[I_MILIT];
            lnd_dies_fighting_che(lp);
        }
index c55fb6d..7602495 100644 (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
 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
-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
-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
 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
@@ -463,10 +463,10 @@ timestamp owner type id x y
 0 4 3 21 -14 -8
 0 4 3 22 -14 -8
 0 4 3 23 -14 -8
+0 4 3 27 -12 -8
 0 4 0 0 -12 -8
 0 4 3 25 -12 -8
 0 4 3 26 -12 -8
-0 4 3 27 -12 -8
 0 4 3 28 -8 -8
 0 4 0 0 -16 -6
 0 4 0 0 -8 -6
index 5e5d9a9..d651b6a 100644 (file)
     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 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 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   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 Guerrilla warfare in -10,-8
     Play#0 output Play#0 1   body count: troops: 10, rebels: 5
index fad6b91..ced92ee 100644 (file)
@@ -39,8 +39,6 @@ tester@127.0.0.1 logged in as country #0
 Triggering unscheduled update
 production update (60 ETUs)
 preparing sectors...
-Oops: taken < mc in ../src/lib/update/revolt.c:471
-Crash dump complete
 done preparing sectors.
 producing for countries...
 done producing for countries.