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 /* Server overrides */
161 virtual MapBlock * emergeBlock(v3s16 p, bool allow_generate=true)
162 { return getBlockNoCreateNoEx(p); }
164 // Returns InvalidPositionException if not found
165 bool isNodeUnderground(v3s16 p);
167 bool isValidPosition(v3s16 p);
169 // throws InvalidPositionException if not found
170 MapNode getNode(v3s16 p);
172 // throws InvalidPositionException if not found
173 void setNode(v3s16 p, MapNode & n);
175 // Returns a CONTENT_IGNORE node if not found
176 MapNode getNodeNoEx(v3s16 p);
178 void unspreadLight(enum LightBank bank,
179 core::map<v3s16, u8> & from_nodes,
180 core::map<v3s16, bool> & light_sources,
181 core::map<v3s16, MapBlock*> & modified_blocks);
183 void unLightNeighbors(enum LightBank bank,
184 v3s16 pos, u8 lightwas,
185 core::map<v3s16, bool> & light_sources,
186 core::map<v3s16, MapBlock*> & modified_blocks);
188 void spreadLight(enum LightBank bank,
189 core::map<v3s16, bool> & from_nodes,
190 core::map<v3s16, MapBlock*> & modified_blocks);
192 void lightNeighbors(enum LightBank bank,
194 core::map<v3s16, MapBlock*> & modified_blocks);
196 v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
198 s16 propagateSunlight(v3s16 start,
199 core::map<v3s16, MapBlock*> & modified_blocks);
201 void updateLighting(enum LightBank bank,
202 core::map<v3s16, MapBlock*> & a_blocks,
203 core::map<v3s16, MapBlock*> & modified_blocks);
205 void updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
206 core::map<v3s16, MapBlock*> & modified_blocks);
209 These handle lighting but not faces.
211 void addNodeAndUpdate(v3s16 p, MapNode n,
212 core::map<v3s16, MapBlock*> &modified_blocks, std::string &player_name);
213 void removeNodeAndUpdate(v3s16 p,
214 core::map<v3s16, MapBlock*> &modified_blocks);
217 Wrappers for the latter ones.
219 Return true if succeeded, false if not.
221 bool addNodeWithEvent(v3s16 p, MapNode n);
222 bool removeNodeWithEvent(v3s16 p);
225 Takes the blocks at the edges into account
227 bool dayNightDiffed(v3s16 blockpos);
229 //core::aabbox3d<s16> getDisplayedBlockArea();
231 //bool updateChangedVisibleArea();
233 // Call these before and after saving of many blocks
234 virtual void beginSave() {return;};
235 virtual void endSave() {return;};
237 virtual void save(bool only_changed){assert(0);};
239 // Server implements this.
240 // Client leaves it as no-op.
241 virtual void saveBlock(MapBlock *block){};
244 Updates usage timers and unloads unused blocks and sectors.
245 Saves modified blocks before unloading on MAPTYPE_SERVER.
247 void timerUpdate(float dtime, float unload_timeout,
248 core::list<v3s16> *unloaded_blocks=NULL);
250 // Deletes sectors and their blocks from memory
251 // Takes cache into account
252 // If deleted sector is in sector cache, clears cache
253 void deleteSectors(core::list<v2s16> &list);
258 = flush changed to disk and delete from memory, if usage timer of
259 block is more than timeout
261 void unloadUnusedData(float timeout,
262 core::list<v3s16> *deleted_blocks=NULL);
265 // For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
266 virtual void PrintInfo(std::ostream &out);
268 void transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks);
272 These are basically coordinate wrappers to MapBlock
275 NodeMetadata* getNodeMetadata(v3s16 p);
276 void setNodeMetadata(v3s16 p, NodeMetadata *meta);
277 void removeNodeMetadata(v3s16 p);
278 void nodeMetadataStep(float dtime,
279 core::map<v3s16, MapBlock*> &changed_blocks);
284 core::map<v2s16, MapSector*> *getSectorsPtr(){return &m_sectors;}
292 std::ostream &m_dout;
294 core::map<MapEventReceiver*, bool> m_event_receivers;
296 core::map<v2s16, MapSector*> m_sectors;
298 // Be sure to set this to NULL when the cached sector is deleted
299 MapSector *m_sector_cache;
300 v2s16 m_sector_cache_p;
302 // Queued transforming water nodes
303 UniqueQueue<v3s16> m_transforming_liquid;
309 This is the only map class that is able to generate map.
312 class ServerMap : public Map
316 savedir: directory to which map data should be saved
318 ServerMap(std::string savedir);
323 return MAPTYPE_SERVER;
327 Get a sector from somewhere.
329 - Check disk (doesn't load blocks)
332 ServerMapSector * createSector(v2s16 p);
335 Blocks are generated by using these and makeBlock().
337 void initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos);
338 MapBlock* finishBlockMake(mapgen::BlockMakeData *data,
339 core::map<v3s16, MapBlock*> &changed_blocks);
341 // A non-threaded wrapper to the above
342 MapBlock * generateBlock(
344 core::map<v3s16, MapBlock*> &modified_blocks
348 Get a block from somewhere.
352 MapBlock * createBlock(v3s16 p);
355 Forcefully get a block from somewhere.
360 MapBlock * emergeBlock(v3s16 p, bool allow_generate=true);
362 // Helper for placing objects on ground level
363 s16 findGroundLevel(v2s16 p2d);
366 Misc. helper functions for fiddling with directory and file
369 void createDirs(std::string path);
370 // returns something like "map/sectors/xxxxxxxx"
371 std::string getSectorDir(v2s16 pos, int layout = 2);
372 // dirname: final directory name
373 v2s16 getSectorPos(std::string dirname);
374 v3s16 getBlockPos(std::string sectordir, std::string blockfile);
375 static std::string getBlockFilename(v3s16 p);
380 // Create the database structure
381 void createDatabase();
382 // Verify we can read/write to the database
383 void verifyDatabase();
384 // Get an integer suitable for a block
385 static sqlite3_int64 getBlockAsInteger(const v3s16 pos);
386 static v3s16 getIntegerAsBlock(sqlite3_int64 i);
388 // Returns true if the database file does not exist
389 bool loadFromFolders();
391 // Call these before and after saving of blocks
395 void save(bool only_changed);
398 void listAllLoadableBlocks(core::list<v3s16> &dst);
400 // Saves map seed and possibly other stuff
404 /*void saveChunkMeta();
405 void loadChunkMeta();*/
407 // The sector mutex should be locked when calling most of these
409 // This only saves sector-specific data such as the heightmap
411 // DEPRECATED? Sectors have no metadata anymore.
412 void saveSectorMeta(ServerMapSector *sector);
413 MapSector* loadSectorMeta(std::string dirname, bool save_after_load);
414 bool loadSectorMeta(v2s16 p2d);
416 // Full load of a sector including all blocks.
417 // returns true on success, false on failure.
418 bool loadSectorFull(v2s16 p2d);
419 // If sector is not found in memory, try to load it from disk.
420 // Returns true if sector now resides in memory
421 //bool deFlushSector(v2s16 p2d);
423 void saveBlock(MapBlock *block);
424 // This will generate a sector with getSector if not found.
425 void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector, bool save_after_load=false);
426 MapBlock* loadBlock(v3s16 p);
428 void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false);
430 // For debug printing
431 virtual void PrintInfo(std::ostream &out);
433 bool isSavingEnabled(){ return m_map_saving_enabled; }
435 u64 getSeed(){ return m_seed; }
438 // Seed used for all kinds of randomness
441 std::string m_savedir;
442 bool m_map_saving_enabled;
445 // Chunk size in MapSectors
446 // If 0, chunks are disabled.
449 core::map<v2s16, MapChunk*> m_chunks;
453 Metadata is re-written on disk only if this is true.
454 This is reset to false when written on disk.
456 bool m_map_metadata_changed;
459 SQLite database and statements
462 sqlite3_stmt *m_database_read;
463 sqlite3_stmt *m_database_write;
464 sqlite3_stmt *m_database_list;
473 struct MapDrawControl
478 wanted_max_blocks(0),
481 blocks_would_have_drawn(0)
484 // Overrides limits by drawing everything
486 // Wanted drawing range
488 // Maximum number of blocks to draw
489 u32 wanted_max_blocks;
490 // Blocks in this range are drawn regardless of number of blocks drawn
491 float wanted_min_range;
492 // Number of blocks rendered is written here by the renderer
494 // Number of blocks that would have been drawn in wanted_range
495 u32 blocks_would_have_drawn;
503 This is the only map class that is able to render itself on screen.
506 class ClientMap : public Map, public scene::ISceneNode
511 MapDrawControl &control,
512 scene::ISceneNode* parent,
513 scene::ISceneManager* mgr,
521 return MAPTYPE_CLIENT;
529 void updateCamera(v3f pos, v3f dir, f32 fov)
531 JMutexAutoLock lock(m_camera_mutex);
532 m_camera_position = pos;
533 m_camera_direction = dir;
538 Forcefully get a sector from somewhere
540 MapSector * emergeSector(v2s16 p);
542 //void deSerializeSector(v2s16 p2d, std::istream &is);
548 virtual void OnRegisterSceneNode();
550 virtual void render()
552 video::IVideoDriver* driver = SceneManager->getVideoDriver();
553 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
554 renderMap(driver, SceneManager->getSceneNodeRenderPass());
557 virtual const core::aabbox3d<f32>& getBoundingBox() const
562 void renderMap(video::IVideoDriver* driver, s32 pass);
567 Methods for setting temporary modifications to nodes for
570 Returns true if something changed.
572 All blocks whose mesh could have been changed are inserted
575 bool setTempMod(v3s16 p, NodeMod mod,
576 core::map<v3s16, MapBlock*> *affected_blocks=NULL);
577 bool clearTempMod(v3s16 p,
578 core::map<v3s16, MapBlock*> *affected_blocks=NULL);
579 // Efficient implementation needs a cache of TempMods
580 //void clearTempMods();
582 void expireMeshes(bool only_daynight_diffed);
585 Update the faces of the given block and blocks on the
588 void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
590 // Update meshes that touch the node
591 //void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
593 // For debug printing
594 virtual void PrintInfo(std::ostream &out);
596 // Check if sector was drawn on last render()
597 bool sectorWasDrawn(v2s16 p)
599 return (m_last_drawn_sectors.find(p) != NULL);
605 core::aabbox3d<f32> m_box;
607 // This is the master heightmap mesh
608 //scene::SMesh *mesh;
611 MapDrawControl &m_control;
613 v3f m_camera_position;
614 v3f m_camera_direction;
616 JMutex m_camera_mutex;
618 core::map<v2s16, bool> m_last_drawn_sectors;
623 class MapVoxelManipulator : public VoxelManipulator
626 MapVoxelManipulator(Map *map);
627 virtual ~MapVoxelManipulator();
631 VoxelManipulator::clear();
632 m_loaded_blocks.clear();
635 virtual void emerge(VoxelArea a, s32 caller_id=-1);
637 void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
643 value = block existed when loaded
645 core::map<v3s16, bool> m_loaded_blocks;
648 class ManualMapVoxelManipulator : public MapVoxelManipulator
651 ManualMapVoxelManipulator(Map *map);
652 virtual ~ManualMapVoxelManipulator();
654 void setMap(Map *map)
657 virtual void emerge(VoxelArea a, s32 caller_id=-1);
659 void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max);
661 // This is much faster with big chunks of generated data
662 void blitBackAll(core::map<v3s16, MapBlock*> * modified_blocks);