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