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