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