From 236984fc0e217264ab98093723fa7f8649cc3cf4 Mon Sep 17 00:00:00 2001 From: Matthew Cline Date: Mon, 2 Nov 2009 23:33:53 -0800 Subject: arena: respawning slime creatures Deal with two respawning slime creatures merging and then splitting. --- crawl-ref/source/arena.cc | 33 ++++++++++++++++++++++++++------- crawl-ref/source/arena.h | 3 +++ crawl-ref/source/mon-abil.cc | 10 +++++++--- 3 files changed, 36 insertions(+), 10 deletions(-) (limited to 'crawl-ref/source') 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 #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); } -- cgit v1.2.3-54-g00ecf