forked from oerkki/voxelands
add ManualMapVoxelManipulator::blitBackAllWithMeta and make pistons use voxelmanipulators
This commit is contained in:
parent
2a56ad8085
commit
36db988e80
|
@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "environment.h"
|
||||
#include "settings.h"
|
||||
#include "main.h"
|
||||
#include "mapblock.h"
|
||||
|
||||
/*
|
||||
SignNodeMetadata
|
||||
|
@ -3161,24 +3162,47 @@ bool PistonNodeMetadata::extend(v3s16 pos, v3s16 dir, content_t arm, ServerEnvir
|
|||
v3s16 p_prev = pos;
|
||||
v3s16 p_cur = p_prev+dir;
|
||||
v3s16 p_next = p_cur+dir;
|
||||
|
||||
core::map<v3s16, MapBlock*> modified_blocks;
|
||||
ManualMapVoxelManipulator vmanip(&env->getMap());
|
||||
v3s16 piston_blockp = getNodeBlockPos(pos);
|
||||
vmanip.initialEmerge(piston_blockp - v3s16(1,1,1), piston_blockp + v3s16(1,1,1));
|
||||
|
||||
if (arm == CONTENT_CIRCUIT_PISTON_ARM || arm == CONTENT_CIRCUIT_STICKYPISTON_ARM)
|
||||
n_prev = env->getMap().getNodeNoEx(pos);
|
||||
n_prev = vmanip.m_data[vmanip.m_area.index(p_prev)];
|
||||
n_prev.setContent(arm);
|
||||
n_cur = env->getMap().getNodeNoEx(p_cur);
|
||||
n_cur = vmanip.m_data[vmanip.m_area.index(p_cur)];
|
||||
for (int i=0; i<17; i++) {
|
||||
ContentFeatures &f = content_features(n_cur);
|
||||
n_next = env->getMap().getNodeNoEx(p_next);
|
||||
env->getMap().addNodeWithEvent(p_cur,n_prev);
|
||||
n_next = vmanip.m_data[vmanip.m_area.index(p_next)];
|
||||
vmanip.m_data[vmanip.m_area.index(p_cur)] = n_prev;
|
||||
if (f.pressure_type == CST_CRUSHED)
|
||||
return true;
|
||||
break;
|
||||
if (f.pressure_type == CST_CRUSHABLE && n_next.getContent() != CONTENT_AIR)
|
||||
return true;
|
||||
break;
|
||||
n_prev = n_cur;
|
||||
n_cur = n_next;
|
||||
p_prev = p_cur;
|
||||
p_cur = p_next;
|
||||
p_next += dir;
|
||||
}
|
||||
|
||||
vmanip.blitBackAllWithMeta(&modified_blocks);
|
||||
|
||||
// update lighting
|
||||
core::map<v3s16, MapBlock*> lighting_modified_blocks;
|
||||
for (core::map<v3s16, MapBlock*>::Iterator i = modified_blocks.getIterator(); i.atEnd() == false; i++) {
|
||||
lighting_modified_blocks.insert(i.getNode()->getKey(), i.getNode()->getValue());
|
||||
}
|
||||
env->getMap().updateLighting(lighting_modified_blocks, modified_blocks);
|
||||
// Send a MEET_OTHER event
|
||||
MapEditEvent event;
|
||||
event.type = MEET_OTHER;
|
||||
for (core::map<v3s16, MapBlock*>::Iterator i = modified_blocks.getIterator(); i.atEnd() == false; i++) {
|
||||
v3s16 p = i.getNode()->getKey();
|
||||
event.modified_blocks.insert(p, true);
|
||||
}
|
||||
env->getMap().dispatchEvent(&event);
|
||||
return true;
|
||||
}
|
||||
bool PistonNodeMetadata::contract(v3s16 pos, v3s16 dir, bool sticky, ServerEnvironment *env)
|
||||
|
@ -3224,8 +3248,13 @@ bool PistonNodeMetadata::contract(v3s16 pos, v3s16 dir, bool sticky, ServerEnvir
|
|||
|
||||
p_cur = pos+dir;
|
||||
p_next = p_cur+dir;
|
||||
|
||||
core::map<v3s16, MapBlock*> modified_blocks;
|
||||
ManualMapVoxelManipulator vmanip(&env->getMap());
|
||||
v3s16 piston_blockp = getNodeBlockPos(pos);
|
||||
vmanip.initialEmerge(piston_blockp - v3s16(1,1,1), piston_blockp + v3s16(1,1,1));
|
||||
for (int i=0; i<16; i++) {
|
||||
MapNode n = env->getMap().getNodeNoEx(p_next);
|
||||
MapNode n = vmanip.m_data[vmanip.m_area.index(p_next)];
|
||||
if (n.getContent() == CONTENT_IGNORE)
|
||||
break;
|
||||
ContentFeatures &f = content_features(n);
|
||||
|
@ -3235,12 +3264,29 @@ bool PistonNodeMetadata::contract(v3s16 pos, v3s16 dir, bool sticky, ServerEnvir
|
|||
break;
|
||||
if ((!sticky || i) && f.pressure_type != CST_DROPABLE)
|
||||
break;
|
||||
env->getMap().removeNodeWithEvent(p_next);
|
||||
env->getMap().addNodeWithEvent(p_cur,n);
|
||||
vmanip.m_data[vmanip.m_area.index(p_next)] = CONTENT_AIR;
|
||||
vmanip.m_data[vmanip.m_area.index(p_cur)] = n;
|
||||
if (!dropping)
|
||||
break;
|
||||
p_cur = p_next;
|
||||
p_next += dir;
|
||||
}
|
||||
|
||||
vmanip.blitBackAllWithMeta(&modified_blocks);
|
||||
|
||||
// update lighting
|
||||
core::map<v3s16, MapBlock*> lighting_modified_blocks;
|
||||
for (core::map<v3s16, MapBlock*>::Iterator i = modified_blocks.getIterator(); i.atEnd() == false; i++) {
|
||||
lighting_modified_blocks.insert(i.getNode()->getKey(), i.getNode()->getValue());
|
||||
}
|
||||
env->getMap().updateLighting(lighting_modified_blocks, modified_blocks);
|
||||
// Send a MEET_OTHER event
|
||||
MapEditEvent event;
|
||||
event.type = MEET_OTHER;
|
||||
for (core::map<v3s16, MapBlock*>::Iterator i = modified_blocks.getIterator(); i.atEnd() == false; i++) {
|
||||
v3s16 p = i.getNode()->getKey();
|
||||
event.modified_blocks.insert(p, true);
|
||||
}
|
||||
env->getMap().dispatchEvent(&event);
|
||||
return true;
|
||||
}
|
||||
|
|
77
src/map.cpp
77
src/map.cpp
|
@ -4466,20 +4466,16 @@ void ManualMapVoxelManipulator::initialEmerge(
|
|||
void ManualMapVoxelManipulator::blitBackAll(
|
||||
core::map<v3s16, MapBlock*> * modified_blocks)
|
||||
{
|
||||
if(m_area.getExtent() == v3s16(0,0,0))
|
||||
if (m_area.getExtent() == v3s16(0,0,0))
|
||||
return;
|
||||
|
||||
/*
|
||||
Copy data of all blocks
|
||||
*/
|
||||
for(core::map<v3s16, bool>::Iterator
|
||||
i = m_loaded_blocks.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
{
|
||||
for (core::map<v3s16, bool>::Iterator i = m_loaded_blocks.getIterator(); i.atEnd() == false; i++) {
|
||||
v3s16 p = i.getNode()->getKey();
|
||||
bool existed = i.getNode()->getValue();
|
||||
if(existed == false)
|
||||
{
|
||||
if (existed == false) {
|
||||
// The Great Bug was found using this
|
||||
/*infostream<<"ManualMapVoxelManipulator::blitBackAll: "
|
||||
<<"Inexistent ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||
|
@ -4487,8 +4483,7 @@ void ManualMapVoxelManipulator::blitBackAll(
|
|||
continue;
|
||||
}
|
||||
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
||||
if(block == NULL)
|
||||
{
|
||||
if (block == NULL) {
|
||||
infostream<<"WARNING: "<<__FUNCTION_NAME
|
||||
<<": got NULL block "
|
||||
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||
|
@ -4498,9 +4493,71 @@ void ManualMapVoxelManipulator::blitBackAll(
|
|||
|
||||
block->copyFrom(*this);
|
||||
|
||||
if(modified_blocks)
|
||||
if (modified_blocks)
|
||||
modified_blocks->insert(p, block);
|
||||
}
|
||||
}
|
||||
|
||||
void ManualMapVoxelManipulator::blitBackAllWithMeta(
|
||||
core::map<v3s16, MapBlock*> * modified_blocks)
|
||||
{
|
||||
if (m_area.getExtent() == v3s16(0,0,0))
|
||||
return;
|
||||
|
||||
/*
|
||||
Copy data of all blocks
|
||||
*/
|
||||
for (core::map<v3s16, bool>::Iterator i = m_loaded_blocks.getIterator(); i.atEnd() == false; i++) {
|
||||
v3s16 p = i.getNode()->getKey();
|
||||
bool existed = i.getNode()->getValue();
|
||||
if (existed == false) {
|
||||
// The Great Bug was found using this
|
||||
/*infostream<<"ManualMapVoxelManipulator::blitBackAll: "
|
||||
<<"Inexistent ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||
<<std::endl;*/
|
||||
continue;
|
||||
}
|
||||
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
||||
if (block == NULL) {
|
||||
infostream<<"WARNING: "<<__FUNCTION_NAME
|
||||
<<": got NULL block "
|
||||
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||
<<std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
block->copyFrom(*this);
|
||||
|
||||
if (modified_blocks)
|
||||
modified_blocks->insert(p, block);
|
||||
}
|
||||
if (!modified_blocks)
|
||||
return;
|
||||
// iterate over the modified blocks search for
|
||||
// nodes that have metadata that shouldn't
|
||||
// nodes that don't have metadata that should
|
||||
// nodes that have the wrong metadata
|
||||
for (core::map<v3s16, MapBlock*>::Iterator i = modified_blocks->getIterator(); i.atEnd() == false; i++) {
|
||||
v3s16 p = i.getNode()->getKey();
|
||||
MapBlock *block = i.getNode()->getValue();
|
||||
if (block == NULL)
|
||||
continue;
|
||||
v3s16 p0;
|
||||
for(p0.X=0; p0.X<MAP_BLOCKSIZE; p0.X++)
|
||||
for(p0.Y=0; p0.Y<MAP_BLOCKSIZE; p0.Y++)
|
||||
for(p0.Z=0; p0.Z<MAP_BLOCKSIZE; p0.Z++) {
|
||||
v3s16 p = p0 + block->getPosRelative();
|
||||
MapNode n = block->getNodeNoEx(p0);
|
||||
if (content_features(n).initial_metadata != NULL) {
|
||||
NodeMetadata *f = content_features(n).initial_metadata;
|
||||
NodeMetadata *a = block->m_node_metadata.get(p0);
|
||||
if (!a || f->typeId() != a->typeId())
|
||||
block->m_node_metadata.set(p0,f->clone());
|
||||
}else if (block->m_node_metadata.get(p0) != NULL) {
|
||||
block->m_node_metadata.remove(p0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//END
|
||||
|
|
|
@ -662,6 +662,8 @@ public:
|
|||
|
||||
// This is much faster with big chunks of generated data
|
||||
void blitBackAll(core::map<v3s16, MapBlock*> * modified_blocks);
|
||||
// Slower than above, but doesn't screw up node metadata
|
||||
void blitBackAllWithMeta(core::map<v3s16, MapBlock*> * modified_blocks);
|
||||
|
||||
protected:
|
||||
bool m_create_area;
|
||||
|
|
Loading…
Reference in New Issue