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