summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Cline <zelgadis@sourceforge.net>2009-11-02 23:33:53 -0800
committerMatthew Cline <zelgadis@sourceforge.net>2009-11-02 23:33:53 -0800
commit236984fc0e217264ab98093723fa7f8649cc3cf4 (patch)
tree307e14216db42718fb6e9baf8783580bb5199bf4
parent27c812572cca68a61a9d0450dabcfb209e3bae7c (diff)
downloadcrawl-ref-236984fc0e217264ab98093723fa7f8649cc3cf4.tar.gz
crawl-ref-236984fc0e217264ab98093723fa7f8649cc3cf4.zip
arena: respawning slime creatures
Deal with two respawning slime creatures merging and then splitting.
-rw-r--r--crawl-ref/source/arena.cc33
-rw-r--r--crawl-ref/source/arena.h3
-rw-r--r--crawl-ref/source/mon-abil.cc10
3 files changed, 36 insertions, 10 deletions
diff --git a/crawl-ref/source/arena.cc b/crawl-ref/source/arena.cc
index f4395c5336..74d29193d1 100644
--- a/crawl-ref/source/arena.cc
+++ b/crawl-ref/source/arena.cc
@@ -1140,8 +1140,8 @@ bool arena_veto_place_monster(const mgen_data &mg, bool first_band_member,
|| arena::banned_glyphs[mons_char(mg.cls)]);
}
-// XXX: We sometimes get a book-keeping error when a slime creature
-// splits.
+// XXX: Still having some trouble with book-keeping if a slime creature
+// is placed via splitting.
void arena_placed_monster(monsters *monster)
{
if (monster->attitude == ATT_FRIENDLY)
@@ -1225,6 +1225,21 @@ void arena_placed_monster(monsters *monster)
}
}
+// Take care of respawning slime creatures merging and then splitting.
+void arena_split_monster(monsters *split_from, monsters *split_to)
+{
+ if (!arena::respawn)
+ return;
+
+ const int from_idx = split_from->mindex();
+ const int member_idx = arena::to_respawn[from_idx];
+
+ if (member_idx == -1)
+ return;
+
+ arena::to_respawn[split_to->mindex()] = member_idx;
+}
+
void arena_monster_died(monsters *monster, killer_type killer,
int killer_index, bool silent, int corpse)
{
@@ -1281,16 +1296,20 @@ void arena_monster_died(monsters *monster, killer_type killer,
if (fac)
{
- fac->respawn_list.push_back(arena::to_respawn[midx]);
+ int member_idx = arena::to_respawn[midx];
+ fac->respawn_list.push_back(member_idx);
fac->respawn_pos.push_back(monster->pos());
- // Un-merge slime when it respawns.
- // XXX: We're still losing slimes here.
- if (monster->type == MONS_SLIME_CREATURE)
+ // Un-merge slime when it respawns, but only if it's
+ // specifically a slime, and not a random monster which
+ // happens to be a slime.
+ if (monster->type == MONS_SLIME_CREATURE
+ && (fac->members.get_monster(member_idx).mid
+ == MONS_SLIME_CREATURE))
{
for (unsigned int i = 1; i < monster->number; i++)
{
- fac->respawn_list.push_back(arena::to_respawn[midx]);
+ fac->respawn_list.push_back(member_idx);
fac->respawn_pos.push_back(monster->pos());
}
}
diff --git a/crawl-ref/source/arena.h b/crawl-ref/source/arena.h
index 039e2bca3c..619767d841 100644
--- a/crawl-ref/source/arena.h
+++ b/crawl-ref/source/arena.h
@@ -23,8 +23,11 @@ bool arena_veto_random_monster(monster_type type);
bool arena_veto_place_monster(const mgen_data &mg, bool first_band_member,
const coord_def& pos);
+
void arena_placed_monster(monsters *monster);
+void arena_split_monster(monsters *split_from, monsters *split_to);
+
void arena_monster_died(monsters *monster, killer_type killer,
int killer_index, bool silent, int corpse);
diff --git a/crawl-ref/source/mon-abil.cc b/crawl-ref/source/mon-abil.cc
index ed8b22d55c..6cd1f2961e 100644
--- a/crawl-ref/source/mon-abil.cc
+++ b/crawl-ref/source/mon-abil.cc
@@ -13,6 +13,7 @@
#include <conio.h>
#endif
+#include "arena.h"
#include "beam.h"
#include "colour.h"
#include "directn.h"
@@ -196,14 +197,14 @@ static bool _do_split(monsters *thing, coord_def & target)
monsters *new_slime = &env.mons[slime_idx];
+ if (!new_slime)
+ return (false);
+
// Inflict the new slime with any enchantments on the parent.
_split_ench_durations(thing, new_slime);
new_slime->attitude = thing->attitude;
new_slime->flags = thing->flags;
- if (!new_slime)
- return (false);
-
if (you.can_see(thing))
mprf("%s splits.", thing->name(DESC_CAP_A).c_str());
@@ -218,6 +219,9 @@ static bool _do_split(monsters *thing, coord_def & target)
_stats_from_blob_count(thing, hp_per_blob);
_stats_from_blob_count(new_slime, hp_per_blob);
+ if (crawl_state.arena)
+ arena_split_monster(thing, new_slime);
+
return (true);
}