Map generation is now properly threaded and doesn't block block placement and other...
[oweals/minetest.git] / src / map.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010 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 General Public License as published by
7 the Free Software Foundation; either version 2 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 General Public License for more details.
14
15 You should have received a copy of the GNU 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 <jmutex.h>
24 #include <jthread.h>
25 #include <iostream>
26
27 #ifdef _WIN32
28         #include <windows.h>
29         #define sleep_s(x) Sleep((x*1000))
30 #else
31         #include <unistd.h>
32         #define sleep_s(x) sleep(x)
33 #endif
34
35 #include "common_irrlicht.h"
36 #include "mapnode.h"
37 #include "mapblock.h"
38 #include "mapsector.h"
39 #include "constants.h"
40 #include "voxel.h"
41 #include "mapchunk.h"
42 #include "nodemetadata.h"
43
44 #define MAPTYPE_BASE 0
45 #define MAPTYPE_SERVER 1
46 #define MAPTYPE_CLIENT 2
47
48 enum MapEditEventType{
49         MEET_ADDNODE,
50         MEET_REMOVENODE,
51         MEET_OTHER
52 };
53
54 struct MapEditEvent
55 {
56         MapEditEventType type;
57         v3s16 p;
58         MapNode n;
59         core::map<v3s16, bool> modified_blocks;
60         u16 already_known_by_peer;
61
62         MapEditEvent():
63                 type(MEET_OTHER),
64                 already_known_by_peer(0)
65         {
66         }
67         
68         MapEditEvent * clone()
69         {
70                 MapEditEvent *event = new MapEditEvent();
71                 event->type = type;
72                 event->p = p;
73                 event->n = n;
74                 for(core::map<v3s16, bool>::Iterator
75                                 i = modified_blocks.getIterator();
76                                 i.atEnd()==false; i++)
77                 {
78                         v3s16 p = i.getNode()->getKey();
79                         bool v = i.getNode()->getValue();
80                         event->modified_blocks.insert(p, v);
81                 }
82                 return event;
83         }
84 };
85
86 class MapEventReceiver
87 {
88 public:
89         // event shall be deleted by caller after the call.
90         virtual void onMapEditEvent(MapEditEvent *event) = 0;
91 };
92
93 class Map : public NodeContainer
94 {
95 public:
96
97         Map(std::ostream &dout);
98         virtual ~Map();
99
100         virtual u16 nodeContainerId() const
101         {
102                 return NODECONTAINER_ID_MAP;
103         }
104
105         virtual s32 mapType() const
106         {
107                 return MAPTYPE_BASE;
108         }
109         
110         /*
111                 Drop (client) or delete (server) the map.
112         */
113         virtual void drop()
114         {
115                 delete this;
116         }
117
118         void addEventReceiver(MapEventReceiver *event_receiver);
119         void removeEventReceiver(MapEventReceiver *event_receiver);
120         // event shall be deleted by caller after the call.
121         void dispatchEvent(MapEditEvent *event);
122
123         // On failure returns NULL
124         MapSector * getSectorNoGenerateNoExNoLock(v2s16 p2d);
125         // On failure returns NULL
126         MapSector * getSectorNoGenerateNoEx(v2s16 p2d);
127         // On failure throws InvalidPositionException
128         MapSector * getSectorNoGenerate(v2s16 p2d);
129         // Gets an existing sector or creates an empty one
130         //MapSector * getSectorCreate(v2s16 p2d);
131
132         /*
133                 This is overloaded by ClientMap and ServerMap to allow
134                 their differing fetch methods.
135         */
136         virtual MapSector * emergeSector(v2s16 p){ return NULL; }
137         virtual MapSector * emergeSector(v2s16 p,
138                         core::map<v3s16, MapBlock*> &changed_blocks){ return NULL; }
139
140         // Returns InvalidPositionException if not found
141         MapBlock * getBlockNoCreate(v3s16 p);
142         // Returns NULL if not found
143         MapBlock * getBlockNoCreateNoEx(v3s16 p);
144         // Gets an existing block or creates an empty one
145         //MapBlock * getBlockCreate(v3s16 p);
146         
147         // Returns InvalidPositionException if not found
148         bool isNodeUnderground(v3s16 p);
149         
150         // virtual from NodeContainer
151         bool isValidPosition(v3s16 p)
152         {
153                 v3s16 blockpos = getNodeBlockPos(p);
154                 MapBlock *blockref;
155                 try{
156                         blockref = getBlockNoCreate(blockpos);
157                 }
158                 catch(InvalidPositionException &e)
159                 {
160                         return false;
161                 }
162                 return true;
163                 /*v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
164                 bool is_valid = blockref->isValidPosition(relpos);
165                 return is_valid;*/
166         }
167         
168         // virtual from NodeContainer
169         // throws InvalidPositionException if not found
170         MapNode getNode(v3s16 p)
171         {
172                 v3s16 blockpos = getNodeBlockPos(p);
173                 MapBlock * blockref = getBlockNoCreate(blockpos);
174                 v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
175
176                 return blockref->getNodeNoCheck(relpos);
177         }
178
179         // virtual from NodeContainer
180         // throws InvalidPositionException if not found
181         void setNode(v3s16 p, MapNode & n)
182         {
183                 v3s16 blockpos = getNodeBlockPos(p);
184                 MapBlock * blockref = getBlockNoCreate(blockpos);
185                 v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
186                 blockref->setNodeNoCheck(relpos, n);
187         }
188         
189         // Returns a CONTENT_IGNORE node if not found
190         MapNode getNodeNoEx(v3s16 p)
191         {
192                 try{
193                         v3s16 blockpos = getNodeBlockPos(p);
194                         MapBlock * blockref = getBlockNoCreate(blockpos);
195                         v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
196
197                         return blockref->getNodeNoCheck(relpos);
198                 }
199                 catch(InvalidPositionException &e)
200                 {
201                         return MapNode(CONTENT_IGNORE);
202                 }
203         }
204
205         void unspreadLight(enum LightBank bank,
206                         core::map<v3s16, u8> & from_nodes,
207                         core::map<v3s16, bool> & light_sources,
208                         core::map<v3s16, MapBlock*> & modified_blocks);
209
210         void unLightNeighbors(enum LightBank bank,
211                         v3s16 pos, u8 lightwas,
212                         core::map<v3s16, bool> & light_sources,
213                         core::map<v3s16, MapBlock*> & modified_blocks);
214         
215         void spreadLight(enum LightBank bank,
216                         core::map<v3s16, bool> & from_nodes,
217                         core::map<v3s16, MapBlock*> & modified_blocks);
218         
219         void lightNeighbors(enum LightBank bank,
220                         v3s16 pos,
221                         core::map<v3s16, MapBlock*> & modified_blocks);
222
223         v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
224
225         s16 propagateSunlight(v3s16 start,
226                         core::map<v3s16, MapBlock*> & modified_blocks);
227         
228         void updateLighting(enum LightBank bank,
229                         core::map<v3s16, MapBlock*>  & a_blocks,
230                         core::map<v3s16, MapBlock*> & modified_blocks);
231                         
232         void updateLighting(core::map<v3s16, MapBlock*>  & a_blocks,
233                         core::map<v3s16, MapBlock*> & modified_blocks);
234                         
235         /*
236                 These handle lighting but not faces.
237         */
238         void addNodeAndUpdate(v3s16 p, MapNode n,
239                         core::map<v3s16, MapBlock*> &modified_blocks);
240         void removeNodeAndUpdate(v3s16 p,
241                         core::map<v3s16, MapBlock*> &modified_blocks);
242
243         /*
244                 Wrappers for the latter ones.
245                 These emit events.
246                 Return true if succeeded, false if not.
247         */
248         bool addNodeWithEvent(v3s16 p, MapNode n);
249         bool removeNodeWithEvent(v3s16 p);
250         
251         /*
252                 Takes the blocks at the edges into account
253         */
254         bool dayNightDiffed(v3s16 blockpos);
255
256         //core::aabbox3d<s16> getDisplayedBlockArea();
257
258         //bool updateChangedVisibleArea();
259         
260         virtual void save(bool only_changed){assert(0);};
261
262         /*
263                 Updates usage timers
264         */
265         void timerUpdate(float dtime);
266         
267         // Takes cache into account
268         // sector mutex should be locked when calling
269         void deleteSectors(core::list<v2s16> &list, bool only_blocks);
270         
271         // Returns count of deleted sectors
272         u32 deleteUnusedSectors(float timeout, bool only_blocks=false,
273                         core::list<v3s16> *deleted_blocks=NULL);
274
275         // For debug printing
276         virtual void PrintInfo(std::ostream &out);
277         
278         void transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks);
279
280         /*
281                 Node metadata
282                 These are basically coordinate wrappers to MapBlock
283         */
284         
285         NodeMetadata* getNodeMetadata(v3s16 p);
286         void setNodeMetadata(v3s16 p, NodeMetadata *meta);
287         void removeNodeMetadata(v3s16 p);
288         void nodeMetadataStep(float dtime,
289                         core::map<v3s16, MapBlock*> &changed_blocks);
290
291         /*
292                 Variables
293         */
294         
295 protected:
296
297         std::ostream &m_dout;
298
299         core::map<MapEventReceiver*, bool> m_event_receivers;
300         
301         // Mutex is important because on client map is accessed asynchronously
302         core::map<v2s16, MapSector*> m_sectors;
303         JMutex m_sector_mutex;
304
305         // Be sure to set this to NULL when the cached sector is deleted 
306         MapSector *m_sector_cache;
307         v2s16 m_sector_cache_p;
308
309         //WrapperHeightmap m_hwrapper;
310         
311         // Queued transforming water nodes
312         UniqueQueue<v3s16> m_transforming_liquid;
313 };
314
315 /*
316         ServerMap
317
318         This is the only map class that is able to generate map.
319 */
320
321 struct ChunkMakeData;
322
323 class ServerMap : public Map
324 {
325 public:
326         /*
327                 savedir: directory to which map data should be saved
328         */
329         ServerMap(std::string savedir);
330         ~ServerMap();
331
332         s32 mapType() const
333         {
334                 return MAPTYPE_SERVER;
335         }
336
337         /*
338                 Map generation
339         */
340         
341         // Returns the position of the chunk where the sector is in
342         v2s16 sector_to_chunk(v2s16 sectorpos)
343         {
344                 sectorpos.X += m_chunksize / 2;
345                 sectorpos.Y += m_chunksize / 2;
346                 v2s16 chunkpos = getContainerPos(sectorpos, m_chunksize);
347                 return chunkpos;
348         }
349         
350         // Returns the position of the (0,0) sector of the chunk
351         v2s16 chunk_to_sector(v2s16 chunkpos)
352         {
353                 v2s16 sectorpos(
354                         chunkpos.X * m_chunksize,
355                         chunkpos.Y * m_chunksize
356                 );
357                 sectorpos.X -= m_chunksize / 2;
358                 sectorpos.Y -= m_chunksize / 2;
359                 return sectorpos;
360         }
361
362         /*
363                 Get a chunk.
364         */
365         MapChunk *getChunk(v2s16 chunkpos)
366         {
367                 core::map<v2s16, MapChunk*>::Node *n;
368                 n = m_chunks.find(chunkpos);
369                 if(n == NULL)
370                         return NULL;
371                 return n->getValue();
372         }
373
374         /*
375                 True if the chunk and its neighbors are fully generated.
376                 It means the chunk will not be touched in the future by the
377                 generator. If false, generateChunk will make it true.
378         */
379         bool chunkNonVolatile(v2s16 chunkpos)
380         {
381                 /*for(s16 x=-1; x<=1; x++)
382                 for(s16 y=-1; y<=1; y++)*/
383                 s16 x=0;
384                 s16 y=0;
385                 {
386                         v2s16 chunkpos0 = chunkpos + v2s16(x,y);
387                         MapChunk *chunk = getChunk(chunkpos);
388                         if(chunk == NULL)
389                                 return false;
390                         if(chunk->getGenLevel() != GENERATED_FULLY)
391                                 return false;
392                 }
393                 return true;
394         }
395
396         void initChunkMake(ChunkMakeData &data, v2s16 chunkpos);
397         MapChunk* finishChunkMake(ChunkMakeData &data,
398                         core::map<v3s16, MapBlock*> &changed_blocks);
399
400         /*
401                 Generate a chunk.
402
403                 All chunks touching this one can be altered also.
404         */
405         MapChunk* generateChunkRaw(v2s16 chunkpos,
406                         core::map<v3s16, MapBlock*> &changed_blocks,
407                         bool force=false);
408         
409         /*
410                 Generate a chunk and its neighbors so that it won't be touched
411                 anymore.
412         */
413         MapChunk* generateChunk(v2s16 chunkpos,
414                         core::map<v3s16, MapBlock*> &changed_blocks);
415         
416         /*
417                 Generate a sector.
418                 
419                 This is mainly called by generateChunkRaw.
420         */
421         //ServerMapSector * generateSector(v2s16 p);
422         
423         /*
424                 Get a sector from somewhere.
425                 - Check memory
426                 - Check disk (loads blocks also)
427                 - Create blank one
428         */
429         ServerMapSector * createSector(v2s16 p);
430
431         /*
432                 Get a sector from somewhere.
433                 - Check memory
434                 - Check disk (loads blocks also)
435                 - Generate chunk
436         */
437         MapSector * emergeSector(v2s16 p,
438                         core::map<v3s16, MapBlock*> &changed_blocks);
439         
440         MapSector * emergeSector(v2s16 p)
441         {
442                 core::map<v3s16, MapBlock*> changed_blocks;
443                 return emergeSector(p, changed_blocks);
444         }
445
446         MapBlock * generateBlock(
447                         v3s16 p,
448                         MapBlock *original_dummy,
449                         ServerMapSector *sector,
450                         core::map<v3s16, MapBlock*> &changed_blocks,
451                         core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
452         );
453         
454         /*
455                 Get a block from somewhere.
456                 - Memory
457                 - Create blank
458         */
459         MapBlock * createBlock(v3s16 p);
460         
461         /*
462                 only_from_disk, changed_blocks and lighting_invalidated_blocks
463                 are not properly used by the new map generator.
464         */
465         MapBlock * emergeBlock(
466                         v3s16 p,
467                         bool only_from_disk,
468                         core::map<v3s16, MapBlock*> &changed_blocks,
469                         core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
470         );
471
472 #if 0
473         /*
474                 Forcefully get a block from somewhere.
475
476                 Exceptions:
477                 - InvalidPositionException: possible if only_from_disk==true
478                 
479                 changed_blocks:
480                 - All already existing blocks that were modified are added.
481                         - If found on disk, nothing will be added.
482                         - If generated, the new block will not be included.
483
484                 lighting_invalidated_blocks:
485                 - All blocks that have heavy-to-calculate lighting changes
486                   are added.
487                         - updateLighting() should be called for these.
488                 
489                 - A block that is in changed_blocks may not be in
490                   lighting_invalidated_blocks.
491         */
492         MapBlock * emergeBlock(
493                         v3s16 p,
494                         bool only_from_disk,
495                         core::map<v3s16, MapBlock*> &changed_blocks,
496                         core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
497         );
498 #endif
499         
500         // Helper for placing objects on ground level
501         s16 findGroundLevel(v2s16 p2d);
502
503         /*
504                 Misc. helper functions for fiddling with directory and file
505                 names when saving
506         */
507         void createDir(std::string path);
508         void createSaveDir();
509         // returns something like "xxxxxxxx"
510         std::string getSectorSubDir(v2s16 pos);
511         // returns something like "map/sectors/xxxxxxxx"
512         std::string getSectorDir(v2s16 pos);
513         std::string createSectorDir(v2s16 pos);
514         // dirname: final directory name
515         v2s16 getSectorPos(std::string dirname);
516         v3s16 getBlockPos(std::string sectordir, std::string blockfile);
517
518         void save(bool only_changed);
519         void loadAll();
520         
521         // Saves map seed and possibly other stuff
522         void saveMapMeta();
523         void loadMapMeta();
524         
525         void saveChunkMeta();
526         void loadChunkMeta();
527         
528         // The sector mutex should be locked when calling most of these
529         
530         // This only saves sector-specific data such as the heightmap
531         // (no MapBlocks)
532         // DEPRECATED? Sectors have no metadata anymore.
533         void saveSectorMeta(ServerMapSector *sector);
534         MapSector* loadSectorMeta(std::string dirname);
535         
536         // Full load of a sector including all blocks.
537         // returns true on success, false on failure.
538         bool loadSectorFull(v2s16 p2d);
539         // If sector is not found in memory, try to load it from disk.
540         // Returns true if sector now resides in memory
541         //bool deFlushSector(v2s16 p2d);
542         
543         void saveBlock(MapBlock *block);
544         // This will generate a sector with getSector if not found.
545         void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector);
546
547         // For debug printing
548         virtual void PrintInfo(std::ostream &out);
549
550         bool isSavingEnabled(){ return m_map_saving_enabled; }
551
552 private:
553         // Seed used for all kinds of randomness
554         u64 m_seed;
555
556         std::string m_savedir;
557         bool m_map_saving_enabled;
558
559         // Chunk size in MapSectors
560         s16 m_chunksize;
561         // Chunks
562         core::map<v2s16, MapChunk*> m_chunks;
563 };
564
565 /*
566         ClientMap stuff
567 */
568
569 #ifndef SERVER
570
571 struct MapDrawControl
572 {
573         MapDrawControl():
574                 range_all(false),
575                 wanted_range(50),
576                 wanted_max_blocks(0),
577                 wanted_min_range(0),
578                 blocks_drawn(0),
579                 blocks_would_have_drawn(0)
580         {
581         }
582         // Overrides limits by drawing everything
583         bool range_all;
584         // Wanted drawing range
585         float wanted_range;
586         // Maximum number of blocks to draw
587         u32 wanted_max_blocks;
588         // Blocks in this range are drawn regardless of number of blocks drawn
589         float wanted_min_range;
590         // Number of blocks rendered is written here by the renderer
591         u32 blocks_drawn;
592         // Number of blocks that would have been drawn in wanted_range
593         u32 blocks_would_have_drawn;
594 };
595
596 class Client;
597
598 /*
599         ClientMap
600         
601         This is the only map class that is able to render itself on screen.
602 */
603
604 class ClientMap : public Map, public scene::ISceneNode
605 {
606 public:
607         ClientMap(
608                         Client *client,
609                         MapDrawControl &control,
610                         scene::ISceneNode* parent,
611                         scene::ISceneManager* mgr,
612                         s32 id
613         );
614
615         ~ClientMap();
616
617         s32 mapType() const
618         {
619                 return MAPTYPE_CLIENT;
620         }
621
622         void drop()
623         {
624                 ISceneNode::drop();
625         }
626
627         void updateCamera(v3f pos, v3f dir)
628         {
629                 JMutexAutoLock lock(m_camera_mutex);
630                 m_camera_position = pos;
631                 m_camera_direction = dir;
632         }
633
634         /*
635                 Forcefully get a sector from somewhere
636         */
637         MapSector * emergeSector(v2s16 p);
638
639         void deSerializeSector(v2s16 p2d, std::istream &is);
640
641         /*
642                 ISceneNode methods
643         */
644
645         virtual void OnRegisterSceneNode();
646
647         virtual void render()
648         {
649                 video::IVideoDriver* driver = SceneManager->getVideoDriver();
650                 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
651                 renderMap(driver, SceneManager->getSceneNodeRenderPass());
652         }
653         
654         virtual const core::aabbox3d<f32>& getBoundingBox() const
655         {
656                 return m_box;
657         }
658
659         void renderMap(video::IVideoDriver* driver, s32 pass);
660
661         /*
662                 Methods for setting temporary modifications to nodes for
663                 drawing.
664
665                 Returns true if something changed.
666                 
667                 All blocks whose mesh could have been changed are inserted
668                 to affected_blocks.
669         */
670         bool setTempMod(v3s16 p, NodeMod mod,
671                         core::map<v3s16, MapBlock*> *affected_blocks=NULL);
672         bool clearTempMod(v3s16 p,
673                         core::map<v3s16, MapBlock*> *affected_blocks=NULL);
674         // Efficient implementation needs a cache of TempMods
675         //void clearTempMods();
676
677         void expireMeshes(bool only_daynight_diffed);
678         
679         /*
680                 Update the faces of the given block and blocks on the
681                 leading edge.
682         */
683         void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
684         
685         // Update meshes that touch the node
686         //void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
687
688         // For debug printing
689         virtual void PrintInfo(std::ostream &out);
690         
691 private:
692         Client *m_client;
693         
694         core::aabbox3d<f32> m_box;
695         
696         // This is the master heightmap mesh
697         //scene::SMesh *mesh;
698         //JMutex mesh_mutex;
699         
700         MapDrawControl &m_control;
701
702         v3f m_camera_position;
703         v3f m_camera_direction;
704         JMutex m_camera_mutex;
705
706 };
707
708 #endif
709
710 class MapVoxelManipulator : public VoxelManipulator
711 {
712 public:
713         MapVoxelManipulator(Map *map);
714         virtual ~MapVoxelManipulator();
715         
716         virtual void clear()
717         {
718                 VoxelManipulator::clear();
719                 m_loaded_blocks.clear();
720         }
721
722         virtual void emerge(VoxelArea a, s32 caller_id=-1);
723
724         void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
725
726 protected:
727         Map *m_map;
728         /*
729                 key = blockpos
730                 value = block existed when loaded
731         */
732         core::map<v3s16, bool> m_loaded_blocks;
733 };
734
735 class ManualMapVoxelManipulator : public MapVoxelManipulator
736 {
737 public:
738         ManualMapVoxelManipulator(Map *map);
739         virtual ~ManualMapVoxelManipulator();
740
741         void setMap(Map *map)
742         {m_map = map;}
743         
744         virtual void emerge(VoxelArea a, s32 caller_id=-1);
745
746         void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max);
747         
748         // This is much faster with big chunks of generated data
749         void blitBackAll(core::map<v3s16, MapBlock*> * modified_blocks);
750
751 protected:
752         bool m_create_area;
753 };
754
755 struct ChunkMakeData
756 {
757         ManualMapVoxelManipulator vmanip;
758         u64 seed;
759         v2s16 chunkpos;
760         s16 y_blocks_min;
761         s16 y_blocks_max;
762         v2s16 sectorpos_base;
763         s16 sectorpos_base_size;
764         v2s16 sectorpos_bigbase;
765         s16 sectorpos_bigbase_size;
766         s16 max_spread_amount;
767
768         ChunkMakeData():
769                 vmanip(NULL)
770         {}
771 };
772
773 void makeChunk(ChunkMakeData *data);
774
775 #endif
776