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; }