summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/stash.cc
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/source/stash.cc
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/source/stash.cc')
-rw-r--r--crawl-ref/source/stash.cc138
1 files changed, 133 insertions, 5 deletions
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);
+ }
+}