summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-12-01 15:20:32 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-12-01 15:20:32 +0000
commit5c65cedddfd6f3d893c7eaec03f3c8519e266d45 (patch)
treea329dac4fc6be65f3ef947fc22c5af4f3e1e8284
parent7cc367c09ed4fa3239ef8cb300cc1ef21fe129ce (diff)
downloadcrawl-ref-5c65cedddfd6f3d893c7eaec03f3c8519e266d45.tar.gz
crawl-ref-5c65cedddfd6f3d893c7eaec03f3c8519e266d45.zip
[1597293] Preliminary greedy-explore, parked on Ctrl-I. We can (re)move it if necessary.
Stash-tracking is no longer #ifdef conditionalised. I'm not aware of anybody who compiles without it. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@538 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/source/AppHdr.h4
-rw-r--r--crawl-ref/source/acr.cc9
-rw-r--r--crawl-ref/source/chardump.cc2
-rw-r--r--crawl-ref/source/command.cc6
-rw-r--r--crawl-ref/source/delay.cc7
-rw-r--r--crawl-ref/source/direct.cc9
-rw-r--r--crawl-ref/source/enum.h10
-rw-r--r--crawl-ref/source/externs.h7
-rw-r--r--crawl-ref/source/files.cc5
-rw-r--r--crawl-ref/source/initfile.cc98
-rw-r--r--crawl-ref/source/items.cc68
-rw-r--r--crawl-ref/source/items.h3
-rw-r--r--crawl-ref/source/shopping.cc9
-rw-r--r--crawl-ref/source/stash.cc71
-rw-r--r--crawl-ref/source/stash.h18
-rw-r--r--crawl-ref/source/stuff.cc6
-rw-r--r--crawl-ref/source/stuff.h2
-rw-r--r--crawl-ref/source/travel.cc142
-rw-r--r--crawl-ref/source/travel.h20
-rw-r--r--crawl-ref/source/view.cc2
20 files changed, 334 insertions, 164 deletions
diff --git a/crawl-ref/source/AppHdr.h b/crawl-ref/source/AppHdr.h
index 0a0efdd9e8..27594ac3a2 100644
--- a/crawl-ref/source/AppHdr.h
+++ b/crawl-ref/source/AppHdr.h
@@ -52,10 +52,6 @@
# define HASH_CONTAINERS
#endif
-// Enables stash-tracking: keeps track of items in the dungeon as a convenience
-// for the player.
-#define STASH_TRACKING
-
// Uncomment to enable the Crawl Lua bindings.
//
// #define CLUA_BINDINGS
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 9adaefda6a..c52a0724a2 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -1061,13 +1061,10 @@ void process_command( command_type cmd ) {
case CMD_DROP:
drop();
-#ifdef STASH_TRACKING
if (Options.stash_tracking >= STM_DROPPED)
stashes.add_stash();
-#endif
break;
-#ifdef STASH_TRACKING
case CMD_SEARCH_STASHES:
stashes.search_stashes();
break;
@@ -1081,7 +1078,6 @@ void process_command( command_type cmd ) {
if (Options.stash_tracking >= STM_EXPLICIT)
stashes.no_stash();
break;
-#endif
case CMD_BUTCHER:
butchery();
@@ -1239,13 +1235,14 @@ void process_command( command_type cmd ) {
break;
case CMD_EXPLORE:
+ case CMD_EXPLORE_GREEDY:
if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
{
mpr("It would help if you knew where you were, first.");
break;
}
// Start exploring
- start_explore();
+ start_explore(cmd == CMD_EXPLORE_GREEDY);
break;
case CMD_DISPLAY_MAP:
@@ -2407,7 +2404,7 @@ command_type keycode_to_command( keycode_type key ) {
case CONTROL('E'): return CMD_FORGET_STASH;
case CONTROL('F'): return CMD_SEARCH_STASHES;
case CONTROL('G'): return CMD_INTERLEVEL_TRAVEL;
- case CONTROL('I'): return CMD_NO_CMD;
+ case CONTROL('I'): return CMD_EXPLORE_GREEDY;
case CONTROL('M'): return CMD_NO_CMD;
case CONTROL('O'): return CMD_EXPLORE;
case CONTROL('P'): return CMD_REPLAY_MESSAGES;
diff --git a/crawl-ref/source/chardump.cc b/crawl-ref/source/chardump.cc
index e5d65e183a..0c3b343e66 100644
--- a/crawl-ref/source/chardump.cc
+++ b/crawl-ref/source/chardump.cc
@@ -987,12 +987,10 @@ static bool write_dump(
file_name += fname;
-#ifdef STASH_TRACKING
std::string stash_file_name;
stash_file_name = file_name;
stash_file_name += ".lst";
stashes.dump(stash_file_name.c_str(), full_id);
-#endif
file_name += ".txt";
FILE *handle = fopen(file_name.c_str(), "w");
diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc
index baf543036b..0e62d4c811 100644
--- a/crawl-ref/source/command.cc
+++ b/crawl-ref/source/command.cc
@@ -53,9 +53,7 @@ void quit_game(void)
static const char *features[] = {
"",
-#ifdef STASH_TRACKING
"Stash-tracking",
-#endif
#ifdef CLUA_BINDINGS
"Lua",
@@ -586,10 +584,8 @@ static int cmdhelp_keyfilter(int keyin)
static bool cmdhelp_textfilter(const std::string &tag)
{
-#ifdef STASH_TRACKING
if (tag == "s")
return (true);
-#endif
#ifdef WIZARD
if (tag == "wiz")
return (true);
@@ -1096,11 +1092,9 @@ static const char *command_string( int i )
(i == 453) ? "Ctrl-G : interlevel travel" :
(i == 455) ? "Ctrl-O : explore" :
-#ifdef STASH_TRACKING
(i == 456) ? "Ctrl-S : mark stash" :
(i == 457) ? "Ctrl-E : forget stash" :
(i == 458) ? "Ctrl-F : search stashes" :
-#endif
(i == 460) ? "Shift & DIR : long walk" :
(i == 465) ? "/ DIR : long walk" :
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index e473eb685f..204d10f488 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -359,6 +359,13 @@ void handle_delay( void )
switch (delay.type)
{
case DELAY_AUTOPICKUP:
+ // Ask the player if they want to stop explore to examine
+ // the loot, but only if we picked up at least one item
+ // that the character did not throw.
+ int estop = (you.running == RMODE_EXPLORE_GREEDY
+ && delay.parm1)? ES_GREEDY_PICKUP : ES_PICKUP;
+ if ((Options.explore_stop & estop) && prompt_stop_explore(estop))
+ stop_delay();
break;
case DELAY_WEAPON_SWAP:
diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc
index b35f3b3b6d..acbbc1ca0d 100644
--- a/crawl-ref/source/direct.cc
+++ b/crawl-ref/source/direct.cc
@@ -370,9 +370,7 @@ static void describe_oos_square(int x, int y)
if (!in_bounds(x, y) || !is_mapped(x, y))
return;
-#ifdef STASH_TRACKING
describe_stash(x, y);
-#endif
describe_feature(x, y, true);
}
@@ -788,11 +786,8 @@ static bool find_object(int x, int y, int mode)
const int item = igrd[x][y];
// The square need not be in LOS if the stash tracker knows this item.
return (item != NON_ITEM
- && (in_los(x, y)
-#ifdef STASH_TRACKING
- || (Options.target_oos && is_mapped(x, y) && is_stash(x, y))
-#endif
- ));
+ && (in_los(x, y)
+ || (Options.target_oos && is_mapped(x, y) && is_stash(x, y))));
}
static int next_los(int dir, int los, bool wrap)
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index fa119020c3..c9cc1f821a 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -636,6 +636,7 @@ enum command_type
CMD_FORGET_STASH,
CMD_SEARCH_STASHES,
CMD_EXPLORE,
+ CMD_EXPLORE_GREEDY,
CMD_INTERLEVEL_TRAVEL,
CMD_FIX_WAYPOINT,
@@ -2854,10 +2855,11 @@ enum run_dir_type
enum run_mode_type
{
- RMODE_INTERLEVEL = -3, // Interlevel travel (Ctrl+G)
- RMODE_EXPLORE = -2, // Exploring (Ctrl+O)
- RMODE_TRAVEL = -1, // Classic or Plain Old travel
- RMODE_NOT_RUNNING = 0, // must remain equal to 0
+ RMODE_INTERLEVEL = -4, // Interlevel travel (Ctrl+G)
+ RMODE_EXPLORE_GREEDY = -3, // Explore + grab items (Tab/Ctrl+I)
+ RMODE_EXPLORE = -2, // Exploring (Ctrl+O)
+ RMODE_TRAVEL = -1, // Classic or Plain Old travel
+ RMODE_NOT_RUNNING = 0, // must remain equal to 0
RMODE_CONTINUE,
RMODE_START,
RMODE_REST_DURATION = 100
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index a1cb6da756..01806f710d 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -309,6 +309,8 @@ public:
// Returns true if we're currently resting.
bool is_rest() const;
+ bool is_explore() const;
+
// Clears run state.
void clear();
@@ -845,6 +847,8 @@ public:
int explore_stop; // Stop exploring if a previously unseen
// item comes into view
+ int explore_stop_prompt;
+
std::vector<sound_mapping> sound_mappings;
std::vector<colour_mapping> menu_colour_mappings;
@@ -942,8 +946,9 @@ private:
void set_activity_interrupt(const std::string &activity_name,
const std::string &interrupt_names,
bool append_interrupts);
- void add_dump_fields(const std::string &text);
+ void new_dump_fields(const std::string &text, bool add = true);
void do_kill_map(const std::string &from, const std::string &to);
+ int read_explore_stop_conditions(const std::string &) const;
static const std::string interrupt_prefix;
};
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index 037f35f185..a042cbdf48 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -1162,8 +1162,6 @@ void save_level(int level_saved, bool was_a_labyrinth, char where_were_you)
void save_game(bool leave_game)
{
-
-#ifdef STASH_TRACKING
/* Stashes */
std::string stashFile = get_savedir_filename( you.your_name, "", "st" );
FILE *stashf = fopen(stashFile.c_str(), "wb");
@@ -1172,7 +1170,6 @@ void save_game(bool leave_game)
fclose(stashf);
DO_CHMOD_PRIVATE(stashFile.c_str());
}
-#endif
#ifdef CLUA_BINDINGS
/* lua */
@@ -1383,14 +1380,12 @@ void restore_game(void)
fclose(charf);
-#ifdef STASH_TRACKING
std::string stashFile = get_savedir_filename( you.your_name, "", "st" );
FILE *stashf = fopen(stashFile.c_str(), "rb");
if (stashf) {
stashes.load(stashf);
fclose(stashf);
}
-#endif
#ifdef CLUA_BINDINGS
std::string luaFile = get_savedir_filename( you.your_name, "", "lua" );
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 046955401c..19fbf8cae9 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -381,10 +381,26 @@ static unsigned curses_attribute(const std::string &field)
return CHATTR_NORMAL;
}
-void game_options::add_dump_fields(const std::string &text)
+void game_options::new_dump_fields(const std::string &text, bool add)
{
// Easy; chardump.cc has most of the intelligence.
- append_vector(dump_order, split_string(",", text, true, true));
+ std::vector<std::string> fields = split_string(",", text, true, true);
+ if (add)
+ append_vector(dump_order, fields);
+ else
+ {
+ for (int f = 0, size = fields.size(); f < size; ++f)
+ {
+ for (int i = 0, dsize = dump_order.size(); i < dsize; ++i)
+ {
+ if (dump_order[i] == fields[f])
+ {
+ dump_order.erase( dump_order.begin() + i );
+ break;
+ }
+ }
+ }
+ }
}
void game_options::reset_startup_options()
@@ -605,10 +621,14 @@ void game_options::reset_options()
// 10 was the cursor step default on Linux.
level_map_cursor_step = 7;
-#ifdef STASH_TRACKING
stash_tracking = STM_ALL;
-#endif
+
explore_stop = ES_ITEM | ES_STAIR | ES_SHOP | ES_ALTAR;
+
+ // The prompt conditions will be combined into explore_stop after
+ // reading options.
+ explore_stop_prompt = ES_GREEDY_PICKUP;
+
safe_zero_exp = true;
target_zero_exp = false;
target_wrap = true;
@@ -679,7 +699,7 @@ void game_options::reset_options()
// Clear vector options.
dump_order.clear();
- add_dump_fields("header,stats,misc,inventory,skills,"
+ new_dump_fields("header,stats,misc,inventory,skills,"
"spells,,mutations,messages,screenshot,kills,notes");
banned_objects.clear();
@@ -1108,6 +1128,8 @@ void game_options::read_options(InitLineInput &il, bool runscript)
}
#endif
+ Options.explore_stop |= Options.explore_stop_prompt;
+
// Validate save_dir
check_savedir(save_dir);
}
@@ -1135,6 +1157,29 @@ void game_options::do_kill_map(const std::string &from, const std::string &to)
kill_map[ifrom] = ito;
}
+int game_options::read_explore_stop_conditions(const std::string &field) const
+{
+ int conditions = 0;
+ std::vector<std::string> stops = split_string(",", field);
+ for (int i = 0, count = stops.size(); i < count; ++i)
+ {
+ const std::string &c = stops[i];
+ if (c == "item" || c == "items")
+ conditions |= ES_ITEM;
+ else if (c == "pickup")
+ conditions |= ES_PICKUP;
+ else if (c == "greedy_pickup" || c == "greedy pickup")
+ conditions |= ES_GREEDY_PICKUP;
+ else if (c == "shop" || c == "shops")
+ conditions |= ES_SHOP;
+ else if (c == "stair" || c == "stairs")
+ conditions |= ES_STAIR;
+ else if (c == "altar" || c == "altars")
+ conditions |= ES_ALTAR;
+ }
+ return (conditions);
+}
+
void game_options::read_option_line(const std::string &str, bool runscript)
{
std::string key = "";
@@ -1145,6 +1190,7 @@ void game_options::read_option_line(const std::string &str, bool runscript)
int first_dot = str.find('.');
bool plus_equal = false;
+ bool minus_equal = false;
// all lines with no equal-signs we ignore
if (first_equals < 0)
@@ -1174,6 +1220,12 @@ void game_options::read_option_line(const std::string &str, bool runscript)
key = key.substr(0, key.length() - 1);
trim_string(key);
}
+ else if (key.length() && key[key.length() - 1] == '-')
+ {
+ minus_equal = true;
+ key = key.substr(0, key.length() - 1);
+ trim_string(key);
+ }
tolower_string( trim_string( subkey ) );
@@ -1872,22 +1924,25 @@ void game_options::read_option_line(const std::string &str, bool runscript)
}
else if (key == "explore_stop")
{
- explore_stop = ES_NONE;
- std::vector<std::string> stops = split_string(",", field);
- for (int i = 0, count = stops.size(); i < count; ++i)
- {
- const std::string &c = stops[i];
- if (c == "item" || c == "items")
- explore_stop |= ES_ITEM;
- else if (c == "shop" || c == "shops")
- explore_stop |= ES_SHOP;
- else if (c == "stair" || c == "stairs")
- explore_stop |= ES_STAIR;
- else if (c == "altar" || c == "altars")
- explore_stop |= ES_ALTAR;
- }
+ if (!plus_equal && !minus_equal)
+ explore_stop = ES_NONE;
+
+ const int new_conditions = read_explore_stop_conditions(field);
+ if (minus_equal)
+ explore_stop &= ~new_conditions;
+ else
+ explore_stop |= new_conditions;
+ }
+ else if (key == "explore_stop_prompt")
+ {
+ if (!plus_equal && !minus_equal)
+ explore_stop_prompt = ES_NONE;
+ const int new_conditions = read_explore_stop_conditions(field);
+ if (minus_equal)
+ explore_stop_prompt &= ~new_conditions;
+ else
+ explore_stop_prompt |= new_conditions;
}
-#ifdef STASH_TRACKING
else if (key == "stash_tracking")
{
stash_tracking =
@@ -1901,7 +1956,6 @@ void game_options::read_option_line(const std::string &str, bool runscript)
for (int i = 0, count = seg.size(); i < count; ++i)
Stash::filter( seg[i] );
}
-#endif
else if (key == "sound")
{
std::vector<std::string> seg = split_string(",", field);
@@ -1936,7 +1990,7 @@ void game_options::read_option_line(const std::string &str, bool runscript)
if (!plus_equal)
dump_order.clear();
- add_dump_fields(field);
+ new_dump_fields(field, !minus_equal);
}
else if (key == "dump_kill_places")
{
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index e0313a6ff6..c040288570 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -2882,47 +2882,63 @@ static void autoinscribe_items()
autoinscribe_item( mitm[o] );
o = next;
}
-}
+}
-static void autopickup(void)
+bool item_needs_autopickup(const item_def &item)
{
- //David Loewenstern 6/99
- int result, o, next;
- bool did_pickup = false;
-
- if (!Options.autopickup_on || Options.autopickups == 0L)
- return;
+ return (strstr(item.inscription.c_str(), "=g") != 0
+ || ((item.flags & ISFLAG_THROWN) && Options.pickup_thrown)
+ || (((Options.autopickups & (1L << item.base_type))
+#ifdef CLUA_BINDINGS
+ || clua.callbooleanfn(false, "ch_autopickup", "u", &item)
+#endif
+ )
+ && (Options.pickup_dropped || !(item.flags & ISFLAG_DROPPED))
+ && !is_banned(item)));
+}
+
+bool can_autopickup()
+{
+ // [ds] Checking for autopickups == 0 is a bad idea because
+ // autopickup is still possible with inscriptions and
+ // pickup_thrown.
+ if (!Options.autopickup_on)
+ return (false);
if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR
- && you.duration[DUR_TRANSFORMATION] > 0)
- {
- return;
- }
+ && you.duration[DUR_TRANSFORMATION] > 0)
+ return (false);
if (player_is_levitating() && !wearing_amulet(AMU_CONTROLLED_FLIGHT))
- return;
+ return (false);
if ( Options.safe_autopickup && !i_feel_safe() )
- return;
+ return (false);
+ return (true);
+}
+
+static void autopickup(void)
+{
+ //David Loewenstern 6/99
+ int result, o, next;
+ bool did_pickup = false;
+
+ if (!can_autopickup())
+ return;
+
o = igrd[you.x_pos][you.y_pos];
+ int unthrown = 0;
while (o != NON_ITEM)
{
next = mitm[o].link;
- if (
- (strstr(mitm[o].inscription.c_str(), "=g") != 0) || (
-
- ((mitm[o].flags & ISFLAG_THROWN) && Options.pickup_thrown) ||
- ( (Options.autopickups & (1L << mitm[o].base_type)
-#ifdef CLUA_BINDINGS
- || clua.callbooleanfn(false, "ch_autopickup", "u", &mitm[o])
-#endif
- )
- && (Options.pickup_dropped || !(mitm[o].flags & ISFLAG_DROPPED))
- && !is_banned(mitm[o]))))
+ if (item_needs_autopickup(mitm[o]))
{
+ if (!(mitm[o].flags & ISFLAG_THROWN))
+ unthrown++;
+
mitm[o].flags &= ~(ISFLAG_THROWN | ISFLAG_DROPPED);
result = move_item_to_player( o, mitm[o].quantity);
@@ -2950,7 +2966,7 @@ static void autopickup(void)
if (did_pickup)
{
you.turn_is_over = true;
- start_delay( DELAY_AUTOPICKUP, 1 );
+ start_delay( DELAY_AUTOPICKUP, 1, unthrown );
}
}
diff --git a/crawl-ref/source/items.h b/crawl-ref/source/items.h
index 53a779c2b9..f905e024a5 100644
--- a/crawl-ref/source/items.h
+++ b/crawl-ref/source/items.h
@@ -139,4 +139,7 @@ void origin_set_startequip(item_def &item);
void origin_set_unknown(item_def &item);
void origin_set_inventory( void (*oset)(item_def &item) );
+bool item_needs_autopickup(const item_def &);
+bool can_autopickup();
+
#endif
diff --git a/crawl-ref/source/shopping.cc b/crawl-ref/source/shopping.cc
index 6f80839df1..0a8ae39a88 100644
--- a/crawl-ref/source/shopping.cc
+++ b/crawl-ref/source/shopping.cc
@@ -137,9 +137,7 @@ char in_a_shop( char shoppy, id_arr id )
snprintf( info, INFO_SIZE, "Welcome to %s!",
shop_name(env.shop[shoppy].x, env.shop[shoppy].y) );
-#ifdef STASH_TRACKING
ShopInfo &si = stashes.get_shop(env.shop[shoppy].x, env.shop[shoppy].y);
-#endif
shop_print(info, 20);
@@ -161,9 +159,8 @@ char in_a_shop( char shoppy, id_arr id )
clrscr();
itty = igrd[0][5 + shoppy];
-#ifdef STASH_TRACKING
si.reset();
-#endif
+
if (itty == NON_ITEM)
{
shop_print("I'm sorry, my shop is empty now.", 20);
@@ -216,12 +213,10 @@ char in_a_shop( char shoppy, id_arr id )
desc = munge_description(get_item_description(mitm[itty],
Options.verbose_dump,
true ));
-# ifdef STASH_TRACKING
si.add_item(mitm[itty], gp_value);
-# endif
gotoxy(60, i);
- textcolor( can_afford ? LIGHTGREEN : LIGHTRED );
+ textcolor( can_afford ? LIGHTGREEN : LIGHTRED );
snprintf(st_pass, sizeof(st_pass), "%5d", gp_value);
cprintf("%s gold", st_pass);
if (mitm[itty].link == NON_ITEM)
diff --git a/crawl-ref/source/stash.cc b/crawl-ref/source/stash.cc
index b1b027fb3a..02e7ec5125 100644
--- a/crawl-ref/source/stash.cc
+++ b/crawl-ref/source/stash.cc
@@ -31,8 +31,6 @@
#include <fstream>
#include <algorithm>
-#ifdef STASH_TRACKING
-
#define ST_MAJOR_VER ((unsigned char) 4)
#define ST_MINOR_VER ((unsigned char) 4)
@@ -163,14 +161,22 @@ Stash::Stash(int xp, int yp) : enabled(true), items()
bool Stash::are_items_same(const item_def &a, const item_def &b)
{
- return a.base_type == b.base_type &&
- a.sub_type == b.sub_type &&
- a.plus == b.plus &&
- a.plus2 == b.plus2 &&
- a.special == b.special &&
- a.colour == b.colour &&
- a.flags == b.flags &&
- a.quantity == b.quantity;
+ const bool same = a.base_type == b.base_type
+ && a.sub_type == b.sub_type
+ && a.plus == b.plus
+ && a.plus2 == b.plus2
+ && a.special == b.special
+ && a.colour == b.colour
+ && a.flags == b.flags
+ && a.quantity == b.quantity;
+
+ // Account for rotting meat when comparing items.
+ return (same
+ || (a.base_type == b.base_type
+ && (a.base_type == OBJ_CORPSES
+ || (a.base_type == OBJ_FOOD && a.sub_type == FOOD_CHUNK
+ && b.sub_type == FOOD_CHUNK))
+ && a.plus == b.plus));
}
void Stash::filter(const std::string &str)
@@ -216,6 +222,19 @@ bool Stash::is_filtered(const item_def &item)
return false;
}
+bool Stash::unverified() const
+{
+ return (!verified);
+}
+
+bool Stash::pickup_eligible() const
+{
+ for (int i = 0, size = items.size(); i < size; ++i)
+ if (item_needs_autopickup(items[i]))
+ return (true);
+ return (false);
+}
+
void Stash::update()
{
int objl = igrd[x][y];
@@ -247,9 +266,10 @@ void Stash::update()
}
// There's something on this square. Take a squint at it.
- item_def &item = mitm[objl];
+ const item_def &item = mitm[objl];
- if (item.link == NON_ITEM) items.clear();
+ if (item.link == NON_ITEM)
+ items.clear();
// We knew of nothing on this square, so we'll assume this is the
// only item here, but mark it as unverified unless we can see nothing
@@ -268,7 +288,7 @@ void Stash::update()
if (is_filtered(item)) return;
- item_def &first = items[0];
+ const item_def &first = items[0];
// Compare these items
if (!are_items_same(first, item))
{
@@ -841,13 +861,19 @@ bool LevelStashes::isBelowPlayer() const
Stash *LevelStashes::find_stash(int x, int y)
{
+ return const_cast<Stash *>(
+ const_cast<const LevelStashes *>(this)->find_stash(x, y) );
+}
+
+const Stash *LevelStashes::find_stash(int x, int y) const
+{
if (x == -1 || y == -1)
{
x = you.x_pos;
y = you.y_pos;
}
const int abspos = (GXM * y) + x;
- c_stashes::iterator st = stashes.find(abspos);
+ c_stashes::const_iterator st = stashes.find(abspos);
return (st == stashes.end()? NULL : &st->second);
}
@@ -861,6 +887,21 @@ const ShopInfo *LevelStashes::find_shop(int x, int y) const
return (NULL);
}
+bool LevelStashes::shop_needs_visit(int x, int y) const
+{
+ const ShopInfo *shop = find_shop(x, y);
+ return (shop && !shop->is_visited());
+}
+
+bool LevelStashes::needs_visit(int x, int y) const
+{
+ const Stash *s = find_stash(x, y);
+ if (s && (s->unverified() || s->pickup_eligible()))
+ return (true);
+
+ return (shop_needs_visit(x, y));
+}
+
ShopInfo &LevelStashes::get_shop(int x, int y)
{
for (unsigned i = 0; i < shops.size(); ++i)
@@ -1499,5 +1540,3 @@ void StashTracker::display_search_results(
// Global
StashTracker stashes;
-
-#endif
diff --git a/crawl-ref/source/stash.h b/crawl-ref/source/stash.h
index 727fb656e4..9727102067 100644
--- a/crawl-ref/source/stash.h
+++ b/crawl-ref/source/stash.h
@@ -10,8 +10,6 @@
#include "shopping.h"
#include <string>
-#ifdef STASH_TRACKING
-
#include <iostream>
#include <map>
#include <vector>
@@ -48,6 +46,14 @@ public:
bool show_menu(const std::string &place, bool can_travel) const;
+ // Returns true if this Stash contains items that are eligible for
+ // autopickup.
+ bool pickup_eligible() const;
+
+ // Returns true if this Stash is unverified (a visit by the character will
+ // verify the stash).
+ bool unverified() const;
+
bool matches_search(const std::string &prefix,
const base_pattern &search,
stash_search_result &res)
@@ -197,6 +203,7 @@ public:
LevelStashes();
Stash *find_stash(int x = -1, int y = -1);
+ const Stash *find_stash(int x = -1, int y = -1) const;
ShopInfo &get_shop(int x, int y);
const ShopInfo *find_shop(int x, int y) const;
@@ -207,6 +214,11 @@ public:
// location if no parameters are supplied.
bool update_stash(int x = -1, int y = -1);
+ // Returns true if the square at (x,y) contains potentially interesting
+ // swag that merits a personal visit (for EXPLORE_GREEDY).
+ bool needs_visit(int x, int y) const;
+ bool shop_needs_visit(int x, int y) const;
+
// Add stash at (x,y), or player's current location if no parameters are
// supplied
void add_stash(int x = -1, int y = -1);
@@ -315,8 +327,6 @@ extern StashTracker stashes;
bool is_stash(int x, int y);
void describe_stash(int x, int y);
-#endif // STASH_TRACKING
-
std::string userdef_annotate_item(const char *s, const item_def *item,
bool exclusive = false);
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index 9e25382662..0f30d16dc2 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -698,11 +698,13 @@ void canned_msg(unsigned char which_message)
// jmf: general helper (should be used all over in code)
// -- idea borrowed from Nethack
-bool yesno( const char *str, bool safe, int safeanswer, bool clear_after )
+bool yesno( const char *str, bool safe, int safeanswer, bool clear_after,
+ bool interrupt_delays )
{
unsigned char tmp;
- interrupt_activity( AI_FORCE_INTERRUPT );
+ if (interrupt_delays)
+ interrupt_activity( AI_FORCE_INTERRUPT );
for (;;)
{
mpr(str, MSGCH_PROMPT);
diff --git a/crawl-ref/source/stuff.h b/crawl-ref/source/stuff.h
index 2356eeb5d4..7ae7726222 100644
--- a/crawl-ref/source/stuff.h
+++ b/crawl-ref/source/stuff.h
@@ -60,7 +60,7 @@ void redraw_screen(void);
void canned_msg(unsigned char which_message);
bool yesno( const char * str, bool safe = true, int safeanswer = 0,
- bool clear_after = true );
+ bool clear_after = true, bool interrupt_delays = true );
int yesnoquit( const char* str, bool safe = true,
int safeanswer = 0, bool clear_after = true );
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index 49f1002bbd..84bc069b00 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -15,6 +15,8 @@
#include "clua.h"
#include "delay.h"
#include "describe.h"
+#include "itemname.h"
+#include "items.h"
#include "misc.h"
#include "mon-util.h"
#include "player.h"
@@ -252,11 +254,12 @@ static bool is_exclude_root(int x, int y)
const char *run_mode_name(int runmode)
{
- return runmode == RMODE_TRAVEL? "travel" :
- runmode == RMODE_INTERLEVEL? "intertravel" :
- runmode == RMODE_EXPLORE? "explore" :
- runmode > 0? "run" :
- "";
+ return runmode == RMODE_TRAVEL? "travel" :
+ runmode == RMODE_INTERLEVEL? "intertravel" :
+ runmode == RMODE_EXPLORE? "explore" :
+ runmode == RMODE_EXPLORE_GREEDY? "explore_greedy" :
+ runmode > 0? "run" :
+ "";
}
unsigned char is_waypoint(int x, int y)
@@ -267,7 +270,6 @@ unsigned char is_waypoint(int x, int y)
return curr_waypoints[x][y];
}
-#ifdef STASH_TRACKING
inline bool is_stash(LevelStashes *ls, int x, int y)
{
if (!ls)
@@ -275,7 +277,6 @@ inline bool is_stash(LevelStashes *ls, int x, int y)
Stash *s = ls->find_stash(x, y);
return s && s->enabled;
}
-#endif
void clear_excludes()
{
@@ -693,10 +694,30 @@ bool is_travelable_stair(unsigned gridc)
}
}
+// Prompts the user to stop explore if necessary for the given
+// explore-stop condition, returns true if explore should be stopped.
+bool prompt_stop_explore(int es_why)
+{
+ return (!(Options.explore_stop_prompt & es_why)
+ || yesno("Stop exploring?", true, 'n', true, false));
+}
+
+static bool es_say(const char *what)
+{
+ mprf("Spotted %s.", what);
+ return (true);
+}
+
#define ES_item (Options.explore_stop & ES_ITEM)
-#define ES_shop (Options.explore_stop & ES_SHOP)
-#define ES_stair (Options.explore_stop & ES_STAIR)
-#define ES_altar (Options.explore_stop & ES_ALTAR)
+
+#define ES_shop ((Options.explore_stop & ES_SHOP) && \
+ es_say("a shop") && prompt_stop_explore(ES_SHOP))
+
+#define ES_stair ((Options.explore_stop & ES_STAIR) && \
+ es_say("a stair") && prompt_stop_explore(ES_STAIR))
+
+#define ES_altar ((Options.explore_stop & ES_ALTAR) && \
+ es_say("an altar") && prompt_stop_explore(ES_ALTAR))
/*
* Given a square that has just become visible during explore, returns true
@@ -704,14 +725,22 @@ bool is_travelable_stair(unsigned gridc)
*/
static bool is_interesting_square(int x, int y)
{
- if (ES_item && igrd[x + 1][y + 1] != NON_ITEM)
- return true;
+ if (ES_item && igrd[x + 1][y + 1] != NON_ITEM
+ && you.running != RMODE_EXPLORE_GREEDY)
+ {
+ mprf("Spotted %s.",
+ item_name( mitm[ igrd[x + 1][y + 1] ], DESC_NOCAP_A ));
+ if (prompt_stop_explore(ES_ITEM))
+ return (true);
+ }
unsigned char grid = grd[x + 1][y + 1];
- return (ES_shop && grid == DNGN_ENTER_SHOP)
- || (ES_stair && is_stair(grid))
- || (ES_altar && is_altar(grid)
- && you.where_are_you != BRANCH_ECUMENICAL_TEMPLE);
+ return (grid == DNGN_ENTER_SHOP && you.running != RMODE_EXPLORE_GREEDY
+ && ES_shop)
+ || (is_stair(grid) && ES_stair)
+ || (is_altar(grid)
+ && you.where_are_you != BRANCH_ECUMENICAL_TEMPLE
+ && ES_altar);
}
static void userdef_run_stoprunning_hook(void)
@@ -739,9 +768,7 @@ void start_running(void)
{
userdef_run_startrunning_hook();
- if (you.running == RMODE_TRAVEL
- || you.running == RMODE_EXPLORE
- || you.running == RMODE_INTERLEVEL)
+ if (you.running < 0)
start_delay( DELAY_TRAVEL, 1 );
}
@@ -778,7 +805,7 @@ command_type travel()
return CMD_NO_CMD;
}
- if (Options.explore_stop && you.running == RMODE_EXPLORE)
+ if (you.running.is_explore())
{
// Scan through the shadow map, compare it with the actual map, and if
// there are any squares of the shadow map that have just been
@@ -801,9 +828,20 @@ command_type travel()
copy(env.map, mapshadow);
}
- if (you.running == RMODE_EXPLORE)
+ if (you.running.is_explore())
{
// Exploring
+ if (grd[you.x_pos][you.y_pos] == DNGN_ENTER_SHOP
+ && you.running == RMODE_EXPLORE_GREEDY)
+ {
+ LevelStashes *lev = stashes.find_current_level();
+ if (lev && lev->shop_needs_visit(you.x_pos, you.y_pos))
+ {
+ stop_running();
+ return (CMD_GO_UPSTAIRS);
+ }
+ }
+
you.running.x = 0;
find_travel_pos(you.x_pos, you.y_pos, NULL, NULL);
// No place to go?
@@ -839,8 +877,8 @@ command_type travel()
// our travel target, we're on a staircase and should take it.
if (you.x_pos == you.running.x && you.y_pos == you.running.y)
{
- if (runmode == RMODE_EXPLORE)
- you.running = RMODE_EXPLORE; // Turn explore back on
+ if (runmode == RMODE_EXPLORE || runmode == RMODE_EXPLORE_GREEDY)
+ you.running = runmode; // Turn explore back on
// For interlevel travel, we'll want to take the stairs unless
// the interlevel travel specified a destination square and
@@ -945,6 +983,11 @@ static void fill_exclude_radius(const coord_def &c)
}
}
+static bool is_greed_inducing_square(const LevelStashes *ls, int x, int y)
+{
+ return (ls && can_autopickup() && ls->needs_visit(x, y));
+}
+
/*
* The travel algorithm is based on the NetHack travel code written by Warwick
* Allison - used with his permission.
@@ -959,9 +1002,7 @@ void find_travel_pos(int youx, int youy,
int dest_x = youx, dest_y = youy;
bool floodout = false;
unsigned char feature;
-#ifdef STASH_TRACKING
- LevelStashes *lev = features? stashes.find_current_level() : NULL;
-#endif
+ LevelStashes *lev = stashes.find_current_level();
// Normally we start from the destination and floodfill outwards, looking
// for the character's current position. If we're merely trying to populate
@@ -1063,19 +1104,29 @@ void find_travel_pos(int youx, int youy,
for (int dir = 0; dir < 8; (dir += 2) == 8 && (dir = 1))
{
int dx = x + Compass[dir].x, dy = y + Compass[dir].y;
-
- if (dx <= 0 || dx >= GXM || dy <= 0 || dy >= GYM) continue;
+
+ if (!in_bounds(dx, dy))
+ continue;
unsigned char envf = env.map[dx - 1][dy - 1];
- if (floodout && you.running == RMODE_EXPLORE
- && !is_player_mapped(envf))
+ if (floodout && you.running.is_explore()
+ && (!is_player_mapped(envf)
+ || (you.running == RMODE_EXPLORE_GREEDY
+ && is_greed_inducing_square(lev, dx, dy))))
{
// Setting running.x and running.y here is evil - this
// function should ideally not modify game state in any way.
- you.running.x = x;
- you.running.y = y;
-
+ if (!is_player_mapped(envf))
+ {
+ you.running.x = x;
+ you.running.y = y;
+ }
+ else
+ {
+ you.running.x = dx;
+ you.running.y = dy;
+ }
return;
}
@@ -1144,10 +1195,7 @@ void find_travel_pos(int youx, int youy,
&& feature != DNGN_DEEP_WATER
&& feature != DNGN_LAVA)
|| is_waypoint(dx, dy)
-#ifdef STASH_TRACKING
- || is_stash(lev, dx, dy)
-#endif
- )
+ || is_stash(lev, dx, dy))
&& (dx != start_x || dy != start_y))
{
coord_def c = { dx, dy };
@@ -2155,14 +2203,19 @@ void start_travel(int x, int y)
start_running();
}
-void start_explore()
+void start_explore(bool grab_items)
{
- you.running = RMODE_EXPLORE;
- if (Options.explore_stop)
+ you.running = grab_items? RMODE_EXPLORE_GREEDY : RMODE_EXPLORE;
+ if (you.running == RMODE_EXPLORE_GREEDY
+ && Options.stash_tracking != STM_ALL)
{
- // Clone shadow array off map
- copy(env.map, mapshadow);
+ mpr("Explore + pickup is available only if stash_tracking = all");
+ you.running = RMODE_EXPLORE;
}
+
+ // Clone shadow array off map
+ copy(env.map, mapshadow);
+
start_running();
}
@@ -3118,6 +3171,11 @@ bool runrest::is_rest() const
return (runmode > 0 && !x && !y);
}
+bool runrest::is_explore() const
+{
+ return (runmode == RMODE_EXPLORE || runmode == RMODE_EXPLORE_GREEDY);
+}
+
void runrest::rundown()
{
rest();
diff --git a/crawl-ref/source/travel.h b/crawl-ref/source/travel.h
index bd6e4221bc..935840963c 100644
--- a/crawl-ref/source/travel.h
+++ b/crawl-ref/source/travel.h
@@ -46,11 +46,14 @@ void find_travel_pos(int you_x, int you_y, char *move_x, char *move_y,
* Initiates explore - the character runs around the level to map it. Note
* that the caller has to ensure that the level is mappable before calling
* start_explore. start_explore may lock up the game on unmappable levels.
+ * If grab_items is true, greedy explore is triggered - in greedy mode, explore
+ * grabs items that are eligible for autopickup and visits (previously
+ * unvisited) shops.
*
* ***********************************************************************
* called from: acr
* *********************************************************************** */
-void start_explore();
+void start_explore(bool grab_items = false);
struct level_pos;
void start_translevel_travel(const level_pos &pos);
@@ -92,13 +95,15 @@ void arrange_features(std::vector<coord_def> &features);
* *********************************************************************** */
extern short point_distance[GXM][GYM];
-enum EXPLORE_STOP
+enum explore_stop_type
{
- ES_NONE = 0,
- ES_ITEM = 1,
- ES_STAIR = 2,
- ES_SHOP = 4,
- ES_ALTAR = 8
+ ES_NONE = 0x00,
+ ES_ITEM = 0x01,
+ ES_PICKUP = 0x02,
+ ES_GREEDY_PICKUP = 0x04,
+ ES_STAIR = 0x08,
+ ES_SHOP = 0x10,
+ ES_ALTAR = 0x20
};
////////////////////////////////////////////////////////////////////////////
@@ -359,6 +364,7 @@ private:
int level_distance(level_id first, level_id second);
bool can_travel_interlevel();
+bool prompt_stop_explore(int es_why);
extern TravelCache travel_cache;
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 9d989da86a..87fedccb2c 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -1692,10 +1692,8 @@ bool is_feature(int feature, int x, int y) {
case 'F':
case 'W':
return is_waypoint(x, y);
-#ifdef STASH_TRACKING
case 'I':
return is_stash(x, y);
-#endif
case '_':
switch (grid) {
case DNGN_ALTAR_ZIN: