diff options
Diffstat (limited to 'src/nodedef.cpp')
-rw-r--r-- | src/nodedef.cpp | 82 |
1 files changed, 71 insertions, 11 deletions
diff --git a/src/nodedef.cpp b/src/nodedef.cpp index f27a8154b..2b8ebd773 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -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; |