summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mapdef.cc
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-12-08 12:28:30 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-12-08 12:28:30 +0000
commit6c99170d8941c25c6aac7f131f0d55df52caa63a (patch)
tree73993fb9a6610d14975be5239929f26f06b9fc94 /crawl-ref/source/mapdef.cc
parent93de8db42745db1d85c850cb1001baa1ac55bcc0 (diff)
downloadcrawl-ref-6c99170d8941c25c6aac7f131f0d55df52caa63a.tar.gz
crawl-ref-6c99170d8941c25c6aac7f131f0d55df52caa63a.zip
Fixed bug where Pandemonium demonlords did not get their rightful runes
(Cerebov and company) - bug was introduced circa 0.1.3. [1610237] Vaults can request specific items using ITEM: declarations and the item selectors defghijk. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@596 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/mapdef.cc')
-rw-r--r--crawl-ref/source/mapdef.cc212
1 files changed, 201 insertions, 11 deletions
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 7c3c037b7f..59a6c9289f 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -3,10 +3,13 @@
#include <cctype>
#include "AppHdr.h"
+#include "invent.h"
+#include "items.h"
#include "libutil.h"
#include "mapdef.h"
#include "mon-util.h"
#include "stuff.h"
+#include "dungeon.h"
static const char *map_section_names[] = {
"",
@@ -30,6 +33,52 @@ const char *map_section_name(int msect)
return map_section_names[msect];
}
+// Returns true if s contains tag 'tag', and strips out tag from s.
+bool strip_tag(std::string &s, const std::string &tag)
+{
+ if (s == tag)
+ {
+ s.clear();
+ return (true);
+ }
+
+ std::string::size_type pos;
+ if ((pos = s.find(" " + tag + " ")) != std::string::npos)
+ {
+ // Leave one space intact.
+ s.erase(pos, tag.length() + 1);
+ return (true);
+ }
+
+ if ((pos = s.find(tag + " ")) != std::string::npos
+ || (pos = s.find(" " + tag)) != std::string::npos)
+ {
+ s.erase(pos, tag.length() + 1);
+ return (true);
+ }
+
+ return (false);
+}
+
+#define TAG_UNFOUND -20404
+int strip_number_tag(std::string &s, const std::string &tagprefix)
+{
+ std::string::size_type pos = s.find(tagprefix);
+ if (pos == std::string::npos)
+ return (TAG_UNFOUND);
+
+ std::string::size_type ns = s.find(" ", pos);
+ if (ns == std::string::npos)
+ ns = s.length();
+
+ std::string argument =
+ s.substr(pos + tagprefix.length(), ns - pos - tagprefix.length());
+
+ s.erase(pos, ns - pos + 1);
+
+ return atoi(argument.c_str());
+}
+
///////////////////////////////////////////////
// level_range
//
@@ -507,17 +556,6 @@ bool map_def::has_tag(const std::string &tagwanted) const
// mons_list
//
-mons_list::mons_list(int nids, ...) : mons_ids()
-{
- va_list args;
- va_start(args, nids);
-
- for (int i = 0; i < nids; ++i)
- mons_ids.push_back( va_arg(args, int) );
-
- va_end(args);
-}
-
mons_list::mons_list() : mons_ids()
{
}
@@ -594,3 +632,155 @@ int mons_list::mons_by_name(std::string name) const
return (get_monster_by_name(name, true));
}
+
+//////////////////////////////////////////////////////////////////////
+// item_list
+
+void item_list::clear()
+{
+ items.clear();
+}
+
+const std::vector<item_spec_list> &item_list::get_items() const
+{
+ return (items);
+}
+
+std::string item_list::add_item(const std::string &spec)
+{
+ error.clear();
+
+ item_spec_list sp = parse_item_spec(spec);
+ if (error.empty())
+ items.push_back(sp);
+
+ return (error);
+}
+
+item_spec item_list::parse_single_spec(std::string s)
+{
+ item_spec result;
+
+ // If there's a colon, this must be a generation weight.
+ int weight = strip_number_tag(s, "weight:");
+ if (weight != TAG_UNFOUND)
+ {
+ result.genweight = weight;
+ if (result.genweight <= 0)
+ {
+ error = make_stringf("Bad item generation weight: '%d'",
+ result.genweight);
+ return (result);
+ }
+ }
+
+ if (strip_tag(s, "good_item"))
+ result.level = MAKE_GOOD_ITEM;
+ else
+ {
+ int number = strip_number_tag(s, "level:");
+ if (number != TAG_UNFOUND)
+ {
+ if (number <= 0)
+ error = make_stringf("Bad item level: %d", number);
+
+ result.level = number;
+ }
+ }
+
+ if (strip_tag(s, "no_uniq"))
+ result.allow_uniques = 0;
+ if (strip_tag(s, "allow_uniq"))
+ result.allow_uniques = 1;
+ else
+ {
+ int uniq = strip_number_tag(s, "uniq:");
+ if (uniq != TAG_UNFOUND)
+ {
+ if (uniq <= 0)
+ error = make_stringf("Bad uniq level: %d", uniq);
+ result.allow_uniques = uniq;
+ }
+ }
+
+ // Clean up after any tag brain damage.
+ trim_string(s);
+
+ // Completely random?
+ if (s == "random" || s == "any")
+ return (result);
+
+ // Check for "any objclass"
+ if (s.find("any ") == 0)
+ {
+ parse_random_by_class(s.substr(4), result);
+ return (result);
+ }
+
+ if (s.find("random ") == 0)
+ {
+ parse_random_by_class(s.substr(7), result);
+ return (result);
+ }
+
+ // Check for actual item names.
+ parse_raw_name(s, result);
+
+ return (result);
+}
+
+void item_list::parse_random_by_class(std::string c, item_spec &spec)
+{
+ trim_string(c);
+ if (c == "?" || c.empty())
+ {
+ error = make_stringf("Bad item class: '%s'", c.c_str());
+ return;
+ }
+
+ for (int type = OBJ_WEAPONS; type < NUM_OBJECT_CLASSES; ++type)
+ {
+ if (c == item_class_name(type, true))
+ {
+ spec.base_type = type;
+ return;
+ }
+ }
+
+ error = make_stringf("Bad item class: '%s'", c.c_str());
+}
+
+void item_list::parse_raw_name(std::string name, item_spec &spec)
+{
+ trim_string(name);
+ if (name.empty())
+ {
+ error = make_stringf("Bad item name: '%s'", name.c_str());
+ return ;
+ }
+
+ item_def parsed = find_item_type(-1, name);
+ if (parsed.sub_type != OBJ_RANDOM)
+ {
+ spec.base_type = parsed.base_type;
+ spec.sub_type = parsed.sub_type;
+ return;
+ }
+
+ error = make_stringf("Bad item name: '%s'", name.c_str());
+}
+
+item_spec_list item_list::parse_item_spec(std::string spec)
+{
+ lowercase(spec);
+
+ item_spec_list list;
+ std::vector<std::string> specifiers = split_string( "/", spec );
+
+ for (unsigned i = 0; i < specifiers.size() && error.empty(); ++i)
+ {
+ list.push_back( parse_single_spec(specifiers[i]) );
+ }
+
+ return (list);
+}