Add ServerEnvironment::setNode()/removeNode() to allow setting nodes from the C++ side with proper script-defined initialization/destruction

This commit is contained in:
Perttu Ahola 2013-01-02 23:17:52 +02:00
parent 69bd803a32
commit 2c472a66d1
3 changed files with 45 additions and 27 deletions

@ -819,6 +819,45 @@ void ServerEnvironment::addActiveBlockModifier(ActiveBlockModifier *abm)
m_abms.push_back(ABMWithState(abm)); m_abms.push_back(ABMWithState(abm));
} }
bool ServerEnvironment::setNode(v3s16 p, const MapNode &n)
{
INodeDefManager *ndef = m_gamedef->ndef();
MapNode n_old = m_map->getNodeNoEx(p);
// Call destructor
if(ndef->get(n_old).has_on_destruct)
scriptapi_node_on_destruct(m_lua, p, n_old);
// Replace node
bool succeeded = m_map->addNodeWithEvent(p, n);
if(!succeeded)
return false;
// Call post-destructor
if(ndef->get(n_old).has_after_destruct)
scriptapi_node_after_destruct(m_lua, p, n_old);
// Call constructor
if(ndef->get(n).has_on_construct)
scriptapi_node_on_construct(m_lua, p, n);
return true;
}
bool ServerEnvironment::removeNode(v3s16 p)
{
INodeDefManager *ndef = m_gamedef->ndef();
MapNode n_old = m_map->getNodeNoEx(p);
// Call destructor
if(ndef->get(n_old).has_on_destruct)
scriptapi_node_on_destruct(m_lua, p, n_old);
// Replace with air
// This is slightly optimized compared to addNodeWithEvent(air)
bool succeeded = m_map->removeNodeWithEvent(p);
if(!succeeded)
return false;
// Call post-destructor
if(ndef->get(n_old).has_after_destruct)
scriptapi_node_after_destruct(m_lua, p, n_old);
// Air doesn't require constructor
return true;
}
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;

@ -284,6 +284,10 @@ public:
------------------------------------------- -------------------------------------------
*/ */
// Script-aware node setters
bool setNode(v3s16 p, const MapNode &n);
bool removeNode(v3s16 p);
// 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);

@ -3540,20 +3540,7 @@ private:
v3s16 pos = read_v3s16(L, 2); v3s16 pos = read_v3s16(L, 2);
MapNode n = readnode(L, 3, ndef); MapNode n = readnode(L, 3, ndef);
// Do it // Do it
MapNode n_old = env->getMap().getNodeNoEx(pos); bool succeeded = env->setNode(pos, n);
// Call destructor
if(ndef->get(n_old).has_on_destruct)
scriptapi_node_on_destruct(L, pos, n_old);
// Replace node
bool succeeded = env->getMap().addNodeWithEvent(pos, n);
if(succeeded){
// Call post-destructor
if(ndef->get(n_old).has_after_destruct)
scriptapi_node_after_destruct(L, pos, n_old);
// Call constructor
if(ndef->get(n).has_on_construct)
scriptapi_node_on_construct(L, pos, n);
}
lua_pushboolean(L, succeeded); lua_pushboolean(L, succeeded);
return 1; return 1;
} }
@ -3574,20 +3561,8 @@ private:
// parameters // parameters
v3s16 pos = read_v3s16(L, 2); v3s16 pos = read_v3s16(L, 2);
// Do it // Do it
MapNode n_old = env->getMap().getNodeNoEx(pos); bool succeeded = env->removeNode(pos);
// Call destructor
if(ndef->get(n_old).has_on_destruct)
scriptapi_node_on_destruct(L, pos, n_old);
// Replace with air
// This is slightly optimized compared to addNodeWithEvent(air)
bool succeeded = env->getMap().removeNodeWithEvent(pos);
if(succeeded){
// Call post-destructor
if(ndef->get(n_old).has_after_destruct)
scriptapi_node_after_destruct(L, pos, n_old);
}
lua_pushboolean(L, succeeded); lua_pushboolean(L, succeeded);
// Air doesn't require constructor
return 1; return 1;
} }