Luanti 5.11.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"
14#include "nodetimer.h"
15#include "modifiedstate.h"
16#include "util/numeric.h" // getContainerPos
17#include "settings.h"
18
19class Map;
21class IGameDef;
22class MapBlockMesh;
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
77 {
78 for (u32 i = 0; i < nodecount; i++)
81 }
82
84 {
85 return data;
86 }
87
91 void raiseModified(u32 mod, u32 reason=MOD_REASON_UNKNOWN)
92 {
93 if (mod > m_modified) {
94 m_modified = mod;
95 m_modified_reason = reason;
98 } else if (mod == m_modified) {
99 m_modified_reason |= reason;
100 }
101 if (mod == MOD_STATE_WRITE_NEEDED)
102 contents.clear();
103 }
104
105 inline u32 getModified()
106 {
107 return m_modified;
108 }
109
110 inline u32 getModifiedReason()
111 {
112 return m_modified_reason;
113 }
114
115 std::string getModifiedReasonString();
116
117 inline void resetModified()
118 {
121 }
122
126
127 // is_underground getter/setter
128 inline bool getIsUnderground()
129 {
130 return is_underground;
131 }
132
133 inline void setIsUnderground(bool a_is_underground)
134 {
135 is_underground = a_is_underground;
137 }
138
139 inline void setLightingComplete(u16 newflags)
140 {
141 if (newflags != m_lighting_complete) {
142 m_lighting_complete = newflags;
144 }
145 }
146
148 {
149 return m_lighting_complete;
150 }
151
152 inline void setLightingComplete(LightBank bank, u8 direction,
153 bool is_complete)
154 {
155 assert(direction <= 5);
156 if (bank == LIGHTBANK_NIGHT) {
157 direction += 6;
158 }
159 u16 newflags = m_lighting_complete;
160 if (is_complete) {
161 newflags |= 1 << direction;
162 } else {
163 newflags &= ~(1 << direction);
164 }
165 setLightingComplete(newflags);
166 }
167
168 inline bool isLightingComplete(LightBank bank, u8 direction)
169 {
170 assert(direction <= 5);
171 if (bank == LIGHTBANK_NIGHT) {
172 direction += 6;
173 }
174 return (m_lighting_complete & (1 << direction)) != 0;
175 }
176
177 inline bool isGenerated()
178 {
179 return m_generated;
180 }
181
182 inline void setGenerated(bool b)
183 {
184 if (b != m_generated) {
186 m_generated = b;
187 }
188 }
189
193
194 inline v3s16 getPos()
195 {
196 return m_pos;
197 }
198
200 {
201 return m_pos_relative;
202 }
203
204 inline core::aabbox3d<s16> getBox() {
205 return getBox(getPosRelative());
206 }
207
208 static inline core::aabbox3d<s16> getBox(const v3s16 &pos_relative)
209 {
210 return core::aabbox3d<s16>(pos_relative,
211 pos_relative
213 - v3s16(1,1,1));
214 }
215
219
220 inline bool isValidPosition(s16 x, s16 y, s16 z)
221 {
222 return x >= 0 && x < MAP_BLOCKSIZE
223 && y >= 0 && y < MAP_BLOCKSIZE
224 && z >= 0 && z < MAP_BLOCKSIZE;
225 }
226
228 {
229 return isValidPosition(p.X, p.Y, p.Z);
230 }
231
232 inline MapNode getNode(s16 x, s16 y, s16 z, bool *valid_position)
233 {
234 *valid_position = isValidPosition(x, y, z);
235
236 if (!*valid_position)
237 return {CONTENT_IGNORE};
238
239 return data[z * zstride + y * ystride + x];
240 }
241
242 inline MapNode getNode(v3s16 p, bool *valid_position)
243 {
244 return getNode(p.X, p.Y, p.Z, valid_position);
245 }
246
248 {
249 bool is_valid;
250 return getNode(p.X, p.Y, p.Z, &is_valid);
251 }
252
253 inline void setNode(s16 x, s16 y, s16 z, MapNode n)
254 {
255 if (!isValidPosition(x, y, z))
257
258 data[z * zstride + y * ystride + x] = n;
260 }
261
262 inline void setNode(v3s16 p, MapNode n)
263 {
264 setNode(p.X, p.Y, p.Z, n);
265 }
266
270
271 inline MapNode getNodeNoCheck(s16 x, s16 y, s16 z)
272 {
273 return data[z * zstride + y * ystride + x];
274 }
275
277 {
278 return getNodeNoCheck(p.X, p.Y, p.Z);
279 }
280
281 inline void setNodeNoCheck(s16 x, s16 y, s16 z, MapNode n)
282 {
283 data[z * zstride + y * ystride + x] = n;
285 }
286
288 {
289 setNodeNoCheck(p.X, p.Y, p.Z, n);
290 }
291
292 // Copies data to VoxelManipulator to getPosRelative()
293 void copyTo(VoxelManipulator &dst);
294
295 // Copies data from VoxelManipulator to getPosRelative()
296 void copyFrom(const VoxelManipulator &src);
297
298 // Update is air flag.
299 // Sets m_is_air to appropriate value.
300 void actuallyUpdateIsAir();
301
302 // Call this to schedule what the previous function does to be done
303 // when the value is actually needed.
304 void expireIsAirCache();
305
306 inline bool isAir()
307 {
310 return m_is_air;
311 }
312
313 bool onObjectsActivation();
314 bool saveStaticObject(u16 id, const StaticObject &obj, u32 reason);
315
316 void step(float dtime, const std::function<bool(v3s16, MapNode, f32)> &on_timer_cb);
317
321
322 // NOTE: BLOCK_TIMESTAMP_UNDEFINED=0xffffffff means there is no timestamp.
323
329
330 inline void setTimestampNoChangedFlag(u32 time)
331 {
332 m_timestamp = time;
333 }
334
335 inline u32 getTimestamp()
336 {
337 return m_timestamp;
338 }
339
340 inline u32 getDiskTimestamp()
341 {
342 return m_disk_timestamp;
343 }
344
348
349 inline void resetUsageTimer()
350 {
351 m_usage_timer = 0;
352 }
353
354 inline void incrementUsageTimer(float dtime)
355 {
356 m_usage_timer += dtime;
357 }
358
359 inline float getUsageTimer()
360 {
361 return m_usage_timer;
362 }
363
367
368 inline void refGrab()
369 {
370 assert(m_refcount < SHRT_MAX);
371 m_refcount++;
372 }
373
374 inline void refDrop()
375 {
376 assert(m_refcount > 0);
377 m_refcount--;
378 }
379
380 inline short refGet()
381 {
382 return m_refcount;
383 }
384
388
390 {
391 return m_node_timers.get(p);
392 }
393
395 {
397 }
398
399 inline void setNodeTimer(const NodeTimer &t)
400 {
402 }
403
404 inline void clearNodeTimers()
405 {
407 }
408
412
413 // These don't write or read version by itself
414 // Set disk to true for on-disk format, false for over-the-network format
415 // Precondition: version >= SER_FMT_VER_LOWEST_WRITE
416 void serialize(std::ostream &result, u8 version, bool disk, int compression_level);
417 // If disk == true: In addition to doing other things, will add
418 // unknown blocks from id-name mapping to wndef
419 void deSerialize(std::istream &is, u8 version, bool disk);
420
421 void serializeNetworkSpecific(std::ostream &os);
422 void deSerializeNetworkSpecific(std::istream &is);
423
424 bool storeActiveObject(u16 id);
425 // clearObject and return removed objects count
426 u32 clearObjects();
427
428 static const u32 ystride = MAP_BLOCKSIZE;
429 static const u32 zstride = MAP_BLOCKSIZE * MAP_BLOCKSIZE;
430
432
433private:
434 /*
435 Private methods
436 */
437
438 void deSerialize_pre22(std::istream &is, u8 version, bool disk);
439
440 /*
441 * PLEASE NOTE: When adding something here be mindful of position and size
442 * of member variables! This is also the reason for the weird public-private
443 * interleaving.
444 * If in doubt consult `pahole` to see the effects.
445 */
446
447public:
448#if CHECK_CLIENT_BUILD() // Only on client
449 MapBlockMesh *mesh = nullptr;
450
451 // marks the sides which are opaque: 00+Z-Z+Y-Y+X-X
452 u8 solid_sides = 0;
453#endif
454
455private:
456 // see isOrphan()
457 bool m_orphan = false;
458
459 // Position in blocks on parent
461
462 /* Precalculated m_pos_relative value
463 * This caches the value, improving performance by removing 3 s16 multiplications
464 * at runtime on each getPosRelative call.
465 * For a 5 minutes runtime with valgrind this removes 3 * 19M s16 multiplications.
466 * The gain can be estimated in Release Build to 3 * 100M multiply operations for 5 mins.
467 */
469
470 /*
471 Reference count; currently used for determining if this block is in
472 the list of blocks to be drawn.
473 */
474 short m_refcount = 0;
475
476 /*
477 * Note that this is not an inline array because that has implications for
478 * heap fragmentation (the array is exactly 16K), CPU caches and/or
479 * optimizability of algorithms working on this array.
480 */
481 MapNode *const data; // of `nodecount` elements
482
483 // provides the item and node definitions
485
486 /*
487 When the block is accessed, this is set to 0.
488 Map will unload the block when this reaches a timeout.
489 */
490 float m_usage_timer = 0;
491
492public:
494 // True if we never want to cache content types for this block
496 // Cache of content types
497 // This is actually a set but for the small sizes we have a vector should be
498 // more efficient.
499 // Can be empty, in which case nothing was cached yet.
500 std::vector<content_t> contents;
501
502private:
503 // Whether day and night lighting differs
504 bool m_is_air = false;
505 bool m_is_air_expired = true;
506
507 /*
508 - On the server, this is used for telling whether the
509 block has been modified from the one on disk.
510 - On the client, this is used for nothing.
511 */
514
515 /*
516 When block is removed from active blocks, this is set to gametime.
517 Value BLOCK_TIMESTAMP_UNDEFINED=0xffffffff means there is no timestamp.
518 */
520 // The on-disk (or to-be on-disk) timestamp value
522
532
533 // Whether mapgen has generated the content of this block (persisted)
534 bool m_generated = false;
535
536 /*
537 When propagating sunlight and the above block doesn't exist,
538 sunlight is assumed if this is false.
539
540 In practice this is set to true if the block is completely
541 undeground with nothing visible above the ground except
542 caves.
543 */
544 bool is_underground = false;
545
546public:
549
550private:
552};
553
554typedef std::vector<MapBlock*> MapBlockVect;
555
557{
558 const float max_limit_bs = (MAX_MAP_GENERATION_LIMIT + 0.5f) * BS;
559 return p.X < -max_limit_bs ||
560 p.X > max_limit_bs ||
561 p.Y < -max_limit_bs ||
562 p.Y > max_limit_bs ||
563 p.Z < -max_limit_bs ||
564 p.Z > max_limit_bs;
565}
566
568{
569 const s16 max_limit_bp = MAX_MAP_GENERATION_LIMIT / MAP_BLOCKSIZE;
570 return p.X < -max_limit_bp ||
571 p.X > max_limit_bp ||
572 p.Y < -max_limit_bp ||
573 p.Y > max_limit_bp ||
574 p.Z < -max_limit_bp ||
575 p.Z > max_limit_bp;
576}
577
578/*
579 Returns the position of the block where the node is located
580*/
585
586inline void getNodeBlockPosWithOffset(v3s16 p, v3s16 &block, v3s16 &offset)
587{
589}
590
591/*
592 Get a quick string to describe what a block actually contains
593*/
594std::string analyze_block(MapBlock *block);
Definition gamedef.h:36
Definition exceptions.h:108
Definition mapblock_mesh.h:164
Definition mapblock.h:58
bool is_underground
Definition mapblock.h:544
bool m_orphan
Definition mapblock.h:457
u16 getLightingComplete()
Definition mapblock.h:147
bool getIsUnderground()
Definition mapblock.h:128
MapNode *const data
Definition mapblock.h:481
MapNode getNodeNoCheck(s16 x, s16 y, s16 z)
Definition mapblock.h:271
float m_usage_timer
Definition mapblock.h:490
void incrementUsageTimer(float dtime)
Definition mapblock.h:354
void raiseModified(u32 mod, u32 reason=MOD_REASON_UNKNOWN)
Definition mapblock.h:91
u32 m_disk_timestamp
Definition mapblock.h:521
bool isValidPosition(s16 x, s16 y, s16 z)
Definition mapblock.h:220
void removeNodeTimer(v3s16 p)
Definition mapblock.h:394
void setTimestamp(u32 time)
Definition mapblock.h:324
v3s16 getPos()
Definition mapblock.h:194
static const u32 ystride
Definition mapblock.h:428
short refGet()
Definition mapblock.h:380
void clearNodeTimers()
Definition mapblock.h:404
void setTimestampNoChangedFlag(u32 time)
Definition mapblock.h:330
u32 getModified()
Definition mapblock.h:105
MapNode getNodeNoEx(v3s16 p)
Definition mapblock.h:247
v3s16 m_pos_relative
Definition mapblock.h:468
u32 m_timestamp
Definition mapblock.h:519
v3s16 m_pos
Definition mapblock.h:460
void reallocate()
Definition mapblock.h:76
void setGenerated(bool b)
Definition mapblock.h:182
NodeMetadataList m_node_metadata
Definition mapblock.h:547
bool isLightingComplete(LightBank bank, u8 direction)
Definition mapblock.h:168
u32 clearObjects()
Definition mapblock.cpp:592
MapNode getNode(s16 x, s16 y, s16 z, bool *valid_position)
Definition mapblock.h:232
u32 m_modified_reason
Definition mapblock.h:513
bool m_is_air
Definition mapblock.h:504
u16 m_modified
Definition mapblock.h:512
void setNode(s16 x, s16 y, s16 z, MapNode n)
Definition mapblock.h:253
v3s16 getPosRelative()
Definition mapblock.h:199
float getUsageTimer()
Definition mapblock.h:359
bool isGenerated()
Definition mapblock.h:177
bool m_generated
Definition mapblock.h:534
void setNodeNoCheck(v3s16 p, MapNode n)
Definition mapblock.h:287
static const u32 nodecount
Definition mapblock.h:431
void resetModified()
Definition mapblock.h:117
void copyTo(VoxelManipulator &dst)
Definition mapblock.cpp:156
void makeOrphan()
Definition mapblock.h:71
static const u32 zstride
Definition mapblock.h:429
void deSerialize_pre22(std::istream &is, u8 version, bool disk)
Definition mapblock.cpp:605
void refDrop()
Definition mapblock.h:374
bool m_is_air_expired
Definition mapblock.h:505
StaticObjectList m_static_objects
Definition mapblock.h:548
bool saveStaticObject(u16 id, const StaticObject &obj, u32 reason)
Definition mapblock.cpp:100
MapNode getNode(v3s16 p, bool *valid_position)
Definition mapblock.h:242
bool isValidPosition(v3s16 p)
Definition mapblock.h:227
void setNodeNoCheck(s16 x, s16 y, s16 z, MapNode n)
Definition mapblock.h:281
void serialize(std::ostream &result, u8 version, bool disk, int compression_level)
Serialization.
Definition mapblock.cpp:308
bool isAir()
Definition mapblock.h:306
u32 getDiskTimestamp()
Definition mapblock.h:340
bool isOrphan() const
Definition mapblock.h:66
std::vector< content_t > contents
Definition mapblock.h:500
u16 m_lighting_complete
Definition mapblock.h:531
u32 getTimestamp()
Definition mapblock.h:335
std::string getModifiedReasonString()
Definition mapblock.cpp:134
void setLightingComplete(u16 newflags)
Definition mapblock.h:139
NodeTimer getNodeTimer(v3s16 p)
Definition mapblock.h:389
MapNode * getData()
Definition mapblock.h:83
void deSerialize(std::istream &is, u8 version, bool disk)
Definition mapblock.cpp:422
void resetUsageTimer()
Definition mapblock.h:349
void setLightingComplete(LightBank bank, u8 direction, bool is_complete)
Definition mapblock.h:152
void copyFrom(const VoxelManipulator &src)
Definition mapblock.cpp:166
void setNode(v3s16 p, MapNode n)
Definition mapblock.h:262
bool onObjectsActivation()
Definition mapblock.cpp:76
MapNode getNodeNoCheck(v3s16 p)
Definition mapblock.h:276
bool storeActiveObject(u16 id)
Definition mapblock.cpp:581
void deSerializeNetworkSpecific(std::istream &is)
Definition mapblock.cpp:567
MapBlock(v3s16 pos, IGameDef *gamedef)
Definition mapblock.cpp:53
void refGrab()
Definition mapblock.h:368
void setIsUnderground(bool a_is_underground)
Definition mapblock.h:133
u32 getModifiedReason()
Definition mapblock.h:110
void serializeNetworkSpecific(std::ostream &os)
Definition mapblock.cpp:417
~MapBlock()
Definition mapblock.cpp:63
void expireIsAirCache()
Definition mapblock.cpp:194
bool do_not_cache_contents
Definition mapblock.h:495
void setNodeTimer(const NodeTimer &t)
Definition mapblock.h:399
NodeTimerList m_node_timers
Definition mapblock.h:551
void actuallyUpdateIsAir()
Definition mapblock.cpp:176
IGameDef * m_gamedef
Definition mapblock.h:484
static core::aabbox3d< s16 > getBox(const v3s16 &pos_relative)
Definition mapblock.h:208
short m_refcount
Definition mapblock.h:474
core::aabbox3d< s16 > getBox()
Definition mapblock.h:204
void step(float dtime, const std::function< bool(v3s16, MapNode, f32)> &on_timer_cb)
Definition mapblock.cpp:118
Definition map.h:101
Definition nodemetadata.h:65
Definition nodetimer.h:43
void remove(v3s16 p)
Definition nodetimer.h:62
void set(const NodeTimer &timer)
Definition nodetimer.h:90
NodeTimer get(const v3s16 &p)
Definition nodetimer.h:52
void clear()
Definition nodetimer.h:95
Definition nodetimer.h:21
Definition staticobject.h:30
Definition voxel.h:360
#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:554
v3s16 getNodeBlockPos(v3s16 p)
Definition mapblock.h:581
bool objectpos_over_limit(v3f p)
Definition mapblock.h:556
std::string analyze_block(MapBlock *block)
Definition mapblock.cpp:812
#define BLOCK_TIMESTAMP_UNDEFINED
Definition mapblock.h:25
void getNodeBlockPosWithOffset(v3s16 p, v3s16 &block, v3s16 &offset)
Definition mapblock.h:586
bool blockpos_over_max_limit(v3s16 p)
Definition mapblock.h:567
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_REALLOCATE
Definition mapblock.h:32
@ 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:58
LightBank
Definition mapnode.h:80
@ LIGHTBANK_NIGHT
Definition mapnode.h:82
@ 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:31
void getContainerPosWithOffset(s16 p, s16 d, s16 &container, s16 &offset)
Definition numeric.h:70
Definition mapnode.h:124
Definition staticobject.h:17
static std::string p(std::string path)
Definition test_filesys.cpp:53