Fixed small error in mapnode.cpp (didn't cause any harm though)
[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 (modified_blocks are set unsent)
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         // Client leaves it as no-op.
228         virtual void saveBlock(MapBlock *block){};
229
230         /*
231                 Updates usage timers and unloads unused blocks and sectors.
232                 Saves modified blocks before unloading on MAPTYPE_SERVER.
233         */
234         void timerUpdate(float dtime, float unload_timeout,
235                         core::list<v3s16> *unloaded_blocks=NULL);
236                 
237         // Deletes sectors and their blocks from memory
238         // Takes cache into account
239         // If deleted sector is in sector cache, clears cache
240         void deleteSectors(core::list<v2s16> &list);
241
242 #if 0
243         /*
244                 Unload unused data
245                 = flush changed to disk and delete from memory, if usage timer of
246                   block is more than timeout
247         */
248         void unloadUnusedData(float timeout,
249                         core::list<v3s16> *deleted_blocks=NULL);
250 #endif
251
252         // For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
253         virtual void PrintInfo(std::ostream &out);
254         
255         void transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks);
256
257         /*
258                 Node metadata
259                 These are basically coordinate wrappers to MapBlock
260         */
261         
262         NodeMetadata* getNodeMetadata(v3s16 p);
263         void setNodeMetadata(v3s16 p, NodeMetadata *meta);
264         void removeNodeMetadata(v3s16 p);
265         void nodeMetadataStep(float dtime,
266                         core::map<v3s16, MapBlock*> &changed_blocks);
267         
268         /*
269                 Misc.
270         */
271         core::map<v2s16, MapSector*> *getSectorsPtr(){return &m_sectors;}
272
273         /*
274                 Variables
275         */
276         
277 protected:
278
279         std::ostream &m_dout;
280
281         core::map<MapEventReceiver*, bool> m_event_receivers;
282         
283         core::map<v2s16, MapSector*> m_sectors;
284
285         // Be sure to set this to NULL when the cached sector is deleted 
286         MapSector *m_sector_cache;
287         v2s16 m_sector_cache_p;
288
289         // Queued transforming water nodes
290         UniqueQueue<v3s16> m_transforming_liquid;
291 };
292
293 /*
294         ServerMap
295
296         This is the only map class that is able to generate map.
297 */
298
299 class ServerMap : public Map
300 {
301 public:
302         /*
303                 savedir: directory to which map data should be saved
304         */
305         ServerMap(std::string savedir);
306         ~ServerMap();
307
308         s32 mapType() const
309         {
310                 return MAPTYPE_SERVER;
311         }
312
313         /*
314                 Get a sector from somewhere.
315                 - Check memory
316                 - Check disk (doesn't load blocks)
317                 - Create blank one
318         */
319         ServerMapSector * createSector(v2s16 p);
320
321         /*
322                 Blocks are generated by using these and makeBlock().
323         */
324         void initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos);
325         MapBlock* finishBlockMake(mapgen::BlockMakeData *data,
326                         core::map<v3s16, MapBlock*> &changed_blocks);
327         
328         // A non-threaded wrapper to the above
329         MapBlock * generateBlock(
330                         v3s16 p,
331                         core::map<v3s16, MapBlock*> &modified_blocks
332         );
333         
334         /*
335                 Get a block from somewhere.
336                 - Memory
337                 - Create blank
338         */
339         MapBlock * createBlock(v3s16 p);
340
341         /*
342                 Forcefully get a block from somewhere.
343                 - Memory
344                 - Load from disk
345                 - Generate
346         */
347         MapBlock * emergeBlock(v3s16 p, bool allow_generate=true);
348         
349         // Helper for placing objects on ground level
350         s16 findGroundLevel(v2s16 p2d);
351
352         /*
353                 Misc. helper functions for fiddling with directory and file
354                 names when saving
355         */
356         void createDirs(std::string path);
357         // returns something like "map/sectors/xxxxxxxx"
358         std::string getSectorDir(v2s16 pos, int layout = 2);
359         // dirname: final directory name
360         v2s16 getSectorPos(std::string dirname);
361         v3s16 getBlockPos(std::string sectordir, std::string blockfile);
362         static std::string getBlockFilename(v3s16 p);
363
364         void save(bool only_changed);
365         //void loadAll();
366         
367         // Saves map seed and possibly other stuff
368         void saveMapMeta();
369         void loadMapMeta();
370         
371         /*void saveChunkMeta();
372         void loadChunkMeta();*/
373         
374         // The sector mutex should be locked when calling most of these
375         
376         // This only saves sector-specific data such as the heightmap
377         // (no MapBlocks)
378         // DEPRECATED? Sectors have no metadata anymore.
379         void saveSectorMeta(ServerMapSector *sector);
380         MapSector* loadSectorMeta(std::string dirname, bool save_after_load);
381         bool loadSectorMeta(v2s16 p2d);
382         
383         // Full load of a sector including all blocks.
384         // returns true on success, false on failure.
385         bool loadSectorFull(v2s16 p2d);
386         // If sector is not found in memory, try to load it from disk.
387         // Returns true if sector now resides in memory
388         //bool deFlushSector(v2s16 p2d);
389         
390         void saveBlock(MapBlock *block);
391         // This will generate a sector with getSector if not found.
392         void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector, bool save_after_load=false);
393         MapBlock* loadBlock(v3s16 p);
394
395         // For debug printing
396         virtual void PrintInfo(std::ostream &out);
397
398         bool isSavingEnabled(){ return m_map_saving_enabled; }
399
400         u64 getSeed(){ return m_seed; }
401
402 private:
403         // Seed used for all kinds of randomness
404         u64 m_seed;
405
406         std::string m_savedir;
407         bool m_map_saving_enabled;
408
409 #if 0
410         // Chunk size in MapSectors
411         // If 0, chunks are disabled.
412         s16 m_chunksize;
413         // Chunks
414         core::map<v2s16, MapChunk*> m_chunks;
415 #endif
416
417         /*
418                 Metadata is re-written on disk only if this is true.
419                 This is reset to false when written on disk.
420         */
421         bool m_map_metadata_changed;
422 };
423
424 /*
425         ClientMap stuff
426 */
427
428 #ifndef SERVER
429
430 struct MapDrawControl
431 {
432         MapDrawControl():
433                 range_all(false),
434                 wanted_range(50),
435                 wanted_max_blocks(0),
436                 wanted_min_range(0),
437                 blocks_drawn(0),
438                 blocks_would_have_drawn(0)
439         {
440         }
441         // Overrides limits by drawing everything
442         bool range_all;
443         // Wanted drawing range
444         float wanted_range;
445         // Maximum number of blocks to draw
446         u32 wanted_max_blocks;
447         // Blocks in this range are drawn regardless of number of blocks drawn
448         float wanted_min_range;
449         // Number of blocks rendered is written here by the renderer
450         u32 blocks_drawn;
451         // Number of blocks that would have been drawn in wanted_range
452         u32 blocks_would_have_drawn;
453 };
454
455 class Client;
456
457 /*
458         ClientMap
459         
460         This is the only map class that is able to render itself on screen.
461 */
462
463 class ClientMap : public Map, public scene::ISceneNode
464 {
465 public:
466         ClientMap(
467                         Client *client,
468                         MapDrawControl &control,
469                         scene::ISceneNode* parent,
470                         scene::ISceneManager* mgr,
471                         s32 id
472         );
473
474         ~ClientMap();
475
476         s32 mapType() const
477         {
478                 return MAPTYPE_CLIENT;
479         }
480
481         void drop()
482         {
483                 ISceneNode::drop();
484         }
485
486         void updateCamera(v3f pos, v3f dir)
487         {
488                 JMutexAutoLock lock(m_camera_mutex);
489                 m_camera_position = pos;
490                 m_camera_direction = dir;
491         }
492
493         /*
494                 Forcefully get a sector from somewhere
495         */
496         MapSector * emergeSector(v2s16 p);
497
498         //void deSerializeSector(v2s16 p2d, std::istream &is);
499
500         /*
501                 ISceneNode methods
502         */
503
504         virtual void OnRegisterSceneNode();
505
506         virtual void render()
507         {
508                 video::IVideoDriver* driver = SceneManager->getVideoDriver();
509                 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
510                 renderMap(driver, SceneManager->getSceneNodeRenderPass());
511         }
512         
513         virtual const core::aabbox3d<f32>& getBoundingBox() const
514         {
515                 return m_box;
516         }
517
518         void renderMap(video::IVideoDriver* driver, s32 pass);
519
520         /*
521                 Methods for setting temporary modifications to nodes for
522                 drawing.
523
524                 Returns true if something changed.
525                 
526                 All blocks whose mesh could have been changed are inserted
527                 to affected_blocks.
528         */
529         bool setTempMod(v3s16 p, NodeMod mod,
530                         core::map<v3s16, MapBlock*> *affected_blocks=NULL);
531         bool clearTempMod(v3s16 p,
532                         core::map<v3s16, MapBlock*> *affected_blocks=NULL);
533         // Efficient implementation needs a cache of TempMods
534         //void clearTempMods();
535
536         void expireMeshes(bool only_daynight_diffed);
537         
538         /*
539                 Update the faces of the given block and blocks on the
540                 leading edge.
541         */
542         void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
543         
544         // Update meshes that touch the node
545         //void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
546
547         // For debug printing
548         virtual void PrintInfo(std::ostream &out);
549         
550         // Check if sector was drawn on last render()
551         bool sectorWasDrawn(v2s16 p)
552         {
553                 return (m_last_drawn_sectors.find(p) != NULL);
554         }
555         
556 private:
557         Client *m_client;
558         
559         core::aabbox3d<f32> m_box;
560         
561         // This is the master heightmap mesh
562         //scene::SMesh *mesh;
563         //JMutex mesh_mutex;
564         
565         MapDrawControl &m_control;
566
567         v3f m_camera_position;
568         v3f m_camera_direction;
569         JMutex m_camera_mutex;
570         
571         core::map<v2s16, bool> m_last_drawn_sectors;
572 };
573
574 #endif
575
576 class MapVoxelManipulator : public VoxelManipulator
577 {
578 public:
579         MapVoxelManipulator(Map *map);
580         virtual ~MapVoxelManipulator();
581         
582         virtual void clear()
583         {
584                 VoxelManipulator::clear();
585                 m_loaded_blocks.clear();
586         }
587
588         virtual void emerge(VoxelArea a, s32 caller_id=-1);
589
590         void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
591
592 protected:
593         Map *m_map;
594         /*
595                 key = blockpos
596                 value = block existed when loaded
597         */
598         core::map<v3s16, bool> m_loaded_blocks;
599 };
600
601 class ManualMapVoxelManipulator : public MapVoxelManipulator
602 {
603 public:
604         ManualMapVoxelManipulator(Map *map);
605         virtual ~ManualMapVoxelManipulator();
606
607         void setMap(Map *map)
608         {m_map = map;}
609         
610         virtual void emerge(VoxelArea a, s32 caller_id=-1);
611
612         void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max);
613         
614         // This is much faster with big chunks of generated data
615         void blitBackAll(core::map<v3s16, MapBlock*> * modified_blocks);
616
617 protected:
618         bool m_create_area;
619 };
620
621 #endif
622