diff options
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/command.cc | 77 | ||||
-rw-r--r-- | crawl-ref/source/database.cc | 33 | ||||
-rw-r--r-- | crawl-ref/source/database.h | 7 | ||||
-rw-r--r-- | crawl-ref/source/describe.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/describe.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/libutil.h | 7 |
6 files changed, 123 insertions, 5 deletions
diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc index 8a234a49fc..26f55a4f0e 100644 --- a/crawl-ref/source/command.cc +++ b/crawl-ref/source/command.cc @@ -26,6 +26,8 @@ #include "abl-show.h" #include "chardump.h" #include "cio.h" +#include "database.h" +#include "describe.h" #include "files.h" #include "invent.h" #include "itemname.h" @@ -679,6 +681,65 @@ help_file help_files[] = { { NULL, 0, false } }; +static void find_description() +{ + clrscr(); + viewwindow(true, false); + + mpr("Describe what? (can be a partial name or a regex) "); + char buf[80]; + if (cancelable_get_line(buf, sizeof(buf)) || buf[0] == '\0') + { + canned_msg( MSG_OK); + return; + } + + std::string regex = trimmed_string(buf); + + if (regex == "") + { + mpr("Description must contain at least one non-space."); + return; + } + + // Try to get an exact match first. + std::string key = regex; + std::string desc = getLongDescription(key); + + if (desc == "") + { + std::vector<std::string> matches = getLongDescriptionByRegex(regex); + + if (matches.size() == 0) + { + mprf("Nothing matches '%s'", buf); + return; + } + else if (matches.size() > 1) + { + std::string prefix = "No exact match for '" + + regex + "', possible matches are: "; + + // Use mpr_comma_separated_list() because the list + // might be *LONG*. + mpr_comma_separated_list(prefix, matches, " and ", ", ", + MSGCH_PLAIN); + return; + } + else + { + // Only one match, use that. + key = matches[0]; + desc = getLongDescription(key); + } + } + key = uppercase_first(key); + key += "$$"; + + clrscr(); + print_description(key + desc); +} + static int keyhelp_keyfilter(int ch) { switch (ch) @@ -690,10 +751,19 @@ static int keyhelp_keyfilter(int ch) display_notes(); return -1; } - // fall through - default: - return ch; + break; + + case '/': + find_description(); + + if ( getch() == 0 ) + getch(); + + viewwindow(true, false); + + return -1; } + return ch; } static void show_keyhelp_menu(const std::vector<formatted_string> &lines, @@ -733,6 +803,7 @@ static void show_keyhelp_menu(const std::vector<formatted_string> &lines, "<w>~</w>: Macros help\n" "<w>!</w>: Options help\n" "<w>%</w>: Table of aptitudes\n" + "<w>/</w>: Lookup description\n" "<w>Home</w>: This screen\n", true, true, cmdhelp_textfilter); diff --git a/crawl-ref/source/database.cc b/crawl-ref/source/database.cc index f8c97a354c..6de91c3a1e 100644 --- a/crawl-ref/source/database.cc +++ b/crawl-ref/source/database.cc @@ -152,6 +152,28 @@ datum database_fetch(DBM *database, const std::string &key) return result; } +std::vector<std::string> database_find_keys(DBM *database, + const std::string ®ex, + bool ignore_case) +{ + text_pattern tpat(regex, ignore_case); + std::vector<std::string> matches; + + datum dbKey = dbm_firstkey(database); + + while (dbKey.dptr != NULL) + { + std::string key((const char *)dbKey.dptr, dbKey.dsize); + + if (tpat.matches(key)) + matches.push_back(key); + + dbKey = dbm_nextkey(database); + } + + return (matches); +} + /////////////////////////////////////////////////////////////////////////// // Internal DB utility functions static void trim_right(std::string &s) @@ -403,6 +425,17 @@ std::string getLongDescription(const std::string &key) return std::string((const char *)result.dptr, result.dsize); } +std::vector<std::string> getLongDescriptionByRegex(const std::string ®ex) +{ + if (!descriptionDB) + { + std::vector<std::string> empty; + return (empty); + } + + return database_find_keys(descriptionDB, regex, true); +} + static std::vector<std::string> description_txt_paths() { std::vector<std::string> txt_file_names; diff --git a/crawl-ref/source/database.h b/crawl-ref/source/database.h index e1cb3f230e..b30d8814e6 100644 --- a/crawl-ref/source/database.h +++ b/crawl-ref/source/database.h @@ -40,7 +40,12 @@ void databaseSystemShutdown(); DBM *openDB(const char *dbFilename); datum database_fetch(DBM *database, const std::string &key); -std::string getLongDescription(const std::string &key); +std::vector<std::string> database_find_keys(DBM *database, + const std::string ®ex, + bool ignore_case = false); + +std::string getLongDescription(const std::string &key); +std::vector<std::string> getLongDescriptionByRegex(const std::string ®ex); std::string getShoutString(const std::string &monst, const std::string &suffix = ""); diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 169a83af6f..8555459057 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -89,7 +89,7 @@ static void append_value( std::string & description, int valu, bool plussed ) // word and such. The character $ is interpreted as a CR. // //--------------------------------------------------------------- -static void print_description( const std::string &d ) +void print_description( const std::string &d ) { std::string::size_type nextLine = std::string::npos; unsigned int currentPos = 0; diff --git a/crawl-ref/source/describe.h b/crawl-ref/source/describe.h index af067e0415..875c86b8c0 100644 --- a/crawl-ref/source/describe.h +++ b/crawl-ref/source/describe.h @@ -72,6 +72,8 @@ void describe_spell(spell_type spelled); * *********************************************************************** */ std::string ghost_description(const monsters &mons, bool concise = false); +void print_description( const std::string &d ); + const char *trap_name(trap_type trap); int str_to_trap(const std::string &s); diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h index 183f6fac2f..fc42023f70 100644 --- a/crawl-ref/source/libutil.h +++ b/crawl-ref/source/libutil.h @@ -102,6 +102,13 @@ inline std::string lowercase_first(std::string s) return (s); } +inline std::string uppercase_first(std::string s) +{ + if (s.length()) + s[0] = toupper(s[0]); + return (s); +} + template <typename Z> std::string comma_separated_line(Z start, Z end, const std::string &andc = " and ", |