git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9129 c06c8d41-db1a-0410-9941-cceddc491573
OUE4UGFN52K2EW3TMBP27S7VK3323S24J4UXFGO62U5ZLKKOPVEAC
MAEPZUVYTJBTKUCU6XMAJK5FXQLO5WBXIOUTGTQ5ZDRNALQAFHWAC
NQ5X2L66MPWZTR3ANZDBQ5ISPDTJ3AGEYTFQIS437S7MOTXN7A2AC
RLWG3QYUGEXTUSIAHTNCBPUA5VJX43HJPSJR7ARLXXHKYTGD2IQQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
URFOQPK5U6ANCKMHK2R2BYIITZZESHYUNBAEI3WNJCYO7Q66WHNQC
LJK4ZQATLSB4MKZG3ARZX5V6RFGTN3NLCN6GTCUGJQKU26SOXMUAC
QKV56RZTWOX64VLWW52R2DEUM3HGGZNLRAJ2ZV2BHW5K422OPNJQC
FSD7GIK3YLZXWLEH37BU6KV3IUCFGXPQL6IZ7H65YWNRBEKDBX5AC
KAOE5HB3THUKVGFZRO5EZESHEB3Q34WUO5DFMLWIKOBF47LZTIYAC
NNG27Y5ZQAZX6UD7F7M4F6KEZBEDFXPEEC3LFUSX4ESKT7K6UJQAC
TGJZXTUIAKCFZQJ54ZQEBGFBVZSJCAX6AWDRSH3TP7UJRLGUM5SAC
WUWTYSQ2Z7HI637WNO2J55LW6WLPBDF2ILH622T47ICW3AN7OWMQC
ISSEUTHG7EH3QTFLS23GXFIOQXCI5HJPJMK6GWNFMC6NDRD2H34QC
SIDH2P7NBIG5KEOE27XHD3ZT2NQ2OJZFN6VZXWNWYFFY5YVXSSVQC
REOC4SN5SYUZ6IDLV6I6XZ4MPKE36VAJXLCZ2SXYYZB3RECLXSLQC
U6UUTZZVZHQVN3HWPN2CLRNE4VXESLNHS75W4CYUZIAKVHCYRCDQC
542UIZKI65UDRNEMGFFDBWYD5XC7AYLTZ3JZQRR2GHYJALD3YY6QC
ZUV76RGZDBOY745YXVMGFUOWEH2B47J74BCT5MDKHIDHC4URGMKAC
LTX72QGIPNUGWQN5ULPOMFCOPZTK7472DQY4AYX5WM3WHSUVXI5QC
IBCGW7GAP7MBB4EQ5Q6B6GAOUIYG3O7NLU2LCK37E7ZSDMTAAYZQC
OSGS3PH2L5CBTDVZCZS6OCFQNA4A7RMEXBYJQB7DDZBYYJW7QSSAC
// Uses, and updates the global variable mmov.
static void _find_good_alternate_move(monsters *monster,
const FixedArray<bool, 3, 3>& good_move)
{
const int current_distance = distance(monster->pos(), monster->target);
int dir = -1;
for (int i = 0; i < 8; i++)
{
if (mon_compass[i] == mmov)
{
dir = i;
break;
}
}
// Only handle if the original move is to an adjacent square.
if (dir == -1)
return;
int dist[2];
// First 1 away, then 2 (3 is silly).
for (int j = 1; j <= 2; j++)
{
const int FAR_AWAY = 1000000;
// Try both directions (but randomize which one is first.)
const int sdir = coinflip() ? j : -j;
const int inc = -2 * j;
for (int mod = sdir, i = 0; i < 2; mod += inc, i++)
{
int newdir = (dir + 8 + mod) % 8;
if (good_move[mon_compass[newdir].x+1][mon_compass[newdir].y+1])
{
dist[i] = distance(monster->pos()+mon_compass[newdir],
monster->target);
}
else
{
dist[i] = (mons_is_fleeing(monster)) ? (-FAR_AWAY)
: FAR_AWAY;
}
}
// Now choose.
if (dist[0] == dist[1] && abs(dist[0]) == FAR_AWAY)
continue;
// Which one was better? -- depends on FLEEING or not.
if (mons_is_fleeing(monster))
{
if (dist[0] >= dist[1] && dist[0] >= current_distance)
{
mmov = mon_compass[((dir+8)+sdir)%8];
break;
}
if (dist[1] >= dist[0] && dist[1] >= current_distance)
{
mmov = mon_compass[((dir+8)-sdir)%8];
break;
}
}
else
{
if (dist[0] <= dist[1] && dist[0] <= current_distance)
{
mmov = mon_compass[((dir+8)+sdir)%8];
break;
}
if (dist[1] <= dist[0] && dist[1] <= current_distance)
{
mmov = mon_compass[((dir+8)-sdir)%8];
break;
}
}
}
}
{
int current_distance = distance(monster->pos(), monster->target);
int dir = -1;
for (int i = 0; i < 8; i++)
{
if (mon_compass[i] == mmov)
{
dir = i;
break;
}
}
if (dir < 0)
goto forget_it;
int dist[2];
// First 1 away, then 2 (3 is silly).
for (int j = 1; j <= 2; j++)
{
int sdir, inc;
if (coinflip())
{
sdir = -j;
inc = 2*j;
}
else
{
sdir = j;
inc = -2*j;
}
// Try both directions.
for (int mod = sdir, i = 0; i < 2; mod += inc, i++)
{
int newdir = (dir + 8 + mod) % 8;
if (good_move[mon_compass[newdir].x+1][mon_compass[newdir].y+1])
{
dist[i] = distance(monster->pos()+mon_compass[newdir],
monster->target);
}
else
{
dist[i] = (mons_is_fleeing(monster)) ? (-FAR_AWAY)
: FAR_AWAY;
}
}
// Now choose.
if (dist[0] == dist[1] && abs(dist[0]) == FAR_AWAY)
continue;
// Which one was better? -- depends on FLEEING or not.
if (mons_is_fleeing(monster))
{
if (dist[0] >= dist[1] && dist[0] >= current_distance)
{
mmov = mon_compass[((dir+8)+sdir)%8];
break;
}
if (dist[1] >= dist[0] && dist[1] >= current_distance)
{
mmov = mon_compass[((dir+8)-sdir)%8];
break;
}
}
else
{
if (dist[0] <= dist[1] && dist[0] <= current_distance)
{
mmov = mon_compass[((dir+8)+sdir)%8];
break;
}
if (dist[1] <= dist[0] && dist[1] <= current_distance)
{
mmov = mon_compass[((dir+8)-sdir)%8];
break;
}
}
}
} // end - try to find good alternate move
_find_good_alternate_move(monster, good_move);