Problem with holster-type containers, the hoarder trait and phantom volume

My issue is that holsters/sheathes/straps etc’s volume is considered for the hoarder trait morale loss even when the holster has an appropriate item in it.

The birchbark sheath has 0.75L capacity and I have a hunting knife (0.25L) and trench knife (0.5L). I put the hunting knife into the sheath and it is still considered to have 0.5L of free volume despite the fact you cannot fit another knife in there even if could fit (the game correctly prevents you from putting 2 items in the same holster). This 0.5L of unusable volume is still considered by the hoarder trait formula and inventory menu to be free volume.

Another annoying thing is that when I take my quarterstaff out of my spear strap I take a massive (-24) morale penalty since 3 additional litres have opened up . My opinion is that if I am holding an appropriate item for the holster then that holster should not be considered for the morale loss.

There is also an inconsistency in the inventory menu where the volume values do not equate and shows this phantom volume.

A maybe quick fix is to only consider non-holster container volume in the hoarder morale formula then do a -3 for each empty holster container. If the held weapon is compatible with any empty holsters then -1 from the total empty holster containers. I think the main issue is that the formula is just out of date.

If anyone could point me to where the hoarder morale formula is in the code I could attempt to fix it.

Thank you for your consideration,


it -is- meant to be a negative trait, so y’know, taking something out to put it in your hands means the potential of losing it, and therefore being anti-hoarder mentality.

but i get where you’re coming from… the hoarder trait should really only calculate if you don’t have a single container that’s at least 90% full, and it should definitely be the largest container on you (which would probably be a backpack)

unfortunately i have no idea where that’d be code-wise.

But I do!
Well, not on the top of the head, I had to search for it first - sorry for the delayed response.

It’s the function void Character::hoarder_morale_penalty() in character.cpp.

The solution to it probably looks like this, if anyone wants to test and PR it

diff --git a/src/character.cpp b/src/character.cpp
index b76a3c11b6..d844f6e146 100644
--- a/src/character.cpp
+++ b/src/character.cpp
@@ -10493,6 +10493,9 @@ units::volume Character::free_space() const
     for( const item &w : worn ) {
         volume_capacity += w.get_total_capacity();
         for( const item_pocket *pocket : w.contents.get_all_contained_pockets().value() ) {
+            if( pocket->holster && !pocket->empty() ) {
+                volume_capacity -= pocket->volume_capacity();
+            }
             if( pocket->contains_phase( phase_id::SOLID ) ) {
                 for( const item *it : pocket->all_items_top() ) {
                     volume_capacity -= it->volume();