Skip to content

Commit d9a0712

Browse files
committed
Add method set_node_visual and get_node_visual to player Lua object and needed logic around it to allow game to set variant_offset
1 parent 324240a commit d9a0712

23 files changed

+286
-10
lines changed

doc/lua_api.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9058,6 +9058,13 @@ child will follow movement and rotation of that bone.
90589058

90599059
* `get_lighting()`: returns the current state of lighting for the player.
90609060
* Result is a table with the same fields as `light_definition` in `set_lighting`.
9061+
* `set_node_visual(node_name, node_visual)`: sets `node_visual` of `node_name` for the player
9062+
* `node_name` is a name of registered node.
9063+
* `node_visual` is a table with the following optional fields:
9064+
* `variant_offset` this value is added to variant from node param2 value (default: `0`).
9065+
9066+
* `get_node_visual(node_name)`: returns the current `node_visual` of `node_name` for the player.
9067+
* Result is a table with the same fields as `node_visual` in `set_node_visual`.
90619068
* `respawn()`: Respawns the player using the same mechanism as the death screen,
90629069
including calling `on_respawnplayer` callbacks.
90639070
* `get_flags()`: returns a table of player flags (the following boolean fields):

games/devtest/mods/testnodes/init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ dofile(path.."/textures.lua")
1212
dofile(path.."/overlays.lua")
1313
dofile(path.."/variants.lua")
1414
dofile(path.."/commands.lua")
15+
dofile(path.."/node_visual.lua")
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
-- add command to change node_visual
2+
3+
core.register_chatcommand("node_visual", {
4+
params = "nodename field [value]",
5+
description = "Change node_visual field of actual player to value or show value of field.",
6+
func = function(name, param)
7+
local player = core.get_player_by_name(name)
8+
if not player then
9+
return false, "No player."
10+
end
11+
12+
local splits = string.split(param, " ", false, 3)
13+
14+
if #splits < 2 then
15+
return false, "Expected node name and node_visual field as parameters."
16+
end
17+
18+
local node_name = splits[1]
19+
local field_name = splits[2]
20+
21+
if not core.registered_nodes[node_name] then
22+
return false, "Unknown node "..node_name
23+
end
24+
25+
local node_visual = player:get_node_visual(node_name)
26+
27+
if rawequal(node_visual[field_name], nil) then
28+
return false, "Field "..field_name.." not found in node_visual."
29+
end
30+
31+
if #splits > 2 then
32+
if type(node_visual[field_name]) == "number" then
33+
node_visual[field_name] = tonumber(splits[3])
34+
elseif type(node_visual[field_name]) == "table" then
35+
node_visual[field_name] = core.parse_json(splits[3])
36+
if type(node_visual[field_name]) ~= "table" then
37+
return false, "Table in json format is expected as value."
38+
end
39+
else
40+
node_visual[field_name] = splits[3]
41+
end
42+
player:set_node_visual(node_name, node_visual)
43+
return true, "Node "..node_name.." node_visual field "..field_name.." set to value: "..dump(node_visual[field_name])
44+
else
45+
return true, "Node "..node_name.." node_visual field "..field_name.." have value: "..dump(node_visual[field_name])
46+
end
47+
end
48+
})

games/devtest/mods/unittests/player.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,12 @@ local function run_player_hotbar_clamp_tests(player)
204204
player:hud_set_hotbar_itemcount(old_bar_size)
205205
end
206206
unittests.register("test_player_hotbar_clamp", run_player_hotbar_clamp_tests, {player=true})
207+
208+
unittests.register("test_player_node_visual", function (player)
209+
local visual = player:get_node_visual("testnodes:variant_facedir")
210+
player:set_node_visual("testnodes:variant_facedir",
211+
{variant_offset = 5})
212+
local set_visual = player:get_node_visual("testnodes:variant_facedir")
213+
assert(set_visual.variant_offset == 5)
214+
player:set_node_visual("testnodes:variant_facedir", visual)
215+
end, {player = true})

src/client/client.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,6 +1764,18 @@ void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool ur
17641764
addUpdateMeshTask(blockpos + v3s16(0, 0, -1), false, urgent);
17651765
}
17661766

1767+
void Client::updateDrawListBlocks(bool ack_to_server, bool urgent)
1768+
{
1769+
Map *map = &m_env.getMap();
1770+
ClientMap *client_map = dynamic_cast<ClientMap*>(map);
1771+
1772+
auto cb_updateBlock = [this, map, ack_to_server, urgent] (v3s16 block_pos, MapBlock *map_block) {
1773+
m_mesh_update_manager->updateBlock(map, block_pos, ack_to_server, urgent);
1774+
};
1775+
1776+
client_map->callOverDrawList(cb_updateBlock);
1777+
}
1778+
17671779
ClientEvent *Client::getClientEvent()
17681780
{
17691781
FATAL_ERROR_IF(m_client_event_queue.empty(),

src/client/client.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
219219
void handleCommand_MinimapModes(NetworkPacket *pkt);
220220
void handleCommand_SetLighting(NetworkPacket *pkt);
221221
void handleCommand_Camera(NetworkPacket* pkt);
222+
void handleCommand_SetNodeVisual(NetworkPacket *pkt);
222223

223224
void ProcessData(NetworkPacket *pkt);
224225

@@ -305,6 +306,8 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
305306
void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
306307
void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
307308

309+
void updateDrawListBlocks(bool ack_to_server=false, bool urgent=false);
310+
308311
bool hasClientEvents() const { return !m_client_event_queue.empty(); }
309312
// Get event from queue. If queue is empty, it triggers an assertion failure.
310313
ClientEvent * getClientEvent();

src/client/clientmap.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,13 @@ void ClientMap::updateDrawList()
711711
g_profiler->avg("MapBlocks drawn [#]", m_drawlist.size());
712712
}
713713

714+
void ClientMap::callOverDrawList(const std::function<void(v3s16, MapBlock *)> &cb)
715+
{
716+
for (auto &i : m_drawlist) {
717+
cb(i.first, i.second);
718+
}
719+
}
720+
714721
void ClientMap::touchMapBlocks()
715722
{
716723
if (m_control.range_all || m_loops_occlusion_culler)

src/client/clientmap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class ClientMap : public Map, public scene::ISceneNode
9090
void getBlocksInViewRange(v3s16 cam_pos_nodes,
9191
v3s16 *p_blocks_min, v3s16 *p_blocks_max, float range=-1.0f);
9292
void updateDrawList();
93+
void callOverDrawList(const std::function<void(v3s16, MapBlock *)> &cb);
9394
// @brief Calculate statistics about the map and keep the blocks alive
9495
void touchMapBlocks();
9596
void updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir, float radius, float length);

src/database/database-files.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ void PlayerDatabaseFiles::savePlayer(RemotePlayer *player)
140140
std::string savedir = m_savedir + DIR_DELIM;
141141
std::string path = savedir + player->getName();
142142
bool path_found = false;
143-
RemotePlayer testplayer("", NULL);
143+
RemotePlayer testplayer("", NULL, NULL);
144144

145145
for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES && !path_found; i++) {
146146
if (!fs::PathExists(path)) {
@@ -184,7 +184,7 @@ bool PlayerDatabaseFiles::removePlayer(const std::string &name)
184184
std::string players_path = m_savedir + DIR_DELIM;
185185
std::string path = players_path + name;
186186

187-
RemotePlayer temp_player("", NULL);
187+
RemotePlayer temp_player("", NULL, NULL);
188188
for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES; i++) {
189189
// Open file and deserialize
190190
auto is = open_ifstream(path.c_str(), false);
@@ -245,7 +245,7 @@ void PlayerDatabaseFiles::listPlayers(std::vector<std::string> &res)
245245
if (!is.good())
246246
continue;
247247

248-
RemotePlayer player(filename.c_str(), NULL);
248+
RemotePlayer player(filename.c_str(), NULL, NULL);
249249
// Null env & dummy peer_id
250250
PlayerSAO playerSAO(NULL, &player, 15789, false);
251251

src/mapnode.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ void MapNode::getColor(const ContentFeatures &f, video::SColor *color) const
4040

4141
u16 MapNode::getVariant(const ContentFeatures &f) const
4242
{
43-
return f.variant_count > 1 ? f.param2_variant.get(param2) % f.variant_count : 0;
43+
if (f.variant_count > 1)
44+
return (f.param2_variant.get(param2) + f.variant_offset) % f.variant_count;
45+
return 0;
4446
}
4547

4648
u8 MapNode::getFaceDir(const NodeDefManager *nodemgr,

0 commit comments

Comments
 (0)