content_cao: Do not expire visuals when not necessary
authorsfan5 <sfan5@live.de>
Mon, 25 May 2020 21:36:45 +0000 (23:36 +0200)
committersfan5 <sfan5@live.de>
Fri, 29 May 2020 20:54:50 +0000 (22:54 +0200)
fixes #6572

src/client/content_cao.cpp
src/client/content_cao.h

index cdc12f04194aa0bbea4bb68404e1df195051a71b..947c1a279321c6ed7722b32a48b8eb5feb3f7206 100644 (file)
@@ -1457,13 +1457,23 @@ void GenericCAO::updateAttachments()
        }
 }
 
-void GenericCAO::readAOMessageProperties(std::istream &is)
+bool GenericCAO::visualExpiryRequired(const ObjectProperties &new_) const
 {
-       // Reset object properties first
-       m_prop = ObjectProperties();
-
-       // Then read the whole new stream
-       m_prop.deSerialize(is);
+       const ObjectProperties &old = m_prop;
+       // Ordered to compare primitive types before std::vectors
+       return old.backface_culling != new_.backface_culling ||
+               old.initial_sprite_basepos != new_.initial_sprite_basepos ||
+               old.is_visible != new_.is_visible ||
+               old.mesh != new_.mesh ||
+               old.nametag != new_.nametag ||
+               old.nametag_color != new_.nametag_color ||
+               old.spritediv != new_.spritediv ||
+               old.use_texture_alpha != new_.use_texture_alpha ||
+               old.visual != new_.visual ||
+               old.visual_size != new_.visual_size ||
+               old.wield_item != new_.wield_item ||
+               old.colors != new_.colors ||
+               old.textures != new_.textures;
 }
 
 void GenericCAO::processMessage(const std::string &data)
@@ -1473,14 +1483,21 @@ void GenericCAO::processMessage(const std::string &data)
        // command
        u8 cmd = readU8(is);
        if (cmd == AO_CMD_SET_PROPERTIES) {
-               readAOMessageProperties(is);
+               ObjectProperties newprops;
+               newprops.deSerialize(is);
+
+               // Check what exactly changed
+               bool expire_visuals = visualExpiryRequired(newprops);
+
+               // Apply changes
+               m_prop = std::move(newprops);
 
                m_selection_box = m_prop.selectionbox;
                m_selection_box.MinEdge *= BS;
                m_selection_box.MaxEdge *= BS;
 
-               m_tx_size.X = 1.0 / m_prop.spritediv.X;
-               m_tx_size.Y = 1.0 / m_prop.spritediv.Y;
+               m_tx_size.X = 1.0f / m_prop.spritediv.X;
+               m_tx_size.Y = 1.0f / m_prop.spritediv.Y;
 
                if(!m_initial_tx_basepos_set){
                        m_initial_tx_basepos_set = true;
@@ -1500,7 +1517,12 @@ void GenericCAO::processMessage(const std::string &data)
                if ((m_is_player && !m_is_local_player) && m_prop.nametag.empty())
                        m_prop.nametag = m_name;
 
-               expireVisuals();
+               if (expire_visuals) {
+                       expireVisuals();
+               } else {
+                       infostream << "GenericCAO: properties updated but expiring visuals"
+                               << " not necessary" << std::endl;
+               }
        } else if (cmd == AO_CMD_UPDATE_POSITION) {
                // Not sent by the server if this object is an attachment.
                // We might however get here if the server notices the object being detached before the client.
index c53b814333a2a28230d1f388aca638bfa9c8b5a4..03a3552048a7d14f30a845544d1a4c92218f0c7e 100644 (file)
@@ -68,7 +68,6 @@ struct SmoothTranslatorWrappedv3f : SmoothTranslator<v3f>
 class GenericCAO : public ClientActiveObject
 {
 private:
-       void readAOMessageProperties(std::istream &is);
        // Only set at initialization
        std::string m_name = "";
        bool m_is_player = false;
@@ -131,6 +130,8 @@ private:
        // Settings
        bool m_enable_shaders = false;
 
+       bool visualExpiryRequired(const ObjectProperties &newprops) const;
+
 public:
        GenericCAO(Client *client, ClientEnvironment *env);