diff options
-rw-r--r-- | crawl-ref/docs/options_guide.txt | 14 | ||||
-rw-r--r-- | crawl-ref/settings/init.txt | 2 | ||||
-rw-r--r-- | crawl-ref/source/acr.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/initfile.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/stash.cc | 138 | ||||
-rw-r--r-- | crawl-ref/source/stash.h | 15 |
7 files changed, 177 insertions, 7 deletions
diff --git a/crawl-ref/docs/options_guide.txt b/crawl-ref/docs/options_guide.txt index 98d5e94395..f2b13e265d 100644 --- a/crawl-ref/docs/options_guide.txt +++ b/crawl-ref/docs/options_guide.txt @@ -51,7 +51,8 @@ The contents of this text are: trap_prompt, rest_wait_both 4-h Stashes. stash_tracking, stash_filter, annotate_item_class, - annoate_item_dropped + annoate_item_dropped, stash_track_decay, + stash_remove_decay 4-i Command Enhancements. auto_list, easy_open, easy_unequip, easy_confirm, easy_butcher, always_confirm_butcher, chunks_autopickup, @@ -882,6 +883,17 @@ annotate_item_dropped = false init.txt. Annotates dropped items with {dropped} for stash searching. +stash_track_decay = false + If set to true then the stash tracker will remember how long its + been since you've seen chunks of meat or a corpse or skeleton and + tell you what state its in by adding "rotten by now", + "skeletalised by now" or "gone by now" to its name. + +stash_remove_decay = false + If both this and stash_track_decay are set to true, anything that + would have been reported as "gone by now" will instead be + removed from the stash tracker's memory. + 4-i Command Enhancements. ----------------------------- diff --git a/crawl-ref/settings/init.txt b/crawl-ref/settings/init.txt index af9b1a424a..c915c1ac57 100644 --- a/crawl-ref/settings/init.txt +++ b/crawl-ref/settings/init.txt @@ -197,6 +197,8 @@ include = travel_stoppers.txt # stash_filter = 14, 4:21 # annotate_item_class = true # annotate_item_dropped = true +# stash_track_decay = true +# stash_remove_decay = true ##### 4-i Command Enhancements ################## # diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 969fff663f..c9dcd815d8 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -1441,6 +1441,12 @@ static void _input() _world_reacts(); return; } + else + { + // Don't do this while delayed, so as to not slow down resting + // and travel by iterating over all stahses once per player turn. + StashTrack.update_corpses(); + } if ( you.turn_is_over ) { diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 102e7f7fc3..6a04a5081b 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -1714,6 +1714,10 @@ public: int stash_tracking; // How stashes are tracked + bool stash_track_decay; // Keep track of how decayed corpses are + bool stash_remove_decay; // Remove corpses that have most probably + // completely rotted away + int tc_reachable; // Colour for squares that are reachable int tc_excluded; // Colour for excluded squares. int tc_exclude_circle; // Colour for squares in the exclusion radius diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index 1b6b0025ff..3f53faf6bd 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -738,6 +738,9 @@ void game_options::reset_options() stash_tracking = STM_ALL; + stash_track_decay = false; + stash_remove_decay = false; + explore_stop = ES_ITEM | ES_STAIR | ES_PORTAL | ES_SHOP | ES_ALTAR | ES_GREEDY_PICKUP; @@ -2573,6 +2576,8 @@ void game_options::read_option_line(const std::string &str, bool runscript) field == "all" ? STM_ALL : STM_EXPLICIT; } + else BOOL_OPTION(stash_track_decay); + else BOOL_OPTION(stash_remove_decay); else if (key == "stash_filter") { std::vector<std::string> seg = split_string(",", field); diff --git a/crawl-ref/source/stash.cc b/crawl-ref/source/stash.cc index c6f8bc0ea6..694a2996a4 100644 --- a/crawl-ref/source/stash.cc +++ b/crawl-ref/source/stash.cc @@ -25,6 +25,7 @@ #include "menu.h" #include "message.h" #include "misc.h" +#include "mon-util.h" #include "notes.h" #include "overmap.h" #include "place.h" @@ -49,7 +50,7 @@ StashTracker StashTrack; #define ST_MAJOR_VER ((unsigned char) 4) -#define ST_MINOR_VER ((unsigned char) 7) +#define ST_MINOR_VER ((unsigned char) 8) void stash_init_new_level() { @@ -279,7 +280,7 @@ void Stash::update() while (objl != NON_ITEM) { if (!is_filtered(mitm[objl])) - items.push_back(mitm[objl]); + add_item(mitm[objl]); objl = mitm[objl].link; } @@ -310,7 +311,7 @@ void Stash::update() if (items.size() == 0) { if (!is_filtered(item)) - items.push_back(item); + add_item(item); verified = (item.link == NON_ITEM); return ; } @@ -354,17 +355,61 @@ void Stash::update() // Items are different. We'll put this item in the front of our // vector, and mark this as unverified - items.insert(items.begin(), item); + add_item(item, true); verified = false; } } } +static bool _is_rottable(const item_def &item) +{ + return (item.base_type == OBJ_CORPSES + || (item.base_type == OBJ_FOOD && item.sub_type == FOOD_CHUNK)); +} + +static short _min_rot(const item_def &item) +{ + if (item.base_type == OBJ_FOOD) + return 0; + + if (item.base_type == OBJ_CORPSES && item.sub_type == CORPSE_SKELETON) + return 0; + + if (!mons_skeleton(item.plus)) + return 0; + else + return -200; +} + // Returns the item name for a given item, with any appropriate // stash-tracking pre/suffixes. std::string Stash::stash_item_name(const item_def &item) { - return item.name(DESC_NOCAP_A); + std::string name = item.name(DESC_NOCAP_A); + + if (!Options.stash_track_decay || !_is_rottable(item)) + return name; + + if (item.plus2 <= _min_rot(item)) + { + name += " (gone by now)"; + return name; + } + + // Skeletons show no signs of rotting before they're gone + if (item.base_type == OBJ_CORPSES && item.sub_type == CORPSE_SKELETON) + return name; + + // Item was already seen to be rotten + if (item.special < 100) + return name; + + if (item.plus2 <= 0) + name += " (skeletalised by now)"; + else if (item.plus2 < 100) + name += " (rotten by now)"; + + return name; } class StashMenu : public InvMenu @@ -544,6 +589,54 @@ bool Stash::matches_search(const std::string &prefix, return !!res.matches; } +void Stash::_update_corpses(long rot_time) +{ + for (int i = items.size() - 1; i >= 0; i--) + { + item_def &item = items[i]; + + if (!_is_rottable(item)) + continue; + + long new_rot = static_cast<long>(item.plus2) - rot_time; + + if (new_rot <= _min_rot(item)) + { + if (Options.stash_remove_decay) + { + items.erase(items.begin() + i); + continue; + } + new_rot = _min_rot(item); + } + item.plus2 = static_cast<short>(new_rot); + } +} + +void Stash::add_item(const item_def &item, bool add_to_front) +{ + if (add_to_front) + items.insert(items.begin(), item); + else + items.push_back(item); + + if (!_is_rottable(item)) + return; + + // item.special remains unchanged in the stash, to show how fresh it + // was when last seen. It's plus2 that's decayed over time. + if (add_to_front) + { + item_def &it = items.front(); + it.plus2 = it.special; + } + else + { + item_def &it = items.back(); + it.plus2 = it.special; + } +} + void Stash::write(std::ostream &os, int refx, int refy, std::string place, bool identify) const @@ -1128,6 +1221,15 @@ void LevelStashes::get_matching_stashes( } } +void LevelStashes::_update_corpses(long rot_time) +{ + for (stashes_t::iterator iter = m_stashes.begin(); + iter != m_stashes.end(); iter++) + { + iter->second._update_corpses(rot_time); + } +} + void LevelStashes::write(std::ostream &os, bool identify) const { if (visible_stash_count() == 0) @@ -1299,6 +1401,9 @@ void StashTracker::save(writer& outf) const marshallByte(outf, ST_MAJOR_VER); marshallByte(outf, ST_MINOR_VER); + // Time of last corpse update. + marshallFloat(outf, (float) last_corpse_update); + // How many levels have we? marshallShort(outf, (short) levels.size()); @@ -1316,6 +1421,9 @@ void StashTracker::load(reader& inf) minor = unmarshallByte(inf); if (major != ST_MAJOR_VER || minor != ST_MINOR_VER) return ; + // Time of last corpse update. + last_corpse_update = (double) unmarshallFloat(inf); + int count = unmarshallShort(inf); levels.clear(); @@ -1742,3 +1850,23 @@ bool StashTracker::display_search_results( } return false; } + +void StashTracker::update_corpses() +{ + if (!Options.stash_track_decay) + return; + + if (you.elapsed_time - last_corpse_update < 20.0) + return; + + const long rot_time = static_cast<long>((you.elapsed_time - + last_corpse_update) / 20.0); + + last_corpse_update = you.elapsed_time; + + for (stash_levels_t::iterator iter = levels.begin(); + iter != levels.end(); iter++) + { + iter->second._update_corpses(rot_time); + } +} diff --git a/crawl-ref/source/stash.h b/crawl-ref/source/stash.h index 8ca50d0ca3..570a611257 100644 --- a/crawl-ref/source/stash.h +++ b/crawl-ref/source/stash.h @@ -90,6 +90,10 @@ public: // also never removed from the level's map of // stashes. private: + void _update_corpses(long rot_time); + void add_item(const item_def &item, bool add_to_front = false); + +private: bool verified; // Is this correct to the best of our knowledge? unsigned char x, y; int abspos; @@ -109,6 +113,8 @@ private: static bool are_items_same(const item_def &, const item_def &); static bool is_filtered(const item_def &item); + + friend class LevelStashes; }; class ShopInfo @@ -247,6 +253,7 @@ public: private: int _num_enabled_stashes() const; + void _update_corpses(long rot_time); private: typedef std::map<int, Stash> stashes_t; @@ -256,6 +263,8 @@ public: level_id m_place; stashes_t m_stashes; shops_t m_shops; + + friend class StashTracker; }; extern std::ostream &operator << (std::ostream &, const LevelStashes &); @@ -269,7 +278,7 @@ public: || you.level_type == LEVEL_ABYSS; } - StashTracker() : levels() + StashTracker() : levels(), last_corpse_update(0.0) { } @@ -294,6 +303,8 @@ public: // previously marked as stashes. }; + void update_corpses(); + void update_visible_stashes(StashTracker::stash_update_mode = ST_PASSIVE); // Update stash at (x,y) on current level, defaulting to player's current @@ -326,6 +337,8 @@ private: private: typedef std::map<level_id, LevelStashes> stash_levels_t; stash_levels_t levels; + + double last_corpse_update; }; extern StashTracker StashTrack; |