#include "modifiedstate.h"
#include "util/numeric.h" // getContainerPos
#include "settings.h"
-#include "mapgen.h"
+#include "mapgen/mapgen.h"
class Map;
class NodeMetadataList;
class MapBlock
{
public:
- MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy=false);
+ MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef);
~MapBlock();
/*virtual u16 nodeContainerId() const
void reallocate()
{
- delete[] data;
- data = new MapNode[nodecount];
for (u32 i = 0; i < nodecount; i++)
data[i] = MapNode(CONTENT_IGNORE);
-
raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_REALLOCATE);
}
} else if (mod == m_modified) {
m_modified_reason |= reason;
}
+ if (mod == MOD_STATE_WRITE_NEEDED)
+ contents_cached = false;
}
inline u32 getModified()
//// Flags
////
- inline bool isDummy()
- {
- return !data;
- }
-
- inline void unDummify()
- {
- assert(isDummy()); // Pre-condition
- reallocate();
- }
-
// is_underground getter/setter
inline bool getIsUnderground()
{
inline bool isValidPosition(s16 x, s16 y, s16 z)
{
- return data
- && x >= 0 && x < MAP_BLOCKSIZE
+ return x >= 0 && x < MAP_BLOCKSIZE
&& y >= 0 && y < MAP_BLOCKSIZE
&& z >= 0 && z < MAP_BLOCKSIZE;
}
return getNode(p.X, p.Y, p.Z, &is_valid);
}
- inline void setNode(s16 x, s16 y, s16 z, MapNode & n)
+ inline void setNode(s16 x, s16 y, s16 z, MapNode n)
{
if (!isValidPosition(x, y, z))
throw InvalidPositionException();
raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_SET_NODE);
}
- inline void setNode(v3s16 p, MapNode & n)
+ inline void setNode(v3s16 p, MapNode n)
{
setNode(p.X, p.Y, p.Z, n);
}
//// Non-checking variants of the above
////
- inline MapNode getNodeNoCheck(s16 x, s16 y, s16 z, bool *valid_position)
- {
- *valid_position = data != nullptr;
- if (!*valid_position)
- return {CONTENT_IGNORE};
-
- return data[z * zstride + y * ystride + x];
- }
-
- inline MapNode getNodeNoCheck(v3s16 p, bool *valid_position)
- {
- return getNodeNoCheck(p.X, p.Y, p.Z, valid_position);
- }
-
- ////
- //// Non-checking, unsafe variants of the above
- //// MapBlock must be loaded by another function in the same scope/function
- //// Caller must ensure that this is not a dummy block (by calling isDummy())
- ////
-
- inline const MapNode &getNodeUnsafe(s16 x, s16 y, s16 z)
+ inline MapNode getNodeNoCheck(s16 x, s16 y, s16 z)
{
return data[z * zstride + y * ystride + x];
}
- inline const MapNode &getNodeUnsafe(v3s16 &p)
+ inline MapNode getNodeNoCheck(v3s16 p)
{
- return getNodeUnsafe(p.X, p.Y, p.Z);
+ return getNodeNoCheck(p.X, p.Y, p.Z);
}
- inline void setNodeNoCheck(s16 x, s16 y, s16 z, MapNode & n)
+ inline void setNodeNoCheck(s16 x, s16 y, s16 z, MapNode n)
{
- if (!data)
- throw InvalidPositionException();
-
data[z * zstride + y * ystride + x] = n;
raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_SET_NODE_NO_CHECK);
}
- inline void setNodeNoCheck(v3s16 p, MapNode & n)
+ inline void setNodeNoCheck(v3s16 p, MapNode n)
{
setNodeNoCheck(p.X, p.Y, p.Z, n);
}
// is not valid on this MapBlock.
bool isValidPositionParent(v3s16 p);
MapNode getNodeParent(v3s16 p, bool *is_valid_position = NULL);
- void setNodeParent(v3s16 p, MapNode & n);
-
- inline void drawbox(s16 x0, s16 y0, s16 z0, s16 w, s16 h, s16 d, MapNode node)
- {
- for (u16 z = 0; z < d; z++)
- for (u16 y = 0; y < h; y++)
- for (u16 x = 0; x < w; x++)
- setNode(x0 + x, y0 + y, z0 + z, node);
- }
-
- // See comments in mapblock.cpp
- bool propagateSunlight(std::set<v3s16> &light_sources,
- bool remove_light=false, bool *black_air_left=NULL);
// Copies data to VoxelManipulator to getPosRelative()
void copyTo(VoxelManipulator &dst);
return m_day_night_differs;
}
- ////
- //// Miscellaneous stuff
- ////
+ bool onObjectsActivation();
+ bool saveStaticObject(u16 id, const StaticObject &obj, u32 reason);
- /*
- Tries to measure ground level.
- Return value:
- -1 = only air
- -2 = only ground
- -3 = random fail
- 0...MAP_BLOCKSIZE-1 = ground level
- */
- s16 getGroundLevel(v2s16 p2d);
+ void step(float dtime, const std::function<bool(v3s16, MapNode, f32)> &on_timer_cb);
////
//// Timestamp (see m_timestamp)
//// Node Timers
////
- inline NodeTimer getNodeTimer(const v3s16 &p)
+ inline NodeTimer getNodeTimer(v3s16 p)
{
return m_node_timers.get(p);
}
- inline void removeNodeTimer(const v3s16 &p)
+ inline void removeNodeTimer(v3s16 p)
{
m_node_timers.remove(p);
}
// 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_VER_LOWEST_WRITE
- void serialize(std::ostream &os, u8 version, bool disk);
+ void serialize(std::ostream &result, u8 version, bool disk, int compression_level);
// 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);
void deSerializeNetworkSpecific(std::istream &is);
+
+ bool storeActiveObject(u16 id);
+ // clearObject and return removed objects count
+ u32 clearObjects();
+
private:
/*
Private methods
void deSerialize_pre22(std::istream &is, u8 version, bool disk);
- /*
- Used only internally, because changes can't be tracked
- */
-
- inline MapNode &getNodeRef(s16 x, s16 y, s16 z)
- {
- if (!isValidPosition(x, y, z))
- throw InvalidPositionException();
-
- return data[z * zstride + y * ystride + x];
- }
-
- inline MapNode &getNodeRef(v3s16 &p)
- {
- return getNodeRef(p.X, p.Y, p.Z);
- }
-
public:
/*
Public member variables
#endif
NodeMetadataList m_node_metadata;
- NodeTimerList m_node_timers;
StaticObjectList m_static_objects;
static const u32 ystride = MAP_BLOCKSIZE;
static const u32 nodecount = MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE;
+ //// ABM optimizations ////
+ // Cache of content types
+ std::unordered_set<content_t> contents;
+ // True if content types are cached
+ bool contents_cached = false;
+ // True if we never want to cache content types for this block
+ bool do_not_cache_contents = false;
+ // marks the sides which are opaque: 00+Z-Z+Y-Y+X-X
+ u8 solid_sides {0};
+
private:
/*
Private member variables
IGameDef *m_gamedef;
- /*
- If NULL, block is a dummy block.
- Dummy blocks are used for caching not-found-on-disk blocks.
- */
- MapNode *data = nullptr;
-
/*
- On the server, this is used for telling whether the
block has been modified from the one on disk.
the list of blocks to be drawn.
*/
int m_refcount = 0;
+
+ MapNode data[nodecount];
+ NodeTimerList m_node_timers;
};
typedef std::vector<MapBlock*> MapBlockVect;
inline bool objectpos_over_limit(v3f p)
{
- const float max_limit_bs = MAX_MAP_GENERATION_LIMIT * BS;
+ const float max_limit_bs = (MAX_MAP_GENERATION_LIMIT + 0.5f) * BS;
return p.X < -max_limit_bs ||
p.X > max_limit_bs ||
p.Y < -max_limit_bs ||
/*
Returns the position of the block where the node is located
*/
-inline v3s16 getNodeBlockPos(const v3s16 &p)
+inline v3s16 getNodeBlockPos(v3s16 p)
{
return getContainerPos(p, MAP_BLOCKSIZE);
}
-inline void getNodeBlockPosWithOffset(const v3s16 &p, v3s16 &block, v3s16 &offset)
+inline void getNodeBlockPosWithOffset(v3s16 p, v3s16 &block, v3s16 &offset)
{
getContainerPosWithOffset(p, MAP_BLOCKSIZE, block, offset);
}