3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
29 #define sleep_s(x) Sleep((x*1000))
32 #define sleep_s(x) sleep(x)
35 #include "common_irrlicht.h"
38 #include "mapsector.h"
39 #include "constants.h"
43 Some exposed functions
46 double base_rock_level_2d(u64 seed, v2f p);
47 bool get_have_sand_coast(u64 seed, v2f p);
48 bool get_have_sand_ground(u64 seed, v2f p);
49 double get_turbulence_factor_2d(u64 seed, v2f p);
54 #define MAPTYPE_BASE 0
55 #define MAPTYPE_SERVER 1
56 #define MAPTYPE_CLIENT 2
58 enum MapEditEventType{
66 MapEditEventType type;
69 core::map<v3s16, bool> modified_blocks;
70 u16 already_known_by_peer;
74 already_known_by_peer(0)
78 MapEditEvent * clone()
80 MapEditEvent *event = new MapEditEvent();
84 for(core::map<v3s16, bool>::Iterator
85 i = modified_blocks.getIterator();
86 i.atEnd()==false; i++)
88 v3s16 p = i.getNode()->getKey();
89 bool v = i.getNode()->getValue();
90 event->modified_blocks.insert(p, v);
96 class MapEventReceiver
99 // event shall be deleted by caller after the call.
100 virtual void onMapEditEvent(MapEditEvent *event) = 0;
103 class Map : public NodeContainer
107 Map(std::ostream &dout);
110 virtual u16 nodeContainerId() const
112 return NODECONTAINER_ID_MAP;
115 virtual s32 mapType() const
121 Drop (client) or delete (server) the map.
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);
133 // On failure returns NULL
134 MapSector * getSectorNoGenerateNoExNoLock(v2s16 p2d);
135 // On failure returns NULL
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);
143 This is overloaded by ClientMap and ServerMap to allow
144 their differing fetch methods.
146 virtual MapSector * emergeSector(v2s16 p){ return NULL; }
147 virtual MapSector * emergeSector(v2s16 p,
148 core::map<v3s16, MapBlock*> &changed_blocks){ return NULL; }
150 // Returns InvalidPositionException if not found
151 MapBlock * getBlockNoCreate(v3s16 p);
152 // Returns NULL if not found
153 MapBlock * getBlockNoCreateNoEx(v3s16 p);
154 // Gets an existing block or creates an empty one
155 //MapBlock * getBlockCreate(v3s16 p);
157 // Returns InvalidPositionException if not found
158 bool isNodeUnderground(v3s16 p);
160 // virtual from NodeContainer
161 bool isValidPosition(v3s16 p)
163 v3s16 blockpos = getNodeBlockPos(p);
166 blockref = getBlockNoCreate(blockpos);
168 catch(InvalidPositionException &e)
173 /*v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
174 bool is_valid = blockref->isValidPosition(relpos);
178 // virtual from NodeContainer
179 // throws InvalidPositionException if not found
180 MapNode getNode(v3s16 p)
182 v3s16 blockpos = getNodeBlockPos(p);
183 MapBlock * blockref = getBlockNoCreate(blockpos);
184 v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
186 return blockref->getNodeNoCheck(relpos);
189 // virtual from NodeContainer
190 // throws InvalidPositionException if not found
191 void setNode(v3s16 p, MapNode & n)
193 v3s16 blockpos = getNodeBlockPos(p);
194 MapBlock * blockref = getBlockNoCreate(blockpos);
195 v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
196 blockref->setNodeNoCheck(relpos, n);
199 // Returns a CONTENT_IGNORE node if not found
200 MapNode getNodeNoEx(v3s16 p)
203 v3s16 blockpos = getNodeBlockPos(p);
204 MapBlock * blockref = getBlockNoCreate(blockpos);
205 v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
207 return blockref->getNodeNoCheck(relpos);
209 catch(InvalidPositionException &e)
211 return MapNode(CONTENT_IGNORE);
215 void unspreadLight(enum LightBank bank,
216 core::map<v3s16, u8> & from_nodes,
217 core::map<v3s16, bool> & light_sources,
218 core::map<v3s16, MapBlock*> & modified_blocks);
220 void unLightNeighbors(enum LightBank bank,
221 v3s16 pos, u8 lightwas,
222 core::map<v3s16, bool> & light_sources,
223 core::map<v3s16, MapBlock*> & modified_blocks);
225 void spreadLight(enum LightBank bank,
226 core::map<v3s16, bool> & from_nodes,
227 core::map<v3s16, MapBlock*> & modified_blocks);
229 void lightNeighbors(enum LightBank bank,
231 core::map<v3s16, MapBlock*> & modified_blocks);
233 v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
235 s16 propagateSunlight(v3s16 start,
236 core::map<v3s16, MapBlock*> & modified_blocks);
238 void updateLighting(enum LightBank bank,
239 core::map<v3s16, MapBlock*> & a_blocks,
240 core::map<v3s16, MapBlock*> & modified_blocks);
242 void updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
243 core::map<v3s16, MapBlock*> & modified_blocks);
246 These handle lighting but not faces.
248 void addNodeAndUpdate(v3s16 p, MapNode n,
249 core::map<v3s16, MapBlock*> &modified_blocks);
250 void removeNodeAndUpdate(v3s16 p,
251 core::map<v3s16, MapBlock*> &modified_blocks);
254 Wrappers for the latter ones.
256 Return true if succeeded, false if not.
258 bool addNodeWithEvent(v3s16 p, MapNode n);
259 bool removeNodeWithEvent(v3s16 p);
262 Takes the blocks at the edges into account
264 bool dayNightDiffed(v3s16 blockpos);
266 //core::aabbox3d<s16> getDisplayedBlockArea();
268 //bool updateChangedVisibleArea();
270 virtual void save(bool only_changed){assert(0);};
275 void timerUpdate(float dtime);
277 // Takes cache into account
278 // sector mutex should be locked when calling
279 void deleteSectors(core::list<v2s16> &list, bool only_blocks);
281 // Returns count of deleted sectors
282 u32 deleteUnusedSectors(float timeout, bool only_blocks=false,
283 core::list<v3s16> *deleted_blocks=NULL);
285 // For debug printing
286 virtual void PrintInfo(std::ostream &out);
288 void transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks);
296 std::ostream &m_dout;
298 core::map<MapEventReceiver*, bool> m_event_receivers;
300 // Mutex is important because on client map is accessed asynchronously
301 core::map<v2s16, MapSector*> m_sectors;
302 JMutex m_sector_mutex;
304 // Be sure to set this to NULL when the cached sector is deleted
305 MapSector *m_sector_cache;
306 v2s16 m_sector_cache_p;
308 //WrapperHeightmap m_hwrapper;
310 // Queued transforming water nodes
311 UniqueQueue<v3s16> m_transforming_liquid;
317 This is the only map class that is able to generate map.
320 class ServerMap : public Map
324 savedir: directory to which map data should be saved
326 ServerMap(std::string savedir);
331 return MAPTYPE_SERVER;
339 True if the block and its neighbors are fully generated.
340 It means the block will not be touched in the future by the
341 generator. If false, generateBlock will make it true.
343 bool blockNonVolatile(v3s16 blockpos)
345 for(s16 x=-1; x<=1; x++)
346 for(s16 y=-1; y<=1; y++)
347 for(s16 z=-1; z<=1; z++)
349 v3s16 blockpos0 = blockpos + v3s16(x,y,z);
350 MapBlock *block = getBlockNoCreateNoEx(blockpos);
353 if(block->isFullyGenerated() == false)
362 //ServerMapSector * generateSector(v2s16 p);
365 Get a sector from somewhere.
367 - Check disk (loads blocks also)
370 ServerMapSector * createSector(v2s16 p);
373 Get a sector from somewhere.
375 - Check disk (loads blocks also)
378 MapSector * emergeSector(v2s16 p,
379 core::map<v3s16, MapBlock*> &changed_blocks);
381 MapSector * emergeSector(v2s16 p)
383 core::map<v3s16, MapBlock*> changed_blocks;
384 return emergeSector(p, changed_blocks);
387 /*MapBlock * generateBlock(
389 MapBlock *original_dummy,
390 ServerMapSector *sector,
391 core::map<v3s16, MapBlock*> &changed_blocks,
392 core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
398 All blocks touching this one can be altered also.
400 MapBlock* generateBlockRaw(v3s16 blockpos,
401 core::map<v3s16, MapBlock*> &changed_blocks,
405 Generate a block and its neighbors so that it won't be touched
408 MapBlock * generateBlock(
410 MapBlock *original_dummy,
411 ServerMapSector *sector,
412 core::map<v3s16, MapBlock*> &changed_blocks,
413 core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
415 /*MapBlock* generateBlock(v3s16 blockpos,
416 core::map<v3s16, MapBlock*> &changed_blocks);*/
419 Get a block from somewhere.
423 MapBlock * createBlock(v3s16 p);
426 only_from_disk, changed_blocks and lighting_invalidated_blocks
427 are not properly used by the new map generator.
429 MapBlock * emergeBlock(
432 core::map<v3s16, MapBlock*> &changed_blocks,
433 core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
438 Forcefully get a block from somewhere.
441 - InvalidPositionException: possible if only_from_disk==true
444 - All already existing blocks that were modified are added.
445 - If found on disk, nothing will be added.
446 - If generated, the new block will not be included.
448 lighting_invalidated_blocks:
449 - All blocks that have heavy-to-calculate lighting changes
451 - updateLighting() should be called for these.
453 - A block that is in changed_blocks may not be in
454 lighting_invalidated_blocks.
456 MapBlock * emergeBlock(
459 core::map<v3s16, MapBlock*> &changed_blocks,
460 core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
464 // Helper for placing objects on ground level
465 s16 findGroundLevel(v2s16 p2d);
468 Misc. helper functions for fiddling with directory and file
471 void createDir(std::string path);
472 void createSaveDir();
473 // returns something like "xxxxxxxx"
474 std::string getSectorSubDir(v2s16 pos);
475 // returns something like "map/sectors/xxxxxxxx"
476 std::string getSectorDir(v2s16 pos);
477 std::string createSectorDir(v2s16 pos);
478 // dirname: final directory name
479 v2s16 getSectorPos(std::string dirname);
480 v3s16 getBlockPos(std::string sectordir, std::string blockfile);
482 void save(bool only_changed);
485 // Saves map seed and possibly other stuff
489 // The sector mutex should be locked when calling most of these
491 // This only saves sector-specific data such as the heightmap
493 // DEPRECATED? Sectors have no metadata anymore.
494 void saveSectorMeta(ServerMapSector *sector);
495 MapSector* loadSectorMeta(std::string dirname);
497 // Full load of a sector including all blocks.
498 // returns true on success, false on failure.
499 bool loadSectorFull(v2s16 p2d);
500 // If sector is not found in memory, try to load it from disk.
501 // Returns true if sector now resides in memory
502 //bool deFlushSector(v2s16 p2d);
504 void saveBlock(MapBlock *block);
505 // This will generate a sector with getSector if not found.
506 void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector);
508 // For debug printing
509 virtual void PrintInfo(std::ostream &out);
511 bool isSavingEnabled(){ return m_map_saving_enabled; }
513 u64 getSeed(){ return m_seed; }
516 // Seed used for all kinds of randomness
519 std::string m_savedir;
520 bool m_map_saving_enabled;
529 struct MapDrawControl
534 wanted_max_blocks(0),
537 blocks_would_have_drawn(0)
540 // Overrides limits by drawing everything
542 // Wanted drawing range
544 // Maximum number of blocks to draw
545 u32 wanted_max_blocks;
546 // Blocks in this range are drawn regardless of number of blocks drawn
547 float wanted_min_range;
548 // Number of blocks rendered is written here by the renderer
550 // Number of blocks that would have been drawn in wanted_range
551 u32 blocks_would_have_drawn;
559 This is the only map class that is able to render itself on screen.
562 class ClientMap : public Map, public scene::ISceneNode
567 MapDrawControl &control,
568 scene::ISceneNode* parent,
569 scene::ISceneManager* mgr,
577 return MAPTYPE_CLIENT;
585 void updateCamera(v3f pos, v3f dir)
587 JMutexAutoLock lock(m_camera_mutex);
588 m_camera_position = pos;
589 m_camera_direction = dir;
593 Forcefully get a sector from somewhere
595 MapSector * emergeSector(v2s16 p);
597 void deSerializeSector(v2s16 p2d, std::istream &is);
603 virtual void OnRegisterSceneNode();
605 virtual void render()
607 video::IVideoDriver* driver = SceneManager->getVideoDriver();
608 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
609 renderMap(driver, SceneManager->getSceneNodeRenderPass());
612 virtual const core::aabbox3d<f32>& getBoundingBox() const
617 void renderMap(video::IVideoDriver* driver, s32 pass);
620 Methods for setting temporary modifications to nodes for
623 Returns true if something changed.
625 All blocks whose mesh could have been changed are inserted
628 bool setTempMod(v3s16 p, NodeMod mod,
629 core::map<v3s16, MapBlock*> *affected_blocks=NULL);
630 bool clearTempMod(v3s16 p,
631 core::map<v3s16, MapBlock*> *affected_blocks=NULL);
632 // Efficient implementation needs a cache of TempMods
633 //void clearTempMods();
635 void expireMeshes(bool only_daynight_diffed);
638 Update the faces of the given block and blocks on the
641 void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
643 // Update meshes that touch the node
644 void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
646 // For debug printing
647 virtual void PrintInfo(std::ostream &out);
652 core::aabbox3d<f32> m_box;
654 // This is the master heightmap mesh
655 //scene::SMesh *mesh;
658 MapDrawControl &m_control;
660 v3f m_camera_position;
661 v3f m_camera_direction;
662 JMutex m_camera_mutex;
668 class MapVoxelManipulator : public VoxelManipulator
671 MapVoxelManipulator(Map *map);
672 virtual ~MapVoxelManipulator();
676 VoxelManipulator::clear();
677 m_loaded_blocks.clear();
680 virtual void emerge(VoxelArea a, s32 caller_id=-1);
682 void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
688 value = block existed when loaded
690 core::map<v3s16, bool> m_loaded_blocks;
693 class ManualMapVoxelManipulator : public MapVoxelManipulator
696 ManualMapVoxelManipulator(Map *map);
697 virtual ~ManualMapVoxelManipulator();
699 virtual void emerge(VoxelArea a, s32 caller_id=-1);
701 void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max);
703 // This is much faster with big chunks of generated data
704 void blitBackAll(core::map<v3s16, MapBlock*> * modified_blocks);