/*
Minetest
Copyright (C) 2010-2013 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 Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser 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 "map.h"
#include "mapsector.h"
#include "mapblock.h"
#include "filesys.h"
#include "voxel.h"
#include "porting.h"
#include "serialization.h"
#include "nodemetadata.h"
#include "settings.h"
#include "log.h"
#include "profiler.h"
#include "nodedef.h"
#include "gamedef.h"
#include "util/directiontables.h"
#include "util/mathconstants.h"
#include "rollback_interface.h"
#include "environment.h"
#include "emerge.h"
#include "mapgen_v6.h"
#include "mg_biome.h"
#include "config.h"
#include "server.h"
#include "database.h"
#include "database-dummy.h"
#include "database-sqlite3.h"
#include <deque>
#if USE_LEVELDB
#include "database-leveldb.h"
#endif
#if USE_REDIS
#include "database-redis.h"
#endif
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
/*
Map
*/
Map::Map(std::ostream &dout, IGameDef *gamedef):
m_dout(dout),
m_gamedef(gamedef),
m_sector_cache(NULL),
m_transforming_liquid_loop_count_multiplier(1.0f),
m_unprocessed_count(0),
m_inc_trending_up_start_time(0),
m_queue_size_timer_started(false)
{
}
Map::~Map()
{
/*
Free all MapSectors
*/
for(std::map<v2s16, MapSector*>::iterator i = m_sectors.begin();
i != m_sectors.end(); ++i)
{
delete i->second;
}
}
void Map::addEventReceiver(MapEventReceiver *event_receiver)
{
m_event_receivers.insert(event_receiver);
}
void Map::removeEventReceiver(MapEventReceiver *event_receiver)
{
m_event_receivers.erase(event_receiver);
}
void Map::dispatchEvent(MapEditEvent *event)
{
for(std::set<MapEventReceiver*>::iterator
i = m_event_receivers.begin();
i != m_event_receivers.end(); ++i)
{
(*i)->onMapEditEvent(event);
}
}
MapSector * Map::getSectorNoGenerateNoExNoLock(v2s16 p)
{
if(m_sector_cache != NULL && p == m_sector_cache_p){
MapSector * sector = m_sector_cache;
return sector;
}
std::map<v2s16, MapSector*>::iterator n = m_sectors.find(p);
if(n == m_sectors.end())
return NULL;
MapSector *sector = n->second;
// Cache the last result
m_sector_cache_p = p;
m_sector_cache = sector;
return sector;
}
MapSector * Map::getSectorNoGenerateNoEx(v2s16 p)
{
return getSectorNoGenerateNoExNoLock(p);
}
MapSector * Map::getSectorNoGenerate(v2s16 p)
{
MapSector *sector = getSectorNoGenerateNoEx(p);
if(sector == NULL)
throw InvalidPositionException();
return sector;
}
MapBlock * Map::getBlockNoCreateNoEx(v3s16 p3d)
{
v2s16 p2d(p3d.X, p3d.Z);
MapSector * sector = getSectorNoGenerateNoEx(p2d);
if(sector == NULL)
return NULL;
MapBlock *block = sector->getBlockNoCreateNoEx(p3d.Y);
return block;
}
MapBlock * Map::getBlockNoCreate(v3s16 p3d)
{
MapBlock *block = getBlockNoCreateNoEx(p3d);
if(block == NULL)
throw InvalidPositionException();
return block;
}
bool Map::isNodeUnderground(v3s16 p)
{
v3s16 blockpos = getNodeBlockPos(p);
try{
MapBlock * block = getBlockNoCreate(blockpos);
return block->getIsUnderground();
}
catch(InvalidPositionException &e)
{
return false;
}
}
bool Map::isValidPosition(v3s16 p)
{
v3s16 blockpos = getNodeBlockPos(p);
MapBlock *block = getBlockNoCreate(blockpos);
return (block != NULL);
}
// Returns a CONTENT_IGNORE node if not found
MapNode Map::getNodeNoEx(v3s16 p, bool *is_valid_position)
{
v3s16 blockpos = getNodeBlockPos(p);
MapBlock *block = getBlockNoCreateNoEx(blockpos);
if (block == NULL) {
|