Skip to content

Commit

Permalink
Implement client node dig prediction
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sofar authored and sfan5 committed Sep 11, 2017
1 parent d10ccce commit 5b3fbf9
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 1 deletion.
7 changes: 7 additions & 0 deletions doc/lua_api.txt
Expand Up @@ -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>]],
Expand Down
12 changes: 11 additions & 1 deletion src/game.cpp
Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions src/nodedef.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/nodedef.h
Expand Up @@ -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 ---

Expand Down
6 changes: 6 additions & 0 deletions src/script/common/c_content.cpp
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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");
}

/******************************************************************************/
Expand Down

0 comments on commit 5b3fbf9

Please sign in to comment.