From 4ef93fe25f583c5e91fcf85794df78b99680878b Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Wed, 13 Sep 2023 13:57:57 +0200 Subject: [PATCH] Allow place_param2 = 0 node placement predictions (#13787) The placement prediction value 0 was accidentally ignored and made the clients fall back to automatic rotation based on the node paramtype2 value. This now changes the internal representation to properly indicate the disabled state (e.g. 'nil' in Lua). --- src/client/game.cpp | 4 ++-- src/client/wieldmesh.cpp | 6 ++++-- src/itemdef.cpp | 27 ++++++++++++++++++++++++--- src/itemdef.h | 3 ++- src/network/networkprotocol.h | 1 + src/script/common/c_content.cpp | 4 +++- 6 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/client/game.cpp b/src/client/game.cpp index 907f94faa..75a29b131 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3627,10 +3627,10 @@ bool Game::nodePlacement(const ItemDefinition &selected_def, // Compare core.item_place_node() for what the server does with param2 MapNode predicted_node(id, 0, 0); - const u8 place_param2 = selected_def.place_param2; + const auto place_param2 = selected_def.place_param2; if (place_param2) { - predicted_node.setParam2(place_param2); + predicted_node.setParam2(*place_param2); } else if (predicted_f.param_type_2 == CPT2_WALLMOUNTED || predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED) { v3s16 dir = nodepos - neighborpos; diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 60c303c78..d6d2468f5 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -443,7 +443,8 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che default: { // Render non-trivial drawtypes like the actual node MapNode n(id); - n.setParam2(def.place_param2); + if (def.place_param2) + n.setParam2(*def.place_param2); mesh = createSpecialNodeMesh(client, n, &m_colors, f); changeToMesh(mesh); @@ -638,7 +639,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) default: { // Render non-trivial drawtypes like the actual node MapNode n(id); - n.setParam2(def.place_param2); + if (def.place_param2) + n.setParam2(*def.place_param2); mesh = createSpecialNodeMesh(client, n, &result->buffer_colors, f); scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); diff --git a/src/itemdef.cpp b/src/itemdef.cpp index ae252c4a0..daf2295a5 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -123,7 +123,7 @@ void ItemDefinition::reset() sound_use_air = SoundSpec(); range = -1; node_placement_prediction.clear(); - place_param2 = 0; + place_param2.reset(); } void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const @@ -169,10 +169,20 @@ void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const os << serializeString16(short_description); - os << place_param2; + if (protocol_version <= 43) { + // Uncertainity whether 0 is the specified prediction or means disabled + if (place_param2) + os << *place_param2; + else + os << (u8)0; + } sound_use.serializeSimple(os, protocol_version); sound_use_air.serializeSimple(os, protocol_version); + + os << (u8)place_param2.has_value(); // protocol_version >= 43 + if (place_param2) + os << *place_param2; } void ItemDefinition::deSerialize(std::istream &is, u16 protocol_version) @@ -226,10 +236,21 @@ void ItemDefinition::deSerialize(std::istream &is, u16 protocol_version) try { short_description = deSerializeString16(is); - place_param2 = readU8(is); // 0 if missing + if (protocol_version <= 43) { + place_param2 = readU8(is); + // assume disabled prediction + if (place_param2 == 0) + place_param2.reset(); + } sound_use.deSerializeSimple(is, protocol_version); sound_use_air.deSerializeSimple(is, protocol_version); + + if (is.eof()) + throw SerializationError(""); + + if (readU8(is)) // protocol_version >= 43 + place_param2 = readU8(is); } catch(SerializationError &e) {}; } diff --git a/src/itemdef.h b/src/itemdef.h index bad3a3e24..8ce6a15cd 100644 --- a/src/itemdef.h +++ b/src/itemdef.h @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_extrabloated.h" #include #include +#include #include #include "itemgroup.h" #include "sound.h" @@ -87,7 +88,7 @@ struct ItemDefinition // Server will update the precise end result a moment later. // "" = no prediction std::string node_placement_prediction; - u8 place_param2; + std::optional place_param2; /* Some helpful methods diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index c9e29cf12..e012fc06c 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -217,6 +217,7 @@ with this program; if not, write to the Free Software Foundation, Inc., [scheduled bump for 5.7.0] PROTOCOL VERSION 43: "start_time" added to TOCLIENT_PLAY_SOUND + place_param2 type change u8 -> optional [scheduled bump for 5.8.0] */ diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 94f8dcabe..1756c49c5 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -133,7 +133,9 @@ void read_item_definition(lua_State* L, int index, getstringfield(L, index, "node_placement_prediction", def.node_placement_prediction); - getintfield(L, index, "place_param2", def.place_param2); + int place_param2; + if (getintfield(L, index, "place_param2", place_param2)) + def.place_param2 = rangelim(place_param2, 0, U8_MAX); } /******************************************************************************/