/*
-Minetest-c55
-Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+Minetest
+Copyright (C) 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 General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
+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 General Public License for more details.
+GNU Lesser General Public License for more details.
-You should have received a copy of the GNU General Public License along
+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.
*/
#ifndef MAPBLOCK_HEADER
#define MAPBLOCK_HEADER
-#include <jmutex.h>
-#include <jmutexautolock.h>
-#include <exception>
+#include <set>
#include "debug.h"
-#include "common_irrlicht.h"
+#include "irr_v3d.h"
#include "mapnode.h"
#include "exceptions.h"
-#include "serialization.h"
#include "constants.h"
-#include "voxel.h"
#include "staticobject.h"
+#include "nodemetadata.h"
+#include "nodetimer.h"
#include "modifiedstate.h"
+#include "util/numeric.h" // getContainerPos
class Map;
class NodeMetadataList;
class IGameDef;
class MapBlockMesh;
+class VoxelManipulator;
#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
}
}
}
+ void raiseModified(u32 mod, const char *reason)
+ {
+ if (mod > m_modified){
+ m_modified = mod;
+ m_modified_reason = reason;
+ m_modified_reason_too_long = false;
+
+ if (m_modified >= MOD_STATE_WRITE_AT_UNLOAD){
+ m_disk_timestamp = m_timestamp;
+ }
+ }
+ else if (mod == m_modified){
+ if (!m_modified_reason_too_long){
+ if (m_modified_reason.size() < 40)
+ m_modified_reason += ", " + std::string(reason);
+ else{
+ m_modified_reason += "...";
+ m_modified_reason_too_long = true;
+ }
+ }
+ }
+ }
+
u32 getModified()
{
return m_modified;
Regular MapNode get-setters
*/
+ bool isValidPosition(s16 x, s16 y, s16 z)
+ {
+ return data != NULL
+ && x >= 0 && x < MAP_BLOCKSIZE
+ && y >= 0 && y < MAP_BLOCKSIZE
+ && z >= 0 && z < MAP_BLOCKSIZE;
+ }
+
bool isValidPosition(v3s16 p)
{
- if(data == NULL)
- return false;
- return (p.X >= 0 && p.X < MAP_BLOCKSIZE
- && p.Y >= 0 && p.Y < MAP_BLOCKSIZE
- && p.Z >= 0 && p.Z < MAP_BLOCKSIZE);
+ return isValidPosition(p.X, p.Y, p.Z);
}
- MapNode getNode(s16 x, s16 y, s16 z)
+ MapNode getNode(s16 x, s16 y, s16 z, bool *valid_position)
{
- if(data == NULL)
- throw InvalidPositionException();
- if(x < 0 || x >= MAP_BLOCKSIZE) throw InvalidPositionException();
- if(y < 0 || y >= MAP_BLOCKSIZE) throw InvalidPositionException();
- if(z < 0 || z >= MAP_BLOCKSIZE) throw InvalidPositionException();
+ *valid_position = isValidPosition(x, y, z);
+
+ if (!*valid_position)
+ return MapNode(CONTENT_IGNORE);
+
return data[z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + y*MAP_BLOCKSIZE + x];
}
- MapNode getNode(v3s16 p)
+ MapNode getNode(v3s16 p, bool *valid_position)
{
- return getNode(p.X, p.Y, p.Z);
+ return getNode(p.X, p.Y, p.Z, valid_position);
}
MapNode getNodeNoEx(v3s16 p)
{
- try{
- return getNode(p.X, p.Y, p.Z);
- }catch(InvalidPositionException &e){
- return MapNode(CONTENT_IGNORE);
- }
+ bool is_valid;
+ MapNode node = getNode(p.X, p.Y, p.Z, &is_valid);
+ return is_valid ? node : MapNode(CONTENT_IGNORE);
}
void setNode(s16 x, s16 y, s16 z, MapNode & n)
Non-checking variants of the above
*/
- MapNode getNodeNoCheck(s16 x, s16 y, s16 z)
+ MapNode getNodeNoCheck(s16 x, s16 y, s16 z, bool *valid_position)
{
- if(data == NULL)
- throw InvalidPositionException();
+ *valid_position = data != NULL;
+ if(!valid_position)
+ return MapNode(CONTENT_IGNORE);
+
return data[z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + y*MAP_BLOCKSIZE + x];
}
- MapNode getNodeNoCheck(v3s16 p)
+ MapNode getNodeNoCheck(v3s16 p, bool *valid_position)
{
- return getNodeNoCheck(p.X, p.Y, p.Z);
+ return getNodeNoCheck(p.X, p.Y, p.Z, valid_position);
}
void setNodeNoCheck(s16 x, s16 y, s16 z, MapNode & n)
is not valid on this MapBlock.
*/
bool isValidPositionParent(v3s16 p);
- MapNode getNodeParent(v3s16 p);
+ MapNode getNodeParent(v3s16 p, bool *is_valid_position = NULL);
void setNodeParent(v3s16 p, MapNode & n);
- MapNode getNodeParentNoEx(v3s16 p);
void drawbox(s16 x0, s16 y0, s16 z0, s16 w, s16 h, s16 d, MapNode node)
{
}
// See comments in mapblock.cpp
- bool propagateSunlight(core::map<v3s16, bool> & light_sources,
+ bool propagateSunlight(std::set<v3s16> & light_sources,
bool remove_light=false, bool *black_air_left=NULL);
// Copies data to VoxelManipulator to getPosRelative()
Sets m_day_night_differs to appropriate value.
These methods don't care about neighboring blocks.
*/
- void updateDayNightDiff();
+ void actuallyUpdateDayNightDiff();
+ /*
+ Call this to schedule what the previous function does to be done
+ when the value is actually needed.
+ */
+ void expireDayNightDiff();
- bool dayNightDiffed()
+ bool getDayNightDiff()
{
+ if(m_day_night_differs_expired)
+ actuallyUpdateDayNightDiff();
return m_day_night_differs;
}
{
m_usage_timer += dtime;
}
- u32 getUsageTimer()
+ float getUsageTimer()
{
return m_usage_timer;
}
+ /*
+ See m_refcount
+ */
+ void refGrab()
+ {
+ m_refcount++;
+ }
+ void refDrop()
+ {
+ m_refcount--;
+ }
+ int refGet()
+ {
+ return m_refcount;
+ }
+
+ /*
+ Node Timers
+ */
+ // Get timer
+ NodeTimer getNodeTimer(v3s16 p){
+ return m_node_timers.get(p);
+ }
+ // Deletes timer
+ void removeNodeTimer(v3s16 p){
+ m_node_timers.remove(p);
+ }
+ // Deletes old timer and sets a new one
+ void setNodeTimer(v3s16 p, NodeTimer t){
+ m_node_timers.set(p,t);
+ }
+ // Deletes all timers
+ void clearNodeTimers(){
+ m_node_timers.clear();
+ }
+
/*
Serialization
*/
// These don't write or read version by itself
// Set disk to true for on-disk format, false for over-the-network format
+ // Precondition: version >= SER_FMT_CLIENT_VER_LOWEST
void serialize(std::ostream &os, u8 version, bool disk);
// If disk == true: In addition to doing other things, will add
// unknown blocks from id-name mapping to wndef
void deSerialize(std::istream &is, u8 version, bool disk);
+ void serializeNetworkSpecific(std::ostream &os, u16 net_proto_version);
+ void deSerializeNetworkSpecific(std::istream &is);
+
private:
/*
Private methods
*/
- void serialize_pre22(std::ostream &os, u8 version, bool disk);
void deSerialize_pre22(std::istream &is, u8 version, bool disk);
/*
#ifndef SERVER // Only on client
MapBlockMesh *mesh;
- //JMutex mesh_mutex;
#endif
- NodeMetadataList *m_node_metadata;
+ NodeMetadataList m_node_metadata;
+ NodeTimerList m_node_timers;
StaticObjectList m_static_objects;
-
+
private:
/*
Private member variables
// Whether day and night lighting differs
bool m_day_night_differs;
+ bool m_day_night_differs_expired;
bool m_generated;
Map will unload the block when this reaches a timeout.
*/
float m_usage_timer;
+
+ /*
+ Reference count; currently used for determining if this block is in
+ the list of blocks to be drawn.
+ */
+ int m_refcount;
};
inline bool blockpos_over_limit(v3s16 p)
return getContainerPos(y, MAP_BLOCKSIZE);
}
+inline void getNodeBlockPosWithOffset(const v3s16 &p, v3s16 &block, v3s16 &offset)
+{
+ getContainerPosWithOffset(p, MAP_BLOCKSIZE, block, offset);
+}
+
+inline void getNodeSectorPosWithOffset(const v2s16 &p, v2s16 &block, v2s16 &offset)
+{
+ getContainerPosWithOffset(p, MAP_BLOCKSIZE, block, offset);
+}
+
/*
Get a quick string to describe what a block actually contains
*/