3 Copyright (C) 2010-2011 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.
24 #include <jmutexautolock.h>
29 #include "common_irrlicht.h"
31 #include "mapblock_nodemod.h"
32 #include "constants.h"
40 class ServerMapSector;
41 class ClientMapSector;
53 #define MAPTYPE_BASE 0
54 #define MAPTYPE_SERVER 1
55 #define MAPTYPE_CLIENT 2
57 enum MapEditEventType{
58 // Node added (changed from air or something else to something)
60 // Node removed (changed to air)
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)
71 MapEditEventType type;
74 core::map<v3s16, bool> modified_blocks;
75 u16 already_known_by_peer;
79 already_known_by_peer(0)
83 MapEditEvent * clone()
85 MapEditEvent *event = new MapEditEvent();
89 for(core::map<v3s16, bool>::Iterator
90 i = modified_blocks.getIterator();
91 i.atEnd()==false; i++)
93 v3s16 p = i.getNode()->getKey();
94 bool v = i.getNode()->getValue();
95 event->modified_blocks.insert(p, v);
101 class MapEventReceiver
104 // event shall be deleted by caller after the call.
105 virtual void onMapEditEvent(MapEditEvent *event) = 0;
108 class Map /*: public NodeContainer*/
112 Map(std::ostream &dout);
115 /*virtual u16 nodeContainerId() const
117 return NODECONTAINER_ID_MAP;
120 virtual s32 mapType() const
126 Drop (client) or delete (server) the map.
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);
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);
148 This is overloaded by ClientMap and ServerMap to allow
149 their differing fetch methods.
151 virtual MapSector * emergeSector(v2s16 p){ return NULL; }
152 virtual MapSector * emergeSector(v2s16 p,
153 core::map<v3s16, MapBlock*> &changed_blocks){ return NULL; }
155 // Returns InvalidPositionException if not found
156 MapBlock * getBlockNoCreate(v3s16 p);
157 // Returns NULL if not found
158 MapBlock * getBlockNoCreateNoEx(v3s16 p);
160 // Returns InvalidPositionException if not found
161 bool isNodeUnderground(v3s16 p);
163 bool isValidPosition(v3s16 p);
165 // throws InvalidPositionException if not found
166 MapNode getNode(v3s16 p);
168 // throws InvalidPositionException if not found
169 void setNode(v3s16 p, MapNode & n);
171 // Returns a CONTENT_IGNORE node if not found
172 MapNode getNodeNoEx(v3s16 p);
174 void unspreadLight(enum LightBank bank,
175 core::map<v3s16, u8> & from_nodes,
176 core::map<v3s16, bool> & light_sources,
177 core::map<v3s16, MapBlock*> & modified_blocks);
179 void unLightNeighbors(enum LightBank bank,
180 v3s16 pos, u8 lightwas,
181 core::map<v3s16, bool> & light_sources,
182 core::map<v3s16, MapBlock*> & modified_blocks);
184 void spreadLight(enum LightBank bank,
185 core::map<v3s16, bool> & from_nodes,
186 core::map<v3s16, MapBlock*> & modified_blocks);
188 void lightNeighbors(enum LightBank bank,
190 core::map<v3s16, MapBlock*> & modified_blocks);
192 v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
194 s16 propagateSunlight(v3s16 start,
195 core::map<v3s16, MapBlock*> & modified_blocks);
197 void updateLighting(enum LightBank bank,
198 core::map<v3s16, MapBlock*> & a_blocks,
199 core::map<v3s16, MapBlock*> & modified_blocks);
201 void updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
202 core::map<v3s16, MapBlock*> & modified_blocks);
205 These handle lighting but not faces.
207 void addNodeAndUpdate(v3s16 p, MapNode n,
208 core::map<v3s16, MapBlock*> &modified_blocks, std::string &player_name);
209 void removeNodeAndUpdate(v3s16 p,
210 core::map<v3s16, MapBlock*> &modified_blocks);
213 Wrappers for the latter ones.
215 Return true if succeeded, false if not.
217 bool addNodeWithEvent(v3s16 p, MapNode n);
218 bool removeNodeWithEvent(v3s16 p);
221 Takes the blocks at the edges into account
223 bool dayNightDiffed(v3s16 blockpos);
225 //core::aabbox3d<s16> getDisplayedBlockArea();
227 //bool updateChangedVisibleArea();
229 // Call these before and after saving of many blocks
230 virtual void beginSave() {return;};
231 virtual void endSave() {return;};
233 virtual void save(bool only_changed){assert(0);};
235 // Server implements this.
236 // Client leaves it as no-op.
237 virtual void saveBlock(MapBlock *block){};
240 Updates usage timers and unloads unused blocks and sectors.
241 Saves modified blocks before unloading on MAPTYPE_SERVER.
243 void timerUpdate(float dtime, float unload_timeout,
244 core::list<v3s16> *unloaded_blocks=NULL);
246 // Deletes sectors and their blocks from memory
247 // Takes cache into account
248 // If deleted sector is in sector cache, clears cache
249 void deleteSectors(core::list<v2s16> &list);
254 = flush changed to disk and delete from memory, if usage timer of
255 block is more than timeout
257 void unloadUnusedData(float timeout,
258 core::list<v3s16> *deleted_blocks=NULL);
261 // For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
262 virtual void PrintInfo(std::ostream &out);
264 void transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks);
268 These are basically coordinate wrappers to MapBlock
271 NodeMetadata* getNodeMetadata(v3s16 p);
272 void setNodeMetadata(v3s16 p, NodeMetadata *meta);
273 void removeNodeMetadata(v3s16 p);
274 void nodeMetadataStep(float dtime,
275 core::map<v3s16, MapBlock*> &changed_blocks);
280 core::map<v2s16, MapSector*> *getSectorsPtr(){return &m_sectors;}
288 std::ostream &m_dout;
290 core::map<MapEventReceiver*, bool> m_event_receivers;
292 core::map<v2s16, MapSector*> m_sectors;
294 // Be sure to set this to NULL when the cached sector is deleted
295 MapSector *m_sector_cache;
296 v2s16 m_sector_cache_p;
298 // Queued transforming water nodes
299 UniqueQueue<v3s16> m_transforming_liquid;
305 This is the only map class that is able to generate map.
308 class ServerMap : public Map
312 savedir: directory to which map data should be saved
314 ServerMap(std::string savedir);
319 return MAPTYPE_SERVER;
323 Get a sector from somewhere.
325 - Check disk (doesn't load blocks)
328 ServerMapSector * createSector(v2s16 p);
331 Blocks are generated by using these and makeBlock().
333 void initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos);
334 MapBlock* finishBlockMake(mapgen::BlockMakeData *data,
335 core::map<v3s16, MapBlock*> &changed_blocks);
337 // A non-threaded wrapper to the above
338 MapBlock * generateBlock(
340 core::map<v3s16, MapBlock*> &modified_blocks
344 Get a block from somewhere.
348 MapBlock * createBlock(v3s16 p);
351 Forcefully get a block from somewhere.
356 MapBlock * emergeBlock(v3s16 p, bool allow_generate=true);
358 // Helper for placing objects on ground level
359 s16 findGroundLevel(v2s16 p2d);
362 Misc. helper functions for fiddling with directory and file
365 void createDirs(std::string path);
366 // returns something like "map/sectors/xxxxxxxx"
367 std::string getSectorDir(v2s16 pos, int layout = 2);
368 // dirname: final directory name
369 v2s16 getSectorPos(std::string dirname);
370 v3s16 getBlockPos(std::string sectordir, std::string blockfile);
371 static std::string getBlockFilename(v3s16 p);
376 // Create the database structure
377 void createDatabase();
378 // Verify we can read/write to the database
379 void verifyDatabase();
380 // Get an integer suitable for a block
381 static sqlite3_int64 getBlockAsInteger(const v3s16 pos);
383 // Returns true if the database file does not exist
384 bool loadFromFolders();
386 // Call these before and after saving of blocks
390 void save(bool only_changed);
393 // Saves map seed and possibly other stuff
397 /*void saveChunkMeta();
398 void loadChunkMeta();*/
400 // The sector mutex should be locked when calling most of these
402 // This only saves sector-specific data such as the heightmap
404 // DEPRECATED? Sectors have no metadata anymore.
405 void saveSectorMeta(ServerMapSector *sector);
406 MapSector* loadSectorMeta(std::string dirname, bool save_after_load);
407 bool loadSectorMeta(v2s16 p2d);
409 // Full load of a sector including all blocks.
410 // returns true on success, false on failure.
411 bool loadSectorFull(v2s16 p2d);
412 // If sector is not found in memory, try to load it from disk.
413 // Returns true if sector now resides in memory
414 //bool deFlushSector(v2s16 p2d);
416 void saveBlock(MapBlock *block);
417 // This will generate a sector with getSector if not found.
418 void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector, bool save_after_load=false);
419 MapBlock* loadBlock(v3s16 p);
421 void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false);
423 // For debug printing
424 virtual void PrintInfo(std::ostream &out);
426 bool isSavingEnabled(){ return m_map_saving_enabled; }
428 u64 getSeed(){ return m_seed; }
431 // Seed used for all kinds of randomness
434 std::string m_savedir;
435 bool m_map_saving_enabled;
438 // Chunk size in MapSectors
439 // If 0, chunks are disabled.
442 core::map<v2s16, MapChunk*> m_chunks;
446 Metadata is re-written on disk only if this is true.
447 This is reset to false when written on disk.
449 bool m_map_metadata_changed;
452 SQLite database and statements
455 sqlite3_stmt *m_database_read;
456 sqlite3_stmt *m_database_write;
465 struct MapDrawControl
470 wanted_max_blocks(0),
473 blocks_would_have_drawn(0)
476 // Overrides limits by drawing everything
478 // Wanted drawing range
480 // Maximum number of blocks to draw
481 u32 wanted_max_blocks;
482 // Blocks in this range are drawn regardless of number of blocks drawn
483 float wanted_min_range;
484 // Number of blocks rendered is written here by the renderer
486 // Number of blocks that would have been drawn in wanted_range
487 u32 blocks_would_have_drawn;
495 This is the only map class that is able to render itself on screen.
498 class ClientMap : public Map, public scene::ISceneNode
503 MapDrawControl &control,
504 scene::ISceneNode* parent,
505 scene::ISceneManager* mgr,
513 return MAPTYPE_CLIENT;
521 void updateCamera(v3f pos, v3f dir)
523 JMutexAutoLock lock(m_camera_mutex);
524 m_camera_position = pos;
525 m_camera_direction = dir;
529 Forcefully get a sector from somewhere
531 MapSector * emergeSector(v2s16 p);
533 //void deSerializeSector(v2s16 p2d, std::istream &is);
539 virtual void OnRegisterSceneNode();
541 virtual void render()
543 video::IVideoDriver* driver = SceneManager->getVideoDriver();
544 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
545 renderMap(driver, SceneManager->getSceneNodeRenderPass());
548 virtual const core::aabbox3d<f32>& getBoundingBox() const
553 void renderMap(video::IVideoDriver* driver, s32 pass);
556 Methods for setting temporary modifications to nodes for
559 Returns true if something changed.
561 All blocks whose mesh could have been changed are inserted
564 bool setTempMod(v3s16 p, NodeMod mod,
565 core::map<v3s16, MapBlock*> *affected_blocks=NULL);
566 bool clearTempMod(v3s16 p,
567 core::map<v3s16, MapBlock*> *affected_blocks=NULL);
568 // Efficient implementation needs a cache of TempMods
569 //void clearTempMods();
571 void expireMeshes(bool only_daynight_diffed);
574 Update the faces of the given block and blocks on the
577 void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
579 // Update meshes that touch the node
580 //void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
582 // For debug printing
583 virtual void PrintInfo(std::ostream &out);
585 // Check if sector was drawn on last render()
586 bool sectorWasDrawn(v2s16 p)
588 return (m_last_drawn_sectors.find(p) != NULL);
594 core::aabbox3d<f32> m_box;
596 // This is the master heightmap mesh
597 //scene::SMesh *mesh;
600 MapDrawControl &m_control;
602 v3f m_camera_position;
603 v3f m_camera_direction;
604 JMutex m_camera_mutex;
606 core::map<v2s16, bool> m_last_drawn_sectors;
611 class MapVoxelManipulator : public VoxelManipulator
614 MapVoxelManipulator(Map *map);
615 virtual ~MapVoxelManipulator();
619 VoxelManipulator::clear();
620 m_loaded_blocks.clear();
623 virtual void emerge(VoxelArea a, s32 caller_id=-1);
625 void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
631 value = block existed when loaded
633 core::map<v3s16, bool> m_loaded_blocks;
636 class ManualMapVoxelManipulator : public MapVoxelManipulator
639 ManualMapVoxelManipulator(Map *map);
640 virtual ~ManualMapVoxelManipulator();
642 void setMap(Map *map)
645 virtual void emerge(VoxelArea a, s32 caller_id=-1);
647 void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max);
649 // This is much faster with big chunks of generated data
650 void blitBackAll(core::map<v3s16, MapBlock*> * modified_blocks);