summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mon-abil.cc
diff options
context:
space:
mode:
authorCharles Otto <ottochar@gmail.com>2009-11-03 23:59:43 -0500
committerCharles Otto <ottochar@gmail.com>2009-11-04 00:01:01 -0500
commit6953f04ec98630347c5da2ca7f6fec7dbf1e7313 (patch)
tree5687ffc680bb69a51b221c110732f9b3f35f9bf2 /crawl-ref/source/mon-abil.cc
parentdc3b9654d71794bf2264a276e2bd7d6aa472d15c (diff)
downloadcrawl-ref-6953f04ec98630347c5da2ca7f6fec7dbf1e7313.tar.gz
crawl-ref-6953f04ec98630347c5da2ca7f6fec7dbf1e7313.zip
Make slime creatures' merge behavior somewhat less aggressive.
Prevent slime creatures from merging if there is an empty square for them to move on that would reduce the distance to their target.
Diffstat (limited to 'crawl-ref/source/mon-abil.cc')
-rw-r--r--crawl-ref/source/mon-abil.cc47
1 files changed, 34 insertions, 13 deletions
diff --git a/crawl-ref/source/mon-abil.cc b/crawl-ref/source/mon-abil.cc
index 6cd1f2961e..1d85607668 100644
--- a/crawl-ref/source/mon-abil.cc
+++ b/crawl-ref/source/mon-abil.cc
@@ -319,6 +319,11 @@ static bool _disabled_slime(monsters *thing)
// See if there are any appropriate adjacent slime creatures for 'thing'
// to merge with. If so, carry out the merge.
+//
+// A slime creature will merge if there is an adjacent slime, merging
+// onto that slime would reduce the distance to the original slime's
+// target, and there are no empty squares that would also reduce
+// the distance to the target.
static bool _slime_merge(monsters *thing)
{
if (!thing || _disabled_slime(thing) || _unoccupied_slime(thing))
@@ -329,34 +334,50 @@ static bool _slime_merge(monsters *thing)
std::random_shuffle(compass_idx, compass_idx + 8);
coord_def origin = thing->pos();
+ int target_distance = grid_distance(thing->target, thing->pos());
+
+ monsters * merge_target = NULL;
// Check for adjacent slime creatures.
for (int i = 0; i < 8; ++i)
{
coord_def target = origin + Compass[compass_idx[i]];
- monsters *other_thing = monster_at(target);
- // We found an adjacent monster. Is it another slime creature
- // we can consider merging with?
- if (other_thing
+ // If this square won't reduce the distance to our target don't
+ // look for a potential merge, and don't allow this square to
+ // prevent a merge if empty.
+ if(grid_distance(thing->target, target) >= target_distance)
+ continue;
+
+ // Don't merge if there is an open square that reduces distance
+ // to target even if we found a possible slime to merge with.
+ if(!actor_at(target)
+ && mons_class_can_pass(MONS_SLIME_CREATURE, env.grid(target)))
+ return false;
+
+ // Is there a slime creature on this square we can consider
+ // merging with?
+ monsters *other_thing = monster_at(target);
+ if (!merge_target
+ && other_thing
&& other_thing->mons_species() == MONS_SLIME_CREATURE
&& other_thing->attitude == thing->attitude
&& other_thing->is_summoned() == thing->is_summoned()
&& !mons_is_shapeshifter(other_thing)
&& !_disabled_slime(other_thing))
{
- // We can actually merge if doing so won't take us over the
- // merge cap and the 'movement' would bring us closer to our
- // target.
+ // We can potentially merge if doing wouldn't take us over
+ // the merge cap
int new_blob_count = other_thing->number + thing->number;
- if (new_blob_count <= max_slime_merge
- && grid_distance(thing->target, thing->pos()) >
- grid_distance(thing->target, target))
- {
- return (_do_merge(thing, other_thing));
- }
+ if (new_blob_count <= max_slime_merge)
+ merge_target = other_thing;
}
}
+ // We found a merge target and didn't find an open square that
+ // would reduce distance to target, so we can actually merge.
+ if(merge_target)
+ return _do_merge(thing, merge_target);
+
// No adjacent slime creatures we could merge with.
return (false);
}