forked from Mirrorlandia_minetest/minetest
Implement client node dig prediction
Dig prediction allows clients to remove dug nodes without waiting for server acknowledgement. This patch allows mods to override dig prediction, it can either be turned off or a different "prediction node" can be selected.
This commit is contained in:
parent
d10cccee31
commit
5b3fbf9cf7
@ -4240,6 +4240,13 @@ Definition tables
|
|||||||
on ground when the player places the item. Server will always update
|
on ground when the player places the item. Server will always update
|
||||||
actual result to client in a short moment.
|
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 = {
|
sound = {
|
||||||
breaks = "default_tool_break", -- tools only
|
breaks = "default_tool_break", -- tools only
|
||||||
place = --[[<SimpleSoundSpec>]],
|
place = --[[<SimpleSoundSpec>]],
|
||||||
|
10
src/game.cpp
10
src/game.cpp
@ -4104,7 +4104,17 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
|
|||||||
client->getScript()->on_dignode(nodepos, wasnode)) {
|
client->getScript()->on_dignode(nodepos, wasnode)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ContentFeatures &f = client->ndef()->get(wasnode);
|
||||||
|
if (f.node_dig_prediction == "air") {
|
||||||
client->removeNode(nodepos);
|
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);
|
client->interact(2, pointed);
|
||||||
|
@ -335,6 +335,7 @@ void ContentFeatures::reset()
|
|||||||
color = video::SColor(0xFFFFFFFF);
|
color = video::SColor(0xFFFFFFFF);
|
||||||
palette_name = "";
|
palette_name = "";
|
||||||
palette = NULL;
|
palette = NULL;
|
||||||
|
node_dig_prediction = "air";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
|
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
|
// legacy
|
||||||
writeU8(os, legacy_facedir_simple);
|
writeU8(os, legacy_facedir_simple);
|
||||||
writeU8(os, legacy_wallmounted);
|
writeU8(os, legacy_wallmounted);
|
||||||
|
|
||||||
|
os << serializeString(node_dig_prediction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentFeatures::correctAlpha(TileDef *tiles, int length)
|
void ContentFeatures::correctAlpha(TileDef *tiles, int length)
|
||||||
@ -530,6 +533,10 @@ void ContentFeatures::deSerialize(std::istream &is)
|
|||||||
// read legacy properties
|
// read legacy properties
|
||||||
legacy_facedir_simple = readU8(is);
|
legacy_facedir_simple = readU8(is);
|
||||||
legacy_wallmounted = readU8(is);
|
legacy_wallmounted = readU8(is);
|
||||||
|
|
||||||
|
try {
|
||||||
|
node_dig_prediction = deSerializeString(is);
|
||||||
|
} catch(SerializationError &e) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
|
@ -324,6 +324,8 @@ struct ContentFeatures
|
|||||||
// Player cannot build to these (placement prediction disabled)
|
// Player cannot build to these (placement prediction disabled)
|
||||||
bool rightclickable;
|
bool rightclickable;
|
||||||
u32 damage_per_second;
|
u32 damage_per_second;
|
||||||
|
// client dig prediction
|
||||||
|
std::string node_dig_prediction;
|
||||||
|
|
||||||
// --- LIQUID PROPERTIES ---
|
// --- LIQUID PROPERTIES ---
|
||||||
|
|
||||||
|
@ -737,6 +737,10 @@ ContentFeatures read_content_features(lua_State *L, int index)
|
|||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
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;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,6 +865,8 @@ void push_content_features(lua_State *L, const ContentFeatures &c)
|
|||||||
lua_setfield(L, -2, "legacy_facedir_simple");
|
lua_setfield(L, -2, "legacy_facedir_simple");
|
||||||
lua_pushboolean(L, c.legacy_wallmounted);
|
lua_pushboolean(L, c.legacy_wallmounted);
|
||||||
lua_setfield(L, -2, "legacy_wallmounted");
|
lua_setfield(L, -2, "legacy_wallmounted");
|
||||||
|
lua_pushstring(L, c.node_dig_prediction.c_str());
|
||||||
|
lua_setfield(L, -2, "node_dig_prediction");
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
Loading…
Reference in New Issue
Block a user