From 849af9e06c6863ace80b78fed654f1a57a63d3b3 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sat, 17 Sep 2016 11:24:55 +0200 Subject: [PATCH] update/revolt: Change security unit bonus to fix body count Both ordinary ground combat and guerrilla combat basically kill combatants one by one randomly until one side is eliminated. The odds of each side taking a hit are computed from combat strengths. Ordinary combat factors bonuses into the odds. It doesn't mess with the number of men. Guerrilla combat does the same for the bonus due to relative happiness. It doesn't for land units with security capability: these fight as if they had twice as many military. Changes both odds and number of men. This inflates the body count reported to the sector owner. Visible in tests/update/journal.log, where rebels kill 110 out of 70 military. It also complicates take_casualties(). Has been that way since security land units were added in Chainsaw 3. To fix the body count and simplify take_casualties(), make capability security affect only the odds, not the number of men. Without further adjustments, this would reduce guerrilla losses: fewer men mean fewer combat rounds mean fewer chances for rebels to die. To compensate, increase the multiplier from two to four. This should make security units a bit tougher. Document the bonus in "info Guerrilla". More body count bugs remain. Reusing ordinary combat rules and code for guerrilla combat would be nice, but isn't feasible for me right now. Signed-off-by: Markus Armbruster --- info/Guerrilla.t | 5 +++-- src/lib/update/revolt.c | 20 ++++++++++---------- tests/update/99-POGO | 1 - tests/update/final.xdump | 4 ++-- tests/update/journal.log | 6 +++--- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/info/Guerrilla.t b/info/Guerrilla.t index 6be87135..05639bf0 100644 --- a/info/Guerrilla.t +++ b/info/Guerrilla.t @@ -66,7 +66,8 @@ or a sector lost to guerrilla activities! .s1 Land units present in a sector help to fight them, fighting without any multiplier, either offensive or defensive and without any -fortification bonus. Any units with the -\*Qsecurity\*U ability will also kill some che before anything else is +fortification bonus, except units units with the +\*Qsecurity\*U ability fight with a multiplier of four. They +will also kill some che before anything else is done (commando raids). .SA "Populace, Occupation, Updates" diff --git a/src/lib/update/revolt.c b/src/lib/update/revolt.c index 25a24cc3..94680299 100644 --- a/src/lib/update/revolt.c +++ b/src/lib/update/revolt.c @@ -29,7 +29,7 @@ * Known contributors to this file: * Dave Pare, 1986 * Steve McClure, 1997-2000 - * Markus Armbruster, 2004-2012 + * Markus Armbruster, 2004-2016 */ #include @@ -131,6 +131,7 @@ guerrilla(struct sctstr *sp) int ratio; int che; int mil; + int security_bonus; int cc, mc; double odds; int civ; @@ -160,6 +161,7 @@ guerrilla(struct sctstr *sp) actor = sp->sct_oldown; che = sp->sct_che; mil = sp->sct_item[I_MILIT]; + security_bonus = 0; snxtitem_xy(&ni, EF_LAND, sp->sct_x, sp->sct_y); @@ -179,7 +181,7 @@ guerrilla(struct sctstr *sp) if (lchr[(int)lp->lnd_type].l_flags & L_SECURITY) { int che_kill, r; - mil += lp->lnd_item[I_MILIT]; + security_bonus += lp->lnd_item[I_MILIT] * 3; r = (lp->lnd_item[I_MILIT] * lp->lnd_effic) / 500; che_kill = r < 1 ? 0 : roll(r); if (che_kill > che) @@ -218,8 +220,8 @@ guerrilla(struct sctstr *sp) goto domove; } - ratio = mil / che; - odds = (double)che / (mil + che); + ratio = (mil + security_bonus) / che; + odds = (double)che / (mil + security_bonus + che); odds /= hap_fact(tnat, getnatp(sp->sct_oldown)); if (mil == 0) { wu(0, sp->sct_own, "Revolutionary subversion reported in %s!\n", @@ -281,7 +283,7 @@ guerrilla(struct sctstr *sp) */ if (chance(ratio * 0.10)) { n = (mil / 5) + 1; - odds = (double)che / (n + che); + odds = (double)che / (n + security_bonus / 5 + che); odds /= hap_fact(tnat, getnatp(sp->sct_oldown)); while (che > 0 && n > 0) { if (chance(odds)) { @@ -447,8 +449,6 @@ take_casualties(struct sctstr *sp, int mc) if (lp->lnd_ship >= 0) continue; nunits++; - if (lchr[(int)lp->lnd_type].l_flags & L_SECURITY) - nunits++; } if (nunits == 0) @@ -470,10 +470,10 @@ take_casualties(struct sctstr *sp, int mc) if (cantake >= each) { deq = ((double)each / lp->lnd_item[I_MILIT]) * 100.0; - mc -= 2 * each; + mc -= each; } else if (cantake > 0) { deq = ((double)cantake / lp->lnd_item[I_MILIT]) * 100.0; - mc -= 2 * cantake; + mc -= cantake; } else deq = 0; @@ -542,7 +542,7 @@ take_casualties(struct sctstr *sp, int mc) if (!(lchr[(int)lp->lnd_type].l_flags & L_SECURITY)) continue; - mc -= (lp->lnd_effic / 100.0) * lp->lnd_item[I_MILIT] * 2.0; + mc -= (lp->lnd_effic / 100.0) * lp->lnd_item[I_MILIT]; lnd_dies_fighting_che(lp); if (mc <= 0) return; diff --git a/tests/update/99-POGO b/tests/update/99-POGO index 693708e1..d39009b8 100644 --- a/tests/update/99-POGO +++ b/tests/update/99-POGO @@ -179,7 +179,6 @@ land 0:31,-16:-1 | BUG: empty inf#21 dies fighting guerrillas | -12,-8 sec#25 raids, #27 doesn't, che win, kill sec#25/27/inf#26, | BUG: spy#24 dies fighting guerrillas -| BUG: body count off, claims 110m, actually 70m | BUG: "Sector -12,-8 has been retaken!" instead of takeover | -10,-8 che win, don't take over | -8,-8 che lose diff --git a/tests/update/final.xdump b/tests/update/final.xdump index a0f44249..69bc5d0f 100644 --- a/tests/update/final.xdump +++ b/tests/update/final.xdump @@ -157,7 +157,7 @@ owner xloc yloc des effic mobil off loyal terr0 terr1 terr2 terr3 dterr xdist yd 3 14 -8 4 9 120 0 112 0 0 0 0 0 14 -8 9 0 34 1 4 0 0 0 0 0 3 130 0 0 0 0 0 0 0 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 5 -16 -8 4 0 120 0 0 0 0 0 0 0 -16 -8 0 0 100 1 4 0 0 0 0 0 5 124 5 0 0 0 0 0 0 96 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 5 -14 -8 29 100 120 0 0 0 0 0 0 0 -14 -8 0 0 100 1 29 0 0 0 0 0 5 124 5 0 0 0 0 20 100 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 -4 -12 -8 4 37 120 0 35 0 0 0 0 0 -12 -8 38 0 100 1 4 0 0 0 0 0 0 123 5 0 0 0 0 0 0 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 +4 -12 -8 4 37 120 0 35 0 0 0 0 0 -12 -8 38 0 100 1 4 0 0 0 0 0 0 123 5 0 0 0 0 0 0 96 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 4 -10 -8 4 39 120 0 0 0 0 0 0 0 -10 -8 39 0 100 1 4 0 0 0 0 0 4 130 0 0 0 0 0 0 0 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 15 4 0 0 0 0 0 4 -8 -8 4 39 120 0 46 0 0 0 0 0 -8 -8 39 0 100 1 4 0 0 0 0 0 2 130 0 0 0 0 0 0 0 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 4 -6 -8 4 39 120 0 51 0 0 0 0 0 -6 -8 39 0 100 1 4 0 0 0 0 0 2 130 0 0 0 0 0 0 0 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 @@ -172,7 +172,7 @@ owner xloc yloc des effic mobil off loyal terr0 terr1 terr2 terr3 dterr xdist yd 3 13 -7 4 11 120 0 112 0 0 0 0 0 13 -7 12 0 38 0 4 0 0 0 0 0 3 130 0 0 0 0 0 0 0 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 3 15 -7 4 14 120 0 112 0 0 0 0 0 15 -7 14 0 57 1 4 0 0 0 0 0 3 130 0 0 0 0 0 0 0 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 4 -15 -7 4 41 120 0 0 0 0 0 0 0 -15 -7 41 0 100 1 4 0 0 0 0 0 4 130 20 0 0 0 0 0 0 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 -4 -13 -7 4 39 120 0 0 0 0 0 0 0 -13 -7 39 0 100 0 4 0 0 0 0 0 4 130 0 0 0 0 0 0 0 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 133 4 0 0 0 0 0 +4 -13 -7 4 39 120 0 0 0 0 0 0 0 -13 -7 39 0 100 0 4 0 0 0 0 0 4 130 0 0 0 0 0 0 0 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 116 4 0 0 0 0 0 4 -11 -7 4 41 120 0 0 0 0 0 0 0 -11 -7 42 0 100 0 4 0 0 0 0 0 4 130 20 0 0 0 0 0 0 96 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 4 -9 -7 4 39 120 0 0 0 0 0 0 0 -9 -7 39 0 100 0 4 0 0 0 0 0 4 130 0 0 0 0 0 0 0 97 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 4 -7 -7 4 39 120 0 0 0 0 0 0 0 -7 -7 39 0 100 0 4 0 0 0 0 0 4 130 0 0 0 0 0 0 0 96 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 0 0 0 0 0 0 diff --git a/tests/update/journal.log b/tests/update/journal.log index 5ba5cb9a..376a0a11 100644 --- a/tests/update/journal.log +++ b/tests/update/journal.log @@ -1370,7 +1370,7 @@ Play#0 output Play#0 1 sec security #27 dies fighting guerrillas in -12,-8 Play#0 output Play#0 1 Sector -12,-8 has been retaken! Play#0 output Play#0 1 Guerrilla warfare in -12,-8 - Play#0 output Play#0 1 body count: troops: 110, rebels: 71 + Play#0 output Play#0 1 body count: troops: 70, rebels: 88 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 Guerrilla warfare in -8,-8 @@ -1439,7 +1439,7 @@ Play#0 output Play#0 1 own sect eff prd mob uf uf old civ mil uw food work avail fall coa Play#0 output Play#0 1 5 -16,-8 - 0% 120 .. .. 124 5 0 96 100% 0 0 1 Play#0 output Play#0 1 5 -14,-8 b 100% 120 .. .. 124 5 0 97 100% 0 0 1 - Play#0 output Play#0 1 4 -12,-8 - 37% 120 .. .. 0 123 5 0 97 100% 38 0 1 + Play#0 output Play#0 1 4 -12,-8 - 37% 120 .. .. 0 123 5 0 96 100% 38 0 1 Play#0 output Play#0 1 4 -10,-8 - 39% 120 .. .. 130 0 0 97 100% 39 0 1 Play#0 output Play#0 1 4 -8,-8 - 39% 120 .. .. 2 130 0 0 97 100% 39 0 1 Play#0 output Play#0 1 4 -6,-8 - 39% 120 .. .. 2 130 0 0 97 100% 39 0 1 @@ -1588,7 +1588,7 @@ Play#0 output Play#0 1 4 -4,-8 - 39% 0 0 0 0 0 0 Play#0 output Play#0 1 4 -2,-8 - 39% 0 0 0 0 0 0 Play#0 output Play#0 1 4 -15,-7 - 41% 0 0 0 0 0 0 - Play#0 output Play#0 1 4 -13,-7 - 39% 0 4 133 0 0 0 + Play#0 output Play#0 1 4 -13,-7 - 39% 0 4 116 0 0 0 Play#0 output Play#0 1 4 -11,-7 - 41% 0 0 0 0 0 0 Play#0 output Play#0 1 4 -9,-7 - 39% 0 0 0 0 0 0 Play#0 output Play#0 1 4 -7,-7 - 39% 0 0 0 0 0 0