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;
54 #define MAPTYPE_BASE 0
55 #define MAPTYPE_SERVER 1
56 #define MAPTYPE_CLIENT 2
58 enum MapEditEventType{
59 // Node added (changed from air or something else to something)
61 // Node removed (changed to air)
63 // Node metadata of block changed (not knowing which node exactly)
64 // p stores block coordinate
65 MEET_BLOCK_NODE_METADATA_CHANGED,
66 // Anything else (modified_blocks are set unsent)
72 MapEditEventType type;
75 core::map<v3s16, bool> modified_blocks;
76 u16 already_known_by_peer;
80 already_known_by_peer(0)
84 MapEditEvent * clone()
86 MapEditEvent *event = new MapEditEvent();
90 for(core::map<v3s16, bool>::Iterator
91 i = modified_blocks.getIterator();
92 i.atEnd()==false; i++)
94 v3s16 p = i.getNode()->getKey();
95 bool v = i.getNode()->getValue();
96 event->modified_blocks.insert(p, v);
102 class MapEventReceiver
105 // event shall be deleted by caller after the call.
106 virtual void onMapEditEvent(MapEditEvent *event) = 0;
109 class Map /*: public NodeContainer*/
113 Map(std::ostream &dout, IGameDef *gamedef);
116 /*virtual u16 nodeContainerId() const
118 return NODECONTAINER_ID_MAP;
121 virtual s32 mapType() const
127 Drop (client) or delete (server) the map.
134 void addEventReceiver(MapEventReceiver *event_receiver);
135 void removeEventReceiver(MapEventReceiver *event_receiver);
136 // event shall be deleted by caller after the call.
137 void dispatchEvent(MapEditEvent *event);
139 // On failure returns NULL
140 MapSector * getSectorNoGenerateNoExNoLock(v2s16 p2d);
141 // Same as the above (there exists no lock anymore)
142 MapSector * getSectorNoGenerateNoEx(v2s16 p2d);
143 // On failure throws InvalidPositionException
144 MapSector * getSectorNoGenerate(v2s16 p2d);
145 // Gets an existing sector or creates an empty one
146 //MapSector * getSectorCreate(v2s16 p2d);
149 This is overloaded by ClientMap and ServerMap to allow
150 their differing fetch methods.
152 virtual MapSector * emergeSector(v2s16 p){ return NULL; }
153 virtual MapSector * emergeSector(v2s16 p,
154 core::map<v3s16, MapBlock*> &changed_blocks){ return NULL; }
156 // Returns InvalidPositionException if not found
157 MapBlock * getBlockNoCreate(v3s16 p);
158 // Returns NULL if not found
159 MapBlock * getBlockNoCreateNoEx(v3s16 p);
161 /* Server overrides */
162 virtual MapBlock * emergeBlock(v3s16 p, bool allow_generate=true)
163 { return getBlockNoCreateNoEx(p); }
165 // Returns InvalidPositionException if not found
166 bool isNodeUnderground(v3s16 p);
168 bool isValidPosition(v3s16 p);
170 // throws InvalidPositionException if not found
171 MapNode getNode(v3s16 p);
173 // throws InvalidPositionException if not found
174 void setNode(v3s16 p, MapNode & n);
176 // Returns a CONTENT_IGNORE node if not found
177 MapNode getNodeNoEx(v3s16 p);
179 void unspreadLight(enum LightBank bank,
180 core::map<v3s16, u8> & from_nodes,
181 core::map<v3s16, bool> & light_sources,
182 core::map<v3s16, MapBlock*> & modified_blocks);
184 void unLightNeighbors(enum LightBank bank,
185 v3s16 pos, u8 lightwas,
186 core::map<v3s16, bool> & light_sources,
187 core::map<v3s16, MapBlock*> & modified_blocks);
189 void spreadLight(enum LightBank bank,
190 core::map<v3s16, bool> & from_nodes,
191 core::map<v3s16, MapBlock*> & modified_blocks);
193 void lightNeighbors(enum LightBank bank,
195 core::map<v3s16, MapBlock*> & modified_blocks);
197 v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
199 s16 propagateSunlight(v3s16 start,
200 core::map<v3s16, MapBlock*> & modified_blocks);
202 void updateLighting(enum LightBank bank,
203 core::map<v3s16, MapBlock*> & a_blocks,
204 core::map<v3s16, MapBlock*> & modified_blocks);
206 void updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
207 core::map<v3s16, MapBlock*> & modified_blocks);
210 These handle lighting but not faces.
212 void addNodeAndUpdate(v3s16 p, MapNode n,
213 core::map<v3s16, MapBlock*> &modified_blocks, std::string &player_name);
214 void removeNodeAndUpdate(v3s16 p,
215 core::map<v3s16, MapBlock*> &modified_blocks);
218 Wrappers for the latter ones.
220 Return true if succeeded, false if not.
222 bool addNodeWithEvent(v3s16 p, MapNode n);
223 bool removeNodeWithEvent(v3s16 p);
226 Takes the blocks at the edges into account
228 bool dayNightDiffed(v3s16 blockpos);
230 //core::aabbox3d<s16> getDisplayedBlockArea();
232 //bool updateChangedVisibleArea();
234 // Call these before and after saving of many blocks
235 virtual void beginSave() {return;};
236 virtual void endSave() {return;};
238 virtual void save(bool only_changed){assert(0);};
240 // Server implements this.
241 // Client leaves it as no-op.
242 virtual void saveBlock(MapBlock *block){};
245 Updates usage timers and unloads unused blocks and sectors.
246 Saves modified blocks before unloading on MAPTYPE_SERVER.
248 void timerUpdate(float dtime, float unload_timeout,
249 core::list<v3s16> *unloaded_blocks=NULL);
251 // Deletes sectors and their blocks from memory
252 // Takes cache into account
253 // If deleted sector is in sector cache, clears cache
254 void deleteSectors(core::list<v2s16> &list);
259 = flush changed to disk and delete from memory, if usage timer of
260 block is more than timeout
262 void unloadUnusedData(float timeout,
263 core::list<v3s16> *deleted_blocks=NULL);
266 // For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
267 virtual void PrintInfo(std::ostream &out);
269 void transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks);
273 These are basically coordinate wrappers to MapBlock
276 NodeMetadata* getNodeMetadata(v3s16 p);
277 void setNodeMetadata(v3s16 p, NodeMetadata *meta);
278 void removeNodeMetadata(v3s16 p);
279 void nodeMetadataStep(float dtime,
280 core::map<v3s16, MapBlock*> &changed_blocks);
285 core::map<v2s16, MapSector*> *getSectorsPtr(){return &m_sectors;}
293 std::ostream &m_dout; // A bit deprecated, could be removed
297 core::map<MapEventReceiver*, bool> m_event_receivers;
299 core::map<v2s16, MapSector*> m_sectors;
301 // Be sure to set this to NULL when the cached sector is deleted
302 MapSector *m_sector_cache;
303 v2s16 m_sector_cache_p;
305 // Queued transforming water nodes
306 UniqueQueue<v3s16> m_transforming_liquid;
312 This is the only map class that is able to generate map.
315 class ServerMap : public Map
319 savedir: directory to which map data should be saved
321 ServerMap(std::string savedir, IGameDef *gamedef);
326 return MAPTYPE_SERVER;
330 Get a sector from somewhere.
332 - Check disk (doesn't load blocks)
335 ServerMapSector * createSector(v2s16 p);
338 Blocks are generated by using these and makeBlock().
340 void initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos);
341 MapBlock* finishBlockMake(mapgen::BlockMakeData *data,
342 core::map<v3s16, MapBlock*> &changed_blocks);
344 // A non-threaded wrapper to the above
345 MapBlock * generateBlock(
347 core::map<v3s16, MapBlock*> &modified_blocks
351 Get a block from somewhere.
355 MapBlock * createBlock(v3s16 p);
358 Forcefully get a block from somewhere.
363 MapBlock * emergeBlock(v3s16 p, bool allow_generate=true);
365 // Helper for placing objects on ground level
366 s16 findGroundLevel(v2s16 p2d);
369 Misc. helper functions for fiddling with directory and file
372 void createDirs(std::string path);
373 // returns something like "map/sectors/xxxxxxxx"
374 std::string getSectorDir(v2s16 pos, int layout = 2);
375 // dirname: final directory name
376 v2s16 getSectorPos(std::string dirname);
377 v3s16 getBlockPos(std::string sectordir, std::string blockfile);
378 static std::string getBlockFilename(v3s16 p);
383 // Create the database structure
384 void createDatabase();
385 // Verify we can read/write to the database
386 void verifyDatabase();
387 // Get an integer suitable for a block
388 static sqlite3_int64 getBlockAsInteger(const v3s16 pos);
389 static v3s16 getIntegerAsBlock(sqlite3_int64 i);
391 // Returns true if the database file does not exist
392 bool loadFromFolders();
394 // Call these before and after saving of blocks
398 void save(bool only_changed);
401 void listAllLoadableBlocks(core::list<v3s16> &dst);
403 // Saves map seed and possibly other stuff
407 /*void saveChunkMeta();
408 void loadChunkMeta();*/
410 // The sector mutex should be locked when calling most of these
412 // This only saves sector-specific data such as the heightmap
414 // DEPRECATED? Sectors have no metadata anymore.
415 void saveSectorMeta(ServerMapSector *sector);
416 MapSector* loadSectorMeta(std::string dirname, bool save_after_load);
417 bool loadSectorMeta(v2s16 p2d);
419 // Full load of a sector including all blocks.
420 // returns true on success, false on failure.
421 bool loadSectorFull(v2s16 p2d);
422 // If sector is not found in memory, try to load it from disk.
423 // Returns true if sector now resides in memory
424 //bool deFlushSector(v2s16 p2d);
426 void saveBlock(MapBlock *block);
427 // This will generate a sector with getSector if not found.
428 void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector, bool save_after_load=false);
429 MapBlock* loadBlock(v3s16 p);
431 void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false);
433 // For debug printing
434 virtual void PrintInfo(std::ostream &out);
436 bool isSavingEnabled(){ return m_map_saving_enabled; }
438 u64 getSeed(){ return m_seed; }
441 // Seed used for all kinds of randomness in generation
444 std::string m_savedir;
445 bool m_map_saving_enabled;
448 // Chunk size in MapSectors
449 // If 0, chunks are disabled.
452 core::map<v2s16, MapChunk*> m_chunks;
456 Metadata is re-written on disk only if this is true.
457 This is reset to false when written on disk.
459 bool m_map_metadata_changed;
462 SQLite database and statements
465 sqlite3_stmt *m_database_read;
466 sqlite3_stmt *m_database_write;
467 sqlite3_stmt *m_database_list;
476 struct MapDrawControl
481 wanted_max_blocks(0),
484 blocks_would_have_drawn(0)
487 // Overrides limits by drawing everything
489 // Wanted drawing range
491 // Maximum number of blocks to draw
492 u32 wanted_max_blocks;
493 // Blocks in this range are drawn regardless of number of blocks drawn
494 float wanted_min_range;
495 // Number of blocks rendered is written here by the renderer
497 // Number of blocks that would have been drawn in wanted_range
498 u32 blocks_would_have_drawn;
502 class ITextureSource;
507 This is the only map class that is able to render itself on screen.
510 class ClientMap : public Map, public scene::ISceneNode
516 MapDrawControl &control,
517 scene::ISceneNode* parent,
518 scene::ISceneManager* mgr,
526 return MAPTYPE_CLIENT;
534 void updateCamera(v3f pos, v3f dir, f32 fov)
536 JMutexAutoLock lock(m_camera_mutex);
537 m_camera_position = pos;
538 m_camera_direction = dir;
543 Forcefully get a sector from somewhere
545 MapSector * emergeSector(v2s16 p);
547 //void deSerializeSector(v2s16 p2d, std::istream &is);
553 virtual void OnRegisterSceneNode();
555 virtual void render()
557 video::IVideoDriver* driver = SceneManager->getVideoDriver();
558 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
559 renderMap(driver, SceneManager->getSceneNodeRenderPass());
562 virtual const core::aabbox3d<f32>& getBoundingBox() const
567 void renderMap(video::IVideoDriver* driver, s32 pass);
572 Methods for setting temporary modifications to nodes for
575 Returns true if something changed.
577 All blocks whose mesh could have been changed are inserted
580 bool setTempMod(v3s16 p, NodeMod mod,
581 core::map<v3s16, MapBlock*> *affected_blocks=NULL);
582 bool clearTempMod(v3s16 p,
583 core::map<v3s16, MapBlock*> *affected_blocks=NULL);
584 // Efficient implementation needs a cache of TempMods
585 //void clearTempMods();
587 void expireMeshes(bool only_daynight_diffed);
590 Update the faces of the given block and blocks on the
591 leading edge, without threading. Rarely used.
593 void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
595 // Update meshes that touch the node
596 //void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
598 // For debug printing
599 virtual void PrintInfo(std::ostream &out);
601 // Check if sector was drawn on last render()
602 bool sectorWasDrawn(v2s16 p)
604 return (m_last_drawn_sectors.find(p) != NULL);
610 core::aabbox3d<f32> m_box;
612 // This is the master heightmap mesh
613 //scene::SMesh *mesh;
616 MapDrawControl &m_control;
618 v3f m_camera_position;
619 v3f m_camera_direction;
621 JMutex m_camera_mutex;
623 core::map<v2s16, bool> m_last_drawn_sectors;
628 class MapVoxelManipulator : public VoxelManipulator
631 MapVoxelManipulator(Map *map);
632 virtual ~MapVoxelManipulator();
636 VoxelManipulator::clear();
637 m_loaded_blocks.clear();
640 virtual void emerge(VoxelArea a, s32 caller_id=-1);
642 void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
648 value = block existed when loaded
650 core::map<v3s16, bool> m_loaded_blocks;
653 class ManualMapVoxelManipulator : public MapVoxelManipulator
656 ManualMapVoxelManipulator(Map *map);
657 virtual ~ManualMapVoxelManipulator();
659 void setMap(Map *map)
662 virtual void emerge(VoxelArea a, s32 caller_id=-1);
664 void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max);
666 // This is much faster with big chunks of generated data
667 void blitBackAll(core::map<v3s16, MapBlock*> * modified_blocks);