Luanti 5.15.0-dev
 
Loading...
Searching...
No Matches
mapblock.h
Go to the documentation of this file.
1// Luanti
2// SPDX-License-Identifier: LGPL-2.1-or-later
3// Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5#pragma once
6
7#include <vector>
8#include "irr_v3d.h"
9#include "mapnode.h"
10#include "exceptions.h"
11#include "constants.h"
12#include "staticobject.h"
13#include "nodemetadata.h" // NodeMetadataList
14#include "nodetimer.h"
15#include "modifiedstate.h"
16#include "util/numeric.h" // getContainerPos
17
18class Map;
19class IGameDef;
20class MapBlockMesh;
22class NameIdMapping;
23class TestMapBlock;
24
25#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
26
30
52
56
58{
59public:
60 MapBlock(v3s16 pos, IGameDef *gamedef);
61 ~MapBlock();
62
63 // Any server-modding code can "delete" arbitrary blocks (i.e. with
64 // core.delete_area), which makes them orphan. Avoid using orphan blocks for
65 // anything.
66 bool isOrphan() const
67 {
68 return m_orphan;
69 }
70
72 {
73 m_orphan = true;
74 }
75
79 void raiseModified(u32 mod, u32 reason=MOD_REASON_UNKNOWN)
80 {
81 if (mod > m_modified) {
82 m_modified = mod;
83 m_modified_reason = reason;
86 } else if (mod == m_modified) {
87 m_modified_reason |= reason;
88 }
89 if (mod == MOD_STATE_WRITE_NEEDED)
90 contents.clear();
91 }
92
93 inline u32 getModified()
94 {
95 return m_modified;
96 }
97
98 inline u32 getModifiedReason()
99 {
100 return m_modified_reason;
101 }
102
103 std::string getModifiedReasonString();
104
105 inline void resetModified()
106 {
109 }
110
114
115 // is_underground getter/setter
116 inline bool getIsUnderground()
117 {
118 return is_underground;
119 }
120
121 inline void setIsUnderground(bool a_is_underground)
122 {
123 is_underground = a_is_underground;
125 }
126
127 inline void setLightingComplete(u16 newflags)
128 {
129 if (newflags != m_lighting_complete) {
130 m_lighting_complete = newflags;
132 }
133 }
134
136 {
137 return m_lighting_complete;
138 }
139
140 inline void setLightingComplete(LightBank bank, u8 direction,
141 bool is_complete)
142 {
143 assert(direction <= 5);
144 if (bank == LIGHTBANK_NIGHT) {
145 direction += 6;
146 }
147 u16 newflags = m_lighting_complete;
148 if (is_complete) {
149 newflags |= 1 << direction;
150 } else {
151 newflags &= ~(1 << direction);
152 }
153 setLightingComplete(newflags);
154 }
155
156 inline bool isLightingComplete(LightBank bank, u8 direction)
157 {
158 assert(direction <= 5);
159 if (bank == LIGHTBANK_NIGHT) {
160 direction += 6;
161 }
162 return (m_lighting_complete & (1 << direction)) != 0;
163 }
164
165 inline bool isGenerated()
166 {
167 return m_generated;
168 }
169
170 inline void setGenerated(bool b)
171 {
172 if (b != m_generated) {
174 m_generated = b;
175 }
176 }
177
181
183 inline v3s16 getPos()
184 {
185 return m_pos;
186 }
187
190 {
191 return m_pos_relative;
192 }
193
195 inline core::aabbox3d<s16> getBox()
196 {
197 return getBox(getPosRelative());
198 }
199
200 static inline core::aabbox3d<s16> getBox(v3s16 pos_relative)
201 {
202 return core::aabbox3d<s16>(pos_relative,
203 pos_relative + v3s16(MAP_BLOCKSIZE - 1));
204 }
205
209
210 inline bool isValidPosition(s16 x, s16 y, s16 z)
211 {
212 return x >= 0 && x < MAP_BLOCKSIZE
213 && y >= 0 && y < MAP_BLOCKSIZE
214 && z >= 0 && z < MAP_BLOCKSIZE;
215 }
216
218 {
219 return isValidPosition(p.X, p.Y, p.Z);
220 }
221
222 inline MapNode getNode(s16 x, s16 y, s16 z, bool *valid_position)
223 {
224 *valid_position = isValidPosition(x, y, z);
225
226 if (!*valid_position)
227 return {CONTENT_IGNORE};
228
229 return data[m_is_mono_block ? 0 : z * zstride + y * ystride + x];
230 }
231
232 inline MapNode getNode(v3s16 p, bool *valid_position)
233 {
234 return getNode(p.X, p.Y, p.Z, valid_position);
235 }
236
238 {
239 bool is_valid;
240 return getNode(p.X, p.Y, p.Z, &is_valid);
241 }
242
243 inline void setNode(s16 x, s16 y, s16 z, MapNode n)
244 {
245 if (!isValidPosition(x, y, z))
247
249 data[z * zstride + y * ystride + x] = n;
251 }
252
253 inline void setNode(v3s16 p, MapNode n)
254 {
255 setNode(p.X, p.Y, p.Z, n);
256 }
257
261
262 inline MapNode getNodeNoCheck(s16 x, s16 y, s16 z)
263 {
264 return data[m_is_mono_block ? 0 : z * zstride + y * ystride + x];
265 }
266
268 {
269 return getNodeNoCheck(p.X, p.Y, p.Z);
270 }
271
272 inline void setNodeNoCheck(s16 x, s16 y, s16 z, MapNode n)
273 {
275 data[z * zstride + y * ystride + x] = n;
277 }
278
280 {
281 setNodeNoCheck(p.X, p.Y, p.Z, n);
282 }
283
284 // Copies data to VoxelManipulator to getPosRelative()
285 void copyTo(VoxelManipulator &dst);
286
287 // Copies data from VoxelManipulator to getPosRelative()
288 void copyFrom(const VoxelManipulator &src);
289
290 // Update is air flag.
291 // Sets m_is_air to appropriate value.
292 void actuallyUpdateIsAir();
293
294 // Call this to schedule what the previous function does to be done
295 // when the value is actually needed.
296 void expireIsAirCache();
297
298 inline bool isAir()
299 {
302 return m_is_air;
303 }
304
305 bool onObjectsActivation();
306 bool saveStaticObject(u16 id, const StaticObject &obj, u32 reason);
307
309 void step(float dtime, const std::function<bool(v3s16, MapNode, NodeTimer)> &on_timer_cb);
310
314
315 // NOTE: BLOCK_TIMESTAMP_UNDEFINED=0xffffffff means there is no timestamp.
316
322
323 inline void setTimestampNoChangedFlag(u32 time)
324 {
325 m_timestamp = time;
326 }
327
328 inline u32 getTimestamp()
329 {
330 return m_timestamp;
331 }
332
334 inline u32 getDiskTimestamp()
335 {
336 return m_disk_timestamp;
337 }
338
342
343 inline void resetUsageTimer()
344 {
345 m_usage_timer = 0;
346 }
347
348 inline void incrementUsageTimer(float dtime)
349 {
350 m_usage_timer += dtime;
351 }
352
353 inline float getUsageTimer()
354 {
355 return m_usage_timer;
356 }
357
361
362 inline void refGrab()
363 {
364 assert(m_refcount < SHRT_MAX);
365 m_refcount++;
366 }
367
368 inline void refDrop()
369 {
370 assert(m_refcount > 0);
371 m_refcount--;
372 }
373
374 inline short refGet()
375 {
376 return m_refcount;
377 }
378
382
384 {
385 return m_node_timers.get(p);
386 }
387
389 {
391 }
392
393 inline void setNodeTimer(const NodeTimer &t)
394 {
396 }
397
398 inline void clearNodeTimers()
399 {
401 }
402
406
407 // These don't write or read version by itself
408 // Set disk to true for on-disk format, false for over-the-network format
409 // Precondition: version >= SER_FMT_VER_LOWEST_WRITE
410 void serialize(std::ostream &result, u8 version, bool disk, int compression_level);
411 // If disk == true: In addition to doing other things, will add
412 // unknown blocks from id-name mapping to wndef
413 void deSerialize(std::istream &is, u8 version, bool disk);
414
415 void serializeNetworkSpecific(std::ostream &os);
416 void deSerializeNetworkSpecific(std::istream &is);
417
418 bool storeActiveObject(u16 id);
419 // clearObject and return removed objects count
420 u32 clearObjects();
421
422private:
423 static const u32 ystride = MAP_BLOCKSIZE;
424 static const u32 zstride = MAP_BLOCKSIZE * MAP_BLOCKSIZE;
425
427
428private:
429#if BUILD_UNITTESTS
430 // access to data, tryConvertToMonoBlock, deconvertMonoblock
431 friend class TestMapBlock;
432#endif
433
434 /*
435 Private methods
436 */
437
438 void deSerialize_pre22(std::istream &is, u8 version, bool disk);
439 // check if all nodes are identical, if so convert to monoblock
440 void tryShrinkNodes();
441 // if a monoblock, expand storage back to the full array
442 void expandNodesIfNeeded();
443 void reallocate(u32 count, MapNode n);
444
445 static void getBlockNodeIdMapping(NameIdMapping *nimap, MapNode *nodes,
446 u32 count, const NodeDefManager *nodedef);
447 static void correctBlockNodeIds(const NameIdMapping *nimap, MapNode *nodes,
448 IGameDef *gamedef);
449
450 /*
451 * PLEASE NOTE: When adding something here be mindful of position and size
452 * of member variables! This is also the reason for the weird public-private
453 * interleaving.
454 * If in doubt consult `pahole` to see the effects.
455 */
456
457public:
458#if CHECK_CLIENT_BUILD() // Only on client
459 MapBlockMesh *mesh = nullptr;
460
461 // marks the sides which are opaque: 00+Z-Z+Y-Y+X-X
462 u8 solid_sides = 0;
463#endif
464
465private:
466 // see isOrphan()
467 bool m_orphan = false;
468
469 // Position in blocks on parent
471
472 /* Precalculated m_pos_relative value
473 * This caches the value, improving performance by removing 3 s16 multiplications
474 * at runtime on each getPosRelative call.
475 * For a 5 minutes runtime with valgrind this removes 3 * 19M s16 multiplications.
476 * The gain can be estimated in Release Build to 3 * 100M multiply operations for 5 mins.
477 */
479
480 short m_refcount = 0;
481
482 /*
483 * Note that this is not an inline array because that has implications for heap
484 * fragmentation (the array is exactly 16K, or exactly 4 bytes for a "monoblock"),
485 * CPU caches and/or optimizability of algorithms working on this array.
486 */
487 MapNode *data = nullptr;
488
489 // provides the item and node definitions
491
492 /*
493 When the block is accessed, this is set to 0.
494 Map will unload the block when this reaches a timeout.
495 */
496 float m_usage_timer = 0;
497
498 /*
499 * For "monoblocks", the whole block is filled with the same node, only this node is stored.
500 * (For reduced memory usage)
501 */
503public:
505 // True if we never want to cache content types for this block
507 // Cache of content types
508 // This is actually a set but for the small sizes we have a vector should be
509 // more efficient.
510 // Can be empty, in which case nothing was cached yet.
511 std::vector<content_t> contents;
512
513private:
514 // Whether day and night lighting differs
515 bool m_is_air = false;
516 bool m_is_air_expired = true;
517
518 /*
519 - On the server, this is used for telling whether the
520 block has been modified from the one on disk.
521 - On the client, this is used for nothing.
522 */
525
526 /*
527 When block is removed from active blocks, this is set to gametime.
528 Value BLOCK_TIMESTAMP_UNDEFINED=0xffffffff means there is no timestamp.
529 */
531 // The on-disk (or to-be on-disk) timestamp value
533
543
544 // Whether mapgen has generated the content of this block (persisted)
545 bool m_generated = false;
546
547 /*
548 When propagating sunlight and the above block doesn't exist,
549 sunlight is assumed if this is false.
550
551 In practice this is set to true if the block is completely
552 undeground with nothing visible above the ground except
553 caves.
554 */
555 bool is_underground = false;
556
557public:
560
561private:
563};
564
565typedef std::vector<MapBlock*> MapBlockVect;
566
568{
569 const float max_limit_bs = (MAX_MAP_GENERATION_LIMIT + 0.5f) * BS;
570 return p.X < -max_limit_bs ||
571 p.X > max_limit_bs ||
572 p.Y < -max_limit_bs ||
573 p.Y > max_limit_bs ||
574 p.Z < -max_limit_bs ||
575 p.Z > max_limit_bs;
576}
577
579{
580 const s16 max_limit_bp = MAX_MAP_GENERATION_LIMIT / MAP_BLOCKSIZE;
581 return p.X < -max_limit_bp ||
582 p.X > max_limit_bp ||
583 p.Y < -max_limit_bp ||
584 p.Y > max_limit_bp ||
585 p.Z < -max_limit_bp ||
586 p.Z > max_limit_bp;
587}
588
589/*
590 Returns the position of the block where the node is located
591*/
596
597inline void getNodeBlockPosWithOffset(v3s16 p, v3s16 &block, v3s16 &offset)
598{
600}
601
602/*
603 Get a quick string to describe what a block actually contains
604*/
605std::string analyze_block(MapBlock *block);
Definition gamedef.h:26
Definition exceptions.h:108
Definition mapblock_mesh.h:176
Definition mapblock.h:58
bool is_underground
Definition mapblock.h:555
static void correctBlockNodeIds(const NameIdMapping *nimap, MapNode *nodes, IGameDef *gamedef)
Definition mapblock.cpp:351
bool m_orphan
Definition mapblock.h:467
void step(float dtime, const std::function< bool(v3s16, MapNode, NodeTimer)> &on_timer_cb)
Definition mapblock.cpp:174
u16 getLightingComplete()
Definition mapblock.h:135
bool getIsUnderground()
Definition mapblock.h:116
MapNode getNodeNoCheck(s16 x, s16 y, s16 z)
Definition mapblock.h:262
float m_usage_timer
Definition mapblock.h:496
void incrementUsageTimer(float dtime)
Definition mapblock.h:348
void raiseModified(u32 mod, u32 reason=MOD_REASON_UNKNOWN)
Definition mapblock.h:79
u32 m_disk_timestamp
Definition mapblock.h:532
bool isValidPosition(s16 x, s16 y, s16 z)
Definition mapblock.h:210
void removeNodeTimer(v3s16 p)
Definition mapblock.h:388
void setTimestamp(u32 time)
Definition mapblock.h:317
v3s16 getPos()
Definition mapblock.h:183
static const u32 ystride
Definition mapblock.h:423
short refGet()
Definition mapblock.h:374
void clearNodeTimers()
Definition mapblock.h:398
void setTimestampNoChangedFlag(u32 time)
Definition mapblock.h:323
u32 getModified()
Definition mapblock.h:93
MapNode getNodeNoEx(v3s16 p)
Definition mapblock.h:237
v3s16 m_pos_relative
Definition mapblock.h:478
u32 m_timestamp
Definition mapblock.h:530
v3s16 m_pos
Definition mapblock.h:470
void setGenerated(bool b)
Definition mapblock.h:170
NodeMetadataList m_node_metadata
Definition mapblock.h:558
bool isLightingComplete(LightBank bank, u8 direction)
Definition mapblock.h:156
u32 clearObjects()
Definition mapblock.cpp:677
MapNode getNode(s16 x, s16 y, s16 z, bool *valid_position)
Definition mapblock.h:222
u32 m_modified_reason
Definition mapblock.h:524
bool m_is_air
Definition mapblock.h:515
u16 m_modified
Definition mapblock.h:523
void setNode(s16 x, s16 y, s16 z, MapNode n)
Definition mapblock.h:243
v3s16 getPosRelative()
Definition mapblock.h:189
float getUsageTimer()
Definition mapblock.h:353
bool isGenerated()
Definition mapblock.h:165
bool m_generated
Definition mapblock.h:545
void setNodeNoCheck(v3s16 p, MapNode n)
Definition mapblock.h:279
void tryShrinkNodes()
Definition mapblock.cpp:253
static const u32 nodecount
Definition mapblock.h:426
void resetModified()
Definition mapblock.h:105
void copyTo(VoxelManipulator &dst)
Definition mapblock.cpp:214
void makeOrphan()
Definition mapblock.h:71
static const u32 zstride
Definition mapblock.h:424
MapNode * data
Definition mapblock.h:487
void deSerialize_pre22(std::istream &is, u8 version, bool disk)
Definition mapblock.cpp:690
void refDrop()
Definition mapblock.h:368
bool m_is_air_expired
Definition mapblock.h:516
StaticObjectList m_static_objects
Definition mapblock.h:559
bool saveStaticObject(u16 id, const StaticObject &obj, u32 reason)
Definition mapblock.cpp:157
MapNode getNode(v3s16 p, bool *valid_position)
Definition mapblock.h:232
bool isValidPosition(v3s16 p)
Definition mapblock.h:217
void setNodeNoCheck(s16 x, s16 y, s16 z, MapNode n)
Definition mapblock.h:272
void serialize(std::ostream &result, u8 version, bool disk, int compression_level)
Serialization.
Definition mapblock.cpp:388
bool isAir()
Definition mapblock.h:298
void reallocate(u32 count, MapNode n)
Definition mapblock.cpp:236
u32 getDiskTimestamp()
Definition mapblock.h:334
bool isOrphan() const
Definition mapblock.h:66
std::vector< content_t > contents
Definition mapblock.h:511
u16 m_lighting_complete
Definition mapblock.h:542
u32 getTimestamp()
Definition mapblock.h:328
std::string getModifiedReasonString()
Definition mapblock.cpp:192
void setLightingComplete(u16 newflags)
Definition mapblock.h:127
NodeTimer getNodeTimer(v3s16 p)
Definition mapblock.h:383
void deSerialize(std::istream &is, u8 version, bool disk)
Definition mapblock.cpp:502
void resetUsageTimer()
Definition mapblock.h:343
void setLightingComplete(LightBank bank, u8 direction, bool is_complete)
Definition mapblock.h:140
void copyFrom(const VoxelManipulator &src)
Definition mapblock.cpp:224
void expandNodesIfNeeded()
Definition mapblock.cpp:279
static void getBlockNodeIdMapping(NameIdMapping *nimap, MapNode *nodes, u32 count, const NodeDefManager *nodedef)
Definition mapblock.cpp:321
void setNode(v3s16 p, MapNode n)
Definition mapblock.h:253
bool onObjectsActivation()
Definition mapblock.cpp:133
MapNode getNodeNoCheck(v3s16 p)
Definition mapblock.h:267
bool storeActiveObject(u16 id)
Definition mapblock.cpp:666
void deSerializeNetworkSpecific(std::istream &is)
Definition mapblock.cpp:652
MapBlock(v3s16 pos, IGameDef *gamedef)
Definition mapblock.cpp:101
void refGrab()
Definition mapblock.h:362
void setIsUnderground(bool a_is_underground)
Definition mapblock.h:121
static core::aabbox3d< s16 > getBox(v3s16 pos_relative)
Definition mapblock.h:200
u32 getModifiedReason()
Definition mapblock.h:98
void serializeNetworkSpecific(std::ostream &os)
Definition mapblock.cpp:497
~MapBlock()
Definition mapblock.cpp:113
void expireIsAirCache()
Definition mapblock.cpp:308
bool do_not_cache_contents
Definition mapblock.h:506
void setNodeTimer(const NodeTimer &t)
Definition mapblock.h:393
NodeTimerList m_node_timers
Definition mapblock.h:562
void actuallyUpdateIsAir()
Definition mapblock.cpp:286
bool m_is_mono_block
Definition mapblock.h:502
IGameDef * m_gamedef
Definition mapblock.h:490
short m_refcount
Definition mapblock.h:480
core::aabbox3d< s16 > getBox()
Definition mapblock.h:195
Definition map.h:100
Definition nameidmapping.h:17
This class is for getting the actual properties of nodes from their content ID.
Definition nodedef.h:509
Definition nodemetadata.h:66
Definition nodetimer.h:43
void remove(v3s16 p)
Definition nodetimer.h:61
void set(const NodeTimer &timer)
Definition nodetimer.h:88
NodeTimer get(const v3s16 &p)
Definition nodetimer.h:52
void clear()
Definition nodetimer.h:93
Definition nodetimer.h:21
Definition staticobject.h:33
Definition test_mapblock.cpp:17
Definition voxel.h:365
#define BS
Definition constants.h:61
#define MAP_BLOCKSIZE
Definition constants.h:64
#define MAX_MAP_GENERATION_LIMIT
Definition constants.h:54
core::vector3d< s16 > v3s16
Definition irr_v3d.h:13
core::vector3df v3f
Definition irr_v3d.h:11
std::vector< MapBlock * > MapBlockVect
Definition mapblock.h:565
v3s16 getNodeBlockPos(v3s16 p)
Definition mapblock.h:592
bool objectpos_over_limit(v3f p)
Definition mapblock.h:567
std::string analyze_block(MapBlock *block)
Definition mapblock.cpp:897
#define BLOCK_TIMESTAMP_UNDEFINED
Definition mapblock.h:25
void getNodeBlockPosWithOffset(v3s16 p, v3s16 &block, v3s16 &offset)
Definition mapblock.h:597
bool blockpos_over_max_limit(v3s16 p)
Definition mapblock.h:578
ModReason
Definition mapblock.h:31
@ MOD_REASON_SET_TIMESTAMP
Definition mapblock.h:37
@ MOD_REASON_CLEAR_ALL_OBJECTS
Definition mapblock.h:39
@ MOD_REASON_UNKNOWN
Definition mapblock.h:50
@ MOD_REASON_STATIC_DATA_CHANGED
Definition mapblock.h:47
@ MOD_REASON_STATIC_DATA_REMOVED
Definition mapblock.h:46
@ MOD_REASON_SET_IS_UNDERGROUND
Definition mapblock.h:33
@ MOD_REASON_SET_NODE
Definition mapblock.h:36
@ MOD_REASON_TOO_MANY_OBJECTS
Definition mapblock.h:44
@ MOD_REASON_REMOVE_OBJECTS_REMOVE
Definition mapblock.h:42
@ MOD_REASON_REPORT_META_CHANGE
Definition mapblock.h:38
@ MOD_REASON_ADD_ACTIVE_OBJECT_RAW
Definition mapblock.h:41
@ MOD_REASON_EXPIRE_IS_AIR
Definition mapblock.h:48
@ MOD_REASON_BLOCK_EXPIRED
Definition mapblock.h:40
@ MOD_REASON_VMANIP
Definition mapblock.h:49
@ MOD_REASON_SET_GENERATED
Definition mapblock.h:35
@ MOD_REASON_REMOVE_OBJECTS_DEACTIVATE
Definition mapblock.h:43
@ MOD_REASON_STATIC_DATA_ADDED
Definition mapblock.h:45
@ MOD_REASON_SET_LIGHTING_COMPLETE
Definition mapblock.h:34
#define CONTENT_IGNORE
Definition mapnode.h:57
LightBank
Definition mapnode.h:79
@ LIGHTBANK_NIGHT
Definition mapnode.h:81
@ MOD_STATE_WRITE_AT_UNLOAD
Definition modifiedstate.h:15
@ MOD_STATE_CLEAN
Definition modifiedstate.h:12
@ MOD_STATE_WRITE_NEEDED
Definition modifiedstate.h:18
s16 getContainerPos(s16 p, s16 d)
Definition numeric.h:33
void getContainerPosWithOffset(s16 p, s16 d, s16 &container, s16 &offset)
Definition numeric.h:72
Definition mapnode.h:123
Definition staticobject.h:20
static std::string p(std::string path)
Definition test_filesys.cpp:64
constexpr v3f x
Definition test_irr_matrix4.cpp:18
constexpr v3f y
Definition test_irr_matrix4.cpp:19
constexpr v3f z
Definition test_irr_matrix4.cpp:20