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