summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/database.cc
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-03-23 00:51:29 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-03-23 00:51:29 +0000
commit8a2dfbcb11bd09dab998a6b81e8c7407a3c4c42a (patch)
tree3df55b11e9678b3754feb19b6307301cb7ec660e /crawl-ref/source/database.cc
parent435e410c4c086fa96d6068c1f7da3bd7f16f7a1c (diff)
downloadcrawl-ref-8a2dfbcb11bd09dab998a6b81e8c7407a3c4c42a.tar.gz
crawl-ref-8a2dfbcb11bd09dab998a6b81e8c7407a3c4c42a.zip
Modify database lookup to allow for lookup of the nth entry for a
given keyword. Used for more varied recite speech, so that the same prechosen synonym can be used for all of start/continue/stop/finish reciting. The number of the entry is calculated in an embarassingly hacky way: (recite power + hp at beginning of recite + x_pos + y_pos) modulo total weight of the keyword. This makes sure that different synonyms get used, though always the same one (plus its shorter variant) during one round of recite, but it's not as random as I'd like. It works well enough for now, though, and adds some much needed flavour to Zin. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3818 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/database.cc')
-rw-r--r--crawl-ref/source/database.cc133
1 files changed, 86 insertions, 47 deletions
diff --git a/crawl-ref/source/database.cc b/crawl-ref/source/database.cc
index d84ddc8000..aa2d619e99 100644
--- a/crawl-ref/source/database.cc
+++ b/crawl-ref/source/database.cc
@@ -53,7 +53,7 @@ class TextDB
// Convenience functions for (read-only) access to generic
// berkeley DB databases.
-static void store_text_db(const std::string &in, const std::string &out);
+static void _store_text_db(const std::string &in, const std::string &out);
static TextDB AllDBs[] =
{
@@ -170,7 +170,7 @@ void TextDB::_regenerate_db()
for (unsigned int i=0; i<_input_files.size(); i++)
{
std::string full_input_path = datafile_path(_input_files[i], true);
- store_text_db(full_input_path, db_path);
+ _store_text_db(full_input_path, db_path);
}
DO_CHMOD_PRIVATE(full_db_path.c_str());
@@ -270,7 +270,7 @@ std::vector<std::string> database_find_bodies(DBM *database,
///////////////////////////////////////////////////////////////////////////
// Internal DB utility functions
-static void execute_embedded_lua(std::string &str)
+static void _execute_embedded_lua(std::string &str)
{
// Execute any lua code found between "{{" and "}}". The lua code
// is expected to return a string, with which the lua code and braces
@@ -304,14 +304,14 @@ static void execute_embedded_lua(std::string &str)
} // while (pos != std::string::npos)
}
-static void trim_leading_newlines(std::string &s)
+static void _trim_leading_newlines(std::string &s)
{
s.erase(0, s.find_first_not_of("\n"));
}
-static void add_entry(DBM *db, const std::string &k, std::string &v)
+static void _add_entry(DBM *db, const std::string &k, std::string &v)
{
- trim_leading_newlines(v);
+ _trim_leading_newlines(v);
datum key, value;
key.dptr = (char *) k.c_str();
key.dsize = k.length();
@@ -323,7 +323,7 @@ static void add_entry(DBM *db, const std::string &k, std::string &v)
end(1, true, "Error storing %s", k.c_str());
}
-static void parse_text_db(std::ifstream &inf, DBM *db)
+static void _parse_text_db(std::ifstream &inf, DBM *db)
{
char buf[1000];
@@ -341,7 +341,7 @@ static void parse_text_db(std::ifstream &inf, DBM *db)
if (!strncmp(buf, "%%%%", 4))
{
if (!key.empty())
- add_entry(db, key, value);
+ _add_entry(db, key, value);
key.clear();
value.clear();
in_entry = true;
@@ -366,10 +366,10 @@ static void parse_text_db(std::ifstream &inf, DBM *db)
}
if (!key.empty())
- add_entry(db, key, value);
+ _add_entry(db, key, value);
}
-static void store_text_db(const std::string &in, const std::string &out)
+static void _store_text_db(const std::string &in, const std::string &out)
{
std::ifstream inf(in.c_str());
if (!inf)
@@ -377,7 +377,7 @@ static void store_text_db(const std::string &in, const std::string &out)
if (DBM *db = dbm_open(out.c_str(), O_RDWR | O_CREAT, 0660))
{
- parse_text_db(inf, db);
+ _parse_text_db(inf, db);
dbm_close(db);
}
else
@@ -386,7 +386,7 @@ static void store_text_db(const std::string &in, const std::string &out)
inf.close();
}
-static std::string chooseStrByWeight(std::string entry)
+static std::string _chooseStrByWeight(std::string entry, int fixed_weight = -1)
{
std::vector<std::string> parts;
std::vector<int> weights;
@@ -400,6 +400,7 @@ static std::string chooseStrByWeight(std::string entry)
// blank lines.
while (i < size && lines[i] == "")
i++;
+
if (i == size)
break;
@@ -431,9 +432,12 @@ static std::string chooseStrByWeight(std::string entry)
if (parts.size() == 0)
return("BUG, EMPTY ENTRY");
- int choice = random2(total_weight);
- std::string str = "";
-
+ int choice = 0;
+ if (fixed_weight != -1)
+ choice = fixed_weight % total_weight;
+ else
+ choice = random2(total_weight);
+
for (int i = 0, size = parts.size(); i < size; i++)
if (choice < weights[i])
return(parts[i]);
@@ -444,19 +448,10 @@ static std::string chooseStrByWeight(std::string entry)
#define MAX_RECURSION_DEPTH 10
#define MAX_REPLACEMENTS 100
-static std::string getRandomizedStr(DBM *database, const std::string &key,
- const std::string &suffix,
- int &num_replacements,
- int recursion_depth = 0)
+static std::string _getWeightedString(DBM *database, const std::string &key,
+ const std::string &suffix,
+ int fixed_weight = -1)
{
- recursion_depth++;
- if (recursion_depth > MAX_RECURSION_DEPTH)
- {
- mpr("Too many nested replacements, bailing.", MSGCH_DIAGNOSTICS);
-
- return "TOO MUCH RECURSION";
- }
-
// We have to canonicalize the key (in case the user typed it
// in and got the case wrong.)
std::string canonical_key = key + suffix;
@@ -481,11 +476,58 @@ static std::string getRandomizedStr(DBM *database, const std::string &key,
// Cons up a (C++) string to return. The caller must release it.
std::string str = std::string((const char *)result.dptr, result.dsize);
- str = chooseStrByWeight(str);
+ return _chooseStrByWeight(str, fixed_weight);
+}
+
+static void _call_recursive_replacement(std::string &str, DBM *database,
+ const std::string &suffix,
+ int &num_replacements,
+ int recursion_depth = 0);
+
+std::string getWeightedSpeechString(const std::string &key,
+ const std::string &suffix,
+ const int weight)
+{
+ if (!SpeakDB)
+ return ("");
- // Replace any "@foo@" markers that can be found in this database;
- // those that can't be found are left alone for the caller to deal
- // with.
+ std::string result = _getWeightedString(SpeakDB, key, suffix, weight);
+ if (result.empty())
+ return "";
+
+ int num_replacements = 0;
+ _call_recursive_replacement(result, SpeakDB, suffix, num_replacements);
+ return (result);
+}
+
+static std::string _getRandomizedStr(DBM *database, const std::string &key,
+ const std::string &suffix,
+ int &num_replacements,
+ int recursion_depth = 0)
+{
+ recursion_depth++;
+ if (recursion_depth > MAX_RECURSION_DEPTH)
+ {
+ mpr("Too many nested replacements, bailing.", MSGCH_DIAGNOSTICS);
+
+ return "TOO MUCH RECURSION";
+ }
+
+ std::string str = _getWeightedString(database, key, suffix);
+
+ _call_recursive_replacement(str, database, suffix, num_replacements,
+ recursion_depth);
+
+ return str;
+}
+
+// Replace any "@foo@" markers that can be found in this database.
+// Those that can't be found are left alone for the caller to deal with
+static void _call_recursive_replacement(std::string &str, DBM *database,
+ const std::string &suffix,
+ int &num_replacements,
+ int recursion_depth)
+{
std::string::size_type pos = str.find("@");
while (pos != std::string::npos)
{
@@ -493,8 +535,7 @@ static std::string getRandomizedStr(DBM *database, const std::string &key,
if (num_replacements > MAX_REPLACEMENTS)
{
mpr("Too many string replacements, bailing.", MSGCH_DIAGNOSTICS);
-
- return "TOO MANY REPLACEMENTS";
+ return;
}
std::string::size_type end = str.find("@", pos + 1);
@@ -508,8 +549,8 @@ static std::string getRandomizedStr(DBM *database, const std::string &key,
std::string marker = str.substr(pos + 1, end - pos - 1);
std::string replacement =
- getRandomizedStr(database, marker, suffix, num_replacements,
- recursion_depth);
+ _getRandomizedStr(database, marker, suffix, num_replacements,
+ recursion_depth);
if (replacement == "")
// Nothing in database, leave it alone and go onto next @foo@
@@ -524,12 +565,10 @@ static std::string getRandomizedStr(DBM *database, const std::string &key,
pos = str.find("@", pos);
}
} // while (pos != std::string::npos)
-
- return str;
}
-static std::string query_database(DBM *db, std::string key,
- bool canonicalise_key, bool run_lua)
+static std::string _query_database(DBM *db, std::string key,
+ bool canonicalise_key, bool run_lua)
{
if (canonicalise_key)
{
@@ -544,7 +583,7 @@ static std::string query_database(DBM *db, std::string key,
std::string str((const char *)result.dptr, result.dsize);
if (run_lua)
- execute_embedded_lua(str);
+ _execute_embedded_lua(str);
return (str);
}
@@ -557,7 +596,7 @@ std::string getLongDescription(const std::string &key)
if (! DescriptionDB.get())
return ("");
- return query_database(DescriptionDB.get(), key, true, true);
+ return _query_database(DescriptionDB.get(), key, true, true);
}
std::vector<std::string> getLongDescKeysByRegex(const std::string &regex,
@@ -591,8 +630,8 @@ std::string getShoutString(const std::string &monst,
{
int num_replacements = 0;
- return getRandomizedStr(ShoutDB.get(), monst, suffix,
- num_replacements);
+ return _getRandomizedStr(ShoutDB.get(), monst, suffix,
+ num_replacements);
}
/////////////////////////////////////////////////////////////////////////////
@@ -607,7 +646,7 @@ std::string getSpeakString(const std::string &monst)
#ifdef DEBUG_MONSPEAK
mprf(MSGCH_DIAGNOSTICS, "monster speech lookup for %s", monst.c_str());
#endif
- return getRandomizedStr(SpeakDB, monst, "", num_replacements);
+ return _getRandomizedStr(SpeakDB, monst, "", num_replacements);
}
/////////////////////////////////////////////////////////////////////////////
@@ -620,8 +659,8 @@ std::string getRandNameString(const std::string &itemtype,
int num_replacements = 0;
- return getRandomizedStr(RandartDB, itemtype, suffix,
- num_replacements);
+ return _getRandomizedStr(RandartDB, itemtype, suffix,
+ num_replacements);
}
/////////////////////////////////////////////////////////////////////////////
@@ -629,5 +668,5 @@ std::string getRandNameString(const std::string &itemtype,
std::string getHelpString(const std::string &topic)
{
- return query_database(HelpDB.get(), topic, false, true);
+ return _query_database(HelpDB.get(), topic, false, true);
}