minetest/src/nodemetadata.cpp

225 lines
4.7 KiB
C++
Raw Normal View History

2011-04-04 04:13:08 +02:00
/*
2013-02-24 18:40:43 +01:00
Minetest
2013-02-24 19:38:45 +01:00
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
2011-04-04 04:13:08 +02:00
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
2011-04-04 04:13:08 +02:00
(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 Lesser General Public License for more details.
2011-04-04 04:13:08 +02:00
You should have received a copy of the GNU Lesser General Public License along
2011-04-04 04:13:08 +02:00
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "nodemetadata.h"
#include "exceptions.h"
2012-03-19 01:08:04 +01:00
#include "gamedef.h"
2011-04-04 14:13:19 +02:00
#include "inventory.h"
#include "log.h"
#include "util/serialize.h"
#include "constants.h" // MAP_BLOCKSIZE
#include <sstream>
2011-04-04 04:13:08 +02:00
/*
NodeMetadata
*/
NodeMetadata::NodeMetadata(IGameDef *gamedef):
2012-03-19 01:08:04 +01:00
m_stringvars(),
m_inventory(new Inventory(gamedef->idef()))
2011-04-04 04:13:08 +02:00
{
}
NodeMetadata::~NodeMetadata()
{
2012-03-19 01:08:04 +01:00
delete m_inventory;
2011-04-04 04:13:08 +02:00
}
2012-03-19 01:08:04 +01:00
void NodeMetadata::serialize(std::ostream &os) const
2011-11-25 14:17:54 +01:00
{
2012-03-19 01:08:04 +01:00
int num_vars = m_stringvars.size();
writeU32(os, num_vars);
for(std::map<std::string, std::string>::const_iterator
i = m_stringvars.begin(); i != m_stringvars.end(); i++){
os<<serializeString(i->first);
os<<serializeLongString(i->second);
2011-11-25 14:17:54 +01:00
}
2012-03-19 01:08:04 +01:00
m_inventory->serialize(os);
2011-11-25 14:17:54 +01:00
}
2012-03-19 01:08:04 +01:00
void NodeMetadata::deSerialize(std::istream &is)
2011-04-04 04:13:08 +02:00
{
2012-03-19 01:08:04 +01:00
m_stringvars.clear();
int num_vars = readU32(is);
for(int i=0; i<num_vars; i++){
std::string name = deSerializeString(is);
std::string var = deSerializeLongString(is);
m_stringvars[name] = var;
}
2011-04-04 04:13:08 +02:00
2012-03-19 01:08:04 +01:00
m_inventory->deSerialize(is);
2011-04-04 04:13:08 +02:00
}
2012-03-19 01:08:04 +01:00
void NodeMetadata::clear()
2011-04-04 04:13:08 +02:00
{
2012-03-19 01:08:04 +01:00
m_stringvars.clear();
m_inventory->clear();
2011-04-04 04:13:08 +02:00
}
/*
NodeMetadataList
2011-04-04 04:13:08 +02:00
*/
2012-03-19 01:08:04 +01:00
void NodeMetadataList::serialize(std::ostream &os) const
2011-04-04 04:13:08 +02:00
{
2012-03-19 01:08:04 +01:00
/*
Version 0 is a placeholder for "nothing to see here; go away."
*/
if(m_data.size() == 0){
writeU8(os, 0); // version
return;
}
writeU8(os, 1); // version
2011-04-05 09:59:48 +02:00
2011-04-04 04:13:08 +02:00
u16 count = m_data.size();
2012-03-19 01:08:04 +01:00
writeU16(os, count);
2011-04-04 04:13:08 +02:00
2012-03-19 01:08:04 +01:00
for(std::map<v3s16, NodeMetadata*>::const_iterator
i = m_data.begin();
i != m_data.end(); i++)
2011-04-04 04:13:08 +02:00
{
2012-03-19 01:08:04 +01:00
v3s16 p = i->first;
NodeMetadata *data = i->second;
2011-04-04 04:13:08 +02:00
u16 p16 = p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X;
2012-03-19 01:08:04 +01:00
writeU16(os, p16);
2011-04-04 04:13:08 +02:00
data->serialize(os);
}
}
2012-03-19 01:08:04 +01:00
void NodeMetadataList::deSerialize(std::istream &is, IGameDef *gamedef)
2011-04-04 04:13:08 +02:00
{
m_data.clear();
2012-03-19 01:08:04 +01:00
u8 version = readU8(is);
2011-04-04 04:13:08 +02:00
2012-03-19 01:08:04 +01:00
if(version == 0){
// Nothing
return;
}
2011-04-05 09:59:48 +02:00
2012-03-19 01:08:04 +01:00
if(version != 1){
infostream<<__FUNCTION_NAME<<": version "<<version<<" not supported"
2011-04-05 09:59:48 +02:00
<<std::endl;
throw SerializationError("NodeMetadataList::deSerialize");
}
2012-03-19 01:08:04 +01:00
u16 count = readU16(is);
2011-04-04 04:13:08 +02:00
for(u16 i=0; i<count; i++)
{
2012-03-19 01:08:04 +01:00
u16 p16 = readU16(is);
2011-04-04 04:13:08 +02:00
Changed default settings to bring a better gameplay. Reduced viewing_range_nodes_max viewing_range_nodes_max tends to actually push more than it should. Matching the example with the default settings. And adding a further description about it. Missed changing curl timeout. Now set to 4000 Fix leaking global in texture pack menu Simplify loading of Android version of menu Mgv5 get ground level at point function. Fast spawn player version Mgv5 1 up 1 down overgeneration for biome surface continuity Optimise getTileInfo() getTileInfo() ~1.5x faster getSmoothLight ~2.0x faster Optimise functions from CNodeDefManager and VoxelManipulator CNodeDefManager::get() VoxelManipulator::addArea() serialize.h: use machine native byte swapping if available, fall-back to previous generic method if not (supported for GCC using endian.h, detection done in cmake) write/readARGB8() - just write 32-bit color in one op, instead of 4 1-byte ops cleanup: removed unneeded buffer init for some serialize-out functions use a #define for the fixed point factor in read/writeF1000() nodemetadata.cpp, nodetimer.cpp optimzation: simpler deserialize node position method staticobject.cpp: cleanup: use util/serialize.h inlines instead of its own de/serialization serialize.cpp: minor optimization/cleanup: avoid generation of unneeded string temporary CMakeLists.txt, cmake_config.h.in: detection of endian.h config.h: added HAVE_ENDIAN_H Commits due to feedback squashed Signed-off-by: Craig Robbins <kde.psych@gmail.com> Update credits menu
2014-11-20 18:26:42 +01:00
v3s16 p;
p.Z = p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE;
p16 &= MAP_BLOCKSIZE * MAP_BLOCKSIZE - 1;
p.Y = p16 / MAP_BLOCKSIZE;
p16 &= MAP_BLOCKSIZE - 1;
p.X = p16;
2012-03-19 01:08:04 +01:00
if(m_data.find(p) != m_data.end())
2011-04-04 04:13:08 +02:00
{
infostream<<"WARNING: NodeMetadataList::deSerialize(): "
2011-04-04 04:13:08 +02:00
<<"already set data at position"
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring."
2011-04-04 04:13:08 +02:00
<<std::endl;
continue;
2011-04-04 04:13:08 +02:00
}
2012-03-19 01:08:04 +01:00
NodeMetadata *data = new NodeMetadata(gamedef);
data->deSerialize(is);
m_data[p] = data;
2011-04-04 04:13:08 +02:00
}
}
2012-03-19 01:08:04 +01:00
2011-04-04 04:13:08 +02:00
NodeMetadataList::~NodeMetadataList()
{
2012-03-19 01:08:04 +01:00
clear();
2011-04-04 04:13:08 +02:00
}
NodeMetadata* NodeMetadataList::get(v3s16 p)
{
2012-03-19 01:08:04 +01:00
std::map<v3s16, NodeMetadata*>::const_iterator n = m_data.find(p);
if(n == m_data.end())
2011-04-04 04:13:08 +02:00
return NULL;
2012-03-19 01:08:04 +01:00
return n->second;
2011-04-04 04:13:08 +02:00
}
void NodeMetadataList::remove(v3s16 p)
{
NodeMetadata *olddata = get(p);
if(olddata)
{
delete olddata;
2012-03-19 01:08:04 +01:00
m_data.erase(p);
2011-04-04 04:13:08 +02:00
}
}
void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
{
remove(p);
2012-03-19 01:08:04 +01:00
m_data.insert(std::make_pair(p, d));
2011-04-04 04:13:08 +02:00
}
2012-03-19 01:08:04 +01:00
void NodeMetadataList::clear()
2011-04-05 01:56:29 +02:00
{
2012-03-19 01:08:04 +01:00
for(std::map<v3s16, NodeMetadata*>::iterator
i = m_data.begin();
i != m_data.end(); i++)
2011-04-05 01:56:29 +02:00
{
2012-03-19 01:08:04 +01:00
delete i->second;
2011-04-05 01:56:29 +02:00
}
2012-03-19 01:08:04 +01:00
m_data.clear();
2011-04-05 01:56:29 +02:00
}
std::string NodeMetadata::getString(const std::string &name, unsigned short recursion) const
{
std::map<std::string, std::string>::const_iterator it;
it = m_stringvars.find(name);
if (it == m_stringvars.end()) {
return "";
}
return resolveString(it->second, recursion);
}
void NodeMetadata::setString(const std::string &name, const std::string &var)
{
if (var.empty()) {
m_stringvars.erase(name);
} else {
m_stringvars[name] = var;
}
}
std::string NodeMetadata::resolveString(const std::string &str, unsigned short recursion) const
{
if (recursion > 1) {
return str;
}
if (str.substr(0, 2) == "${" && str[str.length() - 1] == '}') {
return getString(str.substr(2, str.length() - 3), recursion + 1);
}
return str;
}