787e1240fd6d821ede30b2988c509aed32cc8152
[oweals/minetest.git] / src / map.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010 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 <jthread.h>
25 #include <iostream>
26 #include <malloc.h>
27
28 #ifdef _WIN32
29         #include <windows.h>
30         #define sleep_s(x) Sleep((x*1000))
31 #else
32         #include <unistd.h>
33         #define sleep_s(x) sleep(x)
34 #endif
35
36 #include "common_irrlicht.h"
37 #include "heightmap.h"
38 #include "mapnode.h"
39 #include "mapblock.h"
40 #include "mapsector.h"
41 #include "constants.h"
42 #include "voxel.h"
43
44 #define MAPTYPE_BASE 0
45 #define MAPTYPE_SERVER 1
46 #define MAPTYPE_CLIENT 2
47
48 class Map : public NodeContainer, public Heightmappish
49 {
50 public:
51
52         Map(std::ostream &dout);
53         virtual ~Map();
54
55         virtual u16 nodeContainerId() const
56         {
57                 return NODECONTAINER_ID_MAP;
58         }
59
60         virtual s32 mapType() const
61         {
62                 return MAPTYPE_BASE;
63         }
64
65         virtual void drop()
66         {
67                 delete this;
68         }
69
70         void updateCamera(v3f pos, v3f dir)
71         {
72                 JMutexAutoLock lock(m_camera_mutex);
73                 m_camera_position = pos;
74                 m_camera_direction = dir;
75         }
76
77         static core::aabbox3d<f32> getNodeBox(v3s16 p)
78         {
79                 return core::aabbox3d<f32>(
80                         (float)p.X * BS - 0.5*BS,
81                         (float)p.Y * BS - 0.5*BS,
82                         (float)p.Z * BS - 0.5*BS,
83                         (float)p.X * BS + 0.5*BS,
84                         (float)p.Y * BS + 0.5*BS,
85                         (float)p.Z * BS + 0.5*BS
86                 );
87         }
88
89         //bool sectorExists(v2s16 p);
90         MapSector * getSectorNoGenerate(v2s16 p2d);
91         /*
92                 This is overloaded by ClientMap and ServerMap to allow
93                 their differing fetch methods.
94         */
95         virtual MapSector * emergeSector(v2s16 p) = 0;
96
97         // Returns InvalidPositionException if not found
98         MapBlock * getBlockNoCreate(v3s16 p);
99         // Returns NULL if not found
100         MapBlock * getBlockNoCreateNoEx(v3s16 p);
101         
102         // Returns InvalidPositionException if not found
103         f32 getGroundHeight(v2s16 p, bool generate=false);
104         void setGroundHeight(v2s16 p, f32 y, bool generate=false);
105
106         // Returns InvalidPositionException if not found
107         bool isNodeUnderground(v3s16 p);
108         
109         // virtual from NodeContainer
110         bool isValidPosition(v3s16 p)
111         {
112                 v3s16 blockpos = getNodeBlockPos(p);
113                 MapBlock *blockref;
114                 try{
115                         blockref = getBlockNoCreate(blockpos);
116                 }
117                 catch(InvalidPositionException &e)
118                 {
119                         return false;
120                 }
121                 return true;
122                 /*v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
123                 bool is_valid = blockref->isValidPosition(relpos);
124                 return is_valid;*/
125         }
126         
127         // virtual from NodeContainer
128         // throws InvalidPositionException if not found
129         MapNode getNode(v3s16 p)
130         {
131                 v3s16 blockpos = getNodeBlockPos(p);
132                 MapBlock * blockref = getBlockNoCreate(blockpos);
133                 v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
134
135                 return blockref->getNodeNoCheck(relpos);
136         }
137
138         // virtual from NodeContainer
139         // throws InvalidPositionException if not found
140         void setNode(v3s16 p, MapNode & n)
141         {
142                 v3s16 blockpos = getNodeBlockPos(p);
143                 MapBlock * blockref = getBlockNoCreate(blockpos);
144                 v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
145                 blockref->setNodeNoCheck(relpos, n);
146         }
147
148         /*MapNode getNodeGenerate(v3s16 p)
149         {
150                 v3s16 blockpos = getNodeBlockPos(p);
151                 MapBlock * blockref = getBlock(blockpos);
152                 v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
153
154                 return blockref->getNode(relpos);
155         }*/
156
157         /*void setNodeGenerate(v3s16 p, MapNode & n)
158         {
159                 v3s16 blockpos = getNodeBlockPos(p);
160                 MapBlock * blockref = getBlock(blockpos);
161                 v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
162                 blockref->setNode(relpos, n);
163         }*/
164
165         void unspreadLight(enum LightBank bank,
166                         core::map<v3s16, u8> & from_nodes,
167                         core::map<v3s16, bool> & light_sources,
168                         core::map<v3s16, MapBlock*> & modified_blocks);
169
170         void unLightNeighbors(enum LightBank bank,
171                         v3s16 pos, u8 lightwas,
172                         core::map<v3s16, bool> & light_sources,
173                         core::map<v3s16, MapBlock*> & modified_blocks);
174         
175         void spreadLight(enum LightBank bank,
176                         core::map<v3s16, bool> & from_nodes,
177                         core::map<v3s16, MapBlock*> & modified_blocks);
178         
179         void lightNeighbors(enum LightBank bank,
180                         v3s16 pos,
181                         core::map<v3s16, MapBlock*> & modified_blocks);
182
183         v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
184
185         s16 propagateSunlight(v3s16 start,
186                         core::map<v3s16, MapBlock*> & modified_blocks);
187         
188         void updateLighting(enum LightBank bank,
189                         core::map<v3s16, MapBlock*>  & a_blocks,
190                         core::map<v3s16, MapBlock*> & modified_blocks);
191                         
192         void updateLighting(core::map<v3s16, MapBlock*>  & a_blocks,
193                         core::map<v3s16, MapBlock*> & modified_blocks);
194                         
195         /*
196                 These handle lighting but not faces.
197         */
198         void addNodeAndUpdate(v3s16 p, MapNode n,
199                         core::map<v3s16, MapBlock*> &modified_blocks);
200         void removeNodeAndUpdate(v3s16 p,
201                         core::map<v3s16, MapBlock*> &modified_blocks);
202         
203 #ifndef SERVER
204         void expireMeshes(bool only_daynight_diffed);
205         
206         /*
207                 Updates the faces of the given block and blocks on the
208                 leading edge.
209         */
210         void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
211 #endif
212
213         /*
214                 Takes the blocks at the edges into account
215         */
216         bool dayNightDiffed(v3s16 blockpos);
217
218         //core::aabbox3d<s16> getDisplayedBlockArea();
219
220         //bool updateChangedVisibleArea();
221         
222         virtual void save(bool only_changed){assert(0);};
223
224         /*
225                 Updates usage timers
226         */
227         void timerUpdate(float dtime);
228         
229         // Takes cache into account
230         // sector mutex should be locked when calling
231         void deleteSectors(core::list<v2s16> &list, bool only_blocks);
232         
233         // Returns count of deleted sectors
234         u32 deleteUnusedSectors(float timeout, bool only_blocks=false,
235                         core::list<v3s16> *deleted_blocks=NULL);
236
237         // For debug printing
238         virtual void PrintInfo(std::ostream &out);
239         
240         void transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks);
241
242         /*
243                 Variables
244         */
245         
246 protected:
247
248         std::ostream &m_dout;
249
250         core::map<v2s16, MapSector*> m_sectors;
251         JMutex m_sector_mutex;
252
253         v3f m_camera_position;
254         v3f m_camera_direction;
255         JMutex m_camera_mutex;
256
257         // Be sure to set this to NULL when the cached sector is deleted 
258         MapSector *m_sector_cache;
259         v2s16 m_sector_cache_p;
260
261         WrapperHeightmap m_hwrapper;
262         
263         // Queued transforming water nodes
264         UniqueQueue<v3s16> m_transforming_liquid;
265 };
266
267 // Master heightmap parameters
268 struct HMParams
269 {
270         HMParams()
271         {
272                 blocksize = 64;
273                 randmax = "constant 70.0";
274                 randfactor = "constant 0.6";
275                 base = "linear 0 80 0";
276         }
277         s16 blocksize;
278         std::string randmax;
279         std::string randfactor;
280         std::string base;
281 };
282
283 // Map parameters
284 struct MapParams
285 {
286         MapParams()
287         {
288                 plants_amount = 1.0;
289                 ravines_amount = 1.0;
290                 //max_objects_in_block = 30;
291         }
292         float plants_amount;
293         float ravines_amount;
294         //u16 max_objects_in_block;
295 };
296
297 /*
298         ServerMap
299
300         This is the only map class that is able to generate map.
301 */
302
303 class ServerMap : public Map
304 {
305 public:
306         /*
307                 savedir: directory to which map data should be saved
308         */
309         ServerMap(std::string savedir, HMParams hmp, MapParams mp);
310         ~ServerMap();
311
312         s32 mapType() const
313         {
314                 return MAPTYPE_SERVER;
315         }
316
317         /*
318                 Forcefully get a sector from somewhere
319         */
320         MapSector * emergeSector(v2s16 p);
321         /*
322                 Forcefully get a block from somewhere.
323
324                 Exceptions:
325                 - InvalidPositionException: possible if only_from_disk==true
326                 
327                 changed_blocks:
328                 - All already existing blocks that were modified are added.
329                         - If found on disk, nothing will be added.
330                         - If generated, the new block will not be included.
331
332                 lighting_invalidated_blocks:
333                 - All blocks that have heavy-to-calculate lighting changes
334                   are added.
335                         - updateLighting() should be called for these.
336                 
337                 - A block that is in changed_blocks may not be in
338                   lighting_invalidated_blocks.
339         */
340         MapBlock * emergeBlock(
341                         v3s16 p,
342                         bool only_from_disk,
343                         core::map<v3s16, MapBlock*> &changed_blocks,
344                         core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
345         );
346
347         void createDir(std::string path);
348         void createSaveDir();
349         // returns something like "xxxxxxxx"
350         std::string getSectorSubDir(v2s16 pos);
351         // returns something like "map/sectors/xxxxxxxx"
352         std::string getSectorDir(v2s16 pos);
353         std::string createSectorDir(v2s16 pos);
354         // dirname: final directory name
355         v2s16 getSectorPos(std::string dirname);
356         v3s16 getBlockPos(std::string sectordir, std::string blockfile);
357
358         void save(bool only_changed);
359         void loadAll();
360
361         void saveMasterHeightmap();
362         void loadMasterHeightmap();
363
364         // The sector mutex should be locked when calling most of these
365         
366         // This only saves sector-specific data such as the heightmap
367         // (no MapBlocks)
368         void saveSectorMeta(ServerMapSector *sector);
369         MapSector* loadSectorMeta(std::string dirname);
370         
371         // Full load of a sector including all blocks.
372         // returns true on success, false on failure.
373         bool loadSectorFull(v2s16 p2d);
374         // If sector is not found in memory, try to load it from disk.
375         // Returns true if sector now resides in memory
376         //bool deFlushSector(v2s16 p2d);
377         
378         void saveBlock(MapBlock *block);
379         // This will generate a sector with getSector if not found.
380         void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector);
381
382         // Gets from master heightmap
383         void getSectorCorners(v2s16 p2d, s16 *corners);
384
385         // For debug printing
386         virtual void PrintInfo(std::ostream &out);
387
388 private:
389         // Generator parameters
390         UnlimitedHeightmap *m_heightmap;
391         MapParams m_params;
392         PointAttributeDatabase m_padb;
393
394         std::string m_savedir;
395         bool m_map_saving_enabled;
396 };
397
398 #ifndef SERVER
399
400 struct MapDrawControl
401 {
402         MapDrawControl():
403                 range_all(false),
404                 wanted_range(50),
405                 wanted_max_blocks(0),
406                 wanted_min_range(0),
407                 blocks_drawn(0),
408                 blocks_would_have_drawn(0)
409         {
410         }
411         // Overrides limits by drawing everything
412         bool range_all;
413         // Wanted drawing range
414         float wanted_range;
415         // Maximum number of blocks to draw
416         u32 wanted_max_blocks;
417         // Blocks in this range are drawn regardless of number of blocks drawn
418         float wanted_min_range;
419         // Number of blocks rendered is written here by the renderer
420         u32 blocks_drawn;
421         // Number of blocks that would have been drawn in wanted_range
422         u32 blocks_would_have_drawn;
423 };
424
425 class Client;
426
427 /*
428         ClientMap
429         
430         This is the only map class that is able to render itself on screen.
431 */
432
433 class ClientMap : public Map, public scene::ISceneNode
434 {
435 public:
436         ClientMap(
437                         Client *client,
438                         MapDrawControl &control,
439                         scene::ISceneNode* parent,
440                         scene::ISceneManager* mgr,
441                         s32 id
442         );
443
444         ~ClientMap();
445
446         s32 mapType() const
447         {
448                 return MAPTYPE_CLIENT;
449         }
450
451         void drop()
452         {
453                 ISceneNode::drop();
454         }
455
456         /*
457                 Forcefully get a sector from somewhere
458         */
459         MapSector * emergeSector(v2s16 p);
460
461         void deSerializeSector(v2s16 p2d, std::istream &is);
462
463         /*
464                 ISceneNode methods
465         */
466
467         virtual void OnRegisterSceneNode();
468
469         virtual void render()
470         {
471                 video::IVideoDriver* driver = SceneManager->getVideoDriver();
472                 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
473                 renderMap(driver, SceneManager->getSceneNodeRenderPass());
474         }
475         
476         virtual const core::aabbox3d<f32>& getBoundingBox() const
477         {
478                 return m_box;
479         }
480
481         void renderMap(video::IVideoDriver* driver, s32 pass);
482
483         /*
484                 Methods for setting temporary modifications to nodes for
485                 drawing.
486                 Return value is position of changed block.
487         */
488         v3s16 setTempMod(v3s16 p, NodeMod mod, bool *changed=NULL);
489         v3s16 clearTempMod(v3s16 p, bool *changed=NULL);
490         // Efficient implementation needs a cache of TempMods
491         //void clearTempMods();
492
493         // For debug printing
494         virtual void PrintInfo(std::ostream &out);
495         
496 private:
497         Client *m_client;
498         
499         core::aabbox3d<f32> m_box;
500         
501         // This is the master heightmap mesh
502         scene::SMesh *mesh;
503         JMutex mesh_mutex;
504         
505         MapDrawControl &m_control;
506 };
507
508 #endif
509
510 class MapVoxelManipulator : public VoxelManipulator
511 {
512 public:
513         MapVoxelManipulator(Map *map);
514         virtual ~MapVoxelManipulator();
515         
516         virtual void clear()
517         {
518                 VoxelManipulator::clear();
519                 m_loaded_blocks.clear();
520         }
521
522         virtual void emerge(VoxelArea a, s32 caller_id=-1);
523
524         void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
525
526 protected:
527         Map *m_map;
528         /*
529                 NOTE: This might be used or not
530                 bool is dummy value
531                 SUGG: How 'bout an another VoxelManipulator for storing the
532                       information about which block is loaded?
533         */
534         core::map<v3s16, bool> m_loaded_blocks;
535 };
536
537 class ManualMapVoxelManipulator : public MapVoxelManipulator
538 {
539 public:
540         ManualMapVoxelManipulator(Map *map);
541         virtual ~ManualMapVoxelManipulator();
542         
543         virtual void emerge(VoxelArea a, s32 caller_id=-1);
544
545         void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max);
546
547 protected:
548 };
549
550 #endif
551