mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-01 17:38:41 +00:00
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
This commit is contained in:
parent
e638072e15
commit
5482e51af0
23 changed files with 286 additions and 10 deletions
|
@ -9136,6 +9136,13 @@ child will follow movement and rotation of that bone.
|
||||||
|
|
||||||
* `get_lighting()`: returns the current state of lighting for the player.
|
* `get_lighting()`: returns the current state of lighting for the player.
|
||||||
* Result is a table with the same fields as `light_definition` in `set_lighting`.
|
* Result is a table with the same fields as `light_definition` in `set_lighting`.
|
||||||
|
* `set_node_visual(node_name, node_visual)`: sets `node_visual` of `node_name` for the player
|
||||||
|
* `node_name` is a name of registered node.
|
||||||
|
* `node_visual` is a table with the following optional fields:
|
||||||
|
* `variant_offset` this value is added to variant from node param2 value (default: `0`).
|
||||||
|
|
||||||
|
* `get_node_visual(node_name)`: returns the current `node_visual` of `node_name` for the player.
|
||||||
|
* Result is a table with the same fields as `node_visual` in `set_node_visual`.
|
||||||
* `respawn()`: Respawns the player using the same mechanism as the death screen,
|
* `respawn()`: Respawns the player using the same mechanism as the death screen,
|
||||||
including calling `on_respawnplayer` callbacks.
|
including calling `on_respawnplayer` callbacks.
|
||||||
* `get_flags()`: returns a table of player flags (the following boolean fields):
|
* `get_flags()`: returns a table of player flags (the following boolean fields):
|
||||||
|
|
|
@ -12,3 +12,4 @@ dofile(path.."/textures.lua")
|
||||||
dofile(path.."/overlays.lua")
|
dofile(path.."/overlays.lua")
|
||||||
dofile(path.."/variants.lua")
|
dofile(path.."/variants.lua")
|
||||||
dofile(path.."/commands.lua")
|
dofile(path.."/commands.lua")
|
||||||
|
dofile(path.."/node_visual.lua")
|
||||||
|
|
48
games/devtest/mods/testnodes/node_visual.lua
Normal file
48
games/devtest/mods/testnodes/node_visual.lua
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
-- add command to change node_visual
|
||||||
|
|
||||||
|
core.register_chatcommand("node_visual", {
|
||||||
|
params = "nodename field [value]",
|
||||||
|
description = "Change node_visual field of actual player to value or show value of field.",
|
||||||
|
func = function(name, param)
|
||||||
|
local player = core.get_player_by_name(name)
|
||||||
|
if not player then
|
||||||
|
return false, "No player."
|
||||||
|
end
|
||||||
|
|
||||||
|
local splits = string.split(param, " ", false, 3)
|
||||||
|
|
||||||
|
if #splits < 2 then
|
||||||
|
return false, "Expected node name and node_visual field as parameters."
|
||||||
|
end
|
||||||
|
|
||||||
|
local node_name = splits[1]
|
||||||
|
local field_name = splits[2]
|
||||||
|
|
||||||
|
if not core.registered_nodes[node_name] then
|
||||||
|
return false, "Unknown node "..node_name
|
||||||
|
end
|
||||||
|
|
||||||
|
local node_visual = player:get_node_visual(node_name)
|
||||||
|
|
||||||
|
if rawequal(node_visual[field_name], nil) then
|
||||||
|
return false, "Field "..field_name.." not found in node_visual."
|
||||||
|
end
|
||||||
|
|
||||||
|
if #splits > 2 then
|
||||||
|
if type(node_visual[field_name]) == "number" then
|
||||||
|
node_visual[field_name] = tonumber(splits[3])
|
||||||
|
elseif type(node_visual[field_name]) == "table" then
|
||||||
|
node_visual[field_name] = core.parse_json(splits[3])
|
||||||
|
if type(node_visual[field_name]) ~= "table" then
|
||||||
|
return false, "Table in json format is expected as value."
|
||||||
|
end
|
||||||
|
else
|
||||||
|
node_visual[field_name] = splits[3]
|
||||||
|
end
|
||||||
|
player:set_node_visual(node_name, node_visual)
|
||||||
|
return true, "Node "..node_name.." node_visual field "..field_name.." set to value: "..dump(node_visual[field_name])
|
||||||
|
else
|
||||||
|
return true, "Node "..node_name.." node_visual field "..field_name.." have value: "..dump(node_visual[field_name])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
|
@ -204,3 +204,12 @@ local function run_player_hotbar_clamp_tests(player)
|
||||||
player:hud_set_hotbar_itemcount(old_bar_size)
|
player:hud_set_hotbar_itemcount(old_bar_size)
|
||||||
end
|
end
|
||||||
unittests.register("test_player_hotbar_clamp", run_player_hotbar_clamp_tests, {player=true})
|
unittests.register("test_player_hotbar_clamp", run_player_hotbar_clamp_tests, {player=true})
|
||||||
|
|
||||||
|
unittests.register("test_player_node_visual", function (player)
|
||||||
|
local visual = player:get_node_visual("testnodes:variant_facedir")
|
||||||
|
player:set_node_visual("testnodes:variant_facedir",
|
||||||
|
{variant_offset = 5})
|
||||||
|
local set_visual = player:get_node_visual("testnodes:variant_facedir")
|
||||||
|
assert(set_visual.variant_offset == 5)
|
||||||
|
player:set_node_visual("testnodes:variant_facedir", visual)
|
||||||
|
end, {player = true})
|
||||||
|
|
|
@ -1761,6 +1761,18 @@ void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool ur
|
||||||
addUpdateMeshTask(blockpos + v3s16(0, 0, -1), false, urgent);
|
addUpdateMeshTask(blockpos + v3s16(0, 0, -1), false, urgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::updateDrawListBlocks(bool ack_to_server, bool urgent)
|
||||||
|
{
|
||||||
|
Map *map = &m_env.getMap();
|
||||||
|
ClientMap *client_map = dynamic_cast<ClientMap*>(map);
|
||||||
|
|
||||||
|
auto cb_updateBlock = [this, map, ack_to_server, urgent] (v3s16 block_pos, MapBlock *map_block) {
|
||||||
|
m_mesh_update_manager->updateBlock(map, block_pos, ack_to_server, urgent);
|
||||||
|
};
|
||||||
|
|
||||||
|
client_map->callOverDrawList(cb_updateBlock);
|
||||||
|
}
|
||||||
|
|
||||||
ClientEvent *Client::getClientEvent()
|
ClientEvent *Client::getClientEvent()
|
||||||
{
|
{
|
||||||
FATAL_ERROR_IF(m_client_event_queue.empty(),
|
FATAL_ERROR_IF(m_client_event_queue.empty(),
|
||||||
|
|
|
@ -219,6 +219,7 @@ public:
|
||||||
void handleCommand_MinimapModes(NetworkPacket *pkt);
|
void handleCommand_MinimapModes(NetworkPacket *pkt);
|
||||||
void handleCommand_SetLighting(NetworkPacket *pkt);
|
void handleCommand_SetLighting(NetworkPacket *pkt);
|
||||||
void handleCommand_Camera(NetworkPacket* pkt);
|
void handleCommand_Camera(NetworkPacket* pkt);
|
||||||
|
void handleCommand_SetNodeVisual(NetworkPacket *pkt);
|
||||||
|
|
||||||
void ProcessData(NetworkPacket *pkt);
|
void ProcessData(NetworkPacket *pkt);
|
||||||
|
|
||||||
|
@ -305,6 +306,8 @@ public:
|
||||||
void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
|
void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
|
||||||
void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
|
void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
|
||||||
|
|
||||||
|
void updateDrawListBlocks(bool ack_to_server=false, bool urgent=false);
|
||||||
|
|
||||||
bool hasClientEvents() const { return !m_client_event_queue.empty(); }
|
bool hasClientEvents() const { return !m_client_event_queue.empty(); }
|
||||||
// Get event from queue. If queue is empty, it triggers an assertion failure.
|
// Get event from queue. If queue is empty, it triggers an assertion failure.
|
||||||
ClientEvent * getClientEvent();
|
ClientEvent * getClientEvent();
|
||||||
|
|
|
@ -716,6 +716,13 @@ void ClientMap::updateDrawList()
|
||||||
g_profiler->avg("MapBlocks drawn [#]", m_drawlist.size());
|
g_profiler->avg("MapBlocks drawn [#]", m_drawlist.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientMap::callOverDrawList(const std::function<void(v3s16, MapBlock *)> &cb)
|
||||||
|
{
|
||||||
|
for (auto &i : m_drawlist) {
|
||||||
|
cb(i.first, i.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ClientMap::touchMapBlocks()
|
void ClientMap::touchMapBlocks()
|
||||||
{
|
{
|
||||||
if (m_control.range_all || m_loops_occlusion_culler)
|
if (m_control.range_all || m_loops_occlusion_culler)
|
||||||
|
|
|
@ -90,6 +90,7 @@ public:
|
||||||
void getBlocksInViewRange(v3s16 cam_pos_nodes,
|
void getBlocksInViewRange(v3s16 cam_pos_nodes,
|
||||||
v3s16 *p_blocks_min, v3s16 *p_blocks_max, float range=-1.0f);
|
v3s16 *p_blocks_min, v3s16 *p_blocks_max, float range=-1.0f);
|
||||||
void updateDrawList();
|
void updateDrawList();
|
||||||
|
void callOverDrawList(const std::function<void(v3s16, MapBlock *)> &cb);
|
||||||
// @brief Calculate statistics about the map and keep the blocks alive
|
// @brief Calculate statistics about the map and keep the blocks alive
|
||||||
void touchMapBlocks();
|
void touchMapBlocks();
|
||||||
void updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir, float radius, float length);
|
void updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir, float radius, float length);
|
||||||
|
|
|
@ -140,7 +140,7 @@ void PlayerDatabaseFiles::savePlayer(RemotePlayer *player)
|
||||||
std::string savedir = m_savedir + DIR_DELIM;
|
std::string savedir = m_savedir + DIR_DELIM;
|
||||||
std::string path = savedir + player->getName();
|
std::string path = savedir + player->getName();
|
||||||
bool path_found = false;
|
bool path_found = false;
|
||||||
RemotePlayer testplayer("", NULL);
|
RemotePlayer testplayer("", NULL, NULL);
|
||||||
|
|
||||||
for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES && !path_found; i++) {
|
for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES && !path_found; i++) {
|
||||||
if (!fs::PathExists(path)) {
|
if (!fs::PathExists(path)) {
|
||||||
|
@ -184,7 +184,7 @@ bool PlayerDatabaseFiles::removePlayer(const std::string &name)
|
||||||
std::string players_path = m_savedir + DIR_DELIM;
|
std::string players_path = m_savedir + DIR_DELIM;
|
||||||
std::string path = players_path + name;
|
std::string path = players_path + name;
|
||||||
|
|
||||||
RemotePlayer temp_player("", NULL);
|
RemotePlayer temp_player("", NULL, NULL);
|
||||||
for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES; i++) {
|
for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES; i++) {
|
||||||
// Open file and deserialize
|
// Open file and deserialize
|
||||||
auto is = open_ifstream(path.c_str(), false);
|
auto is = open_ifstream(path.c_str(), false);
|
||||||
|
@ -245,7 +245,7 @@ void PlayerDatabaseFiles::listPlayers(std::vector<std::string> &res)
|
||||||
if (!is.good())
|
if (!is.good())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RemotePlayer player(filename.c_str(), NULL);
|
RemotePlayer player(filename.c_str(), NULL, NULL);
|
||||||
// Null env & dummy peer_id
|
// Null env & dummy peer_id
|
||||||
PlayerSAO playerSAO(NULL, &player, 15789, false);
|
PlayerSAO playerSAO(NULL, &player, 15789, false);
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,9 @@ void MapNode::getColor(const ContentFeatures &f, video::SColor *color) const
|
||||||
|
|
||||||
u16 MapNode::getVariant(const ContentFeatures &f) const
|
u16 MapNode::getVariant(const ContentFeatures &f) const
|
||||||
{
|
{
|
||||||
return f.variant_count > 1 ? f.param2_variant.get(param2) % f.variant_count : 0;
|
if (f.variant_count > 1)
|
||||||
|
return (f.param2_variant.get(param2) + f.variant_offset) % f.variant_count;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 MapNode::getFaceDir(const NodeDefManager *nodemgr,
|
u8 MapNode::getFaceDir(const NodeDefManager *nodemgr,
|
||||||
|
|
|
@ -105,7 +105,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] =
|
||||||
{ "TOCLIENT_SET_MOON", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudSetMoon }, // 0x5b
|
{ "TOCLIENT_SET_MOON", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudSetMoon }, // 0x5b
|
||||||
{ "TOCLIENT_SET_STARS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudSetStars }, // 0x5c
|
{ "TOCLIENT_SET_STARS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudSetStars }, // 0x5c
|
||||||
{ "TOCLIENT_MOVE_PLAYER_REL", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_MovePlayerRel }, // 0x5d,
|
{ "TOCLIENT_MOVE_PLAYER_REL", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_MovePlayerRel }, // 0x5d,
|
||||||
null_command_handler,
|
{ "TOCLIENT_SET_NODE_VISUAL", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_SetNodeVisual }, // 0x5e
|
||||||
null_command_handler,
|
null_command_handler,
|
||||||
{ "TOCLIENT_SRP_BYTES_S_B", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_SrpBytesSandB }, // 0x60
|
{ "TOCLIENT_SRP_BYTES_S_B", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_SrpBytesSandB }, // 0x60
|
||||||
{ "TOCLIENT_FORMSPEC_PREPEND", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_FormspecPrepend }, // 0x61,
|
{ "TOCLIENT_FORMSPEC_PREPEND", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_FormspecPrepend }, // 0x61,
|
||||||
|
|
|
@ -1795,3 +1795,18 @@ void Client::handleCommand_SetLighting(NetworkPacket *pkt)
|
||||||
>> lighting.bloom_radius;
|
>> lighting.bloom_radius;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::handleCommand_SetNodeVisual(NetworkPacket *pkt)
|
||||||
|
{
|
||||||
|
std::string node_name;
|
||||||
|
NodeVisual node_visual;
|
||||||
|
|
||||||
|
*pkt >> node_name;
|
||||||
|
|
||||||
|
if (pkt->getRemainingBytes() >= 2)
|
||||||
|
*pkt >> node_visual.variant_offset;
|
||||||
|
|
||||||
|
m_nodedef->applyNodeVisual(node_name, node_visual);
|
||||||
|
|
||||||
|
updateDrawListBlocks();
|
||||||
|
}
|
||||||
|
|
|
@ -648,6 +648,12 @@ enum ToClientCommand : u16
|
||||||
v3f added_pos
|
v3f added_pos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
TOCLIENT_SET_NODE_VISUAL = 0x5e,
|
||||||
|
/*
|
||||||
|
std::string nodename
|
||||||
|
u16 variant_offset
|
||||||
|
*/
|
||||||
|
|
||||||
TOCLIENT_SRP_BYTES_S_B = 0x60,
|
TOCLIENT_SRP_BYTES_S_B = 0x60,
|
||||||
/*
|
/*
|
||||||
Belonging to AUTH_MECHANISM_SRP.
|
Belonging to AUTH_MECHANISM_SRP.
|
||||||
|
|
|
@ -205,7 +205,7 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] =
|
||||||
{ "TOCLIENT_SET_MOON", 0, true }, // 0x5b
|
{ "TOCLIENT_SET_MOON", 0, true }, // 0x5b
|
||||||
{ "TOCLIENT_SET_STARS", 0, true }, // 0x5c
|
{ "TOCLIENT_SET_STARS", 0, true }, // 0x5c
|
||||||
{ "TOCLIENT_MOVE_PLAYER_REL", 0, true }, // 0x5d
|
{ "TOCLIENT_MOVE_PLAYER_REL", 0, true }, // 0x5d
|
||||||
null_command_factory, // 0x5e
|
{ "TOCLIENT_SET_NODE_VISUAL", 0, true }, // 0x5e
|
||||||
null_command_factory, // 0x5f
|
null_command_factory, // 0x5f
|
||||||
{ "TOCLIENT_SRP_BYTES_S_B", 0, true }, // 0x60
|
{ "TOCLIENT_SRP_BYTES_S_B", 0, true }, // 0x60
|
||||||
{ "TOCLIENT_FORMSPEC_PREPEND", 0, true }, // 0x61
|
{ "TOCLIENT_FORMSPEC_PREPEND", 0, true }, // 0x61
|
||||||
|
|
|
@ -372,6 +372,7 @@ void ContentFeatures::reset()
|
||||||
param_type = CPT_NONE;
|
param_type = CPT_NONE;
|
||||||
param_type_2 = CPT2_NONE;
|
param_type_2 = CPT2_NONE;
|
||||||
variant_count = 1;
|
variant_count = 1;
|
||||||
|
variant_offset = 0;
|
||||||
param2_variant = BitField<u8>();
|
param2_variant = BitField<u8>();
|
||||||
is_ground_content = false;
|
is_ground_content = false;
|
||||||
light_propagates = false;
|
light_propagates = false;
|
||||||
|
@ -1076,6 +1077,22 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
NodeVisual
|
||||||
|
*/
|
||||||
|
|
||||||
|
NodeVisual::NodeVisual() : variant_offset(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
NodeVisual::NodeVisual(const ContentFeatures &f)
|
||||||
|
{
|
||||||
|
from_contentFeature(f);
|
||||||
|
}
|
||||||
|
void NodeVisual::from_contentFeature(const ContentFeatures &f)
|
||||||
|
{
|
||||||
|
variant_offset = f.variant_offset;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NodeDefManager
|
NodeDefManager
|
||||||
*/
|
*/
|
||||||
|
@ -1224,6 +1241,21 @@ const ContentFeatures& NodeDefManager::get(const std::string &name) const
|
||||||
return get(id);
|
return get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeDefManager::getNodeVisual(const std::string &name, NodeVisual &node_visual) const
|
||||||
|
{
|
||||||
|
const ContentFeatures &f = get(name);
|
||||||
|
node_visual.from_contentFeature(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeDefManager::applyNodeVisual(const std::string &name, const NodeVisual &node_visual)
|
||||||
|
{
|
||||||
|
content_t c = getId(name);
|
||||||
|
if (c < m_content_features.size() && !m_content_features[c].name.empty()) {
|
||||||
|
ContentFeatures& f = m_content_features[c];
|
||||||
|
|
||||||
|
f.variant_offset = node_visual.variant_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// returns CONTENT_IGNORE if no free ID found
|
// returns CONTENT_IGNORE if no free ID found
|
||||||
content_t NodeDefManager::allocateId()
|
content_t NodeDefManager::allocateId()
|
||||||
|
|
|
@ -340,6 +340,8 @@ struct ContentFeatures
|
||||||
ContentParamType2 param_type_2;
|
ContentParamType2 param_type_2;
|
||||||
// Number of node variants
|
// Number of node variants
|
||||||
u16 variant_count = 1;
|
u16 variant_count = 1;
|
||||||
|
// Node variant offset
|
||||||
|
u16 variant_offset = 0;
|
||||||
// Bit field for variant in param2
|
// Bit field for variant in param2
|
||||||
BitField<u8> param2_variant;
|
BitField<u8> param2_variant;
|
||||||
|
|
||||||
|
@ -522,6 +524,15 @@ private:
|
||||||
u8 getAlphaForLegacy() const;
|
u8 getAlphaForLegacy() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NodeVisual {
|
||||||
|
u16 variant_offset = 0;
|
||||||
|
|
||||||
|
NodeVisual();
|
||||||
|
NodeVisual(const ContentFeatures &f);
|
||||||
|
|
||||||
|
void from_contentFeature(const ContentFeatures &f);
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief This class is for getting the actual properties of nodes from their
|
* @brief This class is for getting the actual properties of nodes from their
|
||||||
* content ID.
|
* content ID.
|
||||||
|
@ -617,6 +628,20 @@ public:
|
||||||
return m_selection_box_int_union;
|
return m_selection_box_int_union;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Get NodeVisual object of node
|
||||||
|
* @param name a node name
|
||||||
|
* @param node_visual NodeVisual object to be set
|
||||||
|
*/
|
||||||
|
void getNodeVisual(const std::string &name, NodeVisual &node_visual) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Apply NodeVisual object to node
|
||||||
|
* @param name a node name
|
||||||
|
* @param node_visual NodeVisual object to be applied to node
|
||||||
|
*/
|
||||||
|
void applyNodeVisual(const std::string &name, const NodeVisual &node_visual);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Checks whether a node connects to an adjacent node.
|
* Checks whether a node connects to an adjacent node.
|
||||||
* @param from the node to be checked
|
* @param from the node to be checked
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "convert_json.h"
|
#include "convert_json.h"
|
||||||
#include "server/player_sao.h"
|
#include "server/player_sao.h"
|
||||||
|
#include "nodedef.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
RemotePlayer
|
RemotePlayer
|
||||||
|
@ -22,7 +23,8 @@ bool RemotePlayer::m_setting_cache_loaded = false;
|
||||||
float RemotePlayer::m_setting_chat_message_limit_per_10sec = 0.0f;
|
float RemotePlayer::m_setting_chat_message_limit_per_10sec = 0.0f;
|
||||||
u16 RemotePlayer::m_setting_chat_message_limit_trigger_kick = 0;
|
u16 RemotePlayer::m_setting_chat_message_limit_trigger_kick = 0;
|
||||||
|
|
||||||
RemotePlayer::RemotePlayer(const std::string &name, IItemDefManager *idef):
|
RemotePlayer::RemotePlayer(const std::string &name, IItemDefManager *idef,
|
||||||
|
NodeDefManager *ndef):
|
||||||
Player(name, idef)
|
Player(name, idef)
|
||||||
{
|
{
|
||||||
if (!RemotePlayer::m_setting_cache_loaded) {
|
if (!RemotePlayer::m_setting_cache_loaded) {
|
||||||
|
@ -52,6 +54,9 @@ RemotePlayer::RemotePlayer(const std::string &name, IItemDefManager *idef):
|
||||||
m_sun_params = SkyboxDefaults::getSunDefaults();
|
m_sun_params = SkyboxDefaults::getSunDefaults();
|
||||||
m_moon_params = SkyboxDefaults::getMoonDefaults();
|
m_moon_params = SkyboxDefaults::getMoonDefaults();
|
||||||
m_star_params = SkyboxDefaults::getStarDefaults();
|
m_star_params = SkyboxDefaults::getStarDefaults();
|
||||||
|
|
||||||
|
// NodeDefManager forNodeDefManager for NodeVisual
|
||||||
|
m_ndef = ndef;
|
||||||
}
|
}
|
||||||
|
|
||||||
RemotePlayer::~RemotePlayer()
|
RemotePlayer::~RemotePlayer()
|
||||||
|
@ -99,6 +104,23 @@ RemotePlayerChatResult RemotePlayer::canSendChatMessage()
|
||||||
return RPLAYER_CHATRESULT_OK;
|
return RPLAYER_CHATRESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemotePlayer::setNodeVisual(const std::string &node_name, const NodeVisual &node_visual)
|
||||||
|
{
|
||||||
|
content_t c = m_ndef->getId(node_name);
|
||||||
|
|
||||||
|
m_node_visuals[c] = node_visual;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemotePlayer::getNodeVisual(const std::string &node_name, NodeVisual &node_visual)
|
||||||
|
{
|
||||||
|
content_t c = m_ndef->getId(node_name);
|
||||||
|
|
||||||
|
if (m_node_visuals.find(c) != m_node_visuals.end())
|
||||||
|
node_visual = m_node_visuals[c];
|
||||||
|
else
|
||||||
|
node_visual.from_contentFeature(m_ndef->get(c));
|
||||||
|
}
|
||||||
|
|
||||||
void RemotePlayer::onSuccessfulSave()
|
void RemotePlayer::onSuccessfulSave()
|
||||||
{
|
{
|
||||||
setModified(false);
|
setModified(false);
|
||||||
|
|
|
@ -9,8 +9,11 @@
|
||||||
#include "skyparams.h"
|
#include "skyparams.h"
|
||||||
#include "lighting.h"
|
#include "lighting.h"
|
||||||
#include "network/networkprotocol.h" // session_t
|
#include "network/networkprotocol.h" // session_t
|
||||||
|
#include "mapnode.h" // content_t
|
||||||
|
|
||||||
class PlayerSAO;
|
class PlayerSAO;
|
||||||
|
class NodeDefManager;
|
||||||
|
struct NodeVisual;
|
||||||
|
|
||||||
enum RemotePlayerChatResult
|
enum RemotePlayerChatResult
|
||||||
{
|
{
|
||||||
|
@ -27,7 +30,8 @@ class RemotePlayer : public Player
|
||||||
friend class PlayerDatabaseFiles;
|
friend class PlayerDatabaseFiles;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RemotePlayer(const std::string &name, IItemDefManager *idef);
|
RemotePlayer(const std::string &name, IItemDefManager *idef,
|
||||||
|
NodeDefManager *ndef);
|
||||||
virtual ~RemotePlayer();
|
virtual ~RemotePlayer();
|
||||||
|
|
||||||
PlayerSAO *getPlayerSAO() { return m_sao; }
|
PlayerSAO *getPlayerSAO() { return m_sao; }
|
||||||
|
@ -116,6 +120,10 @@ public:
|
||||||
|
|
||||||
const Lighting& getLighting() const { return m_lighting; }
|
const Lighting& getLighting() const { return m_lighting; }
|
||||||
|
|
||||||
|
void setNodeVisual(const std::string &node_name, const NodeVisual &node_visual);
|
||||||
|
|
||||||
|
void getNodeVisual(const std::string &node_name, NodeVisual &node_visual);
|
||||||
|
|
||||||
void setDirty(bool dirty) { m_dirty = true; }
|
void setDirty(bool dirty) { m_dirty = true; }
|
||||||
|
|
||||||
u16 protocol_version = 0;
|
u16 protocol_version = 0;
|
||||||
|
@ -154,5 +162,8 @@ private:
|
||||||
|
|
||||||
Lighting m_lighting;
|
Lighting m_lighting;
|
||||||
|
|
||||||
|
NodeDefManager *m_ndef;
|
||||||
|
std::map<content_t, NodeVisual> m_node_visuals;
|
||||||
|
|
||||||
session_t m_peer_id = PEER_ID_INEXISTENT;
|
session_t m_peer_id = PEER_ID_INEXISTENT;
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "remoteplayer.h"
|
#include "remoteplayer.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "hud.h"
|
#include "hud.h"
|
||||||
|
#include "nodedef.h"
|
||||||
#include "scripting_server.h"
|
#include "scripting_server.h"
|
||||||
#include "server/luaentity_sao.h"
|
#include "server/luaentity_sao.h"
|
||||||
#include "server/player_sao.h"
|
#include "server/player_sao.h"
|
||||||
|
@ -2749,6 +2750,50 @@ int ObjectRef::l_get_lighting(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set_node_visual(self, node_name, node_visual)
|
||||||
|
int ObjectRef::l_set_node_visual(lua_State *L)
|
||||||
|
{
|
||||||
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
|
||||||
|
RemotePlayer *player = getplayer(ref);
|
||||||
|
if (player == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
std::string node_name = readParam<std::string>(L, 2);
|
||||||
|
|
||||||
|
NodeVisual node_visual;
|
||||||
|
player->getNodeVisual(node_name, node_visual);
|
||||||
|
NodeVisual new_visual = node_visual;
|
||||||
|
|
||||||
|
if (!lua_isnoneornil(L, 3)) {
|
||||||
|
luaL_checktype(L, 3, LUA_TTABLE);
|
||||||
|
new_visual.variant_offset = getfloatfield_default(L, -1, "variant_offset", node_visual.variant_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
getServer(L)->setNodeVisual(player, node_name, new_visual);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get_node_visual(self, node_name)
|
||||||
|
int ObjectRef::l_get_node_visual(lua_State *L)
|
||||||
|
{
|
||||||
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
|
||||||
|
RemotePlayer *player = getplayer(ref);
|
||||||
|
if (player == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
std::string node_name = readParam<std::string>(L, 2);
|
||||||
|
|
||||||
|
NodeVisual node_visual;
|
||||||
|
player->getNodeVisual(node_name, node_visual);
|
||||||
|
|
||||||
|
lua_newtable(L); // result
|
||||||
|
lua_pushnumber(L, node_visual.variant_offset);
|
||||||
|
lua_setfield(L, -2, "variant_offset");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// respawn(self)
|
// respawn(self)
|
||||||
int ObjectRef::l_respawn(lua_State *L)
|
int ObjectRef::l_respawn(lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -2950,6 +2995,8 @@ luaL_Reg ObjectRef::methods[] = {
|
||||||
luamethod(ObjectRef, set_minimap_modes),
|
luamethod(ObjectRef, set_minimap_modes),
|
||||||
luamethod(ObjectRef, set_lighting),
|
luamethod(ObjectRef, set_lighting),
|
||||||
luamethod(ObjectRef, get_lighting),
|
luamethod(ObjectRef, get_lighting),
|
||||||
|
luamethod(ObjectRef, set_node_visual),
|
||||||
|
luamethod(ObjectRef, get_node_visual),
|
||||||
luamethod(ObjectRef, respawn),
|
luamethod(ObjectRef, respawn),
|
||||||
luamethod(ObjectRef, set_flags),
|
luamethod(ObjectRef, set_flags),
|
||||||
luamethod(ObjectRef, get_flags),
|
luamethod(ObjectRef, get_flags),
|
||||||
|
|
|
@ -406,6 +406,12 @@ private:
|
||||||
// get_lighting(self)
|
// get_lighting(self)
|
||||||
static int l_get_lighting(lua_State *L);
|
static int l_get_lighting(lua_State *L);
|
||||||
|
|
||||||
|
// set_node_visual(self, node_name, node_visual)
|
||||||
|
static int l_set_node_visual(lua_State *L);
|
||||||
|
|
||||||
|
// get_node_visual(self, node_name)
|
||||||
|
static int l_get_node_visual(lua_State *L);
|
||||||
|
|
||||||
// respawn(self)
|
// respawn(self)
|
||||||
static int l_respawn(lua_State *L);
|
static int l_respawn(lua_State *L);
|
||||||
|
|
||||||
|
|
|
@ -1965,6 +1965,17 @@ void Server::SendCamera(session_t peer_id, Player *player)
|
||||||
Send(&pkt);
|
Send(&pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::SendSetNodeVisual(session_t peer_id, const std::string &node_name, const NodeVisual &node_visual)
|
||||||
|
{
|
||||||
|
NetworkPacket pkt(TOCLIENT_SET_NODE_VISUAL,
|
||||||
|
4, peer_id);
|
||||||
|
|
||||||
|
pkt << node_name;
|
||||||
|
pkt << node_visual.variant_offset;
|
||||||
|
|
||||||
|
Send(&pkt);
|
||||||
|
}
|
||||||
|
|
||||||
void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed)
|
void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed)
|
||||||
{
|
{
|
||||||
NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id);
|
NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id);
|
||||||
|
@ -3576,6 +3587,13 @@ void Server::setLighting(RemotePlayer *player, const Lighting &lighting)
|
||||||
SendSetLighting(player->getPeerId(), lighting);
|
SendSetLighting(player->getPeerId(), lighting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::setNodeVisual(RemotePlayer *player, const std::string &node_name, const NodeVisual &node_visual)
|
||||||
|
{
|
||||||
|
sanity_check(player);
|
||||||
|
player->setNodeVisual(node_name, node_visual);
|
||||||
|
SendSetNodeVisual(player->getPeerId(), node_name, node_visual);
|
||||||
|
}
|
||||||
|
|
||||||
void Server::notifyPlayers(const std::wstring &msg)
|
void Server::notifyPlayers(const std::wstring &msg)
|
||||||
{
|
{
|
||||||
SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(msg));
|
SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(msg));
|
||||||
|
@ -4103,7 +4121,7 @@ std::unique_ptr<PlayerSAO> Server::emergePlayer(const char *name, session_t peer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!player) {
|
if (!player) {
|
||||||
player = new RemotePlayer(name, idef());
|
player = new RemotePlayer(name, idef(), m_nodedef);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load player
|
// Load player
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "translation.h"
|
#include "translation.h"
|
||||||
#include "script/common/c_types.h" // LuaError
|
#include "script/common/c_types.h" // LuaError
|
||||||
|
#include "nodedef.h"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -387,6 +388,8 @@ public:
|
||||||
|
|
||||||
void setLighting(RemotePlayer *player, const Lighting &lighting);
|
void setLighting(RemotePlayer *player, const Lighting &lighting);
|
||||||
|
|
||||||
|
void setNodeVisual(RemotePlayer *player, const std::string &node_name, const NodeVisual &node_visual);
|
||||||
|
|
||||||
/* con::PeerHandler implementation. */
|
/* con::PeerHandler implementation. */
|
||||||
void peerAdded(con::IPeer *peer);
|
void peerAdded(con::IPeer *peer);
|
||||||
void deletingPeer(con::IPeer *peer, bool timeout);
|
void deletingPeer(con::IPeer *peer, bool timeout);
|
||||||
|
@ -550,6 +553,7 @@ private:
|
||||||
void SendCloudParams(session_t peer_id, const CloudParams ¶ms);
|
void SendCloudParams(session_t peer_id, const CloudParams ¶ms);
|
||||||
void SendOverrideDayNightRatio(session_t peer_id, bool do_override, float ratio);
|
void SendOverrideDayNightRatio(session_t peer_id, bool do_override, float ratio);
|
||||||
void SendSetLighting(session_t peer_id, const Lighting &lighting);
|
void SendSetLighting(session_t peer_id, const Lighting &lighting);
|
||||||
|
void SendSetNodeVisual(session_t peer_id, const std::string &node_name, const NodeVisual &node_visual);
|
||||||
|
|
||||||
void broadcastModChannelMessage(const std::string &channel,
|
void broadcastModChannelMessage(const std::string &channel,
|
||||||
const std::string &message, session_t from_peer);
|
const std::string &message, session_t from_peer);
|
||||||
|
|
|
@ -1902,7 +1902,7 @@ bool ServerEnvironment::migratePlayersDatabase(const GameParams &game_params,
|
||||||
for (auto it = player_list.begin();
|
for (auto it = player_list.begin();
|
||||||
it != player_list.end(); ++it) {
|
it != player_list.end(); ++it) {
|
||||||
actionstream << "Migrating player " << it->c_str() << std::endl;
|
actionstream << "Migrating player " << it->c_str() << std::endl;
|
||||||
RemotePlayer player(it->c_str(), NULL);
|
RemotePlayer player(it->c_str(), NULL, NULL);
|
||||||
PlayerSAO playerSAO(NULL, &player, 15000, false);
|
PlayerSAO playerSAO(NULL, &player, 15000, false);
|
||||||
|
|
||||||
srcdb->loadPlayer(&player, &playerSAO);
|
srcdb->loadPlayer(&player, &playerSAO);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue