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