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