mirror of
https://github.com/minetest/minetest.git
synced 2024-12-23 14:42:24 +01:00
Add minetest.swap_node
This commit is contained in:
parent
752e11e114
commit
d879a539cd
@ -1318,18 +1318,13 @@ minetest.register_node("default:furnace_active", {
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
function hacky_swap_node(pos,name)
|
function swap_node(pos,name)
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local meta0 = meta:to_table()
|
|
||||||
if node.name == name then
|
if node.name == name then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
node.name = name
|
node.name = name
|
||||||
local meta0 = meta:to_table()
|
minetest.swap_node(pos, node)
|
||||||
minetest.set_node(pos,node)
|
|
||||||
meta = minetest.get_meta(pos)
|
|
||||||
meta:from_table(meta0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
@ -1384,7 +1379,7 @@ minetest.register_abm({
|
|||||||
local percent = math.floor(meta:get_float("fuel_time") /
|
local percent = math.floor(meta:get_float("fuel_time") /
|
||||||
meta:get_float("fuel_totaltime") * 100)
|
meta:get_float("fuel_totaltime") * 100)
|
||||||
meta:set_string("infotext","Furnace active: "..percent.."%")
|
meta:set_string("infotext","Furnace active: "..percent.."%")
|
||||||
hacky_swap_node(pos,"default:furnace_active")
|
swap_node(pos,"default:furnace_active")
|
||||||
meta:set_string("formspec",
|
meta:set_string("formspec",
|
||||||
"size[8,9]"..
|
"size[8,9]"..
|
||||||
"image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
|
"image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
|
||||||
@ -1410,7 +1405,7 @@ minetest.register_abm({
|
|||||||
|
|
||||||
if fuel.time <= 0 then
|
if fuel.time <= 0 then
|
||||||
meta:set_string("infotext","Furnace out of fuel")
|
meta:set_string("infotext","Furnace out of fuel")
|
||||||
hacky_swap_node(pos,"default:furnace")
|
swap_node(pos,"default:furnace")
|
||||||
meta:set_string("formspec", default.furnace_inactive_formspec)
|
meta:set_string("formspec", default.furnace_inactive_formspec)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -1418,7 +1413,7 @@ minetest.register_abm({
|
|||||||
if cooked.item:is_empty() then
|
if cooked.item:is_empty() then
|
||||||
if was_active then
|
if was_active then
|
||||||
meta:set_string("infotext","Furnace is empty")
|
meta:set_string("infotext","Furnace is empty")
|
||||||
hacky_swap_node(pos,"default:furnace")
|
swap_node(pos,"default:furnace")
|
||||||
meta:set_string("formspec", default.furnace_inactive_formspec)
|
meta:set_string("formspec", default.furnace_inactive_formspec)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
|
@ -1262,7 +1262,13 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||||||
MapNode n;
|
MapNode n;
|
||||||
n.deSerialize(&data[8], ser_version);
|
n.deSerialize(&data[8], ser_version);
|
||||||
|
|
||||||
addNode(p, n);
|
bool remove_metadata = true;
|
||||||
|
u32 index = 8 + MapNode::serializedLength(ser_version);
|
||||||
|
if ((datasize >= index+1) && data[index]){
|
||||||
|
remove_metadata = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
addNode(p, n, remove_metadata);
|
||||||
}
|
}
|
||||||
else if(command == TOCLIENT_BLOCKDATA)
|
else if(command == TOCLIENT_BLOCKDATA)
|
||||||
{
|
{
|
||||||
@ -2514,7 +2520,7 @@ void Client::removeNode(v3s16 p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::addNode(v3s16 p, MapNode n)
|
void Client::addNode(v3s16 p, MapNode n, bool remove_metadata)
|
||||||
{
|
{
|
||||||
TimeTaker timer1("Client::addNode()");
|
TimeTaker timer1("Client::addNode()");
|
||||||
|
|
||||||
@ -2523,7 +2529,7 @@ void Client::addNode(v3s16 p, MapNode n)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
//TimeTaker timer3("Client::addNode(): addNodeAndUpdate");
|
//TimeTaker timer3("Client::addNode(): addNodeAndUpdate");
|
||||||
m_env.getMap().addNodeAndUpdate(p, n, modified_blocks);
|
m_env.getMap().addNodeAndUpdate(p, n, modified_blocks, remove_metadata);
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e)
|
catch(InvalidPositionException &e)
|
||||||
{}
|
{}
|
||||||
|
@ -365,7 +365,7 @@ public:
|
|||||||
|
|
||||||
// Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
|
// Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
|
||||||
void removeNode(v3s16 p);
|
void removeNode(v3s16 p);
|
||||||
void addNode(v3s16 p, MapNode n);
|
void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
|
||||||
|
|
||||||
void setPlayerControl(PlayerControl &control);
|
void setPlayerControl(PlayerControl &control);
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
added to object properties
|
added to object properties
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LATEST_PROTOCOL_VERSION 21
|
#define LATEST_PROTOCOL_VERSION 22
|
||||||
|
|
||||||
// Server's supported network protocol range
|
// Server's supported network protocol range
|
||||||
#define SERVER_PROTOCOL_VERSION_MIN 13
|
#define SERVER_PROTOCOL_VERSION_MIN 13
|
||||||
@ -139,6 +139,12 @@ enum ToClientCommand
|
|||||||
|
|
||||||
TOCLIENT_BLOCKDATA = 0x20, //TODO: Multiple blocks
|
TOCLIENT_BLOCKDATA = 0x20, //TODO: Multiple blocks
|
||||||
TOCLIENT_ADDNODE = 0x21,
|
TOCLIENT_ADDNODE = 0x21,
|
||||||
|
/*
|
||||||
|
u16 command
|
||||||
|
v3s16 position
|
||||||
|
serialized mapnode
|
||||||
|
u8 keep_metadata // Added in protocol version 22
|
||||||
|
*/
|
||||||
TOCLIENT_REMOVENODE = 0x22,
|
TOCLIENT_REMOVENODE = 0x22,
|
||||||
|
|
||||||
TOCLIENT_PLAYERPOS = 0x23, // Obsolete
|
TOCLIENT_PLAYERPOS = 0x23, // Obsolete
|
||||||
|
@ -874,6 +874,11 @@ bool ServerEnvironment::removeNode(v3s16 p)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ServerEnvironment::swapNode(v3s16 p, const MapNode &n)
|
||||||
|
{
|
||||||
|
return m_map->addNodeWithEvent(p, n, false);
|
||||||
|
}
|
||||||
|
|
||||||
std::set<u16> ServerEnvironment::getObjectsInsideRadius(v3f pos, float radius)
|
std::set<u16> ServerEnvironment::getObjectsInsideRadius(v3f pos, float radius)
|
||||||
{
|
{
|
||||||
std::set<u16> objects;
|
std::set<u16> objects;
|
||||||
|
@ -283,6 +283,7 @@ public:
|
|||||||
// Script-aware node setters
|
// Script-aware node setters
|
||||||
bool setNode(v3s16 p, const MapNode &n);
|
bool setNode(v3s16 p, const MapNode &n);
|
||||||
bool removeNode(v3s16 p);
|
bool removeNode(v3s16 p);
|
||||||
|
bool swapNode(v3s16 p, const MapNode &n);
|
||||||
|
|
||||||
// Find all active objects inside a radius around a point
|
// Find all active objects inside a radius around a point
|
||||||
std::set<u16> getObjectsInsideRadius(v3f pos, float radius);
|
std::set<u16> getObjectsInsideRadius(v3f pos, float radius);
|
||||||
|
12
src/map.cpp
12
src/map.cpp
@ -931,7 +931,8 @@ void Map::updateLighting(std::map<v3s16, MapBlock*> & a_blocks,
|
|||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||||
std::map<v3s16, MapBlock*> &modified_blocks)
|
std::map<v3s16, MapBlock*> &modified_blocks,
|
||||||
|
bool remove_metadata)
|
||||||
{
|
{
|
||||||
INodeDefManager *ndef = m_gamedef->ndef();
|
INodeDefManager *ndef = m_gamedef->ndef();
|
||||||
|
|
||||||
@ -1018,8 +1019,9 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
|||||||
/*
|
/*
|
||||||
Remove node metadata
|
Remove node metadata
|
||||||
*/
|
*/
|
||||||
|
if (remove_metadata) {
|
||||||
removeNodeMetadata(p);
|
removeNodeMetadata(p);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set the node on the map
|
Set the node on the map
|
||||||
@ -1319,17 +1321,17 @@ void Map::removeNodeAndUpdate(v3s16 p,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map::addNodeWithEvent(v3s16 p, MapNode n)
|
bool Map::addNodeWithEvent(v3s16 p, MapNode n, bool remove_metadata)
|
||||||
{
|
{
|
||||||
MapEditEvent event;
|
MapEditEvent event;
|
||||||
event.type = MEET_ADDNODE;
|
event.type = remove_metadata ? MEET_ADDNODE : MEET_SWAPNODE;
|
||||||
event.p = p;
|
event.p = p;
|
||||||
event.n = n;
|
event.n = n;
|
||||||
|
|
||||||
bool succeeded = true;
|
bool succeeded = true;
|
||||||
try{
|
try{
|
||||||
std::map<v3s16, MapBlock*> modified_blocks;
|
std::map<v3s16, MapBlock*> modified_blocks;
|
||||||
addNodeAndUpdate(p, n, modified_blocks);
|
addNodeAndUpdate(p, n, modified_blocks, remove_metadata);
|
||||||
|
|
||||||
// Copy modified_blocks to event
|
// Copy modified_blocks to event
|
||||||
for(std::map<v3s16, MapBlock*>::iterator
|
for(std::map<v3s16, MapBlock*>::iterator
|
||||||
|
@ -61,6 +61,8 @@ enum MapEditEventType{
|
|||||||
MEET_ADDNODE,
|
MEET_ADDNODE,
|
||||||
// Node removed (changed to air)
|
// Node removed (changed to air)
|
||||||
MEET_REMOVENODE,
|
MEET_REMOVENODE,
|
||||||
|
// Node swapped (changed without metadata change)
|
||||||
|
MEET_SWAPNODE,
|
||||||
// Node metadata of block changed (not knowing which node exactly)
|
// Node metadata of block changed (not knowing which node exactly)
|
||||||
// p stores block coordinate
|
// p stores block coordinate
|
||||||
MEET_BLOCK_NODE_METADATA_CHANGED,
|
MEET_BLOCK_NODE_METADATA_CHANGED,
|
||||||
@ -99,6 +101,8 @@ struct MapEditEvent
|
|||||||
return VoxelArea(p);
|
return VoxelArea(p);
|
||||||
case MEET_REMOVENODE:
|
case MEET_REMOVENODE:
|
||||||
return VoxelArea(p);
|
return VoxelArea(p);
|
||||||
|
case MEET_SWAPNODE:
|
||||||
|
return VoxelArea(p);
|
||||||
case MEET_BLOCK_NODE_METADATA_CHANGED:
|
case MEET_BLOCK_NODE_METADATA_CHANGED:
|
||||||
{
|
{
|
||||||
v3s16 np1 = p*MAP_BLOCKSIZE;
|
v3s16 np1 = p*MAP_BLOCKSIZE;
|
||||||
@ -236,7 +240,8 @@ public:
|
|||||||
These handle lighting but not faces.
|
These handle lighting but not faces.
|
||||||
*/
|
*/
|
||||||
void addNodeAndUpdate(v3s16 p, MapNode n,
|
void addNodeAndUpdate(v3s16 p, MapNode n,
|
||||||
std::map<v3s16, MapBlock*> &modified_blocks);
|
std::map<v3s16, MapBlock*> &modified_blocks,
|
||||||
|
bool remove_metadata = true);
|
||||||
void removeNodeAndUpdate(v3s16 p,
|
void removeNodeAndUpdate(v3s16 p,
|
||||||
std::map<v3s16, MapBlock*> &modified_blocks);
|
std::map<v3s16, MapBlock*> &modified_blocks);
|
||||||
|
|
||||||
@ -245,7 +250,7 @@ public:
|
|||||||
These emit events.
|
These emit events.
|
||||||
Return true if succeeded, false if not.
|
Return true if succeeded, false if not.
|
||||||
*/
|
*/
|
||||||
bool addNodeWithEvent(v3s16 p, MapNode n);
|
bool addNodeWithEvent(v3s16 p, MapNode n, bool remove_metadata = true);
|
||||||
bool removeNodeWithEvent(v3s16 p);
|
bool removeNodeWithEvent(v3s16 p);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -120,6 +120,22 @@ int ModApiEnvMod::l_remove_node(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// minetest.swap_node(pos, node)
|
||||||
|
// pos = {x=num, y=num, z=num}
|
||||||
|
int ModApiEnvMod::l_swap_node(lua_State *L)
|
||||||
|
{
|
||||||
|
GET_ENV_PTR;
|
||||||
|
|
||||||
|
INodeDefManager *ndef = env->getGameDef()->ndef();
|
||||||
|
// parameters
|
||||||
|
v3s16 pos = read_v3s16(L, 1);
|
||||||
|
MapNode n = readnode(L, 2, ndef);
|
||||||
|
// Do it
|
||||||
|
bool succeeded = env->swapNode(pos, n);
|
||||||
|
lua_pushboolean(L, succeeded);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// minetest.get_node(pos)
|
// minetest.get_node(pos)
|
||||||
// pos = {x=num, y=num, z=num}
|
// pos = {x=num, y=num, z=num}
|
||||||
int ModApiEnvMod::l_get_node(lua_State *L)
|
int ModApiEnvMod::l_get_node(lua_State *L)
|
||||||
@ -798,6 +814,7 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
|
|||||||
{
|
{
|
||||||
API_FCT(set_node);
|
API_FCT(set_node);
|
||||||
API_FCT(add_node);
|
API_FCT(add_node);
|
||||||
|
API_FCT(swap_node);
|
||||||
API_FCT(add_item);
|
API_FCT(add_item);
|
||||||
API_FCT(remove_node);
|
API_FCT(remove_node);
|
||||||
API_FCT(get_node);
|
API_FCT(get_node);
|
||||||
|
@ -35,6 +35,10 @@ private:
|
|||||||
// pos = {x=num, y=num, z=num}
|
// pos = {x=num, y=num, z=num}
|
||||||
static int l_remove_node(lua_State *L);
|
static int l_remove_node(lua_State *L);
|
||||||
|
|
||||||
|
// minetest.swap_node(pos, node)
|
||||||
|
// pos = {x=num, y=num, z=num}
|
||||||
|
static int l_swap_node(lua_State *L);
|
||||||
|
|
||||||
// minetest.get_node(pos)
|
// minetest.get_node(pos)
|
||||||
// pos = {x=num, y=num, z=num}
|
// pos = {x=num, y=num, z=num}
|
||||||
static int l_get_node(lua_State *L);
|
static int l_get_node(lua_State *L);
|
||||||
|
@ -1582,16 +1582,16 @@ void Server::AsyncRunStep()
|
|||||||
// for them.
|
// for them.
|
||||||
std::list<u16> far_players;
|
std::list<u16> far_players;
|
||||||
|
|
||||||
if(event->type == MEET_ADDNODE)
|
if(event->type == MEET_ADDNODE || event->type == MEET_SWAPNODE)
|
||||||
{
|
{
|
||||||
//infostream<<"Server: MEET_ADDNODE"<<std::endl;
|
//infostream<<"Server: MEET_ADDNODE"<<std::endl;
|
||||||
prof.add("MEET_ADDNODE", 1);
|
prof.add("MEET_ADDNODE", 1);
|
||||||
if(disable_single_change_sending)
|
if(disable_single_change_sending)
|
||||||
sendAddNode(event->p, event->n, event->already_known_by_peer,
|
sendAddNode(event->p, event->n, event->already_known_by_peer,
|
||||||
&far_players, 5);
|
&far_players, 5, event->type == MEET_ADDNODE);
|
||||||
else
|
else
|
||||||
sendAddNode(event->p, event->n, event->already_known_by_peer,
|
sendAddNode(event->p, event->n, event->already_known_by_peer,
|
||||||
&far_players, 30);
|
&far_players, 30, event->type == MEET_ADDNODE);
|
||||||
}
|
}
|
||||||
else if(event->type == MEET_REMOVENODE)
|
else if(event->type == MEET_REMOVENODE)
|
||||||
{
|
{
|
||||||
@ -4070,7 +4070,8 @@ void Server::sendRemoveNode(v3s16 p, u16 ignore_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id,
|
void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id,
|
||||||
std::list<u16> *far_players, float far_d_nodes)
|
std::list<u16> *far_players, float far_d_nodes,
|
||||||
|
bool remove_metadata)
|
||||||
{
|
{
|
||||||
float maxd = far_d_nodes*BS;
|
float maxd = far_d_nodes*BS;
|
||||||
v3f p_f = intToFloat(p, BS);
|
v3f p_f = intToFloat(p, BS);
|
||||||
@ -4106,13 +4107,23 @@ void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create packet
|
// Create packet
|
||||||
u32 replysize = 8 + MapNode::serializedLength(client->serialization_version);
|
u32 replysize = 9 + MapNode::serializedLength(client->serialization_version);
|
||||||
SharedBuffer<u8> reply(replysize);
|
SharedBuffer<u8> reply(replysize);
|
||||||
writeU16(&reply[0], TOCLIENT_ADDNODE);
|
writeU16(&reply[0], TOCLIENT_ADDNODE);
|
||||||
writeS16(&reply[2], p.X);
|
writeS16(&reply[2], p.X);
|
||||||
writeS16(&reply[4], p.Y);
|
writeS16(&reply[4], p.Y);
|
||||||
writeS16(&reply[6], p.Z);
|
writeS16(&reply[6], p.Z);
|
||||||
n.serialize(&reply[8], client->serialization_version);
|
n.serialize(&reply[8], client->serialization_version);
|
||||||
|
u32 index = 8 + MapNode::serializedLength(client->serialization_version);
|
||||||
|
writeU8(&reply[index], remove_metadata ? 0 : 1);
|
||||||
|
|
||||||
|
if (!remove_metadata) {
|
||||||
|
if (client->net_proto_version <= 21) {
|
||||||
|
// Old clients always clear metadata; fix it
|
||||||
|
// by sending the full block again.
|
||||||
|
client->SetBlockNotSent(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Send as reliable
|
// Send as reliable
|
||||||
m_con.Send(client->peer_id, 0, reply, true);
|
m_con.Send(client->peer_id, 0, reply, true);
|
||||||
|
@ -556,7 +556,8 @@ private:
|
|||||||
void sendRemoveNode(v3s16 p, u16 ignore_id=0,
|
void sendRemoveNode(v3s16 p, u16 ignore_id=0,
|
||||||
std::list<u16> *far_players=NULL, float far_d_nodes=100);
|
std::list<u16> *far_players=NULL, float far_d_nodes=100);
|
||||||
void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
|
void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
|
||||||
std::list<u16> *far_players=NULL, float far_d_nodes=100);
|
std::list<u16> *far_players=NULL, float far_d_nodes=100,
|
||||||
|
bool remove_metadata=true);
|
||||||
void setBlockNotSent(v3s16 p);
|
void setBlockNotSent(v3s16 p);
|
||||||
|
|
||||||
// Environment and Connection must be locked when called
|
// Environment and Connection must be locked when called
|
||||||
|
Loading…
Reference in New Issue
Block a user