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).
This commit is contained in:
SmallJoker 2023-09-13 13:57:57 +02:00 committed by GitHub
parent 833c324498
commit 4ef93fe25f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 9 deletions

View File

@ -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;

View File

@ -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));

View File

@ -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) {};
}

View File

@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irrlichttypes_extrabloated.h"
#include <string>
#include <iostream>
#include <optional>
#include <set>
#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<u8> place_param2;
/*
Some helpful methods

View File

@ -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<u8>
[scheduled bump for 5.8.0]
*/

View File

@ -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);
}
/******************************************************************************/