mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-11 17:51:04 +00:00
Node placement / mineral / serialization / iron freq / node_dig callback
- Node placement code moved to Lua - Mineral system removed (added default:stone_with_coal and default:stone_with_iron). - MapBlock and MapNode serialization updated. - Mapgen: Frequency of iron increased. - node_dig callback and related changes.
This commit is contained in:
parent
f22c73f501
commit
157a4cf18c
36 changed files with 1610 additions and 1454 deletions
543
src/mapblock.cpp
543
src/mapblock.cpp
|
@ -507,25 +507,41 @@ s16 MapBlock::getGroundLevel(v2s16 p2d)
|
|||
/*
|
||||
Serialization
|
||||
*/
|
||||
|
||||
// List relevant id-name pairs for ids in the block using nodedef
|
||||
static void getBlockNodeIdMapping(NameIdMapping *nimap, MapBlock *block,
|
||||
// Renumbers the content IDs (starting at 0 and incrementing
|
||||
static void getBlockNodeIdMapping(NameIdMapping *nimap, MapNode *nodes,
|
||||
INodeDefManager *nodedef)
|
||||
{
|
||||
std::map<content_t, content_t> mapping;
|
||||
std::set<content_t> unknown_contents;
|
||||
for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
|
||||
for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
|
||||
for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
|
||||
content_t id_counter = 0;
|
||||
for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
|
||||
{
|
||||
v3s16 p(x0,y0,z0);
|
||||
MapNode n = block->getNode(p);
|
||||
content_t id = n.getContent();
|
||||
const ContentFeatures &f = nodedef->get(id);
|
||||
const std::string &name = f.name;
|
||||
if(name == "")
|
||||
unknown_contents.insert(id);
|
||||
content_t global_id = nodes[i].getContent();
|
||||
content_t id = CONTENT_IGNORE;
|
||||
|
||||
// Try to find an existing mapping
|
||||
std::map<content_t, content_t>::iterator j = mapping.find(global_id);
|
||||
if(j != mapping.end())
|
||||
{
|
||||
id = j->second;
|
||||
}
|
||||
else
|
||||
nimap->set(id, name);
|
||||
{
|
||||
// We have to assign a new mapping
|
||||
id = id_counter++;
|
||||
mapping.insert(std::make_pair(global_id, id));
|
||||
|
||||
const ContentFeatures &f = nodedef->get(global_id);
|
||||
const std::string &name = f.name;
|
||||
if(name == "")
|
||||
unknown_contents.insert(global_id);
|
||||
else
|
||||
nimap->set(id, name);
|
||||
}
|
||||
|
||||
// Update the MapNode
|
||||
nodes[i].setContent(id);
|
||||
}
|
||||
for(std::set<content_t>::const_iterator
|
||||
i = unknown_contents.begin();
|
||||
|
@ -537,7 +553,7 @@ static void getBlockNodeIdMapping(NameIdMapping *nimap, MapBlock *block,
|
|||
// Correct ids in the block to match nodedef based on names.
|
||||
// Unknown ones are added to nodedef.
|
||||
// Will not update itself to match id-name pairs in nodedef.
|
||||
void correctBlockNodeIds(const NameIdMapping *nimap, MapBlock *block,
|
||||
static void correctBlockNodeIds(const NameIdMapping *nimap, MapNode *nodes,
|
||||
IGameDef *gamedef)
|
||||
{
|
||||
INodeDefManager *nodedef = gamedef->ndef();
|
||||
|
@ -547,13 +563,9 @@ void correctBlockNodeIds(const NameIdMapping *nimap, MapBlock *block,
|
|||
// correct ids.
|
||||
std::set<content_t> unnamed_contents;
|
||||
std::set<std::string> unallocatable_contents;
|
||||
for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
|
||||
for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
|
||||
for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
|
||||
for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
|
||||
{
|
||||
v3s16 p(x0,y0,z0);
|
||||
MapNode n = block->getNode(p);
|
||||
content_t local_id = n.getContent();
|
||||
content_t local_id = nodes[i].getContent();
|
||||
std::string name;
|
||||
bool found = nimap->getName(local_id, name);
|
||||
if(!found){
|
||||
|
@ -569,8 +581,7 @@ void correctBlockNodeIds(const NameIdMapping *nimap, MapBlock *block,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
n.setContent(global_id);
|
||||
block->setNode(p, n);
|
||||
nodes[i].setContent(global_id);
|
||||
}
|
||||
for(std::set<content_t>::const_iterator
|
||||
i = unnamed_contents.begin();
|
||||
|
@ -588,7 +599,7 @@ void correctBlockNodeIds(const NameIdMapping *nimap, MapBlock *block,
|
|||
}
|
||||
}
|
||||
|
||||
void MapBlock::serialize(std::ostream &os, u8 version)
|
||||
void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
|
||||
{
|
||||
if(!ser_ver_supported(version))
|
||||
throw VersionMismatchException("ERROR: MapBlock format not supported");
|
||||
|
@ -598,22 +609,226 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
|||
throw SerializationError("ERROR: Not writing dummy block.");
|
||||
}
|
||||
|
||||
if(version <= 21)
|
||||
{
|
||||
serialize_pre22(os, version, disk);
|
||||
return;
|
||||
}
|
||||
|
||||
// First byte
|
||||
u8 flags = 0;
|
||||
if(is_underground)
|
||||
flags |= 0x01;
|
||||
if(m_day_night_differs)
|
||||
flags |= 0x02;
|
||||
if(m_lighting_expired)
|
||||
flags |= 0x04;
|
||||
if(m_generated == false)
|
||||
flags |= 0x08;
|
||||
writeU8(os, flags);
|
||||
|
||||
/*
|
||||
Bulk node data
|
||||
*/
|
||||
NameIdMapping nimap;
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
if(disk)
|
||||
{
|
||||
MapNode *tmp_nodes = new MapNode[nodecount];
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
tmp_nodes[i] = data[i];
|
||||
getBlockNodeIdMapping(&nimap, tmp_nodes, m_gamedef->ndef());
|
||||
|
||||
u8 content_width = 1;
|
||||
/*u8 content_width = (nimap.size() <= 255) ? 1 : 2;*/
|
||||
u8 params_width = 2;
|
||||
writeU8(os, content_width);
|
||||
writeU8(os, params_width);
|
||||
MapNode::serializeBulk(os, version, tmp_nodes, nodecount,
|
||||
content_width, params_width, true);
|
||||
delete[] tmp_nodes;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 content_width = 1;
|
||||
/*u8 content_width = 2;*/
|
||||
u8 params_width = 2;
|
||||
writeU8(os, content_width);
|
||||
writeU8(os, params_width);
|
||||
MapNode::serializeBulk(os, version, data, nodecount,
|
||||
content_width, params_width, true);
|
||||
}
|
||||
|
||||
/*
|
||||
Node metadata
|
||||
*/
|
||||
std::ostringstream oss(std::ios_base::binary);
|
||||
m_node_metadata->serialize(oss);
|
||||
compressZlib(oss.str(), os);
|
||||
|
||||
/*
|
||||
Data that goes to disk, but not the network
|
||||
*/
|
||||
if(disk)
|
||||
{
|
||||
// Static objects
|
||||
m_static_objects.serialize(os);
|
||||
|
||||
// Timestamp
|
||||
writeU32(os, getTimestamp());
|
||||
|
||||
// Write block-specific node definition id mapping
|
||||
nimap.serialize(os);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
|
||||
{
|
||||
if(!ser_ver_supported(version))
|
||||
throw VersionMismatchException("ERROR: MapBlock format not supported");
|
||||
|
||||
if(version <= 21)
|
||||
{
|
||||
deSerialize_pre22(is, version, disk);
|
||||
return;
|
||||
}
|
||||
|
||||
u8 flags = readU8(is);
|
||||
is_underground = (flags & 0x01) ? true : false;
|
||||
m_day_night_differs = (flags & 0x02) ? true : false;
|
||||
m_lighting_expired = (flags & 0x04) ? true : false;
|
||||
m_generated = (flags & 0x08) ? false : true;
|
||||
|
||||
/*
|
||||
Bulk node data
|
||||
*/
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
u8 content_width = readU8(is);
|
||||
u8 params_width = readU8(is);
|
||||
if(content_width != 1)
|
||||
throw SerializationError("MapBlock::deSerialize(): invalid content_width");
|
||||
if(params_width != 2)
|
||||
throw SerializationError("MapBlock::deSerialize(): invalid params_width");
|
||||
MapNode::deSerializeBulk(is, version, data, nodecount,
|
||||
content_width, params_width, true);
|
||||
|
||||
/*
|
||||
NodeMetadata
|
||||
*/
|
||||
// Ignore errors
|
||||
try{
|
||||
std::ostringstream oss(std::ios_base::binary);
|
||||
decompressZlib(is, oss);
|
||||
std::istringstream iss(oss.str(), std::ios_base::binary);
|
||||
m_node_metadata->deSerialize(iss, m_gamedef);
|
||||
}
|
||||
catch(SerializationError &e)
|
||||
{
|
||||
errorstream<<"WARNING: MapBlock::deSerialize(): Ignoring an error"
|
||||
<<" while deserializing node metadata"<<std::endl;
|
||||
}
|
||||
|
||||
/*
|
||||
Data that is only on disk
|
||||
*/
|
||||
if(disk)
|
||||
{
|
||||
// Static objects
|
||||
m_static_objects.deSerialize(is);
|
||||
|
||||
// Timestamp
|
||||
setTimestamp(readU32(is));
|
||||
m_disk_timestamp = m_timestamp;
|
||||
|
||||
// Dynamically re-set ids based on node names
|
||||
NameIdMapping nimap;
|
||||
nimap.deSerialize(is);
|
||||
correctBlockNodeIds(&nimap, data, m_gamedef);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Legacy serialization
|
||||
*/
|
||||
|
||||
// List relevant id-name pairs for ids in the block using nodedef
|
||||
// Before serialization version 22
|
||||
static void getBlockNodeIdMapping_pre22(NameIdMapping *nimap, MapNode *nodes,
|
||||
INodeDefManager *nodedef)
|
||||
{
|
||||
std::set<content_t> unknown_contents;
|
||||
for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
|
||||
{
|
||||
content_t id = nodes[i].getContent();
|
||||
const ContentFeatures &f = nodedef->get(id);
|
||||
const std::string &name = f.name;
|
||||
if(name == "")
|
||||
unknown_contents.insert(id);
|
||||
else
|
||||
nimap->set(id, name);
|
||||
}
|
||||
for(std::set<content_t>::const_iterator
|
||||
i = unknown_contents.begin();
|
||||
i != unknown_contents.end(); i++){
|
||||
errorstream<<"getBlockNodeIdMapping_pre22(): IGNORING ERROR: "
|
||||
<<"Name for node id "<<(*i)<<" not known"<<std::endl;
|
||||
}
|
||||
}
|
||||
void MapBlock::serialize_pre22(std::ostream &os, u8 version, bool disk)
|
||||
{
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
|
||||
MapNode *tmp_data = new MapNode[nodecount];
|
||||
|
||||
// Legacy data changes
|
||||
// This code has to change from post-22 to pre-22 format.
|
||||
INodeDefManager *nodedef = m_gamedef->ndef();
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
{
|
||||
const ContentFeatures &f = nodedef->get(tmp_data[i].getContent());
|
||||
// Mineral
|
||||
if(nodedef->getId("default:stone_with_coal") == tmp_data[i].getContent())
|
||||
{
|
||||
tmp_data[i].setContent(nodedef->getId("default:stone"));
|
||||
tmp_data[i].setParam1(1); // MINERAL_COAL
|
||||
}
|
||||
else if(nodedef->getId("default:stone_with_iron") == tmp_data[i].getContent())
|
||||
{
|
||||
tmp_data[i].setContent(nodedef->getId("default:stone"));
|
||||
tmp_data[i].setParam1(2); // MINERAL_IRON
|
||||
}
|
||||
// facedir_simple
|
||||
if(f.legacy_facedir_simple)
|
||||
{
|
||||
tmp_data[i].setParam1(tmp_data[i].getParam2());
|
||||
tmp_data[i].setParam2(0);
|
||||
}
|
||||
// wall_mounted
|
||||
if(f.legacy_wallmounted)
|
||||
{
|
||||
u8 wallmounted_new_to_old[8] = {0x04, 0x08, 0x01, 0x02, 0x10, 0x20, 0, 0};
|
||||
u8 dir_new_format = tmp_data[i].getParam2() & 7; // lowest 3 bits
|
||||
u8 dir_old_format = wallmounted_new_to_old[dir_new_format];
|
||||
tmp_data[i].setParam2(dir_old_format);
|
||||
}
|
||||
}
|
||||
|
||||
// Serialize nodes
|
||||
u32 ser_length = MapNode::serializedLength(version);
|
||||
SharedBuffer<u8> databuf_nodelist(nodecount * ser_length);
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
{
|
||||
tmp_data[i].serialize(&databuf_nodelist[i*ser_length], version);
|
||||
}
|
||||
|
||||
delete[] tmp_data;
|
||||
|
||||
// These have no compression
|
||||
if(version <= 3 || version == 5 || version == 6)
|
||||
{
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
|
||||
u32 buflen = 1 + nodecount * MapNode::serializedLength(version);
|
||||
SharedBuffer<u8> dest(buflen);
|
||||
|
||||
dest[0] = is_underground;
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
{
|
||||
u32 s = 1 + i * MapNode::serializedLength(version);
|
||||
data[i].serialize(&dest[s], version);
|
||||
}
|
||||
|
||||
os.write((char*)*dest, dest.getSize());
|
||||
writeU8(os, is_underground);
|
||||
os.write((char*)*databuf_nodelist, databuf_nodelist.getSize());
|
||||
}
|
||||
else if(version <= 10)
|
||||
{
|
||||
|
@ -623,15 +838,13 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
|||
*/
|
||||
|
||||
// First byte
|
||||
os.write((char*)&is_underground, 1);
|
||||
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
writeU8(os, is_underground);
|
||||
|
||||
// Get and compress materials
|
||||
SharedBuffer<u8> materialdata(nodecount);
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
{
|
||||
materialdata[i] = data[i].param0;
|
||||
materialdata[i] = databuf_nodelist[i*ser_length];
|
||||
}
|
||||
compress(materialdata, os, version);
|
||||
|
||||
|
@ -639,7 +852,7 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
|||
SharedBuffer<u8> lightdata(nodecount);
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
{
|
||||
lightdata[i] = data[i].param1;
|
||||
lightdata[i] = databuf_nodelist[i*ser_length+1];
|
||||
}
|
||||
compress(lightdata, os, version);
|
||||
|
||||
|
@ -649,7 +862,7 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
|||
SharedBuffer<u8> param2data(nodecount);
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
{
|
||||
param2data[i] = data[i].param2;
|
||||
param2data[i] = databuf_nodelist[i*ser_length+2];
|
||||
}
|
||||
compress(param2data, os, version);
|
||||
}
|
||||
|
@ -670,28 +883,19 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
|||
if(m_generated == false)
|
||||
flags |= 0x08;
|
||||
}
|
||||
os.write((char*)&flags, 1);
|
||||
writeU8(os, flags);
|
||||
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
|
||||
/*
|
||||
Get data
|
||||
*/
|
||||
|
||||
// Serialize nodes
|
||||
SharedBuffer<u8> databuf_nodelist(nodecount*3);
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
{
|
||||
data[i].serialize(&databuf_nodelist[i*3], version);
|
||||
}
|
||||
|
||||
// Create buffer with different parameters sorted
|
||||
SharedBuffer<u8> databuf(nodecount*3);
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
{
|
||||
databuf[i] = databuf_nodelist[i*3];
|
||||
databuf[i+nodecount] = databuf_nodelist[i*3+1];
|
||||
databuf[i+nodecount*2] = databuf_nodelist[i*3+2];
|
||||
databuf[i] = databuf_nodelist[i*ser_length];
|
||||
databuf[i+nodecount] = databuf_nodelist[i*ser_length+1];
|
||||
databuf[i+nodecount*2] = databuf_nodelist[i*ser_length+2];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -728,50 +932,69 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(disk)
|
||||
{
|
||||
// Versions up from 9 have block objects. (DEPRECATED)
|
||||
if(version >= 9)
|
||||
{
|
||||
// count=0
|
||||
writeU16(os, 0);
|
||||
}
|
||||
|
||||
// Versions up from 15 have static objects.
|
||||
if(version >= 15)
|
||||
{
|
||||
m_static_objects.serialize(os);
|
||||
}
|
||||
|
||||
// Timestamp
|
||||
if(version >= 17)
|
||||
{
|
||||
writeU32(os, getTimestamp());
|
||||
}
|
||||
|
||||
// Scan and write node definition id mapping
|
||||
if(version >= 21)
|
||||
{
|
||||
NameIdMapping nimap;
|
||||
getBlockNodeIdMapping_pre22(&nimap, data, m_gamedef->ndef());
|
||||
nimap.serialize(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MapBlock::deSerialize(std::istream &is, u8 version)
|
||||
void MapBlock::deSerialize_pre22(std::istream &is, u8 version, bool disk)
|
||||
{
|
||||
if(!ser_ver_supported(version))
|
||||
throw VersionMismatchException("ERROR: MapBlock format not supported");
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
|
||||
// These have no lighting info
|
||||
if(version <= 1)
|
||||
{
|
||||
setLightingExpired(true);
|
||||
}
|
||||
// Initialize default flags
|
||||
is_underground = false;
|
||||
m_day_night_differs = false;
|
||||
m_lighting_expired = false;
|
||||
m_generated = true;
|
||||
|
||||
// These have no "generated" field
|
||||
if(version < 18)
|
||||
{
|
||||
m_generated = true;
|
||||
}
|
||||
// Make a temporary buffer
|
||||
u32 ser_length = MapNode::serializedLength(version);
|
||||
SharedBuffer<u8> databuf_nodelist(nodecount * ser_length);
|
||||
|
||||
// These have no compression
|
||||
if(version <= 3 || version == 5 || version == 6)
|
||||
{
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
char tmp;
|
||||
is.read(&tmp, 1);
|
||||
if(is.gcount() != 1)
|
||||
throw SerializationError
|
||||
("MapBlock::deSerialize: no enough input data");
|
||||
is_underground = tmp;
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
{
|
||||
s32 len = MapNode::serializedLength(version);
|
||||
SharedBuffer<u8> d(len);
|
||||
is.read((char*)*d, len);
|
||||
if(is.gcount() != len)
|
||||
throw SerializationError
|
||||
("MapBlock::deSerialize: no enough input data");
|
||||
data[i].deSerialize(*d, version);
|
||||
}
|
||||
is.read((char*)*databuf_nodelist, nodecount * ser_length);
|
||||
if(is.gcount() != nodecount * ser_length)
|
||||
throw SerializationError
|
||||
("MapBlock::deSerialize: no enough input data");
|
||||
}
|
||||
else if(version <= 10)
|
||||
{
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
|
||||
u8 t8;
|
||||
is.read((char*)&t8, 1);
|
||||
is_underground = t8;
|
||||
|
@ -786,7 +1009,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
|
|||
("MapBlock::deSerialize: invalid format");
|
||||
for(u32 i=0; i<s.size(); i++)
|
||||
{
|
||||
data[i].param0 = s[i];
|
||||
databuf_nodelist[i*ser_length] = s[i];
|
||||
}
|
||||
}
|
||||
{
|
||||
|
@ -799,7 +1022,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
|
|||
("MapBlock::deSerialize: invalid format");
|
||||
for(u32 i=0; i<s.size(); i++)
|
||||
{
|
||||
data[i].param1 = s[i];
|
||||
databuf_nodelist[i*ser_length + 1] = s[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -814,15 +1037,13 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
|
|||
("MapBlock::deSerialize: invalid format");
|
||||
for(u32 i=0; i<s.size(); i++)
|
||||
{
|
||||
data[i].param2 = s[i];
|
||||
databuf_nodelist[i*ser_length + 2] = s[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// All other versions (newest)
|
||||
else
|
||||
{
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
|
||||
u8 flags;
|
||||
is.read((char*)&flags, 1);
|
||||
is_underground = (flags & 0x01) ? true : false;
|
||||
|
@ -843,11 +1064,9 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
|
|||
// deserialize nodes from buffer
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
{
|
||||
u8 buf[3];
|
||||
buf[0] = s[i];
|
||||
buf[1] = s[i+nodecount];
|
||||
buf[2] = s[i+nodecount*2];
|
||||
data[i].deSerialize(buf, version);
|
||||
databuf_nodelist[i*ser_length] = s[i];
|
||||
databuf_nodelist[i*ser_length + 1] = s[i+nodecount];
|
||||
databuf_nodelist[i*ser_length + 2] = s[i+nodecount*2];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -879,76 +1098,102 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MapBlock::serializeDiskExtra(std::ostream &os, u8 version)
|
||||
{
|
||||
// Versions up from 9 have block objects. (DEPRECATED)
|
||||
if(version >= 9)
|
||||
// Deserialize node data
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
{
|
||||
// count=0
|
||||
writeU16(os, 0);
|
||||
}
|
||||
|
||||
// Versions up from 15 have static objects.
|
||||
if(version >= 15)
|
||||
{
|
||||
m_static_objects.serialize(os);
|
||||
data[i].deSerialize(&databuf_nodelist[i*ser_length], version);
|
||||
}
|
||||
|
||||
// Timestamp
|
||||
if(version >= 17)
|
||||
if(disk)
|
||||
{
|
||||
writeU32(os, getTimestamp());
|
||||
}
|
||||
/*
|
||||
Versions up from 9 have block objects. (DEPRECATED)
|
||||
*/
|
||||
if(version >= 9){
|
||||
u16 count = readU16(is);
|
||||
// Not supported and length not known if count is not 0
|
||||
if(count != 0){
|
||||
errorstream<<"WARNING: MapBlock::deSerialize_pre22(): "
|
||||
<<"Ignoring stuff coming at and after MBOs"<<std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Scan and write node definition id mapping
|
||||
if(version >= 21){
|
||||
/*
|
||||
Versions up from 15 have static objects.
|
||||
*/
|
||||
if(version >= 15)
|
||||
m_static_objects.deSerialize(is);
|
||||
|
||||
// Timestamp
|
||||
if(version >= 17){
|
||||
setTimestamp(readU32(is));
|
||||
m_disk_timestamp = m_timestamp;
|
||||
} else {
|
||||
setTimestamp(BLOCK_TIMESTAMP_UNDEFINED);
|
||||
}
|
||||
|
||||
// Dynamically re-set ids based on node names
|
||||
NameIdMapping nimap;
|
||||
getBlockNodeIdMapping(&nimap, this, m_gamedef->ndef());
|
||||
nimap.serialize(os);
|
||||
// If supported, read node definition id mapping
|
||||
if(version >= 21){
|
||||
nimap.deSerialize(is);
|
||||
// Else set the legacy mapping
|
||||
} else {
|
||||
content_mapnode_get_name_id_mapping(&nimap);
|
||||
}
|
||||
correctBlockNodeIds(&nimap, data, m_gamedef);
|
||||
}
|
||||
}
|
||||
|
||||
void MapBlock::deSerializeDiskExtra(std::istream &is, u8 version)
|
||||
{
|
||||
/*
|
||||
Versions up from 9 have block objects. (DEPRECATED)
|
||||
*/
|
||||
if(version >= 9){
|
||||
u16 count = readU16(is);
|
||||
// Not supported and length not known if count is not 0
|
||||
if(count != 0){
|
||||
errorstream<<"WARNING: MapBlock::deSerializeDiskExtra(): "
|
||||
<<"Ignoring stuff coming at and after MBOs"<<std::endl;
|
||||
return;
|
||||
|
||||
// Legacy data changes
|
||||
// This code has to convert from pre-22 to post-22 format.
|
||||
INodeDefManager *nodedef = m_gamedef->ndef();
|
||||
for(u32 i=0; i<nodecount; i++)
|
||||
{
|
||||
const ContentFeatures &f = nodedef->get(data[i].getContent());
|
||||
// Mineral
|
||||
if(nodedef->getId("default:stone") == data[i].getContent()
|
||||
&& data[i].getParam1() == 1)
|
||||
{
|
||||
//dstream << "legacy coal\n";
|
||||
data[i].setContent(nodedef->getId("default:stone_with_coal"));
|
||||
data[i].setParam1(0);
|
||||
}
|
||||
else if(nodedef->getId("default:stone") == data[i].getContent()
|
||||
&& data[i].getParam1() == 2)
|
||||
{
|
||||
//dstream << "legacy iron\n";
|
||||
data[i].setContent(nodedef->getId("default:stone_with_iron"));
|
||||
data[i].setParam1(0);
|
||||
}
|
||||
// facedir_simple
|
||||
if(f.legacy_facedir_simple)
|
||||
{
|
||||
dstream << "legacy_facedir_simple\n";
|
||||
data[i].setParam2(data[i].getParam1());
|
||||
data[i].setParam1(0);
|
||||
}
|
||||
// wall_mounted
|
||||
if(f.legacy_wallmounted)
|
||||
{
|
||||
dstream << "legacy_wallmounted\n";
|
||||
u8 wallmounted_new_to_old[8] = {0x04, 0x08, 0x01, 0x02, 0x10, 0x20, 0, 0};
|
||||
u8 dir_old_format = data[i].getParam2();
|
||||
u8 dir_new_format = 0;
|
||||
for(u8 j=0; j<8; j++)
|
||||
{
|
||||
if((dir_old_format & wallmounted_new_to_old[j]) != 0)
|
||||
{
|
||||
dir_new_format = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
data[i].setParam2(dir_new_format);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Versions up from 15 have static objects.
|
||||
*/
|
||||
if(version >= 15)
|
||||
m_static_objects.deSerialize(is);
|
||||
|
||||
// Timestamp
|
||||
if(version >= 17){
|
||||
setTimestamp(readU32(is));
|
||||
m_disk_timestamp = m_timestamp;
|
||||
} else {
|
||||
setTimestamp(BLOCK_TIMESTAMP_UNDEFINED);
|
||||
}
|
||||
|
||||
// Dynamically re-set ids based on node names
|
||||
NameIdMapping nimap;
|
||||
// If supported, read node definition id mapping
|
||||
if(version >= 21){
|
||||
nimap.deSerialize(is);
|
||||
// Else set the legacy mapping
|
||||
} else {
|
||||
content_mapnode_get_name_id_mapping(&nimap);
|
||||
}
|
||||
correctBlockNodeIds(&nimap, this, m_gamedef);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue