Node definition names
parent
50d63e4b0a
commit
c0f6395cf0
|
@ -94,6 +94,7 @@ configure_file(
|
|||
)
|
||||
|
||||
set(common_SRCS
|
||||
nameidmapping.cpp
|
||||
tooldef.cpp
|
||||
nodedef.cpp
|
||||
luaentity_common.cpp
|
||||
|
|
|
@ -848,7 +848,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||
//TimeTaker t1("TOCLIENT_ADDNODE");
|
||||
|
||||
MapNode n;
|
||||
n.deSerialize(&data[8], ser_version, m_nodedef);
|
||||
n.deSerialize(&data[8], ser_version);
|
||||
|
||||
addNode(p, n);
|
||||
}
|
||||
|
@ -2331,4 +2331,11 @@ ITextureSource* Client::getTextureSource()
|
|||
{
|
||||
return m_tsrc;
|
||||
}
|
||||
u16 Client::allocateUnknownNodeId(const std::string &name)
|
||||
{
|
||||
errorstream<<"Client::allocateUnknownNodeId(): "
|
||||
<<"Client cannot allocate node IDs"<<std::endl;
|
||||
assert(0);
|
||||
return CONTENT_IGNORE;
|
||||
}
|
||||
|
||||
|
|
|
@ -324,10 +324,10 @@ public:
|
|||
float getRTT(void);
|
||||
|
||||
// IGameDef interface
|
||||
// Under envlock
|
||||
virtual IToolDefManager* getToolDefManager();
|
||||
virtual INodeDefManager* getNodeDefManager();
|
||||
virtual ITextureSource* getTextureSource();
|
||||
virtual u16 allocateUnknownNodeId(const std::string &name);
|
||||
|
||||
private:
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,6 +42,10 @@ extern content_t trans_table_19[21][2];
|
|||
MapNode mapnode_translate_from_internal(MapNode n_from, u8 version);
|
||||
MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
|
||||
|
||||
// Get legacy node name mapping
|
||||
class NameIdMapping;
|
||||
void content_mapnode_get_name_id_mapping(NameIdMapping *nimap);
|
||||
|
||||
/*
|
||||
Node content type IDs
|
||||
Ranges:
|
||||
|
|
|
@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef GAMEDEF_HEADER
|
||||
#define GAMEDEF_HEADER
|
||||
|
||||
#include <string>
|
||||
|
||||
class IToolDefManager;
|
||||
class INodeDefManager;
|
||||
//class IItemDefManager; //TODO
|
||||
|
@ -44,6 +46,9 @@ public:
|
|||
// pointers in other threads than main thread will make things explode.
|
||||
virtual ITextureSource* getTextureSource()=0;
|
||||
|
||||
// Used for keeping track of names/ids of unknown nodes
|
||||
virtual u16 allocateUnknownNodeId(const std::string &name)=0;
|
||||
|
||||
// Shorthands
|
||||
IToolDefManager* tdef(){return getToolDefManager();}
|
||||
INodeDefManager* ndef(){return getNodeDefManager();}
|
||||
|
|
|
@ -3367,10 +3367,10 @@ void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool
|
|||
Save blocks loaded in old format in new format
|
||||
*/
|
||||
|
||||
if(version < SER_FMT_VER_HIGHEST || save_after_load)
|
||||
{
|
||||
//if(version < SER_FMT_VER_HIGHEST || save_after_load)
|
||||
// Only save if asked to; no need to update version
|
||||
if(save_after_load)
|
||||
saveBlock(block);
|
||||
}
|
||||
|
||||
// We just loaded it from, so it's up-to-date.
|
||||
block->resetModified();
|
||||
|
|
127
src/mapblock.cpp
127
src/mapblock.cpp
|
@ -18,14 +18,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "mapblock.h"
|
||||
|
||||
#include <sstream>
|
||||
#include "map.h"
|
||||
// For g_settings
|
||||
#include "main.h"
|
||||
#include "light.h"
|
||||
#include <sstream>
|
||||
#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()="
|
||||
<<mesh_old->getReferenceCount()<<std::endl;
|
||||
u32 c = mesh_old->getMeshBufferCount();
|
||||
for(u32 i=0; i<c; i++)
|
||||
{
|
||||
scene::IMeshBuffer *buf = mesh_old->getMeshBuffer(i);
|
||||
dstream<<"buf->getReferenceCount()="
|
||||
infostream<<"buf->getReferenceCount()="
|
||||
<<buf->getReferenceCount()<<std::endl;
|
||||
}*/
|
||||
|
||||
|
@ -519,6 +523,86 @@ 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,
|
||||
INodeDefManager *nodedef)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
else
|
||||
nimap->set(id, name);
|
||||
}
|
||||
for(std::set<content_t>::const_iterator
|
||||
i = unknown_contents.begin();
|
||||
i != unknown_contents.end(); i++){
|
||||
errorstream<<"getBlockNodeIdMapping(): IGNORING ERROR: "
|
||||
<<"Name for node id "<<(*i)<<" not known"<<std::endl;
|
||||
}
|
||||
}
|
||||
// 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,
|
||||
IGameDef *gamedef)
|
||||
{
|
||||
INodeDefManager *nodedef = gamedef->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<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++)
|
||||
{
|
||||
v3s16 p(x0,y0,z0);
|
||||
MapNode n = block->getNode(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<content_t>::const_iterator
|
||||
i = unnamed_contents.begin();
|
||||
i != unnamed_contents.end(); i++){
|
||||
errorstream<<"correctBlockNodeIds(): IGNORING ERROR: "
|
||||
<<"Block contains id "<<(*i)
|
||||
<<" with no name mapping"<<std::endl;
|
||||
}
|
||||
for(std::set<std::string>::const_iterator
|
||||
i = unallocatable_contents.begin();
|
||||
i != unallocatable_contents.end(); i++){
|
||||
errorstream<<"correctBlockNodeIds(): IGNORING ERROR: "
|
||||
<<"Could not allocate global id for node name \""
|
||||
<<(*i)<<"\""<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void MapBlock::serialize(std::ostream &os, u8 version)
|
||||
{
|
||||
if(!ser_ver_supported(version))
|
||||
|
@ -663,8 +747,6 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
|||
|
||||
void MapBlock::deSerialize(std::istream &is, u8 version)
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->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"<<std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -834,6 +916,13 @@ void MapBlock::serializeDiskExtra(std::ostream &os, u8 version)
|
|||
{
|
||||
writeU32(os, getTimestamp());
|
||||
}
|
||||
|
||||
// Scan and write node definition id mapping
|
||||
if(version >= 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"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
@ -856,19 +944,24 @@ void MapBlock::deSerializeDiskExtra(std::istream &is, u8 version)
|
|||
Versions up from 15 have static objects.
|
||||
*/
|
||||
if(version >= 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;
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
class Map;
|
||||
class NodeMetadataList;
|
||||
class IGameDef;
|
||||
class IWritableNodeDefManager;
|
||||
|
||||
#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
|
||||
|
||||
|
@ -540,8 +541,11 @@ public:
|
|||
// These don't write or read version by itself
|
||||
void serialize(std::ostream &os, u8 version);
|
||||
void deSerialize(std::istream &is, u8 version);
|
||||
|
||||
// Used after the basic ones when writing on disk (serverside)
|
||||
void serializeDiskExtra(std::ostream &os, u8 version);
|
||||
// In addition to doing other things, will add unknown blocks from
|
||||
// id-name mapping to wndef
|
||||
void deSerializeDiskExtra(std::istream &is, u8 version);
|
||||
|
||||
private:
|
||||
|
|
|
@ -268,7 +268,7 @@ void MapNode::serialize(u8 *dest, u8 version)
|
|||
dest[2] = n_foreign.param2;
|
||||
}
|
||||
}
|
||||
void MapNode::deSerialize(u8 *source, u8 version, INodeDefManager *nodemgr)
|
||||
void MapNode::deSerialize(u8 *source, u8 version)
|
||||
{
|
||||
if(!ser_ver_supported(version))
|
||||
throw VersionMismatchException("ERROR: MapNode format not supported");
|
||||
|
@ -280,11 +280,6 @@ void MapNode::deSerialize(u8 *source, u8 version, INodeDefManager *nodemgr)
|
|||
else if(version == 1)
|
||||
{
|
||||
param0 = source[0];
|
||||
// This version doesn't support saved lighting
|
||||
if(nodemgr->get(*this).light_propagates || nodemgr->get(*this).light_source > 0)
|
||||
param1 = 0;
|
||||
else
|
||||
param1 = source[1];
|
||||
}
|
||||
else if(version <= 9)
|
||||
{
|
||||
|
|
|
@ -221,7 +221,7 @@ struct MapNode
|
|||
|
||||
static u32 serializedLength(u8 version);
|
||||
void serialize(u8 *dest, u8 version);
|
||||
void deSerialize(u8 *source, u8 version, INodeDefManager *nodemgr);
|
||||
void deSerialize(u8 *source, u8 version);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "nameidmapping.h"
|
||||
#include "utility.h"
|
||||
|
||||
void NameIdMapping::serialize(std::ostream &os) const
|
||||
{
|
||||
writeU8(os, 0); // version
|
||||
writeU16(os, m_id_to_name.size());
|
||||
for(std::map<u16, std::string>::const_iterator
|
||||
i = m_id_to_name.begin();
|
||||
i != m_id_to_name.end(); i++){
|
||||
writeU16(os, i->first);
|
||||
os<<serializeString(i->second);
|
||||
}
|
||||
}
|
||||
|
||||
void NameIdMapping::deSerialize(std::istream &is)
|
||||
{
|
||||
int version = readU8(is);
|
||||
if(version != 0)
|
||||
throw SerializationError("unsupported NameIdMapping version");
|
||||
u32 count = readU16(is);
|
||||
m_id_to_name.clear();
|
||||
m_name_to_id.clear();
|
||||
for(u32 i=0; i<count; i++){
|
||||
u16 id = readU16(is);
|
||||
std::string name = deSerializeString(is);
|
||||
m_id_to_name[id] = name;
|
||||
m_name_to_id[name] = id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef NAMEIDMAPPING_HEADER
|
||||
#define NAMEIDMAPPING_HEADER
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include "irrlichttypes.h"
|
||||
|
||||
class NameIdMapping
|
||||
{
|
||||
public:
|
||||
void serialize(std::ostream &os) const;
|
||||
void deSerialize(std::istream &is);
|
||||
|
||||
void clear(){
|
||||
m_id_to_name.clear();
|
||||
m_name_to_id.clear();
|
||||
}
|
||||
void set(u16 id, const std::string &name){
|
||||
m_id_to_name[id] = name;
|
||||
m_name_to_id[name] = id;
|
||||
}
|
||||
void removeId(u16 id){
|
||||
std::string name;
|
||||
bool found = getName(id, name);
|
||||
if(!found) return;
|
||||
m_id_to_name.erase(id);
|
||||
m_name_to_id.erase(name);
|
||||
}
|
||||
void eraseName(const std::string &name){
|
||||
u16 id;
|
||||
bool found = getId(name, id);
|
||||
if(!found) return;
|
||||
m_id_to_name.erase(id);
|
||||
m_name_to_id.erase(name);
|
||||
}
|
||||
bool getName(u16 id, std::string &result) const{
|
||||
std::map<u16, std::string>::const_iterator i;
|
||||
i = m_id_to_name.find(id);
|
||||
if(i == m_id_to_name.end())
|
||||
return false;
|
||||
result = i->second;
|
||||
return true;
|
||||
}
|
||||
bool getId(const std::string &name, u16 &result) const{
|
||||
std::map<std::string, u16>::const_iterator i;
|
||||
i = m_name_to_id.find(name);
|
||||
if(i == m_name_to_id.end())
|
||||
return false;
|
||||
result = i->second;
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
std::map<u16, std::string> m_id_to_name;
|
||||
std::map<std::string, u16> m_name_to_id;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
113
src/nodedef.cpp
113
src/nodedef.cpp
|
@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#endif
|
||||
#include "log.h"
|
||||
#include "settings.h"
|
||||
#include "nameidmapping.h"
|
||||
|
||||
/*
|
||||
NodeBox
|
||||
|
@ -318,20 +319,63 @@ class CNodeDefManager: public IWritableNodeDefManager
|
|||
public:
|
||||
void clear()
|
||||
{
|
||||
m_name_id_mapping.clear();
|
||||
for(u16 i=0; i<=MAX_CONTENT; i++)
|
||||
{
|
||||
ContentFeatures *f = &m_content_features[i];
|
||||
f->reset(); // Reset to defaults
|
||||
if(i == CONTENT_IGNORE || i == CONTENT_AIR){
|
||||
f->drawtype = NDT_AIRLIKE;
|
||||
continue;
|
||||
ContentFeatures &f = m_content_features[i];
|
||||
f.reset(); // Reset to defaults
|
||||
f.setAllTextures("unknown_block.png");
|
||||
}
|
||||
f->setAllTextures("unknown_block.png");
|
||||
|
||||
// Set CONTENT_AIR
|
||||
{
|
||||
ContentFeatures f;
|
||||
f.name = "air";
|
||||
f.drawtype = NDT_AIRLIKE;
|
||||
f.param_type = CPT_LIGHT;
|
||||
f.light_propagates = true;
|
||||
f.sunlight_propagates = true;
|
||||
f.walkable = false;
|
||||
f.pointable = false;
|
||||
f.diggable = false;
|
||||
f.buildable_to = true;
|
||||
f.air_equivalent = true;
|
||||
set(CONTENT_AIR, f);
|
||||
}
|
||||
#ifndef SERVER
|
||||
// Make CONTENT_IGNORE to not block the view when occlusion culling
|
||||
m_content_features[CONTENT_IGNORE].solidness = 0;
|
||||
#endif
|
||||
// Set CONTENT_IGNORE
|
||||
{
|
||||
ContentFeatures f;
|
||||
f.name = "ignore";
|
||||
f.drawtype = NDT_AIRLIKE;
|
||||
f.param_type = CPT_LIGHT;
|
||||
f.light_propagates = true;
|
||||
f.sunlight_propagates = true;
|
||||
f.walkable = false;
|
||||
f.pointable = false;
|
||||
f.diggable = false;
|
||||
f.buildable_to = true;
|
||||
f.air_equivalent = true;
|
||||
set(CONTENT_AIR, f);
|
||||
}
|
||||
}
|
||||
// CONTENT_IGNORE = not found
|
||||
content_t getFreeId(bool require_full_param2)
|
||||
{
|
||||
// If allowed, first search in the large 4-byte-param2 pool
|
||||
if(!require_full_param2){
|
||||
for(u16 i=0x800; i<=0xfff; i++){
|
||||
const ContentFeatures &f = m_content_features[i];
|
||||
if(f.name == "")
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// Then search from the small 8-byte-param2 pool
|
||||
for(u16 i=0; i<=125; i++){
|
||||
const ContentFeatures &f = m_content_features[i];
|
||||
if(f.name == "")
|
||||
return i;
|
||||
}
|
||||
return CONTENT_IGNORE;
|
||||
}
|
||||
CNodeDefManager()
|
||||
{
|
||||
|
@ -358,18 +402,54 @@ public:
|
|||
{
|
||||
return get(n.getContent());
|
||||
}
|
||||
// Writable
|
||||
virtual bool getId(const std::string &name, content_t &result) const
|
||||
{
|
||||
return m_name_id_mapping.getId(name, result);
|
||||
}
|
||||
// IWritableNodeDefManager
|
||||
virtual void set(content_t c, const ContentFeatures &def)
|
||||
{
|
||||
infostream<<"registerNode: registering content id \""<<c
|
||||
<<"\": name=\""<<def.name<<"\""<<std::endl;
|
||||
assert(c <= MAX_CONTENT);
|
||||
m_content_features[c] = def;
|
||||
if(def.name != "")
|
||||
m_name_id_mapping.set(c, def.name);
|
||||
}
|
||||
virtual ContentFeatures* getModifiable(content_t c)
|
||||
virtual content_t set(const std::string &name,
|
||||
const ContentFeatures &def)
|
||||
{
|
||||
assert(c <= MAX_CONTENT);
|
||||
return &m_content_features[c];
|
||||
assert(name == def.name);
|
||||
u16 id = CONTENT_IGNORE;
|
||||
bool found = m_name_id_mapping.getId(name, id);
|
||||
if(!found){
|
||||
// Determine if full param2 is required
|
||||
bool require_full_param2 = (
|
||||
def.liquid_type == LIQUID_FLOWING
|
||||
||
|
||||
def.drawtype == NDT_FLOWINGLIQUID
|
||||
||
|
||||
def.drawtype == NDT_TORCHLIKE
|
||||
||
|
||||
def.drawtype == NDT_SIGNLIKE
|
||||
);
|
||||
// Get some id
|
||||
id = getFreeId(require_full_param2);
|
||||
if(id == CONTENT_IGNORE)
|
||||
return CONTENT_IGNORE;
|
||||
if(name != "")
|
||||
m_name_id_mapping.set(id, name);
|
||||
}
|
||||
set(id, def);
|
||||
return id;
|
||||
}
|
||||
virtual content_t allocateDummy(const std::string &name)
|
||||
{
|
||||
assert(name != "");
|
||||
ContentFeatures f;
|
||||
f.name = name;
|
||||
f.setAllTextures("unknown_block.png");
|
||||
return set(name, f);
|
||||
}
|
||||
virtual void updateTextures(ITextureSource *tsrc)
|
||||
{
|
||||
|
@ -499,6 +579,8 @@ public:
|
|||
std::ostringstream tmp_os(std::ios::binary);
|
||||
for(u16 i=0; i<=MAX_CONTENT; i++)
|
||||
{
|
||||
if(i == CONTENT_IGNORE || i == CONTENT_AIR)
|
||||
continue;
|
||||
ContentFeatures *f = &m_content_features[i];
|
||||
if(f->name == "")
|
||||
continue;
|
||||
|
@ -523,10 +605,13 @@ public:
|
|||
}
|
||||
ContentFeatures *f = &m_content_features[i];
|
||||
f->deSerialize(tmp_is, gamedef);
|
||||
if(f->name != "")
|
||||
m_name_id_mapping.set(i, f->name);
|
||||
}
|
||||
}
|
||||
private:
|
||||
ContentFeatures m_content_features[MAX_CONTENT+1];
|
||||
NameIdMapping m_name_id_mapping;
|
||||
};
|
||||
|
||||
IWritableNodeDefManager* createNodeDefManager()
|
||||
|
|
|
@ -253,6 +253,7 @@ public:
|
|||
// Get node definition
|
||||
virtual const ContentFeatures& get(content_t c) const=0;
|
||||
virtual const ContentFeatures& get(const MapNode &n) const=0;
|
||||
virtual bool getId(const std::string &name, content_t &result) const=0;
|
||||
|
||||
virtual void serialize(std::ostream &os)=0;
|
||||
};
|
||||
|
@ -266,10 +267,16 @@ public:
|
|||
// Get node definition
|
||||
virtual const ContentFeatures& get(content_t c) const=0;
|
||||
virtual const ContentFeatures& get(const MapNode &n) const=0;
|
||||
virtual bool getId(const std::string &name, content_t &result) const=0;
|
||||
|
||||
// Register node definition
|
||||
virtual void set(content_t c, const ContentFeatures &def)=0;
|
||||
virtual ContentFeatures* getModifiable(content_t c)=0;
|
||||
// Register node definition by name (allocate an id)
|
||||
// If returns CONTENT_IGNORE, could not allocate id
|
||||
virtual content_t set(const std::string &name,
|
||||
const ContentFeatures &def)=0;
|
||||
// If returns CONTENT_IGNORE, could not allocate id
|
||||
virtual content_t allocateDummy(const std::string &name)=0;
|
||||
|
||||
/*
|
||||
Update tile textures to latest return values of TextueSource.
|
||||
|
|
|
@ -56,11 +56,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
18: new generator (not really necessary, but it's there)
|
||||
19: new content type handling
|
||||
20: many existing content types translated to extended ones
|
||||
21: dynamic content type allocation
|
||||
*/
|
||||
// This represents an uninitialized or invalid format
|
||||
#define SER_FMT_VER_INVALID 255
|
||||
// Highest supported serialization version
|
||||
#define SER_FMT_VER_HIGHEST 20
|
||||
#define SER_FMT_VER_HIGHEST 21
|
||||
// Lowest supported serialization version
|
||||
#define SER_FMT_VER_LOWEST 0
|
||||
|
||||
|
|
|
@ -4428,6 +4428,10 @@ ITextureSource* Server::getTextureSource()
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
u16 Server::allocateUnknownNodeId(const std::string &name)
|
||||
{
|
||||
return m_nodemgr->allocateDummy(name);
|
||||
}
|
||||
|
||||
IWritableToolDefManager* Server::getWritableToolDefManager()
|
||||
{
|
||||
|
|
|
@ -491,6 +491,7 @@ public:
|
|||
virtual IToolDefManager* getToolDefManager();
|
||||
virtual INodeDefManager* getNodeDefManager();
|
||||
virtual ITextureSource* getTextureSource();
|
||||
virtual u16 allocateUnknownNodeId(const std::string &name);
|
||||
|
||||
IWritableToolDefManager* getWritableToolDefManager();
|
||||
IWritableNodeDefManager* getWritableNodeDefManager();
|
||||
|
|
Loading…
Reference in New Issue