summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/output.cc
diff options
context:
space:
mode:
authorRobert Vollmert <rvollmert@gmx.net>2009-10-27 15:18:53 +0100
committerRobert Vollmert <rvollmert@gmx.net>2009-10-27 15:18:53 +0100
commiteda188d2d5045e9fb02c416261d72a3c31b9cf57 (patch)
tree0c331fb2f546e2512f06e62c3630e2248c499d15 /crawl-ref/source/output.cc
parent588ba77a56ffc7262ee41f4f744129371c5bdc75 (diff)
downloadcrawl-ref-eda188d2d5045e9fb02c416261d72a3c31b9cf57.tar.gz
crawl-ref-eda188d2d5045e9fb02c416261d72a3c31b9cf57.zip
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.
Diffstat (limited to 'crawl-ref/source/output.cc')
-rw-r--r--crawl-ref/source/output.cc314
1 files changed, 14 insertions, 300 deletions
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<monster_pane_info> mons;
- get_monster_pane_info(mons);
+ std::vector<monster_info> 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<std::string> 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<monster_pane_info>& mons,
+static void _print_next_monster_desc(const std::vector<monster_info>& mons,
int& start, bool zombified = false,
int idx = -1)
{
@@ -1491,7 +1220,7 @@ static void _print_next_monster_desc(const std::vector<monster_pane_info>& 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<monster_pane_info>& mons,
}
#endif
-void get_monster_pane_info(std::vector<monster_pane_info>& mons)
-{
- std::vector<monsters*> 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<monster_pane_info> mons;
- get_monster_pane_info(mons);
- std::sort(mons.begin(), mons.end(), monster_pane_info::less_than_wrapper);
+ std::vector<monster_info> 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;
}