From c0f6395cf09f658eb95365c60f67b8a89104cb23 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Wed, 16 Nov 2011 13:03:28 +0200 Subject: Node definition names --- src/mapblock.cpp | 129 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 110 insertions(+), 19 deletions(-) (limited to 'src/mapblock.cpp') diff --git a/src/mapblock.cpp b/src/mapblock.cpp index f7cbda74b..06ce9282f 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -18,14 +18,18 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "mapblock.h" + +#include #include "map.h" // For g_settings #include "main.h" #include "light.h" -#include #include "nodedef.h" #include "nodemetadata.h" #include "gamedef.h" +#include "log.h" +#include "nameidmapping.h" +#include "content_mapnode.h" // For legacy name-id mapping /* MapBlock @@ -188,13 +192,13 @@ void MapBlock::replaceMesh(scene::SMesh *mesh_new) IMeshBuffer *buf = mesh_old->getMeshBuffer(i); }*/ - /*dstream<<"mesh_old->getReferenceCount()=" + /*infostream<<"mesh_old->getReferenceCount()=" <getReferenceCount()<getMeshBufferCount(); for(u32 i=0; igetMeshBuffer(i); - dstream<<"buf->getReferenceCount()=" + infostream<<"buf->getReferenceCount()=" <getReferenceCount()< unknown_contents; + for(s16 z0=0; z0getNode(p); + content_t id = n.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::const_iterator + i = unknown_contents.begin(); + i != unknown_contents.end(); i++){ + errorstream<<"getBlockNodeIdMapping(): IGNORING ERROR: " + <<"Name for node id "<<(*i)<<" not known"<ndef(); + // This means the block contains incorrect ids, and we contain + // the information to convert those to names. + // nodedef contains information to convert our names to globally + // correct ids. + std::set unnamed_contents; + std::set unallocatable_contents; + for(s16 z0=0; z0getNode(p); + content_t local_id = n.getContent(); + std::string name; + bool found = nimap->getName(local_id, name); + if(!found){ + unnamed_contents.insert(local_id); + continue; + } + content_t global_id; + found = nodedef->getId(name, global_id); + if(!found){ + global_id = gamedef->allocateUnknownNodeId(name); + if(global_id == CONTENT_IGNORE){ + unallocatable_contents.insert(name); + continue; + } + } + n.setContent(global_id); + block->setNode(p, n); + } + for(std::set::const_iterator + i = unnamed_contents.begin(); + i != unnamed_contents.end(); i++){ + errorstream<<"correctBlockNodeIds(): IGNORING ERROR: " + <<"Block contains id "<<(*i) + <<" with no name mapping"<::const_iterator + i = unallocatable_contents.begin(); + i != unallocatable_contents.end(); i++){ + errorstream<<"correctBlockNodeIds(): IGNORING ERROR: " + <<"Could not allocate global id for node name \"" + <<(*i)<<"\""<ndef(); - if(!ser_ver_supported(version)) throw VersionMismatchException("ERROR: MapBlock format not supported"); @@ -698,7 +780,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version) if(is.gcount() != len) throw SerializationError ("MapBlock::deSerialize: no enough input data"); - data[i].deSerialize(*d, version, nodemgr); + data[i].deSerialize(*d, version); } } else if(version <= 10) @@ -780,7 +862,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version) buf[0] = s[i]; buf[1] = s[i+nodecount]; buf[2] = s[i+nodecount*2]; - data[i].deSerialize(buf, version, m_gamedef->getNodeDefManager()); + data[i].deSerialize(buf, version); } /* @@ -807,7 +889,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version) } catch(SerializationError &e) { - dstream<<"WARNING: MapBlock::deSerialize(): Ignoring an error" + errorstream<<"WARNING: MapBlock::deSerialize(): Ignoring an error" <<" while deserializing node metadata"<= 21){ + NameIdMapping nimap; + getBlockNodeIdMapping(&nimap, this, m_gamedef->ndef()); + nimap.serialize(os); + } } void MapBlock::deSerializeDiskExtra(std::istream &is, u8 version) @@ -841,12 +930,11 @@ void MapBlock::deSerializeDiskExtra(std::istream &is, u8 version) /* Versions up from 9 have block objects. (DEPRECATED) */ - if(version >= 9) - { + if(version >= 9){ u16 count = readU16(is); // Not supported and length not known if count is not 0 if(count != 0){ - dstream<<"WARNING: MapBlock::deSerializeDiskExtra(): " + errorstream<<"WARNING: MapBlock::deSerializeDiskExtra(): " <<"Ignoring stuff coming at and after MBOs"<= 15) - { m_static_objects.deSerialize(is); - } // Timestamp if(version >= 17) - { setTimestamp(readU32(is)); - } 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); } /* @@ -877,9 +970,7 @@ void MapBlock::deSerializeDiskExtra(std::istream &is, u8 version) std::string analyze_block(MapBlock *block) { if(block == NULL) - { return "NULL"; - } std::ostringstream desc; -- cgit v1.2.3