Line data Source code
1 : /*
2 : Minetest
3 : Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 :
5 : This program is free software; you can redistribute it and/or modify
6 : it under the terms of the GNU Lesser General Public License as published by
7 : the Free Software Foundation; either version 2.1 of the License, or
8 : (at your option) any later version.
9 :
10 : This program is distributed in the hope that it will be useful,
11 : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : GNU Lesser General Public License for more details.
14 :
15 : You should have received a copy of the GNU Lesser General Public License along
16 : with this program; if not, write to the Free Software Foundation, Inc.,
17 : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #ifndef MAP_HEADER
21 : #define MAP_HEADER
22 :
23 : #include <iostream>
24 : #include <sstream>
25 : #include <set>
26 : #include <map>
27 : #include <list>
28 :
29 : #include "irrlichttypes_bloated.h"
30 : #include "mapnode.h"
31 : #include "constants.h"
32 : #include "voxel.h"
33 : #include "modifiedstate.h"
34 : #include "util/container.h"
35 : #include "nodetimer.h"
36 :
37 : class Settings;
38 : class Database;
39 : class ClientMap;
40 : class MapSector;
41 : class ServerMapSector;
42 : class MapBlock;
43 : class NodeMetadata;
44 : class IGameDef;
45 : class IRollbackManager;
46 : class EmergeManager;
47 : class ServerEnvironment;
48 : struct BlockMakeData;
49 : struct MapgenParams;
50 :
51 :
52 : /*
53 : MapEditEvent
54 : */
55 :
56 : #define MAPTYPE_BASE 0
57 : #define MAPTYPE_SERVER 1
58 : #define MAPTYPE_CLIENT 2
59 :
60 : enum MapEditEventType{
61 : // Node added (changed from air or something else to something)
62 : MEET_ADDNODE,
63 : // Node removed (changed to air)
64 : MEET_REMOVENODE,
65 : // Node swapped (changed without metadata change)
66 : MEET_SWAPNODE,
67 : // Node metadata of block changed (not knowing which node exactly)
68 : // p stores block coordinate
69 : MEET_BLOCK_NODE_METADATA_CHANGED,
70 : // Anything else (modified_blocks are set unsent)
71 : MEET_OTHER
72 : };
73 :
74 0 : struct MapEditEvent
75 : {
76 : MapEditEventType type;
77 : v3s16 p;
78 : MapNode n;
79 : std::set<v3s16> modified_blocks;
80 : u16 already_known_by_peer;
81 :
82 0 : MapEditEvent():
83 : type(MEET_OTHER),
84 : n(CONTENT_AIR),
85 0 : already_known_by_peer(0)
86 0 : { }
87 :
88 0 : MapEditEvent * clone()
89 : {
90 0 : MapEditEvent *event = new MapEditEvent();
91 0 : event->type = type;
92 0 : event->p = p;
93 0 : event->n = n;
94 0 : event->modified_blocks = modified_blocks;
95 0 : return event;
96 : }
97 :
98 0 : VoxelArea getArea()
99 : {
100 0 : switch(type){
101 : case MEET_ADDNODE:
102 0 : return VoxelArea(p);
103 : case MEET_REMOVENODE:
104 0 : return VoxelArea(p);
105 : case MEET_SWAPNODE:
106 0 : return VoxelArea(p);
107 : case MEET_BLOCK_NODE_METADATA_CHANGED:
108 : {
109 0 : v3s16 np1 = p*MAP_BLOCKSIZE;
110 0 : v3s16 np2 = np1 + v3s16(1,1,1)*MAP_BLOCKSIZE - v3s16(1,1,1);
111 0 : return VoxelArea(np1, np2);
112 : }
113 : case MEET_OTHER:
114 : {
115 0 : VoxelArea a;
116 0 : for(std::set<v3s16>::iterator
117 0 : i = modified_blocks.begin();
118 0 : i != modified_blocks.end(); ++i)
119 : {
120 0 : v3s16 p = *i;
121 0 : v3s16 np1 = p*MAP_BLOCKSIZE;
122 0 : v3s16 np2 = np1 + v3s16(1,1,1)*MAP_BLOCKSIZE - v3s16(1,1,1);
123 0 : a.addPoint(np1);
124 0 : a.addPoint(np2);
125 : }
126 0 : return a;
127 : }
128 : }
129 0 : return VoxelArea();
130 : }
131 : };
132 :
133 0 : class MapEventReceiver
134 : {
135 : public:
136 : // event shall be deleted by caller after the call.
137 : virtual void onMapEditEvent(MapEditEvent *event) = 0;
138 : };
139 :
140 : class Map /*: public NodeContainer*/
141 : {
142 : public:
143 :
144 : Map(std::ostream &dout, IGameDef *gamedef);
145 : virtual ~Map();
146 :
147 : /*virtual u16 nodeContainerId() const
148 : {
149 : return NODECONTAINER_ID_MAP;
150 : }*/
151 :
152 0 : virtual s32 mapType() const
153 : {
154 0 : return MAPTYPE_BASE;
155 : }
156 :
157 : /*
158 : Drop (client) or delete (server) the map.
159 : */
160 0 : virtual void drop()
161 : {
162 0 : delete this;
163 0 : }
164 :
165 : void addEventReceiver(MapEventReceiver *event_receiver);
166 : void removeEventReceiver(MapEventReceiver *event_receiver);
167 : // event shall be deleted by caller after the call.
168 : void dispatchEvent(MapEditEvent *event);
169 :
170 : // On failure returns NULL
171 : MapSector * getSectorNoGenerateNoExNoLock(v2s16 p2d);
172 : // Same as the above (there exists no lock anymore)
173 : MapSector * getSectorNoGenerateNoEx(v2s16 p2d);
174 : // On failure throws InvalidPositionException
175 : MapSector * getSectorNoGenerate(v2s16 p2d);
176 : // Gets an existing sector or creates an empty one
177 : //MapSector * getSectorCreate(v2s16 p2d);
178 :
179 : /*
180 : This is overloaded by ClientMap and ServerMap to allow
181 : their differing fetch methods.
182 : */
183 0 : virtual MapSector * emergeSector(v2s16 p){ return NULL; }
184 0 : virtual MapSector * emergeSector(v2s16 p,
185 0 : std::map<v3s16, MapBlock*> &changed_blocks){ return NULL; }
186 :
187 : // Returns InvalidPositionException if not found
188 : MapBlock * getBlockNoCreate(v3s16 p);
189 : // Returns NULL if not found
190 : MapBlock * getBlockNoCreateNoEx(v3s16 p);
191 :
192 : /* Server overrides */
193 0 : virtual MapBlock * emergeBlock(v3s16 p, bool create_blank=true)
194 0 : { return getBlockNoCreateNoEx(p); }
195 :
196 : // Returns InvalidPositionException if not found
197 : bool isNodeUnderground(v3s16 p);
198 :
199 : bool isValidPosition(v3s16 p);
200 :
201 : // throws InvalidPositionException if not found
202 : void setNode(v3s16 p, MapNode & n);
203 :
204 : // Returns a CONTENT_IGNORE node if not found
205 : // If is_valid_position is not NULL then this will be set to true if the
206 : // position is valid, otherwise false
207 : MapNode getNodeNoEx(v3s16 p, bool *is_valid_position = NULL);
208 :
209 : void unspreadLight(enum LightBank bank,
210 : std::map<v3s16, u8> & from_nodes,
211 : std::set<v3s16> & light_sources,
212 : std::map<v3s16, MapBlock*> & modified_blocks);
213 :
214 : void unLightNeighbors(enum LightBank bank,
215 : v3s16 pos, u8 lightwas,
216 : std::set<v3s16> & light_sources,
217 : std::map<v3s16, MapBlock*> & modified_blocks);
218 :
219 : void spreadLight(enum LightBank bank,
220 : std::set<v3s16> & from_nodes,
221 : std::map<v3s16, MapBlock*> & modified_blocks);
222 :
223 : void lightNeighbors(enum LightBank bank,
224 : v3s16 pos,
225 : std::map<v3s16, MapBlock*> & modified_blocks);
226 :
227 : v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
228 :
229 : s16 propagateSunlight(v3s16 start,
230 : std::map<v3s16, MapBlock*> & modified_blocks);
231 :
232 : void updateLighting(enum LightBank bank,
233 : std::map<v3s16, MapBlock*> & a_blocks,
234 : std::map<v3s16, MapBlock*> & modified_blocks);
235 :
236 : void updateLighting(std::map<v3s16, MapBlock*> & a_blocks,
237 : std::map<v3s16, MapBlock*> & modified_blocks);
238 :
239 : /*
240 : These handle lighting but not faces.
241 : */
242 : void addNodeAndUpdate(v3s16 p, MapNode n,
243 : std::map<v3s16, MapBlock*> &modified_blocks,
244 : bool remove_metadata = true);
245 : void removeNodeAndUpdate(v3s16 p,
246 : std::map<v3s16, MapBlock*> &modified_blocks);
247 :
248 : /*
249 : Wrappers for the latter ones.
250 : These emit events.
251 : Return true if succeeded, false if not.
252 : */
253 : bool addNodeWithEvent(v3s16 p, MapNode n, bool remove_metadata = true);
254 : bool removeNodeWithEvent(v3s16 p);
255 :
256 : /*
257 : Takes the blocks at the edges into account
258 : */
259 : bool getDayNightDiff(v3s16 blockpos);
260 :
261 : //core::aabbox3d<s16> getDisplayedBlockArea();
262 :
263 : //bool updateChangedVisibleArea();
264 :
265 : // Call these before and after saving of many blocks
266 6 : virtual void beginSave() { return; }
267 6 : virtual void endSave() { return; }
268 :
269 0 : virtual void save(ModifiedState save_level) { FATAL_ERROR("FIXME"); }
270 :
271 : // Server implements these.
272 : // Client leaves them as no-op.
273 0 : virtual bool saveBlock(MapBlock *block) { return false; }
274 0 : virtual bool deleteBlock(v3s16 blockpos) { return false; }
275 :
276 : /*
277 : Updates usage timers and unloads unused blocks and sectors.
278 : Saves modified blocks before unloading on MAPTYPE_SERVER.
279 : */
280 : void timerUpdate(float dtime, float unload_timeout,
281 : std::vector<v3s16> *unloaded_blocks=NULL);
282 :
283 : /*
284 : Unloads all blocks with a zero refCount().
285 : Saves modified blocks before unloading on MAPTYPE_SERVER.
286 : */
287 : void unloadUnreferencedBlocks(std::vector<v3s16> *unloaded_blocks=NULL);
288 :
289 : // Deletes sectors and their blocks from memory
290 : // Takes cache into account
291 : // If deleted sector is in sector cache, clears cache
292 : void deleteSectors(std::vector<v2s16> &list);
293 :
294 : // For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
295 : virtual void PrintInfo(std::ostream &out);
296 :
297 : void transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks);
298 :
299 : /*
300 : Node metadata
301 : These are basically coordinate wrappers to MapBlock
302 : */
303 :
304 : std::vector<v3s16> findNodesWithMetadata(v3s16 p1, v3s16 p2);
305 : NodeMetadata *getNodeMetadata(v3s16 p);
306 :
307 : /**
308 : * Sets metadata for a node.
309 : * This method sets the metadata for a given node.
310 : * On success, it returns @c true and the object pointed to
311 : * by @p meta is then managed by the system and should
312 : * not be deleted by the caller.
313 : *
314 : * In case of failure, the method returns @c false and the
315 : * caller is still responsible for deleting the object!
316 : *
317 : * @param p node coordinates
318 : * @param meta pointer to @c NodeMetadata object
319 : * @return @c true on success, false on failure
320 : */
321 : bool setNodeMetadata(v3s16 p, NodeMetadata *meta);
322 : void removeNodeMetadata(v3s16 p);
323 :
324 : /*
325 : Node Timers
326 : These are basically coordinate wrappers to MapBlock
327 : */
328 :
329 : NodeTimer getNodeTimer(v3s16 p);
330 : void setNodeTimer(v3s16 p, NodeTimer t);
331 : void removeNodeTimer(v3s16 p);
332 :
333 : /*
334 : Misc.
335 : */
336 : std::map<v2s16, MapSector*> *getSectorsPtr(){return &m_sectors;}
337 :
338 : /*
339 : Variables
340 : */
341 :
342 : void transforming_liquid_add(v3s16 p);
343 : s32 transforming_liquid_size();
344 :
345 : protected:
346 : friend class LuaVoxelManip;
347 :
348 : std::ostream &m_dout; // A bit deprecated, could be removed
349 :
350 : IGameDef *m_gamedef;
351 :
352 : std::set<MapEventReceiver*> m_event_receivers;
353 :
354 : std::map<v2s16, MapSector*> m_sectors;
355 :
356 : // Be sure to set this to NULL when the cached sector is deleted
357 : MapSector *m_sector_cache;
358 : v2s16 m_sector_cache_p;
359 :
360 : // Queued transforming water nodes
361 : UniqueQueue<v3s16> m_transforming_liquid;
362 :
363 : private:
364 : f32 m_transforming_liquid_loop_count_multiplier;
365 : u32 m_unprocessed_count;
366 : u32 m_inc_trending_up_start_time; // milliseconds
367 : bool m_queue_size_timer_started;
368 : };
369 :
370 : /*
371 : ServerMap
372 :
373 : This is the only map class that is able to generate map.
374 : */
375 :
376 : class ServerMap : public Map
377 : {
378 : public:
379 : /*
380 : savedir: directory to which map data should be saved
381 : */
382 : ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emerge);
383 : ~ServerMap();
384 :
385 0 : s32 mapType() const
386 : {
387 0 : return MAPTYPE_SERVER;
388 : }
389 :
390 : /*
391 : Get a sector from somewhere.
392 : - Check memory
393 : - Check disk (doesn't load blocks)
394 : - Create blank one
395 : */
396 : ServerMapSector * createSector(v2s16 p);
397 :
398 : /*
399 : Blocks are generated by using these and makeBlock().
400 : */
401 : bool initBlockMake(BlockMakeData *data, v3s16 blockpos);
402 : void finishBlockMake(BlockMakeData *data,
403 : std::map<v3s16, MapBlock*> &changed_blocks);
404 :
405 : /*
406 : Get a block from somewhere.
407 : - Memory
408 : - Create blank
409 : */
410 : MapBlock * createBlock(v3s16 p);
411 :
412 : /*
413 : Forcefully get a block from somewhere.
414 : - Memory
415 : - Load from disk
416 : - Create blank filled with CONTENT_IGNORE
417 :
418 : */
419 : MapBlock *emergeBlock(v3s16 p, bool create_blank=true);
420 :
421 : /*
422 : Try to get a block.
423 : If it does not exist in memory, add it to the emerge queue.
424 : - Memory
425 : - Emerge Queue (deferred disk or generate)
426 : */
427 : MapBlock *getBlockOrEmerge(v3s16 p3d);
428 :
429 : // Carries out any initialization necessary before block is sent
430 : void prepareBlock(MapBlock *block);
431 :
432 : // Helper for placing objects on ground level
433 : s16 findGroundLevel(v2s16 p2d);
434 :
435 : /*
436 : Misc. helper functions for fiddling with directory and file
437 : names when saving
438 : */
439 : void createDirs(std::string path);
440 : // returns something like "map/sectors/xxxxxxxx"
441 : std::string getSectorDir(v2s16 pos, int layout = 2);
442 : // dirname: final directory name
443 : v2s16 getSectorPos(std::string dirname);
444 : v3s16 getBlockPos(std::string sectordir, std::string blockfile);
445 : static std::string getBlockFilename(v3s16 p);
446 :
447 : /*
448 : Database functions
449 : */
450 : static Database *createDatabase(const std::string &name, const std::string &savedir, Settings &conf);
451 : // Verify we can read/write to the database
452 : void verifyDatabase();
453 :
454 : // Returns true if the database file does not exist
455 : bool loadFromFolders();
456 :
457 : // Call these before and after saving of blocks
458 : void beginSave();
459 : void endSave();
460 :
461 : void save(ModifiedState save_level);
462 : void listAllLoadableBlocks(std::vector<v3s16> &dst);
463 : void listAllLoadedBlocks(std::vector<v3s16> &dst);
464 : // Saves map seed and possibly other stuff
465 : void saveMapMeta();
466 : void loadMapMeta();
467 :
468 : /*void saveChunkMeta();
469 : void loadChunkMeta();*/
470 :
471 : // The sector mutex should be locked when calling most of these
472 :
473 : // This only saves sector-specific data such as the heightmap
474 : // (no MapBlocks)
475 : // DEPRECATED? Sectors have no metadata anymore.
476 : void saveSectorMeta(ServerMapSector *sector);
477 : MapSector* loadSectorMeta(std::string dirname, bool save_after_load);
478 : bool loadSectorMeta(v2s16 p2d);
479 :
480 : // Full load of a sector including all blocks.
481 : // returns true on success, false on failure.
482 : bool loadSectorFull(v2s16 p2d);
483 : // If sector is not found in memory, try to load it from disk.
484 : // Returns true if sector now resides in memory
485 : //bool deFlushSector(v2s16 p2d);
486 :
487 : bool saveBlock(MapBlock *block);
488 : static bool saveBlock(MapBlock *block, Database *db);
489 : // This will generate a sector with getSector if not found.
490 : void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector, bool save_after_load=false);
491 : MapBlock* loadBlock(v3s16 p);
492 : // Database version
493 : void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false);
494 :
495 : bool deleteBlock(v3s16 blockpos);
496 :
497 : void updateVManip(v3s16 pos);
498 :
499 : // For debug printing
500 : virtual void PrintInfo(std::ostream &out);
501 :
502 0 : bool isSavingEnabled(){ return m_map_saving_enabled; }
503 :
504 : u64 getSeed();
505 : s16 getWaterLevel();
506 :
507 : private:
508 : // Emerge manager
509 : EmergeManager *m_emerge;
510 :
511 : std::string m_savedir;
512 : bool m_map_saving_enabled;
513 :
514 : #if 0
515 : // Chunk size in MapSectors
516 : // If 0, chunks are disabled.
517 : s16 m_chunksize;
518 : // Chunks
519 : core::map<v2s16, MapChunk*> m_chunks;
520 : #endif
521 :
522 : /*
523 : Metadata is re-written on disk only if this is true.
524 : This is reset to false when written on disk.
525 : */
526 : bool m_map_metadata_changed;
527 : Database *dbase;
528 : };
529 :
530 :
531 : #define VMANIP_BLOCK_DATA_INEXIST 1
532 : #define VMANIP_BLOCK_CONTAINS_CIGNORE 2
533 :
534 : class MMVManip : public VoxelManipulator
535 : {
536 : public:
537 : MMVManip(Map *map);
538 : virtual ~MMVManip();
539 :
540 0 : virtual void clear()
541 : {
542 0 : VoxelManipulator::clear();
543 0 : m_loaded_blocks.clear();
544 0 : }
545 :
546 : void setMap(Map *map)
547 : {m_map = map;}
548 :
549 : void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
550 : bool load_if_inexistent = true);
551 :
552 : // This is much faster with big chunks of generated data
553 : void blitBackAll(std::map<v3s16, MapBlock*> * modified_blocks,
554 : bool overwrite_generated = true);
555 :
556 : bool m_is_dirty;
557 :
558 : protected:
559 : bool m_create_area;
560 : Map *m_map;
561 : /*
562 : key = blockpos
563 : value = flags describing the block
564 : */
565 : std::map<v3s16, u8> m_loaded_blocks;
566 : };
567 :
568 : #endif
|