X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fmap.h;h=e049588713fcaacff9b32745a72d1a0c09b4b682;hb=7701e70dc92262c41d68cf1c9f7fbd0c333e5c52;hp=9317642150e2fcf3c0a712baf2569ef821e21b8d;hpb=e16a470d59069692d654f5c1529ab313a01ded67;p=minetest.git diff --git a/src/map.h b/src/map.h index 931764215..e04958871 100644 --- a/src/map.h +++ b/src/map.h @@ -26,12 +26,14 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "irrlichttypes_bloated.h" +#include "mapblock.h" #include "mapnode.h" #include "constants.h" #include "voxel.h" #include "modifiedstate.h" #include "util/container.h" #include "util/metricsbackend.h" +#include "util/numeric.h" #include "nodetimer.h" #include "map_settings_manager.h" #include "debug.h" @@ -77,21 +79,21 @@ struct MapEditEvent MapEditEvent() = default; + // Sets the event's position and marks the block as modified. + void setPositionModified(v3s16 pos) + { + p = pos; + modified_blocks.insert(getNodeBlockPos(pos)); + } + VoxelArea getArea() const { switch(type){ case MEET_ADDNODE: - return VoxelArea(p); case MEET_REMOVENODE: - return VoxelArea(p); case MEET_SWAPNODE: - return VoxelArea(p); case MEET_BLOCK_NODE_METADATA_CHANGED: - { - v3s16 np1 = p*MAP_BLOCKSIZE; - v3s16 np2 = np1 + v3s16(1,1,1)*MAP_BLOCKSIZE - v3s16(1,1,1); - return VoxelArea(np1, np2); - } + return VoxelArea(p); case MEET_OTHER: { VoxelArea a; @@ -161,7 +163,7 @@ class Map /*: public NodeContainer*/ bool isValidPosition(v3s16 p); // throws InvalidPositionException if not found - void setNode(v3s16 p, MapNode & n); + void setNode(v3s16 p, MapNode n); // Returns a CONTENT_IGNORE node if not found // If is_valid_position is not NULL then this will be set to true if the @@ -205,7 +207,7 @@ class Map /*: public NodeContainer*/ Updates usage timers and unloads unused blocks and sectors. Saves modified blocks before unloading if possible. */ - void timerUpdate(float dtime, float unload_timeout, u32 max_loaded_blocks, + void timerUpdate(float dtime, float unload_timeout, s32 max_loaded_blocks, std::vector *unloaded_blocks=NULL); /* @@ -257,9 +259,43 @@ class Map /*: public NodeContainer*/ void removeNodeTimer(v3s16 p); /* - Variables + Utilities */ + // Iterates through all nodes in the area in an unspecified order. + // The given callback takes the position as its first argument and the node + // as its second. If it returns false, forEachNodeInArea returns early. + template + void forEachNodeInArea(v3s16 minp, v3s16 maxp, F func) + { + v3s16 bpmin = getNodeBlockPos(minp); + v3s16 bpmax = getNodeBlockPos(maxp); + for (s16 bz = bpmin.Z; bz <= bpmax.Z; bz++) + for (s16 bx = bpmin.X; bx <= bpmax.X; bx++) + for (s16 by = bpmin.Y; by <= bpmax.Y; by++) { + // y is iterated innermost to make use of the sector cache. + v3s16 bp(bx, by, bz); + MapBlock *block = getBlockNoCreateNoEx(bp); + v3s16 basep = bp * MAP_BLOCKSIZE; + s16 minx_block = rangelim(minp.X - basep.X, 0, MAP_BLOCKSIZE - 1); + s16 miny_block = rangelim(minp.Y - basep.Y, 0, MAP_BLOCKSIZE - 1); + s16 minz_block = rangelim(minp.Z - basep.Z, 0, MAP_BLOCKSIZE - 1); + s16 maxx_block = rangelim(maxp.X - basep.X, 0, MAP_BLOCKSIZE - 1); + s16 maxy_block = rangelim(maxp.Y - basep.Y, 0, MAP_BLOCKSIZE - 1); + s16 maxz_block = rangelim(maxp.Z - basep.Z, 0, MAP_BLOCKSIZE - 1); + for (s16 z_block = minz_block; z_block <= maxz_block; z_block++) + for (s16 y_block = miny_block; y_block <= maxy_block; y_block++) + for (s16 x_block = minx_block; x_block <= maxx_block; x_block++) { + v3s16 p = basep + v3s16(x_block, y_block, z_block); + MapNode n = block ? + block->getNodeNoCheck(x_block, y_block, z_block) : + MapNode(CONTENT_IGNORE); + if (!func(p, n)) + return; + } + } + } + bool isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes); protected: IGameDef *m_gamedef;