From eda188d2d5045e9fb02c416261d72a3c31b9cf57 Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Tue, 27 Oct 2009 15:18:53 +0100 Subject: Move monster_pane_info out into mon-info.cc and rename. I plan to use monster_info to get monster data out to the player safely via Lua. --- crawl-ref/source/output.cc | 314 ++------------------------------------------- 1 file changed, 14 insertions(+), 300 deletions(-) (limited to 'crawl-ref/source/output.cc') diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc index 9f43ad1427..520e58760e 100644 --- a/crawl-ref/source/output.cc +++ b/crawl-ref/source/output.cc @@ -34,6 +34,7 @@ #include "message.h" #include "misc.h" #include "monstuff.h" +#include "mon-info.h" #include "mon-util.h" #include "newgame.h" #include "jobs.h" @@ -1081,7 +1082,7 @@ static bool _mons_hostile(const monsters *mon) return (!mons_friendly(mon) && !mons_neutral(mon)); } -static std::string _get_monster_name(const monster_pane_info& m, +static std::string _get_monster_name(const monster_info& m, int count) { std::string desc = ""; @@ -1149,8 +1150,8 @@ bool compare_monsters_attitude( const monsters *m1, const monsters *m2 ) std::string mpr_monster_list(bool past) { // Get monsters via the monster_pane_info, sorted by difficulty. - std::vector mons; - get_monster_pane_info(mons); + std::vector mons; + get_monster_info(mons); std::string msg = ""; if (mons.empty()) @@ -1162,13 +1163,13 @@ std::string mpr_monster_list(bool past) return (msg); } - std::sort(mons.begin(), mons.end(), monster_pane_info::less_than_wrapper); + std::sort(mons.begin(), mons.end(), monster_info::less_than_wrapper); std::vector describe; int count = 0; for (unsigned int i = 0; i < mons.size(); ++i) { - if (i > 0 && monster_pane_info::less_than(mons[i-1], mons[i])) + if (i > 0 && monster_info::less_than(mons[i-1], mons[i])) { describe.push_back(_get_monster_name(mons[i-1], count).c_str()); count = 0; @@ -1191,278 +1192,6 @@ std::string mpr_monster_list(bool past) return (msg); } -monster_pane_info::monster_pane_info(const monsters *m) - : m_mon(m), m_attitude(ATT_HOSTILE), m_difficulty(0), - m_brands(0), m_fullname(true) -{ - // XXX: this doesn't take into account ENCH_NEUTRAL, but that's probably - // a bug for mons_attitude, not this. - // XXX: also, mons_attitude_type should be sorted hostile/neutral/friendly; - // will break saves a little bit though. - m_attitude = mons_attitude(m); - - int mtype = m->type; - if (mtype == MONS_RAKSHASA_FAKE) - mtype = MONS_RAKSHASA; - - // Currently, difficulty is defined as "average hp". - m_difficulty = mons_difficulty(mtype); - - // [ds] XXX: Kill the magic numbers. - if (mons_looks_stabbable(m)) m_brands |= 1; - if (mons_looks_distracted(m)) m_brands |= 2; - if (m->has_ench(ENCH_BERSERK)) m_brands |= 4; -} - -// Needed because gcc 4.3 sort does not like comparison functions that take -// more than 2 arguments. -bool monster_pane_info::less_than_wrapper(const monster_pane_info& m1, - const monster_pane_info& m2) -{ - return monster_pane_info::less_than(m1, m2, true); -} - -// Sort monsters by (in that order): attitude, difficulty, type, brand -bool monster_pane_info::less_than(const monster_pane_info& m1, - const monster_pane_info& m2, bool zombified) -{ - if (m1.m_attitude < m2.m_attitude) - return (true); - else if (m1.m_attitude > m2.m_attitude) - return (false); - - int m1type = m1.m_mon->type; - int m2type = m2.m_mon->type; - - // Don't differentiate real rakshasas from fake ones. - if (m1type == MONS_RAKSHASA_FAKE) - m1type = MONS_RAKSHASA; - if (m2type == MONS_RAKSHASA_FAKE) - m2type = MONS_RAKSHASA; - - // Force plain but different coloured draconians to be treated like the - // same sub-type. - if (!zombified && m1type >= MONS_DRACONIAN - && m1type <= MONS_PALE_DRACONIAN - && m2type >= MONS_DRACONIAN - && m2type <= MONS_PALE_DRACONIAN) - { - return (false); - } - - // By descending difficulty - if (m1.m_difficulty > m2.m_difficulty) - return (true); - else if (m1.m_difficulty < m2.m_difficulty) - return (false); - - // Force mimics of different types to be treated like the same one. - if (mons_is_mimic(m1type) && mons_is_mimic(m2type)) - return (false); - - if (m1type < m2type) - return (true); - else if (m1type > m2type) - return (false); - - // Never distinguish between dancing weapons. - // The above checks guarantee that *both* monsters are of this type. - if (m1type == MONS_DANCING_WEAPON) - return (false); - - if (zombified) - { - // Because of the type checks above, if one of the two is zombified, so - // is the other, and of the same type. - if (mons_is_zombified(m1.m_mon) - && m1.m_mon->base_monster < m2.m_mon->base_monster) - { - return (true); - } - - // Both monsters are hydras or hydra zombies, sort by number of heads. - if (m1.m_mon->has_hydra_multi_attack() - && m1.m_mon->number > m2.m_mon->number) - { - return (true); - } - } - - if (m1.m_fullname && m2.m_fullname || m1type == MONS_PLAYER_GHOST) - return (m1.m_mon->name(DESC_PLAIN) < m1.m_mon->name(DESC_PLAIN)); - -#if 0 // for now, sort brands together. - // By descending brands, so no brands sorts to the end - if (m1.m_brands > m2.m_brands) - return (true); - else if (m1.m_brands < m2.m_brands) - return (false); -#endif - - return (false); -} - -static std::string _verbose_info(const monsters* m) -{ - if (mons_is_caught(m)) - return (" (caught)"); - - if (mons_behaviour_perceptible(m)) - { - if (mons_is_petrified(m)) - return(" (petrified)"); - if (mons_is_paralysed(m)) - return(" (paralysed)"); - if (mons_is_petrifying(m)) - return(" (petrifying)"); - if (mons_is_confused(m)) - return(" (confused)"); - if (mons_is_fleeing(m)) - return(" (fleeing)"); - if (mons_is_sleeping(m)) - { - if (mons_holiness(m) == MH_UNDEAD - || mons_holiness(m) == MH_NONLIVING - || mons_holiness(m) == MH_PLANT) - { - return(" (dormant)"); - } - else - return(" (sleeping)"); - } - if (mons_is_wandering(m) && !mons_is_batty(m) - && !(m->attitude == ATT_STRICT_NEUTRAL)) - { - // Labeling strictly neutral monsters as fellow slimes is more important. - return(" (wandering)"); - } - if (m->foe == MHITNOT && !mons_is_batty(m) && !mons_neutral(m) - && !mons_friendly(m)) - { - return (" (unaware)"); - } - } - - if (m->has_ench(ENCH_STICKY_FLAME)) - return (" (burning)"); - - if (m->has_ench(ENCH_ROT)) - return (" (rotting)"); - - if (m->has_ench(ENCH_INVIS)) - return (" (invisible)"); - - return (""); -} - -void monster_pane_info::to_string(int count, std::string& desc, - int& desc_color) const -{ - std::ostringstream out; - - if (count == 1) - { - if (mons_is_mimic(m_mon->type)) - out << mons_type_name(m_mon->type, DESC_PLAIN); - else - out << m_mon->full_name(DESC_PLAIN); - } - else - { - // Don't pluralise uniques, ever. Multiple copies of the same unique - // are unlikely in the dungeon currently, but quite common in the - // arena. This prevens "4 Gra", etc. {due} - if (mons_is_unique(m_mon->type)) - { - out << count << " " - << m_mon->name(DESC_PLAIN); - } - // Don't differentiate between dancing weapons, mimics, (very) - // ugly things or draconians of different types. - else if (m_fullname - && m_mon->type != MONS_DANCING_WEAPON - && mons_genus(m_mon->type) != MONS_DRACONIAN - && m_mon->type != MONS_UGLY_THING - && m_mon->type != MONS_VERY_UGLY_THING - && !mons_is_mimic(m_mon->type) - && m_mon->mname.empty()) - { - out << count << " " - << pluralise(m_mon->name(DESC_PLAIN)); - } - else if (m_mon->type >= MONS_DRACONIAN - && m_mon->type <= MONS_PALE_DRACONIAN) - { - out << count << " " - << pluralise(mons_type_name(MONS_DRACONIAN, DESC_PLAIN)); - } - else - { - out << count << " " - << pluralise(mons_type_name(m_mon->type, DESC_PLAIN)); - } - } - -#if DEBUG_DIAGNOSTICS - out << " av" << m_difficulty << " " - << m_mon->hit_points << "/" << m_mon->max_hit_points; -#endif - - if (count == 1) - { - if (m_mon->has_ench(ENCH_BERSERK)) - out << " (berserk)"; - else if (Options.verbose_monster_pane) - out << _verbose_info(m_mon); - else if (mons_looks_stabbable(m_mon)) - out << " (resting)"; - else if (mons_looks_distracted(m_mon)) - out << " (distracted)"; - else if (m_mon->has_ench(ENCH_INVIS)) - out << " (invisible)"; - } - - // Friendliness - switch (m_attitude) - { - case ATT_FRIENDLY: - //out << " (friendly)"; - desc_color = GREEN; - break; - case ATT_GOOD_NEUTRAL: - case ATT_NEUTRAL: - //out << " (neutral)"; - desc_color = BROWN; - break; - case ATT_STRICT_NEUTRAL: - out << " (fellow slime)"; - desc_color = BROWN; - break; - case ATT_HOSTILE: - // out << " (hostile)"; - desc_color = LIGHTGREY; - break; - } - - // Evilness of attacking - switch (m_attitude) - { - case ATT_NEUTRAL: - case ATT_HOSTILE: - if (count == 1 && you.religion == GOD_SHINING_ONE - && !tso_unchivalric_attack_safe_monster(m_mon) - && is_unchivalric_attack(&you, m_mon)) - { - desc_color = Options.evil_colour; - } - break; - default: - break; - } - - desc = out.str(); -} - #ifndef USE_TILE static char _mlist_index_to_letter(int index) { @@ -1482,7 +1211,7 @@ static char _mlist_index_to_letter(int index) return (index); } -static void _print_next_monster_desc(const std::vector& mons, +static void _print_next_monster_desc(const std::vector& mons, int& start, bool zombified = false, int idx = -1) { @@ -1491,7 +1220,7 @@ static void _print_next_monster_desc(const std::vector& mons, for (end = start + 1; end < mons.size(); ++end) { // Array is sorted, so if !(m1 < m2), m1 and m2 are "equal". - if (monster_pane_info::less_than(mons[start], mons[end], zombified)) + if (monster_info::less_than(mons[start], mons[end], zombified)) break; } // Postcondition: all monsters in [start, end) are "equal" @@ -1595,21 +1324,6 @@ static void _print_next_monster_desc(const std::vector& mons, } #endif -void get_monster_pane_info(std::vector& mons) -{ - std::vector visible = get_nearby_monsters(); - for (unsigned int i = 0; i < visible.size(); i++) - { - if (Options.target_zero_exp - || !mons_class_flag( visible[i]->type, M_NO_EXP_GAIN ) - || visible[i]->type == MONS_KRAKEN_TENTACLE) - { - mons.push_back(monster_pane_info(visible[i])); - } - } - std::sort(mons.begin(), mons.end(), monster_pane_info::less_than_wrapper); -} - #ifndef USE_TILE #define BOTTOM_JUSTIFY_MONSTER_LIST 0 // Returns -1 if the monster list is empty, 0 if there are so many monsters @@ -1625,14 +1339,14 @@ int update_monster_pane() if (max_print <= 0) return (-1); - std::vector mons; - get_monster_pane_info(mons); - std::sort(mons.begin(), mons.end(), monster_pane_info::less_than_wrapper); + std::vector mons; + get_monster_info(mons); + std::sort(mons.begin(), mons.end(), monster_info::less_than_wrapper); // Count how many groups of monsters there are. unsigned int lines_needed = mons.size(); for (unsigned int i = 1; i < mons.size(); i++) - if (!monster_pane_info::less_than(mons[i-1], mons[i])) + if (!monster_info::less_than(mons[i-1], mons[i])) --lines_needed; bool full_info = true; @@ -1646,11 +1360,11 @@ int update_monster_pane() mons[i].m_fullname = false; std::sort(mons.begin(), mons.end(), - monster_pane_info::less_than_wrapper); + monster_info::less_than_wrapper); lines_needed = mons.size(); for (unsigned int i = 1; i < mons.size(); i++) - if (!monster_pane_info::less_than(mons[i-1], mons[i], false)) + if (!monster_info::less_than(mons[i-1], mons[i], false)) --lines_needed; } -- cgit v1.2.3-54-g00ecf