summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorCharles Otto <ottochar@gmail.com>2009-10-25 19:41:44 -0400
committerCharles Otto <ottochar@gmail.com>2009-10-30 20:31:29 -0400
commitc7d2e28d1714aea898a0ab394bd3cce8cde29e01 (patch)
tree2a8d967ccd143e545d968ef8a74c9424893f21a9 /crawl-ref
parentd0f35e86de825119d5fa255f6075a55a89f2f20b (diff)
downloadcrawl-ref-c7d2e28d1714aea898a0ab394bd3cce8cde29e01.tar.gz
crawl-ref-c7d2e28d1714aea898a0ab394bd3cce8cde29e01.zip
Various slime creature improvements
Make splitting while out of sight actually work When merging average enchantment durations for the two slimes When splitting add the parents ench durations to the offspring slime Better messaging for merging/splitting Cap the merge count to 5, use size adjectives instead of numbers for the combiend slime creature names. Don't group different size slime creatures together in the monster list
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/mon-util.cc15
-rw-r--r--crawl-ref/source/monstuff.cc8
-rw-r--r--crawl-ref/source/mstuff2.cc111
3 files changed, 111 insertions, 23 deletions
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 3e8ab4d865..be90ff2d48 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -2207,17 +2207,12 @@ static std::string _str_monam(const monsters& mon, description_level_type desc,
if(mon.mons_species() == MONS_SLIME_CREATURE && desc != DESC_DBNAME)
{
- if (mon.number < 11)
- {
- const char* cardinals[] = {"one", "two", "three", "four", "five",
- "six", "seven", "eight", "nine", "ten"};
- result += cardinals[mon.number - 1];
- }
- else
- result += make_stringf("%d", mon.number);
-
- result += "-blob ";
+ ASSERT(mon.number <=5);
+ const char* cardinals[] = {"", "large ", "very large ",
+ "enormous ", "titanic "};
+ result += cardinals[mon.number - 1];
}
+
// Done here to cover cases of undead versions of hydras.
if (mons_species(nametype) == MONS_HYDRA
&& mon.number > 0 && desc != DESC_DBNAME)
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 0fce237d74..545ae44016 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -5861,9 +5861,11 @@ static bool _handle_special_ability(monsters *monster, bolt & beem)
? draco_subspecies( monster )
: static_cast<monster_type>( monster->type );
- if (!mons_near(monster)
- || mons_is_sleeping(monster)
- || mons_is_submerged(monster))
+ // Slime creatures can split while out of sight.
+ if ((!mons_near(monster)
+ || mons_is_sleeping(monster)
+ || mons_is_submerged(monster))
+ && monster->mons_species() != MONS_SLIME_CREATURE)
{
return (false);
}
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index 6dcf1f66a3..5770cb940d 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -2588,22 +2588,77 @@ bool ugly_thing_mutate(monsters *ugly, bool proximity)
return (false);
}
+// Inflict any enchantments the parent slime has on its offspring,
+// leaving durations unchanged I guess. -cao
+static void _split_ench_durations(monsters * initial_slime, monsters * split_off)
+{
+ mon_enchant_list::iterator i;
+
+ for( i=initial_slime->enchantments.begin();
+ i!=initial_slime->enchantments.end(); ++i)
+ {
+ split_off->add_ench(i->second);
+ }
+
+}
+
+// What to do about any enchantments these two slimes may have?
+// For now we are averaging the durations -cao
+static void _merge_ench_durations(monsters * initial_slime, monsters * merge_to)
+{
+ mon_enchant_list::iterator i;
+
+ int initial_count = initial_slime->number;
+ int merge_to_count = merge_to->number;
+ int total_count = initial_count + merge_to_count;
+
+ for (i = initial_slime->enchantments.begin();
+ i != initial_slime->enchantments.end(); ++i)
+ {
+ // does the other slime have this enchantment as well?
+ mon_enchant temp = merge_to->get_ench(i->first);
+ // If not use duration 0 for their part of the average.
+ int duration = temp.ench == ENCH_NONE ? 0 : temp.duration;
+
+ i->second.duration = (i->second.duration * initial_count
+ + duration * merge_to_count)/total_count;
+
+ if(!i->second.duration)
+ i->second.duration=1;
+
+ merge_to->add_ench(i->second);
+ }
+
+ for (i = merge_to->enchantments.begin();
+ i != merge_to->enchantments.end(); ++i)
+ {
+ if(initial_slime->enchantments.find(i->first)
+ != initial_slime->enchantments.end()
+ && i->second.duration > 1)
+ {
+ i->second.duration = (merge_to_count * i->second.duration)
+ /total_count;
+
+ merge_to->update_ench(i->second);
+ }
+ }
+}
+
+
// Calculate slime creature Hp and hd based on how many are merged.
static void _stats_from_blob_count(monsters * slime, float hp_per_blob)
{
- int hd_per_blob = 11;
+ monsterentry* entry = get_monster_data(slime->type);
+ int base_hd = entry->hpdice[0];
slime->max_hit_points = int(slime->number * hp_per_blob);
slime->hit_points = slime->max_hit_points;
- slime->hit_dice = slime->number * hd_per_blob;
+ slime->hit_dice = slime->number * base_hd;
}
static bool _split_slime(monsters * thing, coord_def & target)
{
- mprf("Splitting slime at pos %d, %d", thing->pos().x, thing->pos().y);
- mprf("splitting to %d, %d", target.x, target.y);
-
// create a new slime
int slime_idx = create_monster(mgen_data(MONS_SLIME_CREATURE,
thing->behaviour,
@@ -2618,9 +2673,18 @@ static bool _split_slime(monsters * thing, coord_def & target)
monsters * new_slime = &env.mons[slime_idx];
+ // Inflict the new slime with any enchantments on the parent
+ _split_ench_durations(thing, new_slime);
+ new_slime->attitude = thing->attitude;
+
if(!new_slime)
return false;
+ if(you.can_see(thing))
+ {
+ mprf("%s splits.", thing->name(DESC_CAP_A).c_str());
+ }
+
int split_off = thing->number / 2;
float hp_per_blob = thing->max_hit_points / float(thing->number);
@@ -2635,14 +2699,36 @@ static bool _split_slime(monsters * thing, coord_def & target)
static bool _merge_slimes(monsters * initial_slime, monsters * merge_to)
{
- mprf("Merging slimes, inital at %d, %d", initial_slime->pos().x, initial_slime->pos().y);
- mprf("Merging to %d, %d", merge_to->pos().x, merge_to->pos().y);
+ // Combine enchantment durations
+ _merge_ench_durations(initial_slime, merge_to);
merge_to->number += initial_slime->number;
merge_to->max_hit_points += initial_slime->max_hit_points;
merge_to->hit_points += initial_slime->max_hit_points;
merge_to->hit_dice += initial_slime->hit_dice;
+ // Overwrite the state of the slime getting merged into because
+ // it might have been resting or something.
+ merge_to->behaviour = initial_slime->behaviour;
+ merge_to->foe = initial_slime->foe;
+
+ behaviour_event(merge_to, ME_EVAL);
+
+ // Messaging
+ if(you.can_see(merge_to))
+ {
+ if(you.can_see(initial_slime))
+ {
+ mprf("Two slime creatures merge to form %s.",
+ merge_to->name(DESC_NOCAP_A).c_str());
+ }
+ else
+ {
+ mprf("A slime creatures suddenly becomes %s.",
+ merge_to->name(DESC_NOCAP_A).c_str());
+ }
+ }
+
// have to 'kill' the slime doing the merging
monster_die(initial_slime, KILL_MISC, NON_MONSTER, true);
@@ -2651,12 +2737,16 @@ static bool _merge_slimes(monsters * initial_slime, monsters * merge_to)
bool slime_split_merge(monsters * thing)
{
+ // No merging/splitting shapeshifters
+ if(mons_is_shapeshifter(thing))
+ return false;
+
int compass_idx[8] = {0, 1, 2, 3, 4, 5, 6 ,7};
std::random_shuffle(compass_idx, compass_idx+8);
coord_def origin = thing->pos();
- int max_slime_merge = 8;
+ int max_slime_merge = 5;
// We can split if in an 'inactive' state (wandering or sleeping for now)
if (mons_is_sleeping(thing) || mons_is_wandering(thing)
@@ -2694,11 +2784,12 @@ bool slime_split_merge(monsters * thing)
// our current position.
if(other_thing
&& other_thing->mons_species() == MONS_SLIME_CREATURE
- && other_thing->attitude == thing->attitude)
+ && other_thing->attitude == thing->attitude
+ && other_thing->is_summoned() == thing->is_summoned())
{
int new_blob_count = other_thing->number + thing->number;
- if(new_blob_count < max_slime_merge
+ if(new_blob_count <= max_slime_merge
&& grid_distance(thing->target, thing->pos()) >
grid_distance(thing->target, target))
{