From 11625c077288bd5dcbfa765633a5398976458ad9 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Sat, 12 Nov 2016 01:24:03 +0000 Subject: [PATCH 1/2] Make free actions easier to predict, nonfree actions more predictable This fixes melee kiting more comprehensively (it now doesn't work against slower monsters either), and prevents you doing things like opening up a gap when running from an imp (you couldn't do that in 3.4.3). --- src/allmain.c | 13 ++++++------- src/mon.c | 30 +++++++++++++++++------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/allmain.c b/src/allmain.c index de1fb1557..1ca917a74 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -132,14 +132,13 @@ boolean resuming; moveamt = youmonst.data->mmove; if (Very_fast) { /* speed boots or potion */ - /* average movement is 1.67 times normal */ - moveamt += NORMAL_SPEED / 2; - if (rn2(3) == 0) - moveamt += NORMAL_SPEED / 2; - } else if (Fast) { - /* average movement is 1.33 times normal */ + /* gain a free action on 2/3 of turns */ if (rn2(3) != 0) - moveamt += NORMAL_SPEED / 2; + moveamt += NORMAL_SPEED; + } else if (Fast) { + /* gain a free action on 1/3 of turns */ + if (rn2(3) == 0) + moveamt += NORMAL_SPEED; } } diff --git a/src/mon.c b/src/mon.c index 35966e381..f387655e7 100644 --- a/src/mon.c +++ b/src/mon.c @@ -582,6 +582,7 @@ mcalcmove(mon) struct monst *mon; { int mmove = mon->data->mmove; + int mmove_adj; /* Note: MSLOW's `+ 1' prevents slowed speed 1 getting reduced to 0; * MFAST's `+ 2' prevents hasted speed 1 from becoming a no-op; @@ -592,21 +593,24 @@ struct monst *mon; else if (mon->mspeed == MFAST) mmove = (4 * mmove + 2) / 3; - if (mon == u.usteed) { - if (u.ugallop && context.mv) { - /* average movement is 1.50 times normal */ - mmove = ((rn2(2) ? 4 : 5) * mmove) / 3; - } - } else if (mmove) { - /* vary movement points allocated to slightly reduce predictability; - random increment (avg +2) exceeds random decrement (avg +1) by - a small amount; normal speed monsters will occasionally get an - extra move and slow ones won't be quite as slow */ - mmove += rn2(5) - rn2(3); /* + 0..4 - 0..2, average net +1 */ - if (mmove < 1) - mmove = 1; + if (mon == u.usteed && u.ugallop && context.mv) { + /* increase movement by a factor of 1.5; also increase variance of + movement speed (if it's naturally 24, we don't want it to always + become 36) */ + mmove = ((rn2(2) ? 4 : 5) * mmove) / 3; } + /* Randomly round the monster's speed to a multiple of NORMAL_SPEED. This + makes it impossible for the player to predict when they'll get a free + turn (thus preventing exploits like "melee kiting"), while retaining + guarantees about shopkeepers not being outsped by a normal-speed player, + normal-speed players being unable to open up a gap when fleeing a + normal-speed monster, etc.*/ + mmove_adj = mmove % NORMAL_SPEED; + mmove -= mmove_adj; + if (rn2(NORMAL_SPEED) < mmove_adj) + mmove += NORMAL_SPEED; + return mmove; } From ec2beee61fd9b3ebd53895f3d8b69922f7a306ba Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Sat, 12 Nov 2016 01:28:47 +0000 Subject: [PATCH 2/2] Changelog for movement speed changes --- doc/fixes36.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 30731b652..90e77dc6a 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -355,6 +355,8 @@ wielding Trollsbane prevents trolls from reviving wielding Demonbane prevents demons summoning friends Elbereth must now be on a square by itself to function Elbereth now erodes based on attacks by the player, not monsters scared +movement speeds are made less predictable by using random rounding, rather + than via adding a random offset Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository