LCOV - code coverage report
Current view: top level - src - map.h (source / functions) Hit Total Coverage
Test: report Lines: 2 53 3.8 %
Date: 2015-07-11 18:23:49 Functions: 2 18 11.1 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      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 Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser 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.
      18             : */
      19             : 
      20             : #ifndef MAP_HEADER
      21             : #define MAP_HEADER
      22             : 
      23             : #include <iostream>
      24             : #include <sstream>
      25             : #include <set>
      26             : #include <map>
      27             : #include <list>
      28             : 
      29             : #include "irrlichttypes_bloated.h"
      30             : #include "mapnode.h"
      31             : #include "constants.h"
      32             : #include "voxel.h"
      33             : #include "modifiedstate.h"
      34             : #include "util/container.h"
      35             : #include "nodetimer.h"
      36             : 
      37             : class Settings;
      38             : class Database;
      39             : class ClientMap;
      40             : class MapSector;
      41             : class ServerMapSector;
      42             : class MapBlock;
      43             : class NodeMetadata;
      44             : class IGameDef;
      45             : class IRollbackManager;
      46             : class EmergeManager;
      47             : class ServerEnvironment;
      48             : struct BlockMakeData;
      49             : struct MapgenParams;
      50             : 
      51             : 
      52             : /*
      53             :         MapEditEvent
      54             : */
      55             : 
      56             : #define MAPTYPE_BASE 0
      57             : #define MAPTYPE_SERVER 1
      58             : #define MAPTYPE_CLIENT 2
      59             : 
      60             : enum MapEditEventType{
      61             :         // Node added (changed from air or something else to something)
      62             :         MEET_ADDNODE,
      63             :         // Node removed (changed to air)
      64             :         MEET_REMOVENODE,
      65             :         // Node swapped (changed without metadata change)
      66             :         MEET_SWAPNODE,
      67             :         // Node metadata of block changed (not knowing which node exactly)
      68             :         // p stores block coordinate
      69             :         MEET_BLOCK_NODE_METADATA_CHANGED,
      70             :         // Anything else (modified_blocks are set unsent)
      71             :         MEET_OTHER
      72             : };
      73             : 
      74           0 : struct MapEditEvent
      75             : {
      76             :         MapEditEventType type;
      77             :         v3s16 p;
      78             :         MapNode n;
      79             :         std::set<v3s16> modified_blocks;
      80             :         u16 already_known_by_peer;
      81             : 
      82           0 :         MapEditEvent():
      83             :                 type(MEET_OTHER),
      84             :                 n(CONTENT_AIR),
      85           0 :                 already_known_by_peer(0)
      86           0 :         { }
      87             : 
      88           0 :         MapEditEvent * clone()
      89             :         {
      90           0 :                 MapEditEvent *event = new MapEditEvent();
      91           0 :                 event->type = type;
      92           0 :                 event->p = p;
      93           0 :                 event->n = n;
      94           0 :                 event->modified_blocks = modified_blocks;
      95           0 :                 return event;
      96             :         }
      97             : 
      98           0 :         VoxelArea getArea()
      99             :         {
     100           0 :                 switch(type){
     101             :                 case MEET_ADDNODE:
     102           0 :                         return VoxelArea(p);
     103             :                 case MEET_REMOVENODE:
     104           0 :                         return VoxelArea(p);
     105             :                 case MEET_SWAPNODE:
     106           0 :                         return VoxelArea(p);
     107             :                 case MEET_BLOCK_NODE_METADATA_CHANGED:
     108             :                 {
     109           0 :                         v3s16 np1 = p*MAP_BLOCKSIZE;
     110           0 :                         v3s16 np2 = np1 + v3s16(1,1,1)*MAP_BLOCKSIZE - v3s16(1,1,1);
     111           0 :                         return VoxelArea(np1, np2);
     112             :                 }
     113             :                 case MEET_OTHER:
     114             :                 {
     115           0 :                         VoxelArea a;
     116           0 :                         for(std::set<v3s16>::iterator
     117           0 :                                         i = modified_blocks.begin();
     118           0 :                                         i != modified_blocks.end(); ++i)
     119             :                         {
     120           0 :                                 v3s16 p = *i;
     121           0 :                                 v3s16 np1 = p*MAP_BLOCKSIZE;
     122           0 :                                 v3s16 np2 = np1 + v3s16(1,1,1)*MAP_BLOCKSIZE - v3s16(1,1,1);
     123           0 :                                 a.addPoint(np1);
     124           0 :                                 a.addPoint(np2);
     125             :                         }
     126           0 :                         return a;
     127             :                 }
     128             :                 }
     129           0 :                 return VoxelArea();
     130             :         }
     131             : };
     132             : 
     133           0 : class MapEventReceiver
     134             : {
     135             : public:
     136             :         // event shall be deleted by caller after the call.
     137             :         virtual void onMapEditEvent(MapEditEvent *event) = 0;
     138             : };
     139             : 
     140             : class Map /*: public NodeContainer*/
     141             : {
     142             : public:
     143             : 
     144             :         Map(std::ostream &dout, IGameDef *gamedef);
     145             :         virtual ~Map();
     146             : 
     147             :         /*virtual u16 nodeContainerId() const
     148             :         {
     149             :                 return NODECONTAINER_ID_MAP;
     150             :         }*/
     151             : 
     152           0 :         virtual s32 mapType() const
     153             :         {
     154           0 :                 return MAPTYPE_BASE;
     155             :         }
     156             : 
     157             :         /*
     158             :                 Drop (client) or delete (server) the map.
     159             :         */
     160           0 :         virtual void drop()
     161             :         {
     162           0 :                 delete this;
     163           0 :         }
     164             : 
     165             :         void addEventReceiver(MapEventReceiver *event_receiver);
     166             :         void removeEventReceiver(MapEventReceiver *event_receiver);
     167             :         // event shall be deleted by caller after the call.
     168             :         void dispatchEvent(MapEditEvent *event);
     169             : 
     170             :         // On failure returns NULL
     171             :         MapSector * getSectorNoGenerateNoExNoLock(v2s16 p2d);
     172             :         // Same as the above (there exists no lock anymore)
     173             :         MapSector * getSectorNoGenerateNoEx(v2s16 p2d);
     174             :         // On failure throws InvalidPositionException
     175             :         MapSector * getSectorNoGenerate(v2s16 p2d);
     176             :         // Gets an existing sector or creates an empty one
     177             :         //MapSector * getSectorCreate(v2s16 p2d);
     178             : 
     179             :         /*
     180             :                 This is overloaded by ClientMap and ServerMap to allow
     181             :                 their differing fetch methods.
     182             :         */
     183           0 :         virtual MapSector * emergeSector(v2s16 p){ return NULL; }
     184           0 :         virtual MapSector * emergeSector(v2s16 p,
     185           0 :                         std::map<v3s16, MapBlock*> &changed_blocks){ return NULL; }
     186             : 
     187             :         // Returns InvalidPositionException if not found
     188             :         MapBlock * getBlockNoCreate(v3s16 p);
     189             :         // Returns NULL if not found
     190             :         MapBlock * getBlockNoCreateNoEx(v3s16 p);
     191             : 
     192             :         /* Server overrides */
     193           0 :         virtual MapBlock * emergeBlock(v3s16 p, bool create_blank=true)
     194           0 :         { return getBlockNoCreateNoEx(p); }
     195             : 
     196             :         // Returns InvalidPositionException if not found
     197             :         bool isNodeUnderground(v3s16 p);
     198             : 
     199             :         bool isValidPosition(v3s16 p);
     200             : 
     201             :         // throws InvalidPositionException if not found
     202             :         void setNode(v3s16 p, MapNode & n);
     203             : 
     204             :         // Returns a CONTENT_IGNORE node if not found
     205             :         // If is_valid_position is not NULL then this will be set to true if the
     206             :         // position is valid, otherwise false
     207             :         MapNode getNodeNoEx(v3s16 p, bool *is_valid_position = NULL);
     208             : 
     209             :         void unspreadLight(enum LightBank bank,
     210             :                         std::map<v3s16, u8> & from_nodes,
     211             :                         std::set<v3s16> & light_sources,
     212             :                         std::map<v3s16, MapBlock*> & modified_blocks);
     213             : 
     214             :         void unLightNeighbors(enum LightBank bank,
     215             :                         v3s16 pos, u8 lightwas,
     216             :                         std::set<v3s16> & light_sources,
     217             :                         std::map<v3s16, MapBlock*> & modified_blocks);
     218             : 
     219             :         void spreadLight(enum LightBank bank,
     220             :                         std::set<v3s16> & from_nodes,
     221             :                         std::map<v3s16, MapBlock*> & modified_blocks);
     222             : 
     223             :         void lightNeighbors(enum LightBank bank,
     224             :                         v3s16 pos,
     225             :                         std::map<v3s16, MapBlock*> & modified_blocks);
     226             : 
     227             :         v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
     228             : 
     229             :         s16 propagateSunlight(v3s16 start,
     230             :                         std::map<v3s16, MapBlock*> & modified_blocks);
     231             : 
     232             :         void updateLighting(enum LightBank bank,
     233             :                         std::map<v3s16, MapBlock*>  & a_blocks,
     234             :                         std::map<v3s16, MapBlock*> & modified_blocks);
     235             : 
     236             :         void updateLighting(std::map<v3s16, MapBlock*>  & a_blocks,
     237             :                         std::map<v3s16, MapBlock*> & modified_blocks);
     238             : 
     239             :         /*
     240             :                 These handle lighting but not faces.
     241             :         */
     242             :         void addNodeAndUpdate(v3s16 p, MapNode n,
     243             :                         std::map<v3s16, MapBlock*> &modified_blocks,
     244             :                         bool remove_metadata = true);
     245             :         void removeNodeAndUpdate(v3s16 p,
     246             :                         std::map<v3s16, MapBlock*> &modified_blocks);
     247             : 
     248             :         /*
     249             :                 Wrappers for the latter ones.
     250             :                 These emit events.
     251             :                 Return true if succeeded, false if not.
     252             :         */
     253             :         bool addNodeWithEvent(v3s16 p, MapNode n, bool remove_metadata = true);
     254             :         bool removeNodeWithEvent(v3s16 p);
     255             : 
     256             :         /*
     257             :                 Takes the blocks at the edges into account
     258             :         */
     259             :         bool getDayNightDiff(v3s16 blockpos);
     260             : 
     261             :         //core::aabbox3d<s16> getDisplayedBlockArea();
     262             : 
     263             :         //bool updateChangedVisibleArea();
     264             : 
     265             :         // Call these before and after saving of many blocks
     266           6 :         virtual void beginSave() { return; }
     267           6 :         virtual void endSave() { return; }
     268             : 
     269           0 :         virtual void save(ModifiedState save_level) { FATAL_ERROR("FIXME"); }
     270             : 
     271             :         // Server implements these.
     272             :         // Client leaves them as no-op.
     273           0 :         virtual bool saveBlock(MapBlock *block) { return false; }
     274           0 :         virtual bool deleteBlock(v3s16 blockpos) { return false; }
     275             : 
     276             :         /*
     277             :                 Updates usage timers and unloads unused blocks and sectors.
     278             :                 Saves modified blocks before unloading on MAPTYPE_SERVER.
     279             :         */
     280             :         void timerUpdate(float dtime, float unload_timeout,
     281             :                         std::vector<v3s16> *unloaded_blocks=NULL);
     282             : 
     283             :         /*
     284             :                 Unloads all blocks with a zero refCount().
     285             :                 Saves modified blocks before unloading on MAPTYPE_SERVER.
     286             :         */
     287             :         void unloadUnreferencedBlocks(std::vector<v3s16> *unloaded_blocks=NULL);
     288             : 
     289             :         // Deletes sectors and their blocks from memory
     290             :         // Takes cache into account
     291             :         // If deleted sector is in sector cache, clears cache
     292             :         void deleteSectors(std::vector<v2s16> &list);
     293             : 
     294             :         // For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
     295             :         virtual void PrintInfo(std::ostream &out);
     296             : 
     297             :         void transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks);
     298             : 
     299             :         /*
     300             :                 Node metadata
     301             :                 These are basically coordinate wrappers to MapBlock
     302             :         */
     303             : 
     304             :         std::vector<v3s16> findNodesWithMetadata(v3s16 p1, v3s16 p2);
     305             :         NodeMetadata *getNodeMetadata(v3s16 p);
     306             : 
     307             :         /**
     308             :          * Sets metadata for a node.
     309             :          * This method sets the metadata for a given node.
     310             :          * On success, it returns @c true and the object pointed to
     311             :          * by @p meta is then managed by the system and should
     312             :          * not be deleted by the caller.
     313             :          *
     314             :          * In case of failure, the method returns @c false and the
     315             :          * caller is still responsible for deleting the object!
     316             :          *
     317             :          * @param p node coordinates
     318             :          * @param meta pointer to @c NodeMetadata object
     319             :          * @return @c true on success, false on failure
     320             :          */
     321             :         bool setNodeMetadata(v3s16 p, NodeMetadata *meta);
     322             :         void removeNodeMetadata(v3s16 p);
     323             : 
     324             :         /*
     325             :                 Node Timers
     326             :                 These are basically coordinate wrappers to MapBlock
     327             :         */
     328             : 
     329             :         NodeTimer getNodeTimer(v3s16 p);
     330             :         void setNodeTimer(v3s16 p, NodeTimer t);
     331             :         void removeNodeTimer(v3s16 p);
     332             : 
     333             :         /*
     334             :                 Misc.
     335             :         */
     336             :         std::map<v2s16, MapSector*> *getSectorsPtr(){return &m_sectors;}
     337             : 
     338             :         /*
     339             :                 Variables
     340             :         */
     341             : 
     342             :         void transforming_liquid_add(v3s16 p);
     343             :         s32 transforming_liquid_size();
     344             : 
     345             : protected:
     346             :         friend class LuaVoxelManip;
     347             : 
     348             :         std::ostream &m_dout; // A bit deprecated, could be removed
     349             : 
     350             :         IGameDef *m_gamedef;
     351             : 
     352             :         std::set<MapEventReceiver*> m_event_receivers;
     353             : 
     354             :         std::map<v2s16, MapSector*> m_sectors;
     355             : 
     356             :         // Be sure to set this to NULL when the cached sector is deleted
     357             :         MapSector *m_sector_cache;
     358             :         v2s16 m_sector_cache_p;
     359             : 
     360             :         // Queued transforming water nodes
     361             :         UniqueQueue<v3s16> m_transforming_liquid;
     362             : 
     363             : private:
     364             :         f32 m_transforming_liquid_loop_count_multiplier;
     365             :         u32 m_unprocessed_count;
     366             :         u32 m_inc_trending_up_start_time; // milliseconds
     367             :         bool m_queue_size_timer_started;
     368             : };
     369             : 
     370             : /*
     371             :         ServerMap
     372             : 
     373             :         This is the only map class that is able to generate map.
     374             : */
     375             : 
     376             : class ServerMap : public Map
     377             : {
     378             : public:
     379             :         /*
     380             :                 savedir: directory to which map data should be saved
     381             :         */
     382             :         ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emerge);
     383             :         ~ServerMap();
     384             : 
     385           0 :         s32 mapType() const
     386             :         {
     387           0 :                 return MAPTYPE_SERVER;
     388             :         }
     389             : 
     390             :         /*
     391             :                 Get a sector from somewhere.
     392             :                 - Check memory
     393             :                 - Check disk (doesn't load blocks)
     394             :                 - Create blank one
     395             :         */
     396             :         ServerMapSector * createSector(v2s16 p);
     397             : 
     398             :         /*
     399             :                 Blocks are generated by using these and makeBlock().
     400             :         */
     401             :         bool initBlockMake(BlockMakeData *data, v3s16 blockpos);
     402             :         void finishBlockMake(BlockMakeData *data,
     403             :                         std::map<v3s16, MapBlock*> &changed_blocks);
     404             : 
     405             :         /*
     406             :                 Get a block from somewhere.
     407             :                 - Memory
     408             :                 - Create blank
     409             :         */
     410             :         MapBlock * createBlock(v3s16 p);
     411             : 
     412             :         /*
     413             :                 Forcefully get a block from somewhere.
     414             :                 - Memory
     415             :                 - Load from disk
     416             :                 - Create blank filled with CONTENT_IGNORE
     417             : 
     418             :         */
     419             :         MapBlock *emergeBlock(v3s16 p, bool create_blank=true);
     420             : 
     421             :         /*
     422             :                 Try to get a block.
     423             :                 If it does not exist in memory, add it to the emerge queue.
     424             :                 - Memory
     425             :                 - Emerge Queue (deferred disk or generate)
     426             :         */
     427             :         MapBlock *getBlockOrEmerge(v3s16 p3d);
     428             : 
     429             :         // Carries out any initialization necessary before block is sent
     430             :         void prepareBlock(MapBlock *block);
     431             : 
     432             :         // Helper for placing objects on ground level
     433             :         s16 findGroundLevel(v2s16 p2d);
     434             : 
     435             :         /*
     436             :                 Misc. helper functions for fiddling with directory and file
     437             :                 names when saving
     438             :         */
     439             :         void createDirs(std::string path);
     440             :         // returns something like "map/sectors/xxxxxxxx"
     441             :         std::string getSectorDir(v2s16 pos, int layout = 2);
     442             :         // dirname: final directory name
     443             :         v2s16 getSectorPos(std::string dirname);
     444             :         v3s16 getBlockPos(std::string sectordir, std::string blockfile);
     445             :         static std::string getBlockFilename(v3s16 p);
     446             : 
     447             :         /*
     448             :                 Database functions
     449             :         */
     450             :         static Database *createDatabase(const std::string &name, const std::string &savedir, Settings &conf);
     451             :         // Verify we can read/write to the database
     452             :         void verifyDatabase();
     453             : 
     454             :         // Returns true if the database file does not exist
     455             :         bool loadFromFolders();
     456             : 
     457             :         // Call these before and after saving of blocks
     458             :         void beginSave();
     459             :         void endSave();
     460             : 
     461             :         void save(ModifiedState save_level);
     462             :         void listAllLoadableBlocks(std::vector<v3s16> &dst);
     463             :         void listAllLoadedBlocks(std::vector<v3s16> &dst);
     464             :         // Saves map seed and possibly other stuff
     465             :         void saveMapMeta();
     466             :         void loadMapMeta();
     467             : 
     468             :         /*void saveChunkMeta();
     469             :         void loadChunkMeta();*/
     470             : 
     471             :         // The sector mutex should be locked when calling most of these
     472             : 
     473             :         // This only saves sector-specific data such as the heightmap
     474             :         // (no MapBlocks)
     475             :         // DEPRECATED? Sectors have no metadata anymore.
     476             :         void saveSectorMeta(ServerMapSector *sector);
     477             :         MapSector* loadSectorMeta(std::string dirname, bool save_after_load);
     478             :         bool loadSectorMeta(v2s16 p2d);
     479             : 
     480             :         // Full load of a sector including all blocks.
     481             :         // returns true on success, false on failure.
     482             :         bool loadSectorFull(v2s16 p2d);
     483             :         // If sector is not found in memory, try to load it from disk.
     484             :         // Returns true if sector now resides in memory
     485             :         //bool deFlushSector(v2s16 p2d);
     486             : 
     487             :         bool saveBlock(MapBlock *block);
     488             :         static bool saveBlock(MapBlock *block, Database *db);
     489             :         // This will generate a sector with getSector if not found.
     490             :         void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector, bool save_after_load=false);
     491             :         MapBlock* loadBlock(v3s16 p);
     492             :         // Database version
     493             :         void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false);
     494             : 
     495             :         bool deleteBlock(v3s16 blockpos);
     496             : 
     497             :         void updateVManip(v3s16 pos);
     498             : 
     499             :         // For debug printing
     500             :         virtual void PrintInfo(std::ostream &out);
     501             : 
     502           0 :         bool isSavingEnabled(){ return m_map_saving_enabled; }
     503             : 
     504             :         u64 getSeed();
     505             :         s16 getWaterLevel();
     506             : 
     507             : private:
     508             :         // Emerge manager
     509             :         EmergeManager *m_emerge;
     510             : 
     511             :         std::string m_savedir;
     512             :         bool m_map_saving_enabled;
     513             : 
     514             : #if 0
     515             :         // Chunk size in MapSectors
     516             :         // If 0, chunks are disabled.
     517             :         s16 m_chunksize;
     518             :         // Chunks
     519             :         core::map<v2s16, MapChunk*> m_chunks;
     520             : #endif
     521             : 
     522             :         /*
     523             :                 Metadata is re-written on disk only if this is true.
     524             :                 This is reset to false when written on disk.
     525             :         */
     526             :         bool m_map_metadata_changed;
     527             :         Database *dbase;
     528             : };
     529             : 
     530             : 
     531             : #define VMANIP_BLOCK_DATA_INEXIST     1
     532             : #define VMANIP_BLOCK_CONTAINS_CIGNORE 2
     533             : 
     534             : class MMVManip : public VoxelManipulator
     535             : {
     536             : public:
     537             :         MMVManip(Map *map);
     538             :         virtual ~MMVManip();
     539             : 
     540           0 :         virtual void clear()
     541             :         {
     542           0 :                 VoxelManipulator::clear();
     543           0 :                 m_loaded_blocks.clear();
     544           0 :         }
     545             : 
     546             :         void setMap(Map *map)
     547             :         {m_map = map;}
     548             : 
     549             :         void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
     550             :                 bool load_if_inexistent = true);
     551             : 
     552             :         // This is much faster with big chunks of generated data
     553             :         void blitBackAll(std::map<v3s16, MapBlock*> * modified_blocks,
     554             :                 bool overwrite_generated = true);
     555             : 
     556             :         bool m_is_dirty;
     557             : 
     558             : protected:
     559             :         bool m_create_area;
     560             :         Map *m_map;
     561             :         /*
     562             :                 key = blockpos
     563             :                 value = flags describing the block
     564             :         */
     565             :         std::map<v3s16, u8> m_loaded_blocks;
     566             : };
     567             : 
     568             : #endif

Generated by: LCOV version 1.11