Page 1 of 2

[PATCH] Show [empty] tags on empty containers

Posted: 04 Mar 2019, 19:32
by CyberShadow
I remember newer Creation Engine versions had this.

Screenshot:
Image

Code:

Code: Select all

diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp
index 47dfa27b3..363bfbfce 100644
--- a/apps/openmw/mwclass/container.cpp
+++ b/apps/openmw/mwclass/container.cpp
@@ -209,6 +209,16 @@ namespace MWClass
         return ptr.getRefData().getCustomData()->asContainerCustomData().mContainerStore;
     }
 
+    const MWWorld::ContainerStore* Container::getConstContainerStore (const MWWorld::ConstPtr& ptr)
+        const
+    {
+        const ContainerCustomData* customData = dynamic_cast<const ContainerCustomData*>
+            (ptr.getRefData().getCustomData());
+        if (!customData)
+            return nullptr;
+        return &customData->mContainerStore;
+    }
+
     std::string Container::getScript (const MWWorld::ConstPtr& ptr) const
     {
         const MWWorld::LiveCellRef<ESM::Container> *ref = ptr.get<ESM::Container>();
@@ -246,6 +256,10 @@ namespace MWClass
         if (ptr.getCellRef().getTrap() != "")
             text += "\n#{sTrapped}";
 
+        const MWWorld::ContainerStore* containerStore = getConstContainerStore (ptr);
+        if (containerStore && lockLevel <= 0 && containerStore->isEmpty())
+            text += "\n[empty]";
+
         if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
             text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
             text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp
index e38d98b5c..1ea264563 100644
--- a/apps/openmw/mwclass/container.hpp
+++ b/apps/openmw/mwclass/container.hpp
@@ -34,6 +34,7 @@ namespace MWClass
             ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
 
             virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const;
+            virtual const MWWorld::ContainerStore* getConstContainerStore (const MWWorld::ConstPtr& ptr) const;
             ///< Return container store
 
             virtual std::string getScript (const MWWorld::ConstPtr& ptr) const;
diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp
index 6725fb935..0ac6efc50 100644
--- a/apps/openmw/mwworld/containerstore.cpp
+++ b/apps/openmw/mwworld/containerstore.cpp
@@ -39,6 +39,20 @@ namespace
         return sum;
     }
 
+    template<typename T>
+    bool isEmpty (const MWWorld::CellRefList<T>& cellRefList)
+    {
+        for (typename MWWorld::CellRefList<T>::List::const_iterator iter (
+            cellRefList.mList.begin());
+            iter!=cellRefList.mList.end();
+            ++iter)
+        {
+            if (iter->mData.getCount()>0)
+                return false;
+        }
+        return true;
+    }
+
     template<typename T>
     MWWorld::Ptr searchId (MWWorld::CellRefList<T>& list, const std::string& id,
         MWWorld::ContainerStore *store)
@@ -635,6 +649,23 @@ float MWWorld::ContainerStore::getWeight() const
     return mCachedWeight;
 }
 
+bool MWWorld::ContainerStore::isEmpty() const
+{
+    return
+        ::isEmpty (potions)   &&
+        ::isEmpty (appas)     &&
+        ::isEmpty (armors)    &&
+        ::isEmpty (books)     &&
+        ::isEmpty (clothes)   &&
+        ::isEmpty (ingreds)   &&
+        ::isEmpty (lights)    &&
+        ::isEmpty (lockpicks) &&
+        ::isEmpty (miscItems) &&
+        ::isEmpty (probes)    &&
+        ::isEmpty (repairs)   &&
+        ::isEmpty (weapons);
+}
+
 int MWWorld::ContainerStore::getType (const ConstPtr& ptr)
 {
     if (ptr.isEmpty())
diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp
index 4564d2fa3..a61b0ddbe 100644
--- a/apps/openmw/mwworld/containerstore.hpp
+++ b/apps/openmw/mwworld/containerstore.hpp
@@ -195,6 +195,8 @@ namespace MWWorld
             float getWeight() const;
             ///< Return total weight of the items contained in *this.
 
+            bool isEmpty() const;
+
             static int getType (const ConstPtr& ptr);
             ///< This function throws an exception, if ptr does not point to an object, that can be
             /// put into a container.
The code is a bit iff. w.r.t. getConstContainerStore though.

Re: [PATCH] Show [empty] tags on empty containers

Posted: 04 Mar 2019, 19:34
by wareya
This has the potential to conflict with containers with random contents in the future because contents are supposed to be determined upon opening them. Why? Because it has real effects on normal gameplay because of leveled lists. https://gitlab.com/OpenMW/openmw/issues/3862

Re: [PATCH] Show [empty] tags on empty containers

Posted: 04 Mar 2019, 19:45
by CyberShadow
That's interesting. How can I test against such a container? EDIT: Oh, you mean in a future implementation.

I tried to make the code conservative, and only show the [empty] tag only when all the information to know whether the container is empty or not is available.

Re: [PATCH] Show [empty] tags on empty containers

Posted: 04 Mar 2019, 20:07
by akortunov
We should avoid to use non-localized strings.

Re: [PATCH] Show [empty] tags on empty containers

Posted: 04 Mar 2019, 20:13
by CyberShadow
I did not find "empty" among localized strings.

Re: [PATCH] Show [empty] tags on empty containers

Posted: 04 Mar 2019, 20:20
by werdanith
The "no localized strings" rule is a valid concern, to the extent that since it's considered a blocker for so many other features, perhaps the priority of a localization of framework could be reexamined.
On this particular case though, what about using the utf character for the empty set instead: ∅
assuming the fonts support it.

Re: [PATCH] Show [empty] tags on empty containers

Posted: 04 Mar 2019, 20:26
by CyberShadow
werdanith wrote:
04 Mar 2019, 20:20
assuming the fonts support it.
They do not (shows up as a question mark).

Re: [PATCH] Show [empty] tags on empty containers

Posted: 04 Mar 2019, 20:35
by werdanith
I'm going on tangent here, but since I've had this issue while messing with fonts, would it be possible for OpenMW to fallback on a system font if a symbol is not covered?

Re: [PATCH] Show [empty] tags on empty containers

Posted: 05 Mar 2019, 05:12
by akortunov
werdanith wrote:
04 Mar 2019, 20:35
I'm going on tangent here, but since I've had this issue while messing with fonts, would it be possible for OpenMW to fallback on a system font if a symbol is not covered?
I doubt it has has much sense even if it is possible.

As for this feature, it is a quite questionable:
1. Some users may or may not prefer to have this lable on locked containers
2. Some users may prefer to have a Fallout4-style quick looting system
3. This feature will conflict with classic herbalism mods
4. We do not have strings to localize it.

That's why I did not implement it earlier.

As I said, a good idea for simple tweakable mod, which overrides tooltip creation for containers.

Re: [PATCH] Show [empty] tags on empty containers

Posted: 05 Mar 2019, 14:59
by AnyOldName3
Still, falling back on a system font wouldn't be a terrible idea, would it?