diff options
author | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-01-06 08:53:11 +0000 |
---|---|---|
committer | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-01-06 08:53:11 +0000 |
commit | f739b7d8bb5d57d55a69b93c24bf88dc3299ab21 (patch) | |
tree | 4c9c931623e56d11c72fa5e2d6a806fa8aa44bc2 | |
parent | 1b3ea6aedea0afd31cc4ee29d26468fc45733a28 (diff) | |
download | crawl-ref-f739b7d8bb5d57d55a69b93c24bf88dc3299ab21.tar.gz crawl-ref-f739b7d8bb5d57d55a69b93c24bf88dc3299ab21.zip |
Slightly improved handling of ties and suicidal giant spores, plus more sanity
checking.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8267 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r-- | crawl-ref/source/arena.cc | 130 |
1 files changed, 113 insertions, 17 deletions
diff --git a/crawl-ref/source/arena.cc b/crawl-ref/source/arena.cc index 2650510515..cfbd012772 100644 --- a/crawl-ref/source/arena.cc +++ b/crawl-ref/source/arena.cc @@ -37,17 +37,17 @@ namespace arena mons_list members; bool friendly; int active_members; - bool suicide_attack; + bool won; faction(bool fr) : members(), friendly(fr), active_members(0), - suicide_attack(false) { } + won(false) { } void place_at(const coord_def &pos); void reset() { active_members = 0; - suicide_attack = false; + won = false; } void clear() @@ -465,6 +465,20 @@ namespace arena int orig_a = faction_a.active_members; int orig_b = faction_b.active_members; + if (orig_a < 0) + { + mpr("Book-keeping says faction_a has negative active members.", + MSGCH_ERROR); + more(); + } + + if (orig_b < 0) + { + mpr("Book-keeping says faction_b has negative active members.", + MSGCH_ERROR); + more(); + } + faction_a.active_members = 0; faction_b.active_members = 0; @@ -485,16 +499,40 @@ namespace arena { mpr("Book-keeping error in faction member count.", MSGCH_ERROR); more(); + + if (faction_a.active_members > 0 + && faction_b.active_members <= 0) + { + faction_a.won = true; + faction_b.won = false; + } + else if (faction_b.active_members > 0 + && faction_a.active_members <= 0) + { + faction_b.won = true; + faction_a.won = false; + } } - } + } // count_foes() // Returns true as long as at least one member of each faction is alive. bool fight_is_on() { if (faction_a.active_members > 0 && faction_b.active_members > 0) + { + if (faction_a.won || faction_b.won) + { + mpr("Both factions alive but one delcared the winner.", + MSGCH_ERROR); + more(); + faction_a.won = false; + faction_b.won = false; + } return true; + } - // Sync up our book-keeping with the actual state. + // Sync up our book-keeping with the actual state, and report + // any inconsistencies. count_foes(); return (faction_a.active_members > 0 && faction_b.active_members > 0); @@ -572,6 +610,7 @@ namespace arena mesclr(true); { cursor_control coff(false); + int turns = 0; while (fight_is_on()) { if (kbhit()) @@ -586,6 +625,10 @@ namespace arena } } + // Check the consistency of our book-keeping every 100 turns. + if ((turns++ % 100) == 0) + count_foes(); + viewwindow(true, false); unwind_var<coord_def> pos(you.position); // Move hero offscreen. @@ -607,19 +650,58 @@ namespace arena trials_done++; - bool team_a_won = false; - bool was_tied = false; - if (faction_a.active_members > 0 || faction_a.suicide_attack) + // We bother with all this to properly deal ties, and with ball + // lightning or giant spores winning the fight via suicide. + // The sanity checking is probably just paranoia. + bool was_tied = false; + if (!faction_a.won && !faction_b.won) { - team_a_wins++; - team_a_won = true; + if (faction_a.active_members > 0) + { + mpr("Tie declared, but faction_a won.", MSGCH_ERROR); + more(); + team_a_wins++; + faction_a.won = true; + } + else if (faction_b.active_members > 0) + { + mpr("Tie declared, but faction_b won.", MSGCH_ERROR); + more(); + faction_b.won = true; + } + else + { + ties++; + was_tied = true; + } } - else if (faction_a.active_members == faction_b.active_members - && !faction_b.suicide_attack) + else if (faction_a.won && faction_b.won) { - ties++; - was_tied = true; + faction_a.won = false; + faction_b.won = false; + + mpr("*BOTH* factions won?!", MSGCH_ERROR); + if (faction_a.active_members > 0) + { + mpr("Faction_a real winner.", MSGCH_ERROR); + team_a_wins++; + faction_a.won = true; + } + else if (faction_b.active_members > 0) + { + mpr("Faction_b real winner.", MSGCH_ERROR); + faction_b.won = true; + } + else + { + mpr("Both sides dead.", MSGCH_ERROR); + ties++; + was_tied = true; + } + more(); } + else if (faction_a.won) + team_a_wins++; show_fight_banner(true); @@ -636,7 +718,8 @@ namespace arena mprf(msg.c_str()); else mprf(msg.c_str(), - team_a_won ? faction_a.desc.c_str() : faction_b.desc.c_str()); + faction_a.won ? faction_a.desc.c_str() + : faction_b.desc.c_str()); dump_messages(); } @@ -856,6 +939,19 @@ void arena_monster_died(monsters *monster, killer_type killer, else if (monster->attitude == ATT_HOSTILE) arena::faction_b.active_members--; + if (arena::faction_a.active_members > 0 + && arena::faction_b.active_members <= 0) + { + arena::faction_a.won = true; + return; + } + else if (arena::faction_b.active_members > 0 + && arena::faction_a.active_members <= 0) + { + arena::faction_b.won = true; + return; + } + // Was the death caused by the suicide attack of a gas spore or // ball lightning which was the final member of its faction? if (arena::faction_a.active_members <= 0 @@ -868,9 +964,9 @@ void arena_monster_died(monsters *monster, killer_type killer, if (monster->attitude != atk->attitude && mons_self_destructs(atk)) { if (atk->attitude == ATT_FRIENDLY) - arena::faction_a.suicide_attack = true; + arena::faction_a.won = true; else if (atk->attitude == ATT_HOSTILE) - arena::faction_b.suicide_attack = true; + arena::faction_b.won = true; } } } |