summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/docs/crawl_options.txt36
-rw-r--r--crawl-ref/init.txt11
-rw-r--r--crawl-ref/source/externs.h3
-rw-r--r--crawl-ref/source/initfile.cc34
-rw-r--r--crawl-ref/source/items.cc49
5 files changed, 99 insertions, 34 deletions
diff --git a/crawl-ref/docs/crawl_options.txt b/crawl-ref/docs/crawl_options.txt
index f492c658e8..921798e3f5 100644
--- a/crawl-ref/docs/crawl_options.txt
+++ b/crawl-ref/docs/crawl_options.txt
@@ -18,10 +18,10 @@ The contents of this text are:
gearset.lua, eat.lua, trapwalk.lua
4- Interface.
4-a Dropping and Picking up.
- autopickup, default_autopickup, safe_autopickup,
- autopickup_no_burden, safe_zero_exp, pickup_thrown,
- pickup_dropped, assign_item_slot, ban_pickup, drop_mode,
- pickup_mode, drop_filter;
+ autopickup, autopickup_exceptions, default_autopickup,
+ safe_autopickup, autopickup_no_burden, safe_zero_exp,
+ pickup_thrown, pickup_dropped, assign_item_slot,
+ ban_pickup, drop_mode, pickup_mode, drop_filter;
lua: ch_autopickup (advanced autopickup exceptions)
4-b Targeting.
target_zero_exp, target_oos, target_los_first,
@@ -229,6 +229,32 @@ autopickup = $?!+"/%
If you teleport or blink onto a square with interesting items, these
will not be picked up.
+autopickup_exceptions = <pickup-regex, >don't-pickup-regex, ...
+ A set of regexes that force matching items to be picked up (if prefixed
+ with <), or never picked up (if prefixed with >). Excludes (>) take
+ precedence over includes (<), so if the same item is matched by both
+ an exclude and an include, it will not be subject to autopickup.
+
+ An example:
+ autopickup_exceptions = <(poisoned|curare-tipped) needle
+ Forces autopickup to grab all poisoned and curare-tipped needles, even
+ if missiles are not set in the "autopickup" option.
+
+ Whitespace between <> and the match expression is significant, so this
+ is a mistake:
+ autopickup_exceptions = < ebony casket
+
+ autopickup_exceptions is a superset of ban_pickup (see below). Using
+ autopickup_exceptions = >decay, >degeneration
+ is the same as using
+ ban_pickup = decay, degeneration
+
+ If the regexes are not prefixed with < or >, > is implied. So the option
+ setting above can also be written as
+ autopickup_exceptions = decay, degeneration
+
+ You can use multiple autopickup_exceptions lines.
+
default_autopickup = true
When set false, the game starts with autopickup turned off. You can
still toggle autopickup in-game with Ctrl-A.
@@ -278,6 +304,8 @@ ban_pickup = <regex>
ban_pickup = scrolls? of paper, immolation, curse armour, curse weapon
ban_pickup = forgetfulness, uselessness, noise, torment
+ See also autopickup_exceptions, which is a superset of ban_pickup.
+
drop_mode = (multi | single)
Single is the classic behaviour; when you select an inventory letter,
that item will be dropped immediately. Multidrop allows you to select
diff --git a/crawl-ref/init.txt b/crawl-ref/init.txt
index f99043eff9..cd7da6dcae 100644
--- a/crawl-ref/init.txt
+++ b/crawl-ref/init.txt
@@ -14,10 +14,11 @@
# cases (the character's name and specifying files or directories when
# on a system that has case-sensitive filenames).
#
-# White space is stripped from the begining and end of the line, as
-# well as imediately before and after the '='. If the option allows multiple
-# comma/semicolon-separated terms (such as ban_pickup), all whitespace around
-# the separator is also trimmed. All other whitespace is left intact.
+# White space is stripped from the begining and end of the line, as well as
+# imediately before and after the '='. If the option allows multiple
+# comma/semicolon-separated terms (such as autopickup_exceptions), all
+# whitespace around the separator is also trimmed. All other whitespace is left
+# intact.
#
# For descriptions concerning the option consult the file
# crawl_options.txt
@@ -74,7 +75,7 @@ lua_file = lua/trapwalk.lua
# pickup_dropped = true
# assign_item_slot = backward
#
-# ban_pickup = scrolls? of random uselessness
+# autopickup_exceptions = scrolls? of random uselessness
#
# drop_mode = (multi | single)
# pickup_mode = (single | multi | auto:5)
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 1458cac4c5..3d90aeb275 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -874,7 +874,8 @@ public:
std::vector<std::pair<int, int> > mp_colour;
std::string map_file_name; // name of mapping file to use
- std::vector<text_pattern> banned_objects; // Objects we'll never pick up
+ std::vector<text_pattern> never_pickup; // Objects we'll never pick up
+ std::vector<text_pattern> always_pickup; // Stuff we always pick up
std::vector<text_pattern> note_monsters; // Interesting monsters
std::vector<text_pattern> note_messages; // Interesting messages
std::vector<std::pair<text_pattern, std::string> > autoinscriptions;
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 84e41f56f4..d5ae9102d1 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -741,7 +741,8 @@ void game_options::reset_options()
mp_colour.push_back(std::pair<int, int>(100, LIGHTGREY));
mp_colour.push_back(std::pair<int, int>(50, YELLOW));
mp_colour.push_back(std::pair<int, int>(25, RED));
- banned_objects.clear();
+ never_pickup.clear();
+ always_pickup.clear();
note_monsters.clear();
note_messages.clear();
autoinscriptions.clear();
@@ -1802,22 +1803,39 @@ void game_options::read_option_line(const std::string &str, bool runscript)
}
else if (key == "ban_pickup")
{
- append_vector(banned_objects, split_string(",", field));
+ append_vector(never_pickup, split_string(",", field));
+ }
+ else if (key == "autopickup_exceptions")
+ {
+ std::vector<std::string> args = split_string(",", field);
+ for (int i = 0, size = args.size(); i < size; ++i)
+ {
+ const std::string &s = args[i];
+ if (s.empty())
+ continue;
+
+ if (s[0] == '>')
+ never_pickup.push_back( s.substr(1) );
+ else if (s[0] == '<')
+ always_pickup.push_back( s.substr(1) );
+ else
+ never_pickup.push_back( s );
+ }
}
else if (key == "note_items")
{
- append_vector(note_items, split_string(",", field));
+ append_vector(note_items, split_string(",", field));
}
else if (key == "autoinscribe")
{
- std::vector<std::string> thesplit = split_string(":", field);
- autoinscriptions.push_back(
- std::pair<text_pattern,std::string>(thesplit[0],
- thesplit[1]));
+ std::vector<std::string> thesplit = split_string(":", field);
+ autoinscriptions.push_back(
+ std::pair<text_pattern,std::string>(thesplit[0],
+ thesplit[1]));
}
else if (key == "map_file_name")
{
- map_file_name = field;
+ map_file_name = field;
}
else if (key == "hp_colour" || key == "hp_color")
{
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index 1c7e4681c3..a9093da5fa 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -2897,23 +2897,35 @@ static void autoinscribe_item( item_def& item )
/* if there's an inscription already do nothing */
if ( item.inscription.size() > 0 )
- return;
+ return;
- for ( unsigned i = 0; i < Options.autoinscriptions.size(); ++i ) {
- if ( Options.autoinscriptions[i].first.matches(iname) ) {
- item.inscription += Options.autoinscriptions[i].second;
- }
+ for ( unsigned i = 0; i < Options.autoinscriptions.size(); ++i )
+ {
+ if ( Options.autoinscriptions[i].first.matches(iname) )
+ {
+ item.inscription += Options.autoinscriptions[i].second;
+ }
}
}
-static bool is_banned(const item_def &item) {
- static char name[ITEMNAME_SIZE];
- item_name(item, DESC_INVENTORY, name, false);
+static bool is_denied_autopickup(const item_def &item)
+{
+ std::string iname = item_name(item, DESC_PLAIN);
+ for (unsigned i = 0, size = Options.never_pickup.size(); i < size; ++i)
+ {
+ if (Options.never_pickup[i].matches(iname))
+ return (true);
+ }
+ return false;
+}
- std::string iname = name;
- for (unsigned i = 0; i < Options.banned_objects.size(); ++i) {
- if (Options.banned_objects[i].matches(iname))
- return true;
+static bool is_forced_autopickup(const item_def &item)
+{
+ std::string iname = item_name(item, DESC_PLAIN);
+ for (unsigned i = 0, size = Options.always_pickup.size(); i < size; ++i)
+ {
+ if (Options.always_pickup[i].matches(iname))
+ return (true);
}
return false;
}
@@ -2933,15 +2945,20 @@ static void autoinscribe_items()
bool item_needs_autopickup(const item_def &item)
{
- return (strstr(item.inscription.c_str(), "=g") != 0
- || ((item.flags & ISFLAG_THROWN) && Options.pickup_thrown)
- || (((Options.autopickups & (1L << item.base_type))
+ if (strstr(item.inscription.c_str(), "=g") != 0)
+ return (true);
+
+ if ((item.flags & ISFLAG_THROWN) && Options.pickup_thrown)
+ return (true);
+
+ return (((Options.autopickups & (1L << item.base_type))
+ || is_forced_autopickup(item)
#ifdef CLUA_BINDINGS
|| clua.callbooleanfn(false, "ch_autopickup", "u", &item)
#endif
)
&& (Options.pickup_dropped || !(item.flags & ISFLAG_DROPPED))
- && !is_banned(item)));
+ && !is_denied_autopickup(item));
}
bool can_autopickup()