]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Use place_param2 client-side for item appearance & prediction (#11024)
authorsfan5 <sfan5@live.de>
Mon, 8 Mar 2021 23:56:53 +0000 (00:56 +0100)
committerGitHub <noreply@github.com>
Mon, 8 Mar 2021 23:56:53 +0000 (00:56 +0100)
src/client/game.cpp
src/client/wieldmesh.cpp
src/itemdef.cpp
src/itemdef.h
src/script/common/c_content.cpp

index 27eaec3b892ad3aee3f5aad6a2eb2efbcb391b4d..2575e5406f197aaf3b345e56d8582e465039b275 100644 (file)
@@ -3287,7 +3287,8 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
        const ItemStack &selected_item, const v3s16 &nodepos, const v3s16 &neighbourpos,
        const PointedThing &pointed, const NodeMetadata *meta)
 {
-       std::string prediction = selected_def.node_placement_prediction;
+       const auto &prediction = selected_def.node_placement_prediction;
+
        const NodeDefManager *nodedef = client->ndef();
        ClientMap &map = client->getEnv().getClientMap();
        MapNode node;
@@ -3357,8 +3358,7 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
 
        if (!found) {
                errorstream << "Node placement prediction failed for "
-                       << selected_def.name << " (places "
-                       << prediction
+                       << selected_def.name << " (places " << prediction
                        << ") - Name not known" << std::endl;
                // Handle this as if prediction was empty
                // Report to server
@@ -3369,9 +3369,14 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
        const ContentFeatures &predicted_f = nodedef->get(id);
 
        // Predict param2 for facedir and wallmounted nodes
+       // Compare core.item_place_node() for what the server does
        u8 param2 = 0;
 
-       if (predicted_f.param_type_2 == CPT2_WALLMOUNTED ||
+       const u8 place_param2 = selected_def.place_param2;
+
+       if (place_param2) {
+               param2 = place_param2;
+       } else if (predicted_f.param_type_2 == CPT2_WALLMOUNTED ||
                        predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED) {
                v3s16 dir = nodepos - neighbourpos;
 
@@ -3382,9 +3387,7 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
                } else {
                        param2 = dir.Z < 0 ? 5 : 4;
                }
-       }
-
-       if (predicted_f.param_type_2 == CPT2_FACEDIR ||
+       } else if (predicted_f.param_type_2 == CPT2_FACEDIR ||
                        predicted_f.param_type_2 == CPT2_COLORED_FACEDIR) {
                v3s16 dir = nodepos - floatToInt(client->getEnv().getLocalPlayer()->getPosition(), BS);
 
@@ -3395,11 +3398,9 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
                }
        }
 
-       assert(param2 <= 5);
-
-       //Check attachment if node is in group attached_node
-       if (((ItemGroupList) predicted_f.groups)["attached_node"] != 0) {
-               static v3s16 wallmounted_dirs[8] = {
+       // Check attachment if node is in group attached_node
+       if (itemgroup_get(predicted_f.groups, "attached_node") != 0) {
+               const static v3s16 wallmounted_dirs[8] = {
                        v3s16(0, 1, 0),
                        v3s16(0, -1, 0),
                        v3s16(1, 0, 0),
@@ -3424,11 +3425,11 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
        }
 
        // Apply color
-       if ((predicted_f.param_type_2 == CPT2_COLOR
+       if (!place_param2 && (predicted_f.param_type_2 == CPT2_COLOR
                        || predicted_f.param_type_2 == CPT2_COLORED_FACEDIR
                        || predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED)) {
-               const std::string &indexstr = selected_item.metadata.getString(
-                       "palette_index", 0);
+               const auto &indexstr = selected_item.metadata.
+                       getString("palette_index", 0);
                if (!indexstr.empty()) {
                        s32 index = mystoi(indexstr);
                        if (predicted_f.param_type_2 == CPT2_COLOR) {
@@ -3468,11 +3469,10 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
                        soundmaker->m_player_rightpunch_sound = selected_def.sound_place_failed;
                        return false;
                }
-       } catch (InvalidPositionException &e) {
+       } catch (const InvalidPositionException &e) {
                errorstream << "Node placement prediction failed for "
                        << selected_def.name << " (places "
-                       << prediction
-                       << ") - Position not loaded" << std::endl;
+                       << prediction << ") - Position not loaded" << std::endl;
                soundmaker->m_player_rightpunch_sound = selected_def.sound_place_failed;
                return false;
        }
index ad583210a6a22303e608144b8a8439dd20d67dfa..387eb17c38d84fa28bdaa775da7bd7a86fa788a3 100644 (file)
@@ -294,7 +294,7 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
                }
                material.setFlag(video::EMF_ANISOTROPIC_FILTER, m_anisotropic_filter);
                // mipmaps cause "thin black line" artifacts
-#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
+#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
                material.setFlag(video::EMF_USE_MIP_MAPS, false);
 #endif
                if (m_enable_shaders) {
@@ -303,23 +303,26 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
        }
 }
 
-scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vector<ItemPartColor> *colors, const ContentFeatures &f)
+static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n,
+       std::vector<ItemPartColor> *colors, const ContentFeatures &f)
 {
        MeshMakeData mesh_make_data(client, false);
        MeshCollector collector;
        mesh_make_data.setSmoothLighting(false);
        MapblockMeshGenerator gen(&mesh_make_data, &collector);
-       u8 param2 = 0;
-       if (f.param_type_2 == CPT2_WALLMOUNTED ||
+
+       if (n.getParam2()) {
+               // keep it
+       } else if (f.param_type_2 == CPT2_WALLMOUNTED ||
                        f.param_type_2 == CPT2_COLORED_WALLMOUNTED) {
                if (f.drawtype == NDT_TORCHLIKE)
-                       param2 = 1;
+                       n.setParam2(1);
                else if (f.drawtype == NDT_SIGNLIKE ||
                                f.drawtype == NDT_NODEBOX ||
                                f.drawtype == NDT_MESH)
-                       param2 = 4;
+                       n.setParam2(4);
        }
-       gen.renderSingle(id, param2);
+       gen.renderSingle(n.getContent(), n.getParam2());
 
        colors->clear();
        scene::SMesh *mesh = new scene::SMesh();
@@ -413,9 +416,12 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
                case NDT_LIQUID:
                        setCube(f, def.wield_scale);
                        break;
-               default:
+               default: {
                        // Render non-trivial drawtypes like the actual node
-                       mesh = createSpecialNodeMesh(client, id, &m_colors, f);
+                       MapNode n(id);
+                       n.setParam2(def.place_param2);
+
+                       mesh = createSpecialNodeMesh(client, n, &m_colors, f);
                        changeToMesh(mesh);
                        mesh->drop();
                        m_meshnode->setScale(
@@ -423,6 +429,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
                                / (BS * f.visual_scale));
                        break;
                }
+               }
 
                u32 material_count = m_meshnode->getMaterialCount();
                for (u32 i = 0; i < material_count; ++i) {
@@ -585,12 +592,16 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
                        result->buffer_colors.emplace_back(l0.has_color, l0.color);
                        break;
                }
-               default:
+               default: {
                        // Render non-trivial drawtypes like the actual node
-                       mesh = createSpecialNodeMesh(client, id, &result->buffer_colors, f);
+                       MapNode n(id);
+                       n.setParam2(def.place_param2);
+
+                       mesh = createSpecialNodeMesh(client, n, &result->buffer_colors, f);
                        scaleMesh(mesh, v3f(0.12, 0.12, 0.12));
                        break;
                }
+               }
 
                u32 mc = mesh->getMeshBufferCount();
                for (u32 i = 0; i < mc; ++i) {
index 5fb1e4c470019df5a9921977d107da0973c22c6a..d79d6b263f9860f25a1ee06bac12fba07846889f 100644 (file)
@@ -71,13 +71,11 @@ ItemDefinition& ItemDefinition::operator=(const ItemDefinition &def)
        stack_max = def.stack_max;
        usable = def.usable;
        liquids_pointable = def.liquids_pointable;
-       if(def.tool_capabilities)
-       {
-               tool_capabilities = new ToolCapabilities(
-                               *def.tool_capabilities);
-       }
+       if (def.tool_capabilities)
+               tool_capabilities = new ToolCapabilities(*def.tool_capabilities);
        groups = def.groups;
        node_placement_prediction = def.node_placement_prediction;
+       place_param2 = def.place_param2;
        sound_place = def.sound_place;
        sound_place_failed = def.sound_place_failed;
        range = def.range;
@@ -120,8 +118,8 @@ void ItemDefinition::reset()
        sound_place = SimpleSoundSpec();
        sound_place_failed = SimpleSoundSpec();
        range = -1;
-
        node_placement_prediction = "";
+       place_param2 = 0;
 }
 
 void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const
@@ -166,6 +164,8 @@ void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const
        os << serializeString16(wield_overlay);
 
        os << serializeString16(short_description);
+
+       os << place_param2;
 }
 
 void ItemDefinition::deSerialize(std::istream &is)
@@ -219,6 +219,8 @@ void ItemDefinition::deSerialize(std::istream &is)
        // block to not need to increase the version.
        try {
                short_description = deSerializeString16(is);
+
+               place_param2 = readU8(is); // 0 if missing
        } catch(SerializationError &e) {};
 }
 
index ebf0d35273b5cbce57b7586393748db4d3d91e4f..3e302840f9254dbfa7267a71384667f11db874f9 100644 (file)
@@ -86,6 +86,7 @@ struct ItemDefinition
        // Server will update the precise end result a moment later.
        // "" = no prediction
        std::string node_placement_prediction;
+       u8 place_param2;
 
        /*
                Some helpful methods
index 6995f6b610c8062d23d7b24859a399b2d4d341a5..eca0c89d1702f93495db7bb3641d61d796c2eb49 100644 (file)
@@ -119,6 +119,8 @@ void read_item_definition(lua_State* L, int index,
        // "" = no prediction
        getstringfield(L, index, "node_placement_prediction",
                        def.node_placement_prediction);
+
+       getintfield(L, index, "place_param2", def.place_param2);
 }
 
 /******************************************************************************/