]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/nodedef.cpp
Merge branch 'master' of https://github.com/minetest/minetest
[dragonfireclient.git] / src / nodedef.cpp
index f27a8154b3ad5f9e8e701244375d2764d07712ad..2b8ebd77393c8ace40479fc9afb65d8ff5f70e1f 100644 (file)
@@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "nameidmapping.h"
 #include "util/numeric.h"
 #include "util/serialize.h"
+#include "util/string.h"
 #include "exceptions.h"
 #include "debug.h"
 #include "gamedef.h"
@@ -207,7 +208,28 @@ void TileDef::serialize(std::ostream &os, u16 protocol_version) const
        u8 version = 6;
        writeU8(os, version);
 
-       os << serializeString16(name);
+       if (protocol_version > 39) {
+               os << serializeString16(name);
+       } else {
+               // Before f018737, TextureSource::getTextureAverageColor did not handle
+               // missing textures. "[png" can be used as base texture, but is not known
+               // on older clients. Hence use "blank.png" to avoid this problem.
+               // To be forward-compatible with future base textures/modifiers,
+               // we apply the same prefix to any texture beginning with [,
+               // except for the ones that are supported on older clients.
+               bool pass_through = true;
+
+               if (!name.empty() && name[0] == '[') {
+                       pass_through = str_starts_with(name, "[combine:") ||
+                               str_starts_with(name, "[inventorycube{") ||
+                               str_starts_with(name, "[lowpart:");
+               }
+
+               if (pass_through)
+                       os << serializeString16(name);
+               else
+                       os << serializeString16("blank.png^" + name);
+       }
        animation.serialize(os, version);
        bool has_scale = scale > 0;
        u16 flags = 0;
@@ -403,6 +425,8 @@ void ContentFeatures::reset()
        palette_name = "";
        palette = NULL;
        node_dig_prediction = "air";
+       move_resistance = 0;
+       liquid_move_physics = false;
 }
 
 void ContentFeatures::setAlphaFromLegacy(u8 legacy_alpha)
@@ -440,7 +464,12 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
        writeU16(os, groups.size());
        for (const auto &group : groups) {
                os << serializeString16(group.first);
-               writeS16(os, group.second);
+               if (protocol_version < 41 && group.first.compare("bouncy") == 0) {
+                       // Old clients may choke on negative bouncy value
+                       writeS16(os, abs(group.second));
+               } else {
+                       writeS16(os, group.second);
+               }
        }
        writeU8(os, param_type);
        writeU8(os, param_type_2);
@@ -489,7 +518,16 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
        writeU32(os, damage_per_second);
 
        // liquid
-       writeU8(os, liquid_type);
+       LiquidType liquid_type_bc = liquid_type;
+       if (protocol_version <= 39) {
+               // Since commit 7f25823, liquid drawtypes can be used even with LIQUID_NONE
+               // solution: force liquid type accordingly to accepted values
+               if (drawtype == NDT_LIQUID)
+                       liquid_type_bc = LIQUID_SOURCE;
+               else if (drawtype == NDT_FLOWINGLIQUID)
+                       liquid_type_bc = LIQUID_FLOWING;
+       }
+       writeU8(os, liquid_type_bc);
        os << serializeString16(liquid_alternative_flowing);
        os << serializeString16(liquid_alternative_source);
        writeU8(os, liquid_viscosity);
@@ -512,9 +550,12 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
        writeU8(os, legacy_facedir_simple);
        writeU8(os, legacy_wallmounted);
 
+       // new attributes
        os << serializeString16(node_dig_prediction);
        writeU8(os, leveled_max);
        writeU8(os, alpha);
+       writeU8(os, move_resistance);
+       writeU8(os, liquid_move_physics);
 }
 
 void ContentFeatures::deSerialize(std::istream &is)
@@ -584,9 +625,11 @@ void ContentFeatures::deSerialize(std::istream &is)
 
        // liquid
        liquid_type = (enum LiquidType) readU8(is);
+       liquid_move_physics = liquid_type != LIQUID_NONE;
        liquid_alternative_flowing = deSerializeString16(is);
        liquid_alternative_source = deSerializeString16(is);
        liquid_viscosity = readU8(is);
+       move_resistance = liquid_viscosity; // set default move_resistance
        liquid_renewable = readU8(is);
        liquid_range = readU8(is);
        drowning = readU8(is);
@@ -618,6 +661,16 @@ void ContentFeatures::deSerialize(std::istream &is)
                if (is.eof())
                        throw SerializationError("");
                alpha = static_cast<enum AlphaMode>(tmp);
+
+               tmp = readU8(is);
+               if (is.eof())
+                       throw SerializationError("");
+               move_resistance = tmp;
+
+               tmp = readU8(is);
+               if (is.eof())
+                       throw SerializationError("");
+               liquid_move_physics = tmp;
        } catch(SerializationError &e) {};
 }
 
@@ -634,7 +687,7 @@ static void fillTileAttribs(ITextureSource *tsrc, TileLayer *layer,
        bool has_scale = tiledef.scale > 0;
        bool use_autoscale = tsettings.autoscale_mode == AUTOSCALE_FORCE ||
                (tsettings.autoscale_mode == AUTOSCALE_ENABLE && !has_scale);
-       if (use_autoscale) {
+       if (use_autoscale && layer->texture) {
                auto texture_size = layer->texture->getOriginalSize();
                float base_size = tsettings.node_texture_size;
                float size = std::fmin(texture_size.Width, texture_size.Height);
@@ -670,6 +723,7 @@ static void fillTileAttribs(ITextureSource *tsrc, TileLayer *layer,
        // Animation parameters
        int frame_count = 1;
        if (layer->material_flags & MATERIAL_FLAG_ANIMATION) {
+               assert(layer->texture);
                int frame_length_ms;
                tiledef.animation.determineParams(layer->texture->getOriginalSize(),
                                &frame_count, &frame_length_ms, NULL);
@@ -680,14 +734,13 @@ static void fillTileAttribs(ITextureSource *tsrc, TileLayer *layer,
        if (frame_count == 1) {
                layer->material_flags &= ~MATERIAL_FLAG_ANIMATION;
        } else {
-               std::ostringstream os(std::ios::binary);
-               if (!layer->frames) {
+               assert(layer->texture);
+               if (!layer->frames)
                        layer->frames = new std::vector<FrameSpec>();
-               }
                layer->frames->resize(frame_count);
 
+               std::ostringstream os(std::ios::binary);
                for (int i = 0; i < frame_count; i++) {
-
                        FrameSpec frame;
 
                        os.str("");
@@ -779,8 +832,10 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
        TileDef tdef[6];
        for (u32 j = 0; j < 6; j++) {
                tdef[j] = tiledef[j];
-               if (tdef[j].name.empty())
-                       tdef[j].name = "unknown_node.png";
+               if (tdef[j].name.empty()) {
+                       tdef[j].name = "no_texture.png";
+                       tdef[j].backface_culling = false;
+               }
        }
        // also the overlay tiles
        TileDef tdef_overlay[6];
@@ -788,8 +843,9 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
                tdef_overlay[j] = tiledef_overlay[j];
        // also the special tiles
        TileDef tdef_spec[6];
-       for (u32 j = 0; j < CF_SPECIAL_COUNT; j++)
+       for (u32 j = 0; j < CF_SPECIAL_COUNT; j++) {
                tdef_spec[j] = tiledef_special[j];
+       }
 
        bool is_liquid = false;
 
@@ -1035,6 +1091,10 @@ void NodeDefManager::clear()
        {
                ContentFeatures f;
                f.name = "unknown";
+               TileDef unknownTile;
+               unknownTile.name = "unknown_node.png";
+               for (int t = 0; t < 6; t++)
+                       f.tiledef[t] = unknownTile;
                // Insert directly into containers
                content_t c = CONTENT_UNKNOWN;
                m_content_features[c] = f;