diff options
author | Matthew Cline <zelgadis@sourceforge.net> | 2009-10-19 22:25:14 -0700 |
---|---|---|
committer | Matthew Cline <zelgadis@sourceforge.net> | 2009-10-19 22:25:14 -0700 |
commit | 01df4fd74ab47950bfb907adf8a68dd783971e83 (patch) | |
tree | 65c70e3f2ffc5d5535521dbd535f4141382f6f3a /crawl-ref/source/arena.cc | |
parent | 5dc279a92195600107c3a0c4d868bddb66c3a232 (diff) | |
download | crawl-ref-01df4fd74ab47950bfb907adf8a68dd783971e83.tar.gz crawl-ref-01df4fd74ab47950bfb907adf8a68dd783971e83.zip |
arena.cc: Try harder to preserve respawners
If there isn't any room to place a respawning monster in, then rather
than letting it vanish, keep it on the list of pending-respawns and hope
that space clears up later. Also, if a side with pending-respawns is
about to loose because it has 0 active members, then *make* room to
place a respawn.
Diffstat (limited to 'crawl-ref/source/arena.cc')
-rw-r--r-- | crawl-ref/source/arena.cc | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/crawl-ref/source/arena.cc b/crawl-ref/source/arena.cc index bb7d007661..b7c7461df8 100644 --- a/crawl-ref/source/arena.cc +++ b/crawl-ref/source/arena.cc @@ -766,8 +766,10 @@ namespace arena void do_respawn(faction &fac) { - for (unsigned int i = 0; i < fac.respawn_list.size(); i++) + for (unsigned int _i = fac.respawn_list.size(); _i > 0; _i--) { + unsigned int i = _i - 1; + coord_def pos = fac.respawn_pos[i]; int spec_idx = fac.respawn_list[i]; mons_spec spec = fac.members.get_monster(spec_idx); @@ -777,11 +779,52 @@ namespace arena int idx = dgn_place_monster(spec, 0, pos, false, true); + if (idx == -1 && fac.active_members == 0 + && mgrd(pos) != NON_MONSTER) + { + // We have no members left, so to prevent the round + // from ending attempt to displace whatever is in + // our position. + int midx = mgrd(pos); + monsters* other = &menv[midx]; + + if (to_respawn[midx] == -1) + { + // The other monster isn't a respawner itself, so + // just get rid of it. + mprf(MSGCH_DIAGNOSTICS, + "Dismissing non-repsawner %s to make room " + "respawner whose side has 0 active members.", + other->name(DESC_PLAIN, true).c_str()); + monster_die(other, KILL_DISMISSED, NON_MONSTER); + } + else + { + // Other monster is a respawner, try to move it. + mprf(MSGCH_DIAGNOSTICS, + "Teleporting respawner %s to make room " + "other respawner whose side has 0 active members.", + other->name(DESC_PLAIN, true).c_str()); + monster_teleport(other, true); + } + + idx = dgn_place_monster(spec, 0, pos, false, true); + } + if (idx != -1) + { + // We succeeded, so remove from list. + fac.respawn_list.erase(fac.respawn_list.begin() + i); + fac.respawn_pos.erase(fac.respawn_pos.begin() + i); + to_respawn[idx] = spec_idx; + } + else + { + // Couldn't respawn, so leave it on the list; hopefully + // space will open up later. + } } - fac.respawn_list.clear(); - fac.respawn_pos.clear(); } void do_fight() @@ -1225,6 +1268,9 @@ void arena_monster_died(monsters *monster, killer_type killer, fac->respawn_pos.push_back(monster->pos()); arena::to_respawn[midx] = -1; + + arena::faction_a.won = false; + arena::faction_b.won = false; } } |