isn't very sophisticated, especially if there's friendly monsters between the worm and the nearest wall, but it's a srart.
Added rock worms to the Lair and the Dungeon with the same depth and rarity as trapdoor spiders.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7721 c06c8d41-db1a-0410-9941-cceddc491573
BR42OZ3CHR5F5MKPBUOPRG3EXIEQRRRWD5L54BTZQRDXV6VBLATQC
ZJMTMMZBCXHCPFHBTI2PL3Q4XTJQUWMMHCCG6JDIEDMJYCC33TFQC
3HGELZU7NELOQ635HZO6IJIYLBSNCJ5VPH46IE22KA3OSLEFK7AQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
LP5MU6UP3OYGF6NFKN25QOQI7WDXZYGX5CHW37VN4L37BT65REFAC
HFZQADL3R7ITWM3VPW5G3NCB2AHRMAMKYZOI3STW5LWUCTV4FFFQC
P5TRGRH7XMQSPCZKM5IEEO34TY6WMLGHHX7BU6Y453JFRXLUR2VQC
AS2IQQJNNCEQNXXKTGYHLB7RO3ZKCF4F7GK6FJH66BOOKDDRGNIQC
OPNCHI4UGN7WBIYPAXVV2C4N22ZSWROA435FJCY5UZVXKWRYQ42QC
IO5CHPT4QBYSFAPSZGGJAYMN33RDAQKGLVW6OKK25HVIEEQEI4IQC
OMTU7OMVWDVAGJCQGQJDZ3YU252T6IM2LPS2ZMPWB7MIXCJK62AQC
IBCGW7GAP7MBB4EQ5Q6B6GAOUIYG3O7NLU2LCK37E7ZSDMTAAYZQC
PSCYVKJ7DGXAL3V5U4O6AJTRV6Q3N3SHQWAZ73VIPRTE4W64F2XAC
LHYTGOCNDWX3CVD2HSQ6LAYC6NLKKI6ZKKNWZ5IQWP6YP5PQEVWQC
SPWOUV6ZNHLBSAX455ACJDBEJYVFHGO4H76L4NPAE5DF6BEAK34QC
static bool _find_wall_target(monsters *mon)
{
ASSERT(mons_wall_shielded(mon));
if (mon->travel_target == MTRAV_WALL)
{
coord_def targ_pos(mon->travel_path[mon->travel_path.size() - 1]);
// Target grid might have changed since we started, like if the
// player destroys the wall the monster wants to hide in.
if (grid_is_solid(targ_pos)
&& monster_habitable_grid(mon, grd(targ_pos)))
{
// Wall is still good.
#ifdef DEBUG_PATHFIND
mprf("%s target is (%d, %d), dist = %d",
mon->name(DESC_PLAIN, true).c_str(),
targ_pos.x, targ_pos.y, (int) (mon->pos() - targ_pos).rdist());
#endif
return (true);
}
mon->travel_path.clear();
mon->travel_target = MTRAV_NONE;
}
monster_los lm;
lm.set_monster(mon);
lm.set_los_range(LOS_RADIUS);
lm.fill_los_field();
int best_dist = INT_MAX;
bool best_closer_to_player = false;
coord_def best_target;
for (radius_iterator ri(mon->pos(), LOS_RADIUS, true, false);
ri; ++ri)
{
if (!grid_is_solid(*ri)
|| monster_habitable_grid(mon, grd(*ri)))
{
continue;
}
int dist = (mon->pos() - *ri).rdist();
bool closer_to_player = false;
if (dist > (you.pos() - *ri).rdist())
closer_to_player = true;
if (dist < best_dist)
{
best_dist = dist;
best_closer_to_player = closer_to_player;
best_target = *ri;
}
else if (best_closer_to_player && !closer_to_player
&& dist == best_dist)
{
best_closer_to_player = false;
best_target = *ri;
}
}
if (best_dist == INT_MAX || !in_bounds(best_target))
return (false);
monster_pathfind mp;
#ifdef WIZARD
// Remove old highlighted areas to make place for the new ones.
for (rectangle_iterator ri(1); ri; ++ri)
env.map(*ri).property &= ~(FPROP_HIGHLIGHT);
#endif
if (mp.init_pathfind(mon, best_target))
{
mon->travel_path = mp.calc_waypoints();
if (!mon->travel_path.empty())
{
#ifdef WIZARD
for (unsigned int i = 0; i < mon->travel_path.size(); i++)
env.map(mon->travel_path[i]).property |= FPROP_HIGHLIGHT;
#endif
#ifdef DEBUG_PATHFIND
mprf("Found a path to (%d, %d)", best_target.x, best_target.y);
#endif
// Okay then, we found a path. Let's use it!
mon->target = mon->travel_path[0];
mon->travel_target = MTRAV_WALL;
return (true);
}
}
return (false);
}
// XXX: If a monster can move through solid grids, then it
// should preferentially flee towards the nearest solid grid
// it can move through. It will be (mostly) safe as soon as
// it enters the wall, and even if it isn't, once it moves
// again it will be on the other side of the wall and likely
// beyond the reach of the player.