summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mapdef.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/mapdef.cc')
-rw-r--r--crawl-ref/source/mapdef.cc116
1 files changed, 111 insertions, 5 deletions
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 3cf3ad9b41..2420d3ba9e 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -3,6 +3,7 @@
#include <cctype>
#include "AppHdr.h"
+#include "branch.h"
#include "describe.h"
#include "direct.h"
#include "invent.h"
@@ -122,17 +123,75 @@ static std::string split_key_item(const std::string &s,
// level_range
//
-level_range::level_range(int s, int d)
- : shallowest(), deepest()
+level_range::level_range(branch_type br, int s, int d)
+ : branch(br), shallowest(), deepest(), deny(false)
{
set(s, d);
}
+level_range::level_range(const raw_range &r)
+ : branch(r.branch), shallowest(r.shallowest), deepest(r.deepest),
+ deny(r.deny)
+{
+}
+
+std::string level_range::str_depth_range() const
+{
+ if (shallowest == -1)
+ return (":??");
+
+ if (shallowest == 1 && deepest >= branches[branch].depth)
+ return ("");
+
+ if (shallowest == deepest)
+ return make_stringf(":%d", shallowest);
+
+ return make_stringf(":%d-%d", shallowest, deepest);
+}
+
+std::string level_range::describe() const
+{
+ return make_stringf("%s%s%s",
+ deny? "!" : "",
+ branch == NUM_BRANCHES? "Any" :
+ branches[branch].abbrevname,
+ str_depth_range().c_str());
+}
+
+level_range::operator raw_range () const
+{
+ raw_range r;
+ r.branch = branch;
+ r.shallowest = shallowest;
+ r.deepest = deepest;
+ r.deny = deny;
+ return (r);
+}
+
+void level_range::set(const std::string &br, int s, int d)
+ throw (std::string)
+{
+ if (br == "any" || br == "Any")
+ branch = NUM_BRANCHES;
+ else
+ {
+ if ((branch = str_to_branch(br)) == NUM_BRANCHES)
+ throw make_stringf("Unknown branch: '%s'", br.c_str());
+ }
+
+ shallowest = s;
+ deepest = d;
+
+ if (deepest < shallowest)
+ throw make_stringf("Level-range %s:%d-%d is malformed",
+ br.c_str(), s, d);
+}
+
void level_range::set(int s, int d)
{
shallowest = s;
deepest = d;
- if (deepest == -1)
+ if (deepest == -1 || deepest < shallowest)
deepest = shallowest;
}
@@ -141,7 +200,16 @@ void level_range::reset()
deepest = shallowest = -1;
}
-bool level_range::contains(int x) const
+bool level_range::matches(const level_id &lid) const
+{
+ if (branch == NUM_BRANCHES)
+ return (matches(absdungeon_depth(lid.branch, lid.depth)));
+ else
+ return (branch == lid.branch
+ && lid.depth >= shallowest && lid.depth <= deepest);
+}
+
+bool level_range::matches(int x) const
{
// [ds] The level ranges used by the game are zero-based, adjust for that.
++x;
@@ -559,7 +627,7 @@ void map_def::init()
place.clear();
items.clear();
keyspecs.clear();
- depth.reset();
+ depths.clear();
orient = MAP_NONE;
// Base chance; this is not a percentage.
@@ -573,6 +641,38 @@ void map_def::init()
mons.clear();
}
+bool map_def::is_usable_in(const level_id &lid) const
+{
+ bool any_matched = false;
+ for (int i = 0, size = depths.size(); i < size; ++i)
+ {
+ const level_range &lr = depths[i];
+ if (lr.matches(lid))
+ {
+ if (lr.deny)
+ return (false);
+ any_matched = true;
+ }
+ }
+ return (any_matched);
+}
+
+void map_def::add_depth(const level_range &range)
+{
+ depths.push_back(range);
+}
+
+void map_def::add_depths(depth_ranges::const_iterator s,
+ depth_ranges::const_iterator e)
+{
+ depths.insert(depths.end(), s, e);
+}
+
+bool map_def::has_depth() const
+{
+ return (!depths.empty());
+}
+
bool map_def::is_minivault() const
{
return (orient == MAP_NONE);
@@ -796,6 +896,12 @@ bool map_def::has_tag(const std::string &tagwanted) const
&& tags.find(" " + tagwanted + " ") != std::string::npos;
}
+bool map_def::has_tag_prefix(const std::string &prefix) const
+{
+ return !tags.empty() && !prefix.empty()
+ && tags.find(" " + prefix) != std::string::npos;
+}
+
keyed_mapspec *map_def::mapspec_for_key(int key)
{
keyed_specs::iterator i = keyspecs.find(key);