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
B7WPMRRKAV6AOZXA6F3UAOFCFTAGJAWSPLACLRACVCPQVLXFJ6CQC
4ZAYR6K7SNJ45QYS5KLZOJ2T7OKYL4M2RY5UIIMOWRQGZLTME6UQC
6DNB4AIWKSKXWFY7XYHZMSDBEPGQLMIMU4YB2XTTCLN6ZXWKYOKQC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
DMLFJIPOE4ZXUFQ25VVEZCMURP2UPJBBWDGQS3DPQVUNVBBQ4GDQC
T4IH76FA5TWHFOZUJFHLQXQJENJHWTUZZP4EGNA7D4GTZY7D4ZKAC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
3ZG5KLXXSZA4K72X5IZ5GCXVQQGZRQE6MHGTR33R3PZ4RGAVQ5HQC
ILOED4VB4I6VPAUTR75ZWX6MXDYXB5DO2EDK2UH67O3HNKWV23RQC
5KJCHLIUFKRPMIVWUAYT6EOF7SW4PTQF6Y5OPEFWXGLE7DUGYLZAC
3TNMXC6XG723NP5RJDQS3ONETVCXPTZXOG3YTDFT2JKKGLCYL7WAC
547JREUJXTZNYVGHNNAET5F5O5JYYGNTDQB6ABZNT7YX5EY64OHAC
XVX7AVLLYZJIJUZA2LZ6T57PHULWPDRZOHELDF4JHZ35EMINFFZQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
RVST2QHYJ757ZHK4AUJ5NGPDZ44AD6RVFVXYPKQIBJXZBDNUCHXQC
EOMCPVNQLX3IMLC46EAO67DPBH5KEG2FQTPBLGU62HIRWA3UQ7XQC
2ZFV5PKZU3HDHMLJWVWPPFV43NUNUON6YSAITHB26D7L4XIVWUHQC
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;
}
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;
}
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 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);
}