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 "environment.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "mapblock.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SignNodeMetadata
|
SignNodeMetadata
|
||||||
|
@ -3161,24 +3162,47 @@ bool PistonNodeMetadata::extend(v3s16 pos, v3s16 dir, content_t arm, ServerEnvir
|
||||||
v3s16 p_prev = pos;
|
v3s16 p_prev = pos;
|
||||||
v3s16 p_cur = p_prev+dir;
|
v3s16 p_cur = p_prev+dir;
|
||||||
v3s16 p_next = p_cur+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)
|
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_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++) {
|
for (int i=0; i<17; i++) {
|
||||||
ContentFeatures &f = content_features(n_cur);
|
ContentFeatures &f = content_features(n_cur);
|
||||||
n_next = env->getMap().getNodeNoEx(p_next);
|
n_next = vmanip.m_data[vmanip.m_area.index(p_next)];
|
||||||
env->getMap().addNodeWithEvent(p_cur,n_prev);
|
vmanip.m_data[vmanip.m_area.index(p_cur)] = n_prev;
|
||||||
if (f.pressure_type == CST_CRUSHED)
|
if (f.pressure_type == CST_CRUSHED)
|
||||||
return true;
|
break;
|
||||||
if (f.pressure_type == CST_CRUSHABLE && n_next.getContent() != CONTENT_AIR)
|
if (f.pressure_type == CST_CRUSHABLE && n_next.getContent() != CONTENT_AIR)
|
||||||
return true;
|
break;
|
||||||
n_prev = n_cur;
|
n_prev = n_cur;
|
||||||
n_cur = n_next;
|
n_cur = n_next;
|
||||||
p_prev = p_cur;
|
p_prev = p_cur;
|
||||||
p_cur = p_next;
|
p_cur = p_next;
|
||||||
p_next += dir;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
bool PistonNodeMetadata::contract(v3s16 pos, v3s16 dir, bool sticky, ServerEnvironment *env)
|
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_cur = pos+dir;
|
||||||
p_next = p_cur+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++) {
|
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)
|
if (n.getContent() == CONTENT_IGNORE)
|
||||||
break;
|
break;
|
||||||
ContentFeatures &f = content_features(n);
|
ContentFeatures &f = content_features(n);
|
||||||
|
@ -3235,12 +3264,29 @@ bool PistonNodeMetadata::contract(v3s16 pos, v3s16 dir, bool sticky, ServerEnvir
|
||||||
break;
|
break;
|
||||||
if ((!sticky || i) && f.pressure_type != CST_DROPABLE)
|
if ((!sticky || i) && f.pressure_type != CST_DROPABLE)
|
||||||
break;
|
break;
|
||||||
env->getMap().removeNodeWithEvent(p_next);
|
vmanip.m_data[vmanip.m_area.index(p_next)] = CONTENT_AIR;
|
||||||
env->getMap().addNodeWithEvent(p_cur,n);
|
vmanip.m_data[vmanip.m_area.index(p_cur)] = n;
|
||||||
if (!dropping)
|
if (!dropping)
|
||||||
break;
|
break;
|
||||||
p_cur = p_next;
|
p_cur = p_next;
|
||||||
p_next += dir;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
77
src/map.cpp
77
src/map.cpp
|
@ -4466,20 +4466,16 @@ void ManualMapVoxelManipulator::initialEmerge(
|
||||||
void ManualMapVoxelManipulator::blitBackAll(
|
void ManualMapVoxelManipulator::blitBackAll(
|
||||||
core::map<v3s16, MapBlock*> * modified_blocks)
|
core::map<v3s16, MapBlock*> * modified_blocks)
|
||||||
{
|
{
|
||||||
if(m_area.getExtent() == v3s16(0,0,0))
|
if (m_area.getExtent() == v3s16(0,0,0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copy data of all blocks
|
Copy data of all blocks
|
||||||
*/
|
*/
|
||||||
for(core::map<v3s16, bool>::Iterator
|
for (core::map<v3s16, bool>::Iterator i = m_loaded_blocks.getIterator(); i.atEnd() == false; i++) {
|
||||||
i = m_loaded_blocks.getIterator();
|
|
||||||
i.atEnd() == false; i++)
|
|
||||||
{
|
|
||||||
v3s16 p = i.getNode()->getKey();
|
v3s16 p = i.getNode()->getKey();
|
||||||
bool existed = i.getNode()->getValue();
|
bool existed = i.getNode()->getValue();
|
||||||
if(existed == false)
|
if (existed == false) {
|
||||||
{
|
|
||||||
// The Great Bug was found using this
|
// The Great Bug was found using this
|
||||||
/*infostream<<"ManualMapVoxelManipulator::blitBackAll: "
|
/*infostream<<"ManualMapVoxelManipulator::blitBackAll: "
|
||||||
<<"Inexistent ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
<<"Inexistent ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||||
|
@ -4487,8 +4483,7 @@ void ManualMapVoxelManipulator::blitBackAll(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
||||||
if(block == NULL)
|
if (block == NULL) {
|
||||||
{
|
|
||||||
infostream<<"WARNING: "<<__FUNCTION_NAME
|
infostream<<"WARNING: "<<__FUNCTION_NAME
|
||||||
<<": got NULL block "
|
<<": got NULL block "
|
||||||
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||||
|
@ -4498,9 +4493,71 @@ void ManualMapVoxelManipulator::blitBackAll(
|
||||||
|
|
||||||
block->copyFrom(*this);
|
block->copyFrom(*this);
|
||||||
|
|
||||||
if(modified_blocks)
|
if (modified_blocks)
|
||||||
modified_blocks->insert(p, block);
|
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
|
//END
|
||||||
|
|
|
@ -662,6 +662,8 @@ public:
|
||||||
|
|
||||||
// This is much faster with big chunks of generated data
|
// This is much faster with big chunks of generated data
|
||||||
void blitBackAll(core::map<v3s16, MapBlock*> * modified_blocks);
|
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:
|
protected:
|
||||||
bool m_create_area;
|
bool m_create_area;
|
||||||
|
|
Loading…
Reference in New Issue