b1b3b9aff42aaf94a229951c07cacca028c42abf
[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
289         /*
290                 Variables
291         */
292         
293 protected:
294
295         std::ostream &m_dout;
296
297         core::map<MapEventReceiver*, bool> m_event_receivers;
298         
299         // Mutex is important because on client map is accessed asynchronously
300         core::map<v2s16, MapSector*> m_sectors;
301         JMutex m_sector_mutex;
302
303         // Be sure to set this to NULL when the cached sector is deleted 
304         MapSector *m_sector_cache;
305         v2s16 m_sector_cache_p;
306
307         //WrapperHeightmap m_hwrapper;
308         
309         // Queued transforming water nodes
310         UniqueQueue<v3s16> m_transforming_liquid;
311 };
312
313 /*
314         ServerMap
315
316         This is the only map class that is able to generate map.
317 */
318
319 class ServerMap : public Map
320 {
321 public:
322         /*
323                 savedir: directory to which map data should be saved
324         */
325         ServerMap(std::string savedir);
326         ~ServerMap();
327
328         s32 mapType() const
329         {
330                 return MAPTYPE_SERVER;
331         }
332
333         /*
334                 Map generation
335         */
336         
337         // Returns the position of the chunk where the sector is in
338         v2s16 sector_to_chunk(v2s16 sectorpos)
339         {
340                 sectorpos.X += m_chunksize / 2;
341                 sectorpos.Y += m_chunksize / 2;
342                 v2s16 chunkpos = getContainerPos(sectorpos, m_chunksize);
343                 return chunkpos;
344         }
345         
346         // Returns the position of the (0,0) sector of the chunk
347         v2s16 chunk_to_sector(v2s16 chunkpos)
348         {
349                 v2s16 sectorpos(
350                         chunkpos.X * m_chunksize,
351                         chunkpos.Y * m_chunksize
352                 );
353                 sectorpos.X -= m_chunksize / 2;
354                 sectorpos.Y -= m_chunksize / 2;
355                 return sectorpos;
356         }
357
358         /*
359                 Get a chunk.
360         */
361         MapChunk *getChunk(v2s16 chunkpos)
362         {
363                 core::map<v2s16, MapChunk*>::Node *n;
364                 n = m_chunks.find(chunkpos);
365                 if(n == NULL)
366                         return NULL;
367                 return n->getValue();
368         }
369
370         /*
371                 True if the chunk and its neighbors are fully generated.
372                 It means the chunk will not be touched in the future by the
373                 generator. If false, generateChunk will make it true.
374         */
375         bool chunkNonVolatile(v2s16 chunkpos)
376         {
377                 /*for(s16 x=-1; x<=1; x++)
378                 for(s16 y=-1; y<=1; y++)*/
379                 s16 x=0;
380                 s16 y=0;
381                 {
382                         v2s16 chunkpos0 = chunkpos + v2s16(x,y);
383                         MapChunk *chunk = getChunk(chunkpos);
384                         if(chunk == NULL)
385                                 return false;
386                         if(chunk->getGenLevel() != GENERATED_FULLY)
387                                 return false;
388                 }
389                 return true;
390         }
391
392         /*
393                 Generate a chunk.
394
395                 All chunks touching this one can be altered also.
396         */
397         MapChunk* generateChunkRaw(v2s16 chunkpos,
398                         core::map<v3s16, MapBlock*> &changed_blocks,
399                         bool force=false);
400         
401         /*
402                 Generate a chunk and its neighbors so that it won't be touched
403                 anymore.
404         */
405         MapChunk* generateChunk(v2s16 chunkpos,
406                         core::map<v3s16, MapBlock*> &changed_blocks);
407         
408         /*
409                 Generate a sector.
410                 
411                 This is mainly called by generateChunkRaw.
412         */
413         //ServerMapSector * generateSector(v2s16 p);
414         
415         /*
416                 Get a sector from somewhere.
417                 - Check memory
418                 - Check disk (loads blocks also)
419                 - Create blank one
420         */
421         ServerMapSector * createSector(v2s16 p);
422
423         /*
424                 Get a sector from somewhere.
425                 - Check memory
426                 - Check disk (loads blocks also)
427                 - Generate chunk
428         */
429         MapSector * emergeSector(v2s16 p,
430                         core::map<v3s16, MapBlock*> &changed_blocks);
431         
432         MapSector * emergeSector(v2s16 p)
433         {
434                 core::map<v3s16, MapBlock*> changed_blocks;
435                 return emergeSector(p, changed_blocks);
436         }
437
438         MapBlock * generateBlock(
439                         v3s16 p,
440                         MapBlock *original_dummy,
441                         ServerMapSector *sector,
442                         core::map<v3s16, MapBlock*> &changed_blocks,
443                         core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
444         );
445         
446         /*
447                 Get a block from somewhere.
448                 - Memory
449                 - Create blank
450         */
451         MapBlock * createBlock(v3s16 p);
452         
453         /*
454                 only_from_disk, changed_blocks and lighting_invalidated_blocks
455                 are not properly used by the new map generator.
456         */
457         MapBlock * emergeBlock(
458                         v3s16 p,
459                         bool only_from_disk,
460                         core::map<v3s16, MapBlock*> &changed_blocks,
461                         core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
462         );
463
464 #if 0
465         /*
466                 Forcefully get a block from somewhere.
467
468                 Exceptions:
469                 - InvalidPositionException: possible if only_from_disk==true
470                 
471                 changed_blocks:
472                 - All already existing blocks that were modified are added.
473                         - If found on disk, nothing will be added.
474                         - If generated, the new block will not be included.
475
476                 lighting_invalidated_blocks:
477                 - All blocks that have heavy-to-calculate lighting changes
478                   are added.
479                         - updateLighting() should be called for these.
480                 
481                 - A block that is in changed_blocks may not be in
482                   lighting_invalidated_blocks.
483         */
484         MapBlock * emergeBlock(
485                         v3s16 p,
486                         bool only_from_disk,
487                         core::map<v3s16, MapBlock*> &changed_blocks,
488                         core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
489         );
490 #endif
491         
492         // Helper for placing objects on ground level
493         s16 findGroundLevel(v2s16 p2d);
494
495         /*
496                 Misc. helper functions for fiddling with directory and file
497                 names when saving
498         */
499         void createDir(std::string path);
500         void createSaveDir();
501         // returns something like "xxxxxxxx"
502         std::string getSectorSubDir(v2s16 pos);
503         // returns something like "map/sectors/xxxxxxxx"
504         std::string getSectorDir(v2s16 pos);
505         std::string createSectorDir(v2s16 pos);
506         // dirname: final directory name
507         v2s16 getSectorPos(std::string dirname);
508         v3s16 getBlockPos(std::string sectordir, std::string blockfile);
509
510         void save(bool only_changed);
511         void loadAll();
512         
513         // Saves map seed and possibly other stuff
514         void saveMapMeta();
515         void loadMapMeta();
516         
517         void saveChunkMeta();
518         void loadChunkMeta();
519         
520         // The sector mutex should be locked when calling most of these
521         
522         // This only saves sector-specific data such as the heightmap
523         // (no MapBlocks)
524         // DEPRECATED? Sectors have no metadata anymore.
525         void saveSectorMeta(ServerMapSector *sector);
526         MapSector* loadSectorMeta(std::string dirname);
527         
528         // Full load of a sector including all blocks.
529         // returns true on success, false on failure.
530         bool loadSectorFull(v2s16 p2d);
531         // If sector is not found in memory, try to load it from disk.
532         // Returns true if sector now resides in memory
533         //bool deFlushSector(v2s16 p2d);
534         
535         void saveBlock(MapBlock *block);
536         // This will generate a sector with getSector if not found.
537         void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector);
538
539         // For debug printing
540         virtual void PrintInfo(std::ostream &out);
541
542         bool isSavingEnabled(){ return m_map_saving_enabled; }
543
544 private:
545         // Seed used for all kinds of randomness
546         u64 m_seed;
547
548         std::string m_savedir;
549         bool m_map_saving_enabled;
550
551         // Chunk size in MapSectors
552         s16 m_chunksize;
553         // Chunks
554         core::map<v2s16, MapChunk*> m_chunks;
555 };
556
557 /*
558         ClientMap stuff
559 */
560
561 #ifndef SERVER
562
563 struct MapDrawControl
564 {
565         MapDrawControl():
566                 range_all(false),
567                 wanted_range(50),
568                 wanted_max_blocks(0),
569                 wanted_min_range(0),
570                 blocks_drawn(0),
571                 blocks_would_have_drawn(0)
572         {
573         }
574         // Overrides limits by drawing everything
575         bool range_all;
576         // Wanted drawing range
577         float wanted_range;
578         // Maximum number of blocks to draw
579         u32 wanted_max_blocks;
580         // Blocks in this range are drawn regardless of number of blocks drawn
581         float wanted_min_range;
582         // Number of blocks rendered is written here by the renderer
583         u32 blocks_drawn;
584         // Number of blocks that would have been drawn in wanted_range
585         u32 blocks_would_have_drawn;
586 };
587
588 class Client;
589
590 /*
591         ClientMap
592         
593         This is the only map class that is able to render itself on screen.
594 */
595
596 class ClientMap : public Map, public scene::ISceneNode
597 {
598 public:
599         ClientMap(
600                         Client *client,
601                         MapDrawControl &control,
602                         scene::ISceneNode* parent,
603                         scene::ISceneManager* mgr,
604                         s32 id
605         );
606
607         ~ClientMap();
608
609         s32 mapType() const
610         {
611                 return MAPTYPE_CLIENT;
612         }
613
614         void drop()
615         {
616                 ISceneNode::drop();
617         }
618
619         void updateCamera(v3f pos, v3f dir)
620         {
621                 JMutexAutoLock lock(m_camera_mutex);
622                 m_camera_position = pos;
623                 m_camera_direction = dir;
624         }
625
626         /*
627                 Forcefully get a sector from somewhere
628         */
629         MapSector * emergeSector(v2s16 p);
630
631         void deSerializeSector(v2s16 p2d, std::istream &is);
632
633         /*
634                 ISceneNode methods
635         */
636
637         virtual void OnRegisterSceneNode();
638
639         virtual void render()
640         {
641                 video::IVideoDriver* driver = SceneManager->getVideoDriver();
642                 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
643                 renderMap(driver, SceneManager->getSceneNodeRenderPass());
644         }
645         
646         virtual const core::aabbox3d<f32>& getBoundingBox() const
647         {
648                 return m_box;
649         }
650
651         void renderMap(video::IVideoDriver* driver, s32 pass);
652
653         /*
654                 Methods for setting temporary modifications to nodes for
655                 drawing.
656
657                 Returns true if something changed.
658                 
659                 All blocks whose mesh could have been changed are inserted
660                 to affected_blocks.
661         */
662         bool setTempMod(v3s16 p, NodeMod mod,
663                         core::map<v3s16, MapBlock*> *affected_blocks=NULL);
664         bool clearTempMod(v3s16 p,
665                         core::map<v3s16, MapBlock*> *affected_blocks=NULL);
666         // Efficient implementation needs a cache of TempMods
667         //void clearTempMods();
668
669         void expireMeshes(bool only_daynight_diffed);
670         
671         /*
672                 Update the faces of the given block and blocks on the
673                 leading edge.
674         */
675         void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
676         
677         // Update meshes that touch the node
678         //void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
679
680         // For debug printing
681         virtual void PrintInfo(std::ostream &out);
682         
683 private:
684         Client *m_client;
685         
686         core::aabbox3d<f32> m_box;
687         
688         // This is the master heightmap mesh
689         //scene::SMesh *mesh;
690         //JMutex mesh_mutex;
691         
692         MapDrawControl &m_control;
693
694         v3f m_camera_position;
695         v3f m_camera_direction;
696         JMutex m_camera_mutex;
697
698 };
699
700 #endif
701
702 class MapVoxelManipulator : public VoxelManipulator
703 {
704 public:
705         MapVoxelManipulator(Map *map);
706         virtual ~MapVoxelManipulator();
707         
708         virtual void clear()
709         {
710                 VoxelManipulator::clear();
711                 m_loaded_blocks.clear();
712         }
713
714         virtual void emerge(VoxelArea a, s32 caller_id=-1);
715
716         void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
717
718 protected:
719         Map *m_map;
720         /*
721                 key = blockpos
722                 value = block existed when loaded
723         */
724         core::map<v3s16, bool> m_loaded_blocks;
725 };
726
727 class ManualMapVoxelManipulator : public MapVoxelManipulator
728 {
729 public:
730         ManualMapVoxelManipulator(Map *map);
731         virtual ~ManualMapVoxelManipulator();
732         
733         virtual void emerge(VoxelArea a, s32 caller_id=-1);
734
735         void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max);
736         
737         // This is much faster with big chunks of generated data
738         void blitBackAll(core::map<v3s16, MapBlock*> * modified_blocks);
739
740 protected:
741         bool m_create_area;
742 };
743
744 #endif
745