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