X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fmapblock.h;h=30e9e38f81e9cc9285995a51012ec4304e51d70e;hb=79799840a23b99aaf7f4af77a94ea4e9efcf5327;hp=ff36e3a7d43447d70379cfaa1f02f0a8be12ebcd;hpb=240499dc2c766c9d022e6df71e770a116a2c95de;p=dragonfireclient.git diff --git a/src/mapblock.h b/src/mapblock.h index ff36e3a7d..30e9e38f8 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -31,8 +31,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "constants.h" #include "mapblockobject.h" #include "voxel.h" +#include "nodemetadata.h" +#include "staticobject.h" -#define MAP_BLOCKSIZE 16 // Named by looking towards z+ enum{ @@ -59,14 +60,87 @@ enum NodeModType struct NodeMod { - NodeMod() + NodeMod(enum NodeModType a_type=NODEMOD_NONE, u16 a_param=0) { - type = NODEMOD_NONE; + type = a_type; + param = a_param; + } + bool operator==(const NodeMod &other) + { + return (type == other.type && param == other.param); } enum NodeModType type; u16 param; }; +class NodeModMap +{ +public: + /* + returns true if the mod was different last time + */ + bool set(v3s16 p, const NodeMod &mod) + { + // See if old is different, cancel if it is not different. + core::map::Node *n = m_mods.find(p); + if(n) + { + NodeMod old = n->getValue(); + if(old == mod) + return false; + + n->setValue(mod); + } + else + { + m_mods.insert(p, mod); + } + + return true; + } + // Returns true if there was one + bool get(v3s16 p, NodeMod *mod) + { + core::map::Node *n; + n = m_mods.find(p); + if(n == NULL) + return false; + if(mod) + *mod = n->getValue(); + return true; + } + bool clear(v3s16 p) + { + if(m_mods.find(p)) + { + m_mods.remove(p); + return true; + } + return false; + } + bool clear() + { + if(m_mods.size() == 0) + return false; + m_mods.clear(); + return true; + } + void copy(NodeModMap &dest) + { + dest.m_mods.clear(); + + for(core::map::Iterator + i = m_mods.getIterator(); + i.atEnd() == false; i++) + { + dest.m_mods.insert(i.getNode()->getKey(), i.getNode()->getValue()); + } + } + +private: + core::map m_mods; +}; + enum { NODECONTAINER_ID_MAPBLOCK, @@ -83,73 +157,87 @@ class NodeContainer virtual MapNode getNode(v3s16 p) = 0; virtual void setNode(v3s16 p, MapNode & n) = 0; virtual u16 nodeContainerId() const = 0; + + MapNode getNodeNoEx(v3s16 p) + { + try{ + return getNode(p); + } + catch(InvalidPositionException &e){ + return MapNode(CONTENT_IGNORE); + } + } }; -class MapBlock : public NodeContainer -{ -public: +/* + Mesh making stuff +*/ - /* - This used by Server's block creation stuff for not sending - blocks that are waiting a lighting update. +class MapBlock; - If true, the block needs some work by the one who set this - to true. +#ifndef SERVER - While true, nobody else should touch the block. - */ - //bool is_incomplete; +struct MeshMakeData +{ + u32 m_daynight_ratio; + NodeModMap m_temp_mods; + VoxelManipulator m_vmanip; + v3s16 m_blockpos; - scene::SMesh *mesh; - JMutex mesh_mutex; + /* + Copy central data directly from block, and other data from + parent of block. + */ + void fill(u32 daynight_ratio, MapBlock *block); +}; - MapBlock(NodeContainer *parent, v3s16 pos, bool dummy=false): - m_parent(parent), - m_pos(pos), - changed(true), - is_underground(false), - m_mesh_expired(false), - m_objects(this) - //is_incomplete(false) - { - data = NULL; - if(dummy == false) - reallocate(); - mesh_mutex.Init(); - mesh = NULL; - } +scene::SMesh* makeMapBlockMesh(MeshMakeData *data); - ~MapBlock() - { - { - JMutexAutoLock lock(mesh_mutex); - - if(mesh != NULL) - { - mesh->drop(); - mesh = NULL; - } - } +#endif - if(data) - delete[] data; - } +u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2, + v3s16 face_dir); + +/* + MapBlock itself +*/ + +class MapBlock : public NodeContainer +{ +public: + MapBlock(NodeContainer *parent, v3s16 pos, bool dummy=false); + ~MapBlock(); virtual u16 nodeContainerId() const { return NODECONTAINER_ID_MAPBLOCK; } - + NodeContainer * getParent() { return m_parent; } + void reallocate() + { + if(data != NULL) + delete[] data; + u32 l = MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE; + data = new MapNode[l]; + for(u32 i=0; i getBox() { return core::aabbox3d(getPosRelative(), @@ -209,19 +330,11 @@ class MapBlock : public NodeContainer + v3s16(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE) - v3s16(1,1,1)); } - - void reallocate() - { - if(data != NULL) - delete[] data; - u32 l = MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE; - data = new MapNode[l]; - for(u32 i=0; i= 0 && p.Z < MAP_BLOCKSIZE); } - /* - Regular MapNode get-setters - */ - MapNode getNode(s16 x, s16 y, s16 z) { if(data == NULL) @@ -302,6 +411,7 @@ class MapBlock : public NodeContainer bool isValidPositionParent(v3s16 p); MapNode getNodeParent(v3s16 p); void setNodeParent(v3s16 p, MapNode & n); + MapNode getNodeParentNoEx(v3s16 p); void drawbox(s16 x0, s16 y0, s16 z0, s16 w, s16 h, s16 d, MapNode node) { @@ -311,36 +421,83 @@ class MapBlock : public NodeContainer setNode(x0+x, y0+y, z0+z, node); } - static FastFace * makeFastFace(TileSpec tile, u8 light, v3f p, - v3s16 dir, v3f scale, v3f posRelative_f); + /* + Graphics-related methods + */ - u8 getFaceLight(u32 daylight_factor, v3s16 p, v3s16 face_dir); + /*// A quick version with nodes passed as parameters + u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2, + v3s16 face_dir);*/ + /*// A more convenient version + u8 getFaceLight(u32 daynight_ratio, v3s16 p, v3s16 face_dir) + { + return getFaceLight(daynight_ratio, + getNodeParentNoEx(p), + getNodeParentNoEx(p + face_dir), + face_dir); + }*/ + u8 getFaceLight2(u32 daynight_ratio, v3s16 p, v3s16 face_dir) + { + return getFaceLight(daynight_ratio, + getNodeParentNoEx(p), + getNodeParentNoEx(p + face_dir), + face_dir); + } + +#ifndef SERVER + // light = 0...255 + /*static void makeFastFace(TileSpec tile, u8 light, v3f p, + v3s16 dir, v3f scale, v3f posRelative_f, + core::array &dest);*/ - TileSpec getNodeTile(v3s16 p, v3s16 face_dir); - u8 getNodeContent(v3s16 p); + /*TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir, + NodeModMap &temp_mods);*/ + /*u8 getNodeContent(v3s16 p, MapNode mn, + NodeModMap &temp_mods);*/ /* - startpos: + Generates the FastFaces of a node row. This has a + ridiculous amount of parameters because that way they + can be precalculated by the caller. + translate_dir: unit vector with only one of x, y or z face_dir: unit vector with only one of x, y or z */ - void updateFastFaceRow( - u32 daylight_factor, + /*void updateFastFaceRow( + u32 daynight_ratio, + v3f posRelative_f, v3s16 startpos, u16 length, v3s16 translate_dir, + v3f translate_dir_f, v3s16 face_dir, - core::list &dest); - - void updateMesh(u32 daylight_factor); + v3f face_dir_f, + core::array &dest, + NodeModMap &temp_mods);*/ + + /* + Thread-safely updates the whole mesh of the mapblock. + */ +#if 1 + void updateMesh(u32 daynight_ratio); +#endif - bool propagateSunlight(core::map & light_sources); + void replaceMesh(scene::SMesh *mesh_new); + +#endif // !SERVER + + // See comments in mapblock.cpp + bool propagateSunlight(core::map & light_sources, + bool remove_light=false, bool *black_air_left=NULL, + bool grow_grass=false); // Copies data to VoxelManipulator to getPosRelative() void copyTo(VoxelManipulator &dst); + // Copies data from VoxelManipulator getPosRelative() + void copyFrom(VoxelManipulator &dst); /* - Object stuff + MapBlockObject stuff */ void serializeObjects(std::ostream &os, u8 version) @@ -349,9 +506,9 @@ class MapBlock : public NodeContainer } // If smgr!=NULL, new objects are added to the scene void updateObjects(std::istream &is, u8 version, - scene::ISceneManager *smgr) + scene::ISceneManager *smgr, u32 daynight_ratio) { - m_objects.update(is, version, smgr); + m_objects.update(is, version, smgr, daynight_ratio); setChangedFlag(); } @@ -382,12 +539,11 @@ class MapBlock : public NodeContainer { return m_objects.getLock(); } - void stepObjects(float dtime, bool server) - { - m_objects.step(dtime, server); - setChangedFlag(); - } + /* + Moves objects, deletes objects and spawns new objects + */ + void stepObjects(float dtime, bool server, u32 daynight_ratio); /*void wrapObject(MapBlockObject *object) { @@ -403,32 +559,86 @@ class MapBlock : public NodeContainer m_objects.getObjects(origin, max_d, dest); } - /*void getPseudoObjects(v3f origin, f32 max_d, - core::array &dest);*/ - s32 getObjectCount() { return m_objects.getCount(); } - + +#ifndef SERVER /* Methods for setting temporary modifications to nodes for drawing + + returns true if the mod was different last time */ - void setTempMod(v3s16 p, NodeMod mod) + bool setTempMod(v3s16 p, const NodeMod &mod) + { + /*dstream<<"setTempMod called on block" + <<" ("<