summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-06-05 08:43:08 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-06-05 08:43:08 +0000
commit3bc86f82a03f66f402afe45bdfc46312310cc565 (patch)
treecef2dd68f626f8caa63ab3ac87b07393923760ee /crawl-ref
parentee9ef53947fd17b16194459da580c197bf2a7474 (diff)
downloadcrawl-ref-3bc86f82a03f66f402afe45bdfc46312310cc565.tar.gz
crawl-ref-3bc86f82a03f66f402afe45bdfc46312310cc565.zip
Added two new stash options, stash_track_decay and stash_remove_decay. If
stash_track_decay is true then the stash tracker will remember how long it's been since you've seen a rottable object (corpses, skeletons and meat chunks) and tell you its condition by appending "rotten by now", "skeletalised by now" or "gone by now" to its name in the stash menu. If stash_remove_decay is also true then any item that would have been marked "gone by now" is instead removed from the stash tracker. Doesn't yet track decay of potions of blood. Breaks stash save data compatibility. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5485 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/docs/options_guide.txt14
-rw-r--r--crawl-ref/settings/init.txt2
-rw-r--r--crawl-ref/source/acr.cc6
-rw-r--r--crawl-ref/source/externs.h4
-rw-r--r--crawl-ref/source/initfile.cc5
-rw-r--r--crawl-ref/source/stash.cc138
-rw-r--r--crawl-ref/source/stash.h15
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;