summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/describe.h
diff options
context:
space:
mode:
authorennewalker <ennewalker@c06c8d41-db1a-0410-9941-cceddc491573>2009-02-12 05:05:43 +0000
committerennewalker <ennewalker@c06c8d41-db1a-0410-9941-cceddc491573>2009-02-12 05:05:43 +0000
commit76a5cc5049290770249b6661a2f4558b7fbb645e (patch)
treefa2131d2cef62d963d3c6c821c3ca230b541260f /crawl-ref/source/describe.h
parentaa6dd78dceb8d09547021cd319aaaef053df1f4f (diff)
downloadcrawl-ref-76a5cc5049290770249b6661a2f4558b7fbb645e.tar.gz
crawl-ref-76a5cc5049290770249b6661a2f4558b7fbb645e.zip
Mousing over monsters, items, and features will now show their description in the message window. This inadvertantly fixes [2469950], where some lines would appear off screen.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9030 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/describe.h')
-rw-r--r--crawl-ref/source/describe.h155
1 files changed, 148 insertions, 7 deletions
diff --git a/crawl-ref/source/describe.h b/crawl-ref/source/describe.h
index ab661c919c..647816ab57 100644
--- a/crawl-ref/source/describe.h
+++ b/crawl-ref/source/describe.h
@@ -11,6 +11,7 @@
#define DESCRIBE_H
#include <string>
+#include <sstream>
#include "externs.h"
#include "enum.h"
@@ -27,6 +28,16 @@ enum item_description_type
NUM_IDESC
};
+struct describe_info
+{
+ std::ostringstream body;
+ std::string title;
+ std::string prefix;
+ std::string suffix;
+ std::string footer;
+ std::string quote;
+};
+
void append_spells(std::string &desc, const item_def &item);
// last updated 12may2000 {dlb}
@@ -53,6 +64,7 @@ void describe_god( god_type which_god, bool give_title );
* called from: directn
* *********************************************************************** */
void describe_feature_wide(int x, int y);
+void get_feature_desc(const coord_def &gc, describe_info &inf);
// last updated 24 Dec 2008 {mpc}
/* ***********************************************************************
@@ -64,8 +76,9 @@ void set_feature_desc_long(const std::string &raw_name,
/* ***********************************************************************
* called from: item_use - shopping
* *********************************************************************** */
-void describe_item( item_def &item, bool allow_inscribe = false );
-void inscribe_item( item_def &item, bool proper_prompt );
+void describe_item(item_def &item, bool allow_inscribe = false);
+void get_item_desc(const item_def &item, describe_info &inf);
+void inscribe_item(item_def &item, bool proper_prompt);
/* ***********************************************************************
* called from: command
@@ -79,6 +92,7 @@ void append_missile_info(std::string &description);
* called from: command - direct
* *********************************************************************** */
void describe_monsters(const monsters &mons);
+void get_monster_desc(const monsters &item, describe_info &inf);
// last updated 12 Jun 2008 {jpeg}
/* ***********************************************************************
@@ -96,11 +110,10 @@ std::string get_skill_description(int skill, bool need_title = false);
void describe_skill(int skill);
-void print_description(const std::string &d, const std::string title = "",
- const std::string suffix = "",
- const std::string prefix = "",
- const std::string footer = "",
- const std::string quote = "");
+void print_description(const std::string &desc);
+void print_description(const describe_info &inf);
+
+template<class T> void process_description(T &proc, const describe_info &inf);
std::string randart_auto_inscription( const item_def& item );
void add_autoinscription( item_def &item, std::string ainscrip);
@@ -110,4 +123,132 @@ int str_to_trap(const std::string &s);
extern const char* god_gain_power_messages[NUM_GODS][MAX_GOD_ABILITIES];
+int count_desc_lines(const std::string _desc, const int width);
+
+/* ***********************************************************************
+ * template implementations
+ * *********************************************************************** */
+// My kingdom for a closure.
+template<class T>
+inline void process_description(T &proc, const describe_info &inf)
+{
+ const unsigned int line_width = proc.width();
+ const int height = proc.height();
+
+ std::string desc;
+
+ if (inf.title.empty())
+ desc = inf.body.str();
+ else
+ {
+ desc = inf.title + "$$";
+ desc += inf.body.str();
+ }
+
+ int num_lines = count_desc_lines(desc, line_width) + 1;
+
+ const int suffix_lines = count_desc_lines(inf.suffix, line_width);
+ const int prefix_lines = count_desc_lines(inf.prefix, line_width);
+ const int footer_lines = count_desc_lines(inf.footer, line_width)
+ + (inf.footer.empty() ? 0 : 1);
+ const int quote_lines = count_desc_lines(inf.quote, line_width);
+
+ // Prefer the footer over the suffix.
+ if (num_lines + suffix_lines + footer_lines <= height)
+ {
+ desc = desc + inf.suffix;
+ num_lines += suffix_lines;
+ }
+
+ // Prefer the footer over the prefix.
+ if (num_lines + prefix_lines + footer_lines <= height)
+ {
+ desc = inf.prefix + desc;
+ num_lines += prefix_lines;
+ }
+
+ // Prefer the footer over the quote.
+ if (num_lines + footer_lines + quote_lines + 1 <= height)
+ {
+ if (!desc.empty())
+ {
+ desc += "$";
+ num_lines++;
+ }
+ desc = desc + inf.quote;
+ num_lines += quote_lines;
+ }
+
+ if (!inf.footer.empty() && num_lines + footer_lines <= height)
+ {
+ const int bottom_line = std::min(std::max(24, num_lines + 2),
+ height - footer_lines + 1);
+ const int newlines = bottom_line - num_lines;
+
+ if (newlines >= 0)
+ {
+ desc.append(newlines, '\n');
+ desc = desc + inf.footer;
+ }
+ }
+
+ std::string::size_type nextLine = std::string::npos;
+ unsigned int currentPos = 0;
+
+ while (currentPos < desc.length())
+ {
+ if (currentPos != 0)
+ proc.nextline();
+
+ // See if $ sign is within one line_width.
+ nextLine = desc.find('$', currentPos);
+
+ if (nextLine >= currentPos && nextLine < currentPos + line_width)
+ {
+ proc.print(desc.substr(currentPos, nextLine-currentPos));
+ currentPos = nextLine + 1;
+ continue;
+ }
+
+ // Handle real line breaks. No substitutions necessary, just update
+ // the counts.
+ nextLine = desc.find('\n', currentPos);
+ if (nextLine >= currentPos && nextLine < currentPos + line_width)
+ {
+ proc.print(desc.substr(currentPos, nextLine-currentPos));
+ currentPos = nextLine + 1;
+ continue;
+ }
+
+ // No newline -- see if rest of string will fit.
+ if (currentPos + line_width >= desc.length())
+ {
+ proc.print(desc.substr(currentPos));
+ return;
+ }
+
+
+ // Ok, try to truncate at space.
+ nextLine = desc.rfind(' ', currentPos + line_width);
+
+ if (nextLine > 0)
+ {
+ proc.print(desc.substr(currentPos, nextLine - currentPos));
+ currentPos = nextLine + 1;
+ continue;
+ }
+
+ // Oops. Just truncate.
+ nextLine = currentPos + line_width;
+
+ nextLine = std::min(inf.body.str().length(), nextLine);
+
+ proc.print(desc.substr(currentPos, nextLine - currentPos));
+ currentPos = nextLine;
+ }
+}
+
+
+
+
#endif