aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt7
-rw-r--r--src/game.cpp12
-rw-r--r--src/nodedef.cpp7
-rw-r--r--src/nodedef.h2
-rw-r--r--src/script/common/c_content.cpp6
5 files changed, 33 insertions, 1 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 6bdb63ef3..9a5754368 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -4240,6 +4240,13 @@ Definition tables
on ground when the player places the item. Server will always update
actual result to client in a short moment.
]]
+ node_dig_prediction = "air",
+ --[[
+ ^ if "", no prediction is made
+ ^ if "air", node is removed
+ ^ Otherwise should be name of node which the client immediately places
+ upon digging. Server will always update actual result shortly.
+ ]]
sound = {
breaks = "default_tool_break", -- tools only
place = --[[<SimpleSoundSpec>]],
diff --git a/src/game.cpp b/src/game.cpp
index 04688e476..d85e34d35 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -4104,7 +4104,17 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
client->getScript()->on_dignode(nodepos, wasnode)) {
return;
}
- client->removeNode(nodepos);
+
+ const ContentFeatures &f = client->ndef()->get(wasnode);
+ if (f.node_dig_prediction == "air") {
+ client->removeNode(nodepos);
+ } else if (!f.node_dig_prediction.empty()) {
+ content_t id;
+ bool found = client->ndef()->getId(f.node_dig_prediction, id);
+ if (found)
+ client->addNode(nodepos, id, true);
+ }
+ // implicit else: no prediction
}
client->interact(2, pointed);
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
index bc03b71e7..e547e31b1 100644
--- a/src/nodedef.cpp
+++ b/src/nodedef.cpp
@@ -335,6 +335,7 @@ void ContentFeatures::reset()
color = video::SColor(0xFFFFFFFF);
palette_name = "";
palette = NULL;
+ node_dig_prediction = "air";
}
void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
@@ -422,6 +423,8 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
// legacy
writeU8(os, legacy_facedir_simple);
writeU8(os, legacy_wallmounted);
+
+ os << serializeString(node_dig_prediction);
}
void ContentFeatures::correctAlpha(TileDef *tiles, int length)
@@ -530,6 +533,10 @@ void ContentFeatures::deSerialize(std::istream &is)
// read legacy properties
legacy_facedir_simple = readU8(is);
legacy_wallmounted = readU8(is);
+
+ try {
+ node_dig_prediction = deSerializeString(is);
+ } catch(SerializationError &e) {};
}
#ifndef SERVER
diff --git a/src/nodedef.h b/src/nodedef.h
index 1392e51d4..853b9bddd 100644
--- a/src/nodedef.h
+++ b/src/nodedef.h
@@ -324,6 +324,8 @@ struct ContentFeatures
// Player cannot build to these (placement prediction disabled)
bool rightclickable;
u32 damage_per_second;
+ // client dig prediction
+ std::string node_dig_prediction;
// --- LIQUID PROPERTIES ---
diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp
index 9e1fed2f1..ad92741f8 100644
--- a/src/script/common/c_content.cpp
+++ b/src/script/common/c_content.cpp
@@ -737,6 +737,10 @@ ContentFeatures read_content_features(lua_State *L, int index)
}
lua_pop(L, 1);
+ // Node immediately placed by client when node is dug
+ getstringfield(L, index, "node_dig_prediction",
+ f.node_dig_prediction);
+
return f;
}
@@ -861,6 +865,8 @@ void push_content_features(lua_State *L, const ContentFeatures &c)
lua_setfield(L, -2, "legacy_facedir_simple");
lua_pushboolean(L, c.legacy_wallmounted);
lua_setfield(L, -2, "legacy_wallmounted");
+ lua_pushstring(L, c.node_dig_prediction.c_str());
+ lua_setfield(L, -2, "node_dig_prediction");
}
/******************************************************************************/