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