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"
34 #include "utility.h" // Needed for UniqueQueue, a member of Map
35 #include "modifiedstate.h"
42 class ServerMapSector;
43 class ClientMapSector;
56 #define MAPTYPE_BASE 0
57 #define MAPTYPE_SERVER 1
58 #define MAPTYPE_CLIENT 2
60 enum MapEditEventType{
61 // Node added (changed from air or something else to something)
63 // Node removed (changed to air)
65 // Node metadata of block changed (not knowing which node exactly)
66 // p stores block coordinate
67 MEET_BLOCK_NODE_METADATA_CHANGED,
68 // Anything else (modified_blocks are set unsent)
74 MapEditEventType type;
77 core::map<v3s16, bool> modified_blocks;
78 u16 already_known_by_peer;
82 already_known_by_peer(0)
86 MapEditEvent * clone()
88 MapEditEvent *event = new MapEditEvent();
92 for(core::map<v3s16, bool>::Iterator
93 i = modified_blocks.getIterator();
94 i.atEnd()==false; i++)
96 v3s16 p = i.getNode()->getKey();
97 bool v = i.getNode()->getValue();
98 event->modified_blocks.insert(p, v);
104 class MapEventReceiver
107 // event shall be deleted by caller after the call.
108 virtual void onMapEditEvent(MapEditEvent *event) = 0;
111 class Map /*: public NodeContainer*/
115 Map(std::ostream &dout, IGameDef *gamedef);
118 /*virtual u16 nodeContainerId() const
120 return NODECONTAINER_ID_MAP;
123 virtual s32 mapType() const
129 Drop (client) or delete (server) the map.
136 void addEventReceiver(MapEventReceiver *event_receiver);
137 void removeEventReceiver(MapEventReceiver *event_receiver);
138 // event shall be deleted by caller after the call.
139 void dispatchEvent(MapEditEvent *event);
141 // On failure returns NULL
142 MapSector * getSectorNoGenerateNoExNoLock(v2s16 p2d);
143 // Same as the above (there exists no lock anymore)
144 MapSector * getSectorNoGenerateNoEx(v2s16 p2d);
145 // On failure throws InvalidPositionException
146 MapSector * getSectorNoGenerate(v2s16 p2d);
147 // Gets an existing sector or creates an empty one
148 //MapSector * getSectorCreate(v2s16 p2d);
151 This is overloaded by ClientMap and ServerMap to allow
152 their differing fetch methods.
154 virtual MapSector * emergeSector(v2s16 p){ return NULL; }
155 virtual MapSector * emergeSector(v2s16 p,
156 core::map<v3s16, MapBlock*> &changed_blocks){ return NULL; }
158 // Returns InvalidPositionException if not found
159 MapBlock * getBlockNoCreate(v3s16 p);
160 // Returns NULL if not found
161 MapBlock * getBlockNoCreateNoEx(v3s16 p);
163 /* Server overrides */
164 virtual MapBlock * emergeBlock(v3s16 p, bool allow_generate=true)
165 { return getBlockNoCreateNoEx(p); }
167 // Returns InvalidPositionException if not found
168 bool isNodeUnderground(v3s16 p);
170 bool isValidPosition(v3s16 p);
172 // throws InvalidPositionException if not found
173 MapNode getNode(v3s16 p);
175 // throws InvalidPositionException if not found
176 void setNode(v3s16 p, MapNode & n);
178 // Returns a CONTENT_IGNORE node if not found
179 MapNode getNodeNoEx(v3s16 p);
181 void unspreadLight(enum LightBank bank,
182 core::map<v3s16, u8> & from_nodes,
183 core::map<v3s16, bool> & light_sources,
184 core::map<v3s16, MapBlock*> & modified_blocks);
186 void unLightNeighbors(enum LightBank bank,
187 v3s16 pos, u8 lightwas,
188 core::map<v3s16, bool> & light_sources,
189 core::map<v3s16, MapBlock*> & modified_blocks);
191 void spreadLight(enum LightBank bank,
192 core::map<v3s16, bool> & from_nodes,
193 core::map<v3s16, MapBlock*> & modified_blocks);
195 void lightNeighbors(enum LightBank bank,
197 core::map<v3s16, MapBlock*> & modified_blocks);
199 v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
201 s16 propagateSunlight(v3s16 start,
202 core::map<v3s16, MapBlock*> & modified_blocks);
204 void updateLighting(enum LightBank bank,
205 core::map<v3s16, MapBlock*> & a_blocks,
206 core::map<v3s16, MapBlock*> & modified_blocks);
208 void updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
209 core::map<v3s16, MapBlock*> & modified_blocks);
212 These handle lighting but not faces.
214 void addNodeAndUpdate(v3s16 p, MapNode n,
215 core::map<v3s16, MapBlock*> &modified_blocks, std::string &player_name);
216 void removeNodeAndUpdate(v3s16 p,
217 core::map<v3s16, MapBlock*> &modified_blocks);
220 Wrappers for the latter ones.
222 Return true if succeeded, false if not.
224 bool addNodeWithEvent(v3s16 p, MapNode n);
225 bool removeNodeWithEvent(v3s16 p);
228 Takes the blocks at the edges into account
230 bool dayNightDiffed(v3s16 blockpos);
232 //core::aabbox3d<s16> getDisplayedBlockArea();
234 //bool updateChangedVisibleArea();
236 // Call these before and after saving of many blocks
237 virtual void beginSave() {return;};
238 virtual void endSave() {return;};
240 virtual void save(ModifiedState save_level){assert(0);};
242 // Server implements this.
243 // Client leaves it as no-op.
244 virtual void saveBlock(MapBlock *block){};
247 Updates usage timers and unloads unused blocks and sectors.
248 Saves modified blocks before unloading on MAPTYPE_SERVER.
250 void timerUpdate(float dtime, float unload_timeout,
251 core::list<v3s16> *unloaded_blocks=NULL);
253 // Deletes sectors and their blocks from memory
254 // Takes cache into account
255 // If deleted sector is in sector cache, clears cache
256 void deleteSectors(core::list<v2s16> &list);
261 = flush changed to disk and delete from memory, if usage timer of
262 block is more than timeout
264 void unloadUnusedData(float timeout,
265 core::list<v3s16> *deleted_blocks=NULL);
268 // For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
269 virtual void PrintInfo(std::ostream &out);
271 void transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks);
275 These are basically coordinate wrappers to MapBlock
278 NodeMetadata* getNodeMetadata(v3s16 p);
279 void setNodeMetadata(v3s16 p, NodeMetadata *meta);
280 void removeNodeMetadata(v3s16 p);
281 void nodeMetadataStep(float dtime,
282 core::map<v3s16, MapBlock*> &changed_blocks);
287 core::map<v2s16, MapSector*> *getSectorsPtr(){return &m_sectors;}
295 std::ostream &m_dout; // A bit deprecated, could be removed
299 core::map<MapEventReceiver*, bool> m_event_receivers;
301 core::map<v2s16, MapSector*> m_sectors;
303 // Be sure to set this to NULL when the cached sector is deleted
304 MapSector *m_sector_cache;
305 v2s16 m_sector_cache_p;
307 // Queued transforming water nodes
308 UniqueQueue<v3s16> m_transforming_liquid;
314 This is the only map class that is able to generate map.
317 class ServerMap : public Map
321 savedir: directory to which map data should be saved
323 ServerMap(std::string savedir, IGameDef *gamedef);
328 return MAPTYPE_SERVER;
332 Get a sector from somewhere.
334 - Check disk (doesn't load blocks)
337 ServerMapSector * createSector(v2s16 p);
340 Blocks are generated by using these and makeBlock().
342 void initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos);
343 MapBlock* finishBlockMake(mapgen::BlockMakeData *data,
344 core::map<v3s16, MapBlock*> &changed_blocks);
346 // A non-threaded wrapper to the above
347 MapBlock * generateBlock(
349 core::map<v3s16, MapBlock*> &modified_blocks
353 Get a block from somewhere.
357 MapBlock * createBlock(v3s16 p);
360 Forcefully get a block from somewhere.
365 MapBlock * emergeBlock(v3s16 p, bool allow_generate=true);
367 // Helper for placing objects on ground level
368 s16 findGroundLevel(v2s16 p2d);
371 Misc. helper functions for fiddling with directory and file
374 void createDirs(std::string path);
375 // returns something like "map/sectors/xxxxxxxx"
376 std::string getSectorDir(v2s16 pos, int layout = 2);
377 // dirname: final directory name
378 v2s16 getSectorPos(std::string dirname);
379 v3s16 getBlockPos(std::string sectordir, std::string blockfile);
380 static std::string getBlockFilename(v3s16 p);
385 // Create the database structure
386 void createDatabase();
387 // Verify we can read/write to the database
388 void verifyDatabase();
389 // Get an integer suitable for a block
390 static sqlite3_int64 getBlockAsInteger(const v3s16 pos);
391 static v3s16 getIntegerAsBlock(sqlite3_int64 i);
393 // Returns true if the database file does not exist
394 bool loadFromFolders();
396 // Call these before and after saving of blocks
400 void save(ModifiedState save_level);
403 void listAllLoadableBlocks(core::list<v3s16> &dst);
405 // Saves map seed and possibly other stuff
409 /*void saveChunkMeta();
410 void loadChunkMeta();*/
412 // The sector mutex should be locked when calling most of these
414 // This only saves sector-specific data such as the heightmap
416 // DEPRECATED? Sectors have no metadata anymore.
417 void saveSectorMeta(ServerMapSector *sector);
418 MapSector* loadSectorMeta(std::string dirname, bool save_after_load);
419 bool loadSectorMeta(v2s16 p2d);
421 // Full load of a sector including all blocks.
422 // returns true on success, false on failure.
423 bool loadSectorFull(v2s16 p2d);
424 // If sector is not found in memory, try to load it from disk.
425 // Returns true if sector now resides in memory
426 //bool deFlushSector(v2s16 p2d);
428 void saveBlock(MapBlock *block);
429 // This will generate a sector with getSector if not found.
430 void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector, bool save_after_load=false);
431 MapBlock* loadBlock(v3s16 p);
433 void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false);
435 // For debug printing
436 virtual void PrintInfo(std::ostream &out);
438 bool isSavingEnabled(){ return m_map_saving_enabled; }
440 u64 getSeed(){ return m_seed; }
443 // Seed used for all kinds of randomness in generation
446 std::string m_savedir;
447 bool m_map_saving_enabled;
450 // Chunk size in MapSectors
451 // If 0, chunks are disabled.
454 core::map<v2s16, MapChunk*> m_chunks;
458 Metadata is re-written on disk only if this is true.
459 This is reset to false when written on disk.
461 bool m_map_metadata_changed;
464 SQLite database and statements
467 sqlite3_stmt *m_database_read;
468 sqlite3_stmt *m_database_write;
469 sqlite3_stmt *m_database_list;
478 struct MapDrawControl
483 wanted_max_blocks(0),
486 blocks_would_have_drawn(0)
489 // Overrides limits by drawing everything
491 // Wanted drawing range
493 // Maximum number of blocks to draw
494 u32 wanted_max_blocks;
495 // Blocks in this range are drawn regardless of number of blocks drawn
496 float wanted_min_range;
497 // Number of blocks rendered is written here by the renderer
499 // Number of blocks that would have been drawn in wanted_range
500 u32 blocks_would_have_drawn;
504 class ITextureSource;
509 This is the only map class that is able to render itself on screen.
512 class ClientMap : public Map, public scene::ISceneNode
518 MapDrawControl &control,
519 scene::ISceneNode* parent,
520 scene::ISceneManager* mgr,
528 return MAPTYPE_CLIENT;
536 void updateCamera(v3f pos, v3f dir, f32 fov)
538 JMutexAutoLock lock(m_camera_mutex);
539 m_camera_position = pos;
540 m_camera_direction = dir;
545 Forcefully get a sector from somewhere
547 MapSector * emergeSector(v2s16 p);
549 //void deSerializeSector(v2s16 p2d, std::istream &is);
555 virtual void OnRegisterSceneNode();
557 virtual void render()
559 video::IVideoDriver* driver = SceneManager->getVideoDriver();
560 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
561 renderMap(driver, SceneManager->getSceneNodeRenderPass());
564 virtual const core::aabbox3d<f32>& getBoundingBox() const
569 void renderMap(video::IVideoDriver* driver, s32 pass);
574 Methods for setting temporary modifications to nodes for
577 Returns true if something changed.
579 All blocks whose mesh could have been changed are inserted
582 bool setTempMod(v3s16 p, NodeMod mod,
583 core::map<v3s16, MapBlock*> *affected_blocks=NULL);
584 bool clearTempMod(v3s16 p,
585 core::map<v3s16, MapBlock*> *affected_blocks=NULL);
586 // Efficient implementation needs a cache of TempMods
587 //void clearTempMods();
589 void expireMeshes(bool only_daynight_diffed);
592 Update the faces of the given block and blocks on the
593 leading edge, without threading. Rarely used.
595 void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
597 // Update meshes that touch the node
598 //void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
600 // For debug printing
601 virtual void PrintInfo(std::ostream &out);
603 // Check if sector was drawn on last render()
604 bool sectorWasDrawn(v2s16 p)
606 return (m_last_drawn_sectors.find(p) != NULL);
612 core::aabbox3d<f32> m_box;
614 // This is the master heightmap mesh
615 //scene::SMesh *mesh;
618 MapDrawControl &m_control;
620 v3f m_camera_position;
621 v3f m_camera_direction;
623 JMutex m_camera_mutex;
625 core::map<v2s16, bool> m_last_drawn_sectors;
630 class MapVoxelManipulator : public VoxelManipulator
633 MapVoxelManipulator(Map *map);
634 virtual ~MapVoxelManipulator();
638 VoxelManipulator::clear();
639 m_loaded_blocks.clear();
642 virtual void emerge(VoxelArea a, s32 caller_id=-1);
644 void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
650 value = block existed when loaded
652 core::map<v3s16, bool> m_loaded_blocks;
655 class ManualMapVoxelManipulator : public MapVoxelManipulator
658 ManualMapVoxelManipulator(Map *map);
659 virtual ~ManualMapVoxelManipulator();
661 void setMap(Map *map)
664 virtual void emerge(VoxelArea a, s32 caller_id=-1);
666 void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max);
668 // This is much faster with big chunks of generated data
669 void blitBackAll(core::map<v3s16, MapBlock*> * modified_blocks);