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>
28 #include "common_irrlicht.h"
30 #include "mapblock_nodemod.h"
31 #include "constants.h"
35 class ServerMapSector;
36 class ClientMapSector;
48 #define MAPTYPE_BASE 0
49 #define MAPTYPE_SERVER 1
50 #define MAPTYPE_CLIENT 2
52 enum MapEditEventType{
53 // Node added (changed from air or something else to something)
55 // Node removed (changed to air)
57 // Node metadata of block changed (not knowing which node exactly)
58 // p stores block coordinate
59 MEET_BLOCK_NODE_METADATA_CHANGED,
66 MapEditEventType type;
69 core::map<v3s16, bool> modified_blocks;
70 u16 already_known_by_peer;
74 already_known_by_peer(0)
78 MapEditEvent * clone()
80 MapEditEvent *event = new MapEditEvent();
84 for(core::map<v3s16, bool>::Iterator
85 i = modified_blocks.getIterator();
86 i.atEnd()==false; i++)
88 v3s16 p = i.getNode()->getKey();
89 bool v = i.getNode()->getValue();
90 event->modified_blocks.insert(p, v);
96 class MapEventReceiver
99 // event shall be deleted by caller after the call.
100 virtual void onMapEditEvent(MapEditEvent *event) = 0;
103 class Map /*: public NodeContainer*/
107 Map(std::ostream &dout);
110 /*virtual u16 nodeContainerId() const
112 return NODECONTAINER_ID_MAP;
115 virtual s32 mapType() const
121 Drop (client) or delete (server) the map.
128 void addEventReceiver(MapEventReceiver *event_receiver);
129 void removeEventReceiver(MapEventReceiver *event_receiver);
130 // event shall be deleted by caller after the call.
131 void dispatchEvent(MapEditEvent *event);
133 // On failure returns NULL
134 MapSector * getSectorNoGenerateNoExNoLock(v2s16 p2d);
135 // Same as the above (there exists no lock anymore)
136 MapSector * getSectorNoGenerateNoEx(v2s16 p2d);
137 // On failure throws InvalidPositionException
138 MapSector * getSectorNoGenerate(v2s16 p2d);
139 // Gets an existing sector or creates an empty one
140 //MapSector * getSectorCreate(v2s16 p2d);
143 This is overloaded by ClientMap and ServerMap to allow
144 their differing fetch methods.
146 virtual MapSector * emergeSector(v2s16 p){ return NULL; }
147 virtual MapSector * emergeSector(v2s16 p,
148 core::map<v3s16, MapBlock*> &changed_blocks){ return NULL; }
150 // Returns InvalidPositionException if not found
151 MapBlock * getBlockNoCreate(v3s16 p);
152 // Returns NULL if not found
153 MapBlock * getBlockNoCreateNoEx(v3s16 p);
155 // Returns InvalidPositionException if not found
156 bool isNodeUnderground(v3s16 p);
158 bool isValidPosition(v3s16 p);
160 // throws InvalidPositionException if not found
161 MapNode getNode(v3s16 p);
163 // throws InvalidPositionException if not found
164 void setNode(v3s16 p, MapNode & n);
166 // Returns a CONTENT_IGNORE node if not found
167 MapNode getNodeNoEx(v3s16 p);
169 void unspreadLight(enum LightBank bank,
170 core::map<v3s16, u8> & from_nodes,
171 core::map<v3s16, bool> & light_sources,
172 core::map<v3s16, MapBlock*> & modified_blocks);
174 void unLightNeighbors(enum LightBank bank,
175 v3s16 pos, u8 lightwas,
176 core::map<v3s16, bool> & light_sources,
177 core::map<v3s16, MapBlock*> & modified_blocks);
179 void spreadLight(enum LightBank bank,
180 core::map<v3s16, bool> & from_nodes,
181 core::map<v3s16, MapBlock*> & modified_blocks);
183 void lightNeighbors(enum LightBank bank,
185 core::map<v3s16, MapBlock*> & modified_blocks);
187 v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
189 s16 propagateSunlight(v3s16 start,
190 core::map<v3s16, MapBlock*> & modified_blocks);
192 void updateLighting(enum LightBank bank,
193 core::map<v3s16, MapBlock*> & a_blocks,
194 core::map<v3s16, MapBlock*> & modified_blocks);
196 void updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
197 core::map<v3s16, MapBlock*> & modified_blocks);
200 These handle lighting but not faces.
202 void addNodeAndUpdate(v3s16 p, MapNode n,
203 core::map<v3s16, MapBlock*> &modified_blocks);
204 void removeNodeAndUpdate(v3s16 p,
205 core::map<v3s16, MapBlock*> &modified_blocks);
208 Wrappers for the latter ones.
210 Return true if succeeded, false if not.
212 bool addNodeWithEvent(v3s16 p, MapNode n);
213 bool removeNodeWithEvent(v3s16 p);
216 Takes the blocks at the edges into account
218 bool dayNightDiffed(v3s16 blockpos);
220 //core::aabbox3d<s16> getDisplayedBlockArea();
222 //bool updateChangedVisibleArea();
224 virtual void save(bool only_changed){assert(0);};
226 // Server implements this.
227 // Client leaves it as no-op.
228 virtual void saveBlock(MapBlock *block){};
231 Updates usage timers and unloads unused blocks and sectors.
232 Saves modified blocks before unloading on MAPTYPE_SERVER.
234 void timerUpdate(float dtime, float unload_timeout,
235 core::list<v3s16> *unloaded_blocks=NULL);
237 // Deletes sectors and their blocks from memory
238 // Takes cache into account
239 // If deleted sector is in sector cache, clears cache
240 void deleteSectors(core::list<v2s16> &list);
245 = flush changed to disk and delete from memory, if usage timer of
246 block is more than timeout
248 void unloadUnusedData(float timeout,
249 core::list<v3s16> *deleted_blocks=NULL);
252 // For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
253 virtual void PrintInfo(std::ostream &out);
255 void transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks);
259 These are basically coordinate wrappers to MapBlock
262 NodeMetadata* getNodeMetadata(v3s16 p);
263 void setNodeMetadata(v3s16 p, NodeMetadata *meta);
264 void removeNodeMetadata(v3s16 p);
265 void nodeMetadataStep(float dtime,
266 core::map<v3s16, MapBlock*> &changed_blocks);
271 core::map<v2s16, MapSector*> *getSectorsPtr(){return &m_sectors;}
279 std::ostream &m_dout;
281 core::map<MapEventReceiver*, bool> m_event_receivers;
283 core::map<v2s16, MapSector*> m_sectors;
285 // Be sure to set this to NULL when the cached sector is deleted
286 MapSector *m_sector_cache;
287 v2s16 m_sector_cache_p;
289 // Queued transforming water nodes
290 UniqueQueue<v3s16> m_transforming_liquid;
296 This is the only map class that is able to generate map.
299 class ServerMap : public Map
303 savedir: directory to which map data should be saved
305 ServerMap(std::string savedir);
310 return MAPTYPE_SERVER;
314 Get a sector from somewhere.
316 - Check disk (doesn't load blocks)
319 ServerMapSector * createSector(v2s16 p);
322 Blocks are generated by using these and makeBlock().
324 void initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos);
325 MapBlock* finishBlockMake(mapgen::BlockMakeData *data,
326 core::map<v3s16, MapBlock*> &changed_blocks);
328 // A non-threaded wrapper to the above
329 MapBlock * generateBlock(
331 core::map<v3s16, MapBlock*> &modified_blocks
335 Get a block from somewhere.
339 MapBlock * createBlock(v3s16 p);
343 NOTE: This comment might be outdated
345 Forcefully get a block from somewhere.
347 InvalidPositionException possible if only_from_disk==true
350 changed_blocks: Blocks that have been modified
352 MapBlock * emergeBlock(
355 core::map<v3s16, MapBlock*> &changed_blocks,
356 core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
360 // Helper for placing objects on ground level
361 s16 findGroundLevel(v2s16 p2d);
364 Misc. helper functions for fiddling with directory and file
367 void createDirs(std::string path);
368 // returns something like "map/sectors/xxxxxxxx"
369 std::string getSectorDir(v2s16 pos, int layout = 2);
370 // dirname: final directory name
371 v2s16 getSectorPos(std::string dirname);
372 v3s16 getBlockPos(std::string sectordir, std::string blockfile);
373 static std::string getBlockFilename(v3s16 p);
375 void save(bool only_changed);
378 // Saves map seed and possibly other stuff
382 /*void saveChunkMeta();
383 void loadChunkMeta();*/
385 // The sector mutex should be locked when calling most of these
387 // This only saves sector-specific data such as the heightmap
389 // DEPRECATED? Sectors have no metadata anymore.
390 void saveSectorMeta(ServerMapSector *sector);
391 MapSector* loadSectorMeta(std::string dirname, bool save_after_load);
392 bool loadSectorMeta(v2s16 p2d);
394 // Full load of a sector including all blocks.
395 // returns true on success, false on failure.
396 bool loadSectorFull(v2s16 p2d);
397 // If sector is not found in memory, try to load it from disk.
398 // Returns true if sector now resides in memory
399 //bool deFlushSector(v2s16 p2d);
401 void saveBlock(MapBlock *block);
402 // This will generate a sector with getSector if not found.
403 void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector, bool save_after_load=false);
404 MapBlock* loadBlock(v3s16 p);
406 // For debug printing
407 virtual void PrintInfo(std::ostream &out);
409 bool isSavingEnabled(){ return m_map_saving_enabled; }
411 u64 getSeed(){ return m_seed; }
414 // Seed used for all kinds of randomness
417 std::string m_savedir;
418 bool m_map_saving_enabled;
421 // Chunk size in MapSectors
422 // If 0, chunks are disabled.
425 core::map<v2s16, MapChunk*> m_chunks;
429 Metadata is re-written on disk only if this is true.
430 This is reset to false when written on disk.
432 bool m_map_metadata_changed;
441 struct MapDrawControl
446 wanted_max_blocks(0),
449 blocks_would_have_drawn(0)
452 // Overrides limits by drawing everything
454 // Wanted drawing range
456 // Maximum number of blocks to draw
457 u32 wanted_max_blocks;
458 // Blocks in this range are drawn regardless of number of blocks drawn
459 float wanted_min_range;
460 // Number of blocks rendered is written here by the renderer
462 // Number of blocks that would have been drawn in wanted_range
463 u32 blocks_would_have_drawn;
471 This is the only map class that is able to render itself on screen.
474 class ClientMap : public Map, public scene::ISceneNode
479 MapDrawControl &control,
480 scene::ISceneNode* parent,
481 scene::ISceneManager* mgr,
489 return MAPTYPE_CLIENT;
497 void updateCamera(v3f pos, v3f dir)
499 JMutexAutoLock lock(m_camera_mutex);
500 m_camera_position = pos;
501 m_camera_direction = dir;
505 Forcefully get a sector from somewhere
507 MapSector * emergeSector(v2s16 p);
509 //void deSerializeSector(v2s16 p2d, std::istream &is);
515 virtual void OnRegisterSceneNode();
517 virtual void render()
519 video::IVideoDriver* driver = SceneManager->getVideoDriver();
520 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
521 renderMap(driver, SceneManager->getSceneNodeRenderPass());
524 virtual const core::aabbox3d<f32>& getBoundingBox() const
529 void renderMap(video::IVideoDriver* driver, s32 pass);
532 Methods for setting temporary modifications to nodes for
535 Returns true if something changed.
537 All blocks whose mesh could have been changed are inserted
540 bool setTempMod(v3s16 p, NodeMod mod,
541 core::map<v3s16, MapBlock*> *affected_blocks=NULL);
542 bool clearTempMod(v3s16 p,
543 core::map<v3s16, MapBlock*> *affected_blocks=NULL);
544 // Efficient implementation needs a cache of TempMods
545 //void clearTempMods();
547 void expireMeshes(bool only_daynight_diffed);
550 Update the faces of the given block and blocks on the
553 void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
555 // Update meshes that touch the node
556 //void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
558 // For debug printing
559 virtual void PrintInfo(std::ostream &out);
561 // Check if sector was drawn on last render()
562 bool sectorWasDrawn(v2s16 p)
564 return (m_last_drawn_sectors.find(p) != NULL);
570 core::aabbox3d<f32> m_box;
572 // This is the master heightmap mesh
573 //scene::SMesh *mesh;
576 MapDrawControl &m_control;
578 v3f m_camera_position;
579 v3f m_camera_direction;
580 JMutex m_camera_mutex;
582 core::map<v2s16, bool> m_last_drawn_sectors;
587 class MapVoxelManipulator : public VoxelManipulator
590 MapVoxelManipulator(Map *map);
591 virtual ~MapVoxelManipulator();
595 VoxelManipulator::clear();
596 m_loaded_blocks.clear();
599 virtual void emerge(VoxelArea a, s32 caller_id=-1);
601 void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
607 value = block existed when loaded
609 core::map<v3s16, bool> m_loaded_blocks;
612 class ManualMapVoxelManipulator : public MapVoxelManipulator
615 ManualMapVoxelManipulator(Map *map);
616 virtual ~ManualMapVoxelManipulator();
618 void setMap(Map *map)
621 virtual void emerge(VoxelArea a, s32 caller_id=-1);
623 void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max);
625 // This is much faster with big chunks of generated data
626 void blitBackAll(core::map<v3s16, MapBlock*> * modified_blocks);