summaryrefslogtreecommitdiff
path: root/src/content_nodemeta.cpp
Commit message (Collapse)AuthorAge
* C++11 patchset 9: move hardcoded init parameters to class definitions (part ↵Loïc Blot2017-06-16
| | | | | | | | | | | | | | | | | | | | | | | | 1) (#5984) * C++11 patchset 9: move hardcoded init parameters to class definitions C++11 introduced the possibility to define the default values directly in class definitions, do it on current code Also remove some unused attributes * CollisionInfo::bouncy * collisionMoveResult::collides_xy * collisionMoveResult::standing_on_unloaded * Clouds::speed * More constructor cleanups + some variables removal * remove only write guiFormSpecMenu::m_old_tooltip * move header included inside defintions in genericobject.h * remove some unused since years exception classes * remove unused & empty debug_stacks_init * remove unused & empty content_nodemeta_serialize_legacy * remove forgotten useless bool (bouncy) in collision.cpp code
* Make node timers more efficientEkdohibs2016-06-11
|
* Rename macros with two leading underscoresShadowNinja2015-10-14
| | | | These names are reserved for the compiler/library implementations.
* Use warningstream for log messages with WARNINGShadowNinja2015-10-14
| | | | Remove DTIME macro and its uses, too
* Various style cleanups + unused code removalest312015-09-19
| | | | | | | | | | -> Don't pass pointer to whole IGameDef to NodeMetadata constructors and deserializers, but only to IItemDefManager, which is needed -> Remove the unused content_mapnode_get_new_name() method -> Fix style for MapBlock::deSerialize and MapBlock::deSerialize_pre22, improving accuracy of error messages a bit -> Fix style at other serialisation methods too -> Improve accuracy of some comments
* Omnicleanup: header cleanup, add ModApiUtil shared between game and mainmenuKahrl2013-08-14
|
* Update Copyright YearsSfan52013-02-24
|
* Change Minetest-c55 to MinetestPilzAdam2013-02-24
|
* Implement formspecdarkrose2012-07-22
|
* Properly and efficiently use split utility headersPerttu Ahola2012-06-17
|
* Switch the license to be LGPLv2/later, with small parts still remaining as ↵Perttu Ahola2012-06-05
| | | | GPLv2/later, by agreement of major contributors
* Fix loading of old signsPerttu Ahola2012-06-04
|
* Fix loading of legacy chestsPerttu Ahola2012-06-03
|
* Implement sign using form field protocolPerttu Ahola2012-06-03
|
* Convert legacy chest inventory list "0" to "main"Perttu Ahola2012-06-03
|
* Strip unneeded variables from NodeMetadatadarkrose2012-06-03
|
* WIP node metadata, node timersKahrl2012-06-03
|
* Fix server hang when stepping a furnace with a huge dtimeKahrl2012-02-02
|
* The huge item definition and item namespace unification patch (itemdef), see ↵Kahrl2012-01-12
| | | | http://c55.me/minetest/wiki/doku.php?id=changes:itemdef
* Move NodeMetadata prototype containers to content_nodemeta.cpp to fix them ↵Perttu Ahola2011-12-01
| | | | not being filled correctly on some systems and compilers
* GenericNodeMetadata and an example furnacePerttu Ahola2011-11-29
|
* Mode node definition loading from Lua (still not finished), fix metadata ↵Perttu Ahola2011-11-29
| | | | creation from name
* Add names to NodeMetadataPerttu Ahola2011-11-29
|
* Do not expose CONTENT_* stuff in content_mapnode.h and use a name converter ↵Perttu Ahola2011-11-29
| | | | wrapper in old code
* Remove burn time definitions from FurnaceNodeMetadataPerttu Ahola2011-11-29
|
* Clean mapnode.h and fix other files accordinglyPerttu Ahola2011-11-29
|
* Create framework for getting rid of global definitions of ↵Perttu Ahola2011-11-29
| | | | node/tool/item/whatever types
* Switch more stuff to use the logging thing and fix segfault on player leave ↵Perttu Ahola2011-10-16
| | | | from server as introduced in a previous switch-to-logging commit
* added locking chests - clean patchdarkrose2011-09-22
|
* Furnace was crashing stuff againJacobF2011-09-02
|
* * Furnace would say it was overloaded when it had a non-cookable sourceJacobF2011-09-01
| | | | | * I didn't understand that expression last fix and now the furnace would burn fuel even when it had no source item.
* If there was no source item in a furnace it would cause a segmentation fault.JacobF2011-08-30
|
* Merge remote-tracking branch 'queatz/furnace-is-not-blackhole'Perttu Ahola2011-08-30
|\
| * Don't remove furnace if something is inside it.JacobF2011-08-24
| |
* | Merged 2 branches because they relied on each other.JacobF2011-08-25
|/ | | | | | | | | | | This one contains these changes from main c55: * Adds a function to check if there is room for a specific item * Using that, you can now pick up rats if you have a full inventory and a not full rat stack * Furnace would cook only 1 item if that item used the last available result slot, now it will continue * Furnace will say it's overloaded * Furnace won't wait until the next step to start on the next item - This caused small fuels to cook slower than meant to - Also caused furnaces to say they were out of fuel after finishing the last fuel item
* Some inventory const-ificationGiuseppe Bilotta2011-08-11
|
* made more things burnable in furnacePerttu Ahola2011-07-30
|
* fixed wrong furnace menu layoutPerttu Ahola2011-06-18
|
* moved inventory menu definition of chest and furnace to content_nodemeta.{h,cpp}Perttu Ahola2011-06-18
|
* Created and moved stuff to content_nodemeta.{h,cpp}Perttu Ahola2011-06-18
">{ *this = a; return; } if(a.MinEdge.X < MinEdge.X) MinEdge.X = a.MinEdge.X; if(a.MinEdge.Y < MinEdge.Y) MinEdge.Y = a.MinEdge.Y; if(a.MinEdge.Z < MinEdge.Z) MinEdge.Z = a.MinEdge.Z; if(a.MaxEdge.X > MaxEdge.X) MaxEdge.X = a.MaxEdge.X; if(a.MaxEdge.Y > MaxEdge.Y) MaxEdge.Y = a.MaxEdge.Y; if(a.MaxEdge.Z > MaxEdge.Z) MaxEdge.Z = a.MaxEdge.Z; } void addPoint(v3s16 p) { if(getExtent() == v3s16(0,0,0)) { MinEdge = p; MaxEdge = p; return; } if(p.X < MinEdge.X) MinEdge.X = p.X; if(p.Y < MinEdge.Y) MinEdge.Y = p.Y; if(p.Z < MinEdge.Z) MinEdge.Z = p.Z; if(p.X > MaxEdge.X) MaxEdge.X = p.X; if(p.Y > MaxEdge.Y) MaxEdge.Y = p.Y; if(p.Z > MaxEdge.Z) MaxEdge.Z = p.Z; } // Pad with d nodes void pad(v3s16 d) { MinEdge -= d; MaxEdge += d; } /*void operator+=(v3s16 off) { MinEdge += off; MaxEdge += off; } void operator-=(v3s16 off) { MinEdge -= off; MaxEdge -= off; }*/ /* const methods */ v3s16 getExtent() const { return MaxEdge - MinEdge + v3s16(1,1,1); } s32 getVolume() const { v3s16 e = getExtent(); return (s32)e.X * (s32)e.Y * (s32)e.Z; } bool contains(const VoxelArea &a) const { // No area contains an empty area // NOTE: Algorithms depend on this, so do not change. if(a.getExtent() == v3s16(0,0,0)) return false; return( a.MinEdge.X >= MinEdge.X && a.MaxEdge.X <= MaxEdge.X && a.MinEdge.Y >= MinEdge.Y && a.MaxEdge.Y <= MaxEdge.Y && a.MinEdge.Z >= MinEdge.Z && a.MaxEdge.Z <= MaxEdge.Z ); } bool contains(v3s16 p) const { return( p.X >= MinEdge.X && p.X <= MaxEdge.X && p.Y >= MinEdge.Y && p.Y <= MaxEdge.Y && p.Z >= MinEdge.Z && p.Z <= MaxEdge.Z ); } bool contains(s32 i) const { return (i >= 0 && i < getVolume()); } bool operator==(const VoxelArea &other) const { return (MinEdge == other.MinEdge && MaxEdge == other.MaxEdge); } VoxelArea operator+(v3s16 off) const { return VoxelArea(MinEdge+off, MaxEdge+off); } VoxelArea operator-(v3s16 off) const { return VoxelArea(MinEdge-off, MaxEdge-off); } /* Returns 0-6 non-overlapping areas that can be added to a to make up this area. a: area inside *this */ void diff(const VoxelArea &a, core::list<VoxelArea> &result) { /* This can result in a maximum of 6 areas */ // If a is an empty area, return the current area as a whole if(a.getExtent() == v3s16(0,0,0)) { VoxelArea b = *this; if(b.getVolume() != 0) result.push_back(b); return; } assert(contains(a)); // Take back area, XY inclusive { v3s16 min(MinEdge.X, MinEdge.Y, a.MaxEdge.Z+1); v3s16 max(MaxEdge.X, MaxEdge.Y, MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take front area, XY inclusive { v3s16 min(MinEdge.X, MinEdge.Y, MinEdge.Z); v3s16 max(MaxEdge.X, MaxEdge.Y, a.MinEdge.Z-1); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take top area, X inclusive { v3s16 min(MinEdge.X, a.MaxEdge.Y+1, a.MinEdge.Z); v3s16 max(MaxEdge.X, MaxEdge.Y, a.MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take bottom area, X inclusive { v3s16 min(MinEdge.X, MinEdge.Y, a.MinEdge.Z); v3s16 max(MaxEdge.X, a.MinEdge.Y-1, a.MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take left area, non-inclusive { v3s16 min(MinEdge.X, a.MinEdge.Y, a.MinEdge.Z); v3s16 max(a.MinEdge.X-1, a.MaxEdge.Y, a.MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take right area, non-inclusive { v3s16 min(a.MaxEdge.X+1, a.MinEdge.Y, a.MinEdge.Z); v3s16 max(MaxEdge.X, a.MaxEdge.Y, a.MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } } /* Translates position from virtual coordinates to array index */ s32 index(s16 x, s16 y, s16 z) const { v3s16 em = getExtent(); v3s16 off = MinEdge; s32 i = (s32)(z-off.Z)*em.Y*em.X + (y-off.Y)*em.X + (x-off.X); //dstream<<" i("<<x<<","<<y<<","<<z<<")="<<i<<" "; return i; } s32 index(v3s16 p) const { return index(p.X, p.Y, p.Z); } // Translate index in the X coordinate void add_x(const v3s16 &extent, u32 &i, s16 a) { i += a; } // Translate index in the Y coordinate void add_y(const v3s16 &extent, u32 &i, s16 a) { i += a * extent.X; } // Translate index in the Z coordinate void add_z(const v3s16 &extent, u32 &i, s16 a) { i += a * extent.X*extent.Y; } // Translate index in space void add_p(const v3s16 &extent, u32 &i, v3s16 a) { i += a.Z*extent.X*extent.Y + a.Y*extent.X + a.X; } /* Print method for debugging */ void print(std::ostream &o) const { v3s16 e = getExtent(); o<<"("<<MinEdge.X <<","<<MinEdge.Y <<","<<MinEdge.Z <<")("<<MaxEdge.X <<","<<MaxEdge.Y <<","<<MaxEdge.Z <<")" <<"="<<e.X<<"x"<<e.Y<<"x"<<e.Z<<"="<<getVolume(); } // Edges are inclusive v3s16 MinEdge; v3s16 MaxEdge; }; // Hasn't been copied from source (emerged) #define VOXELFLAG_NOT_LOADED (1<<0) // Checked as being inexistent in source #define VOXELFLAG_INEXISTENT (1<<1) // Algorithm-dependent #define VOXELFLAG_CHECKED1 (1<<2) // Algorithm-dependent #define VOXELFLAG_CHECKED2 (1<<3) // Algorithm-dependent #define VOXELFLAG_CHECKED3 (1<<4) // Algorithm-dependent #define VOXELFLAG_CHECKED4 (1<<5) enum VoxelPrintMode { VOXELPRINT_NOTHING, VOXELPRINT_MATERIAL, VOXELPRINT_WATERPRESSURE, }; class VoxelManipulator /*: public NodeContainer*/ { public: VoxelManipulator(); virtual ~VoxelManipulator(); /* Virtuals from NodeContainer */ /*virtual u16 nodeContainerId() const { return NODECONTAINER_ID_VOXELMANIPULATOR; } bool isValidPosition(v3s16 p) { emerge(p); return !(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT); }*/ /* These are a bit slow and shouldn't be used internally. Use m_data[m_area.index(p)] instead. */ MapNode getNode(v3s16 p) { emerge(p); if(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT) { dstream<<"EXCEPT: VoxelManipulator::getNode(): " <<"p=("<<p.X<<","<<p.Y<<","<<p.Z<<")" <<", index="<<m_area.index(p) <<", flags="<<(int)m_flags[m_area.index(p)] <<" is inexistent"<<std::endl; throw InvalidPositionException ("VoxelManipulator: getNode: inexistent"); } return m_data[m_area.index(p)]; } MapNode getNodeNoEx(v3s16 p) { emerge(p); if(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT) { return MapNode(CONTENT_IGNORE); } return m_data[m_area.index(p)]; } MapNode getNodeNoExNoEmerge(v3s16 p) { if(m_area.contains(p) == false) return MapNode(CONTENT_IGNORE); if(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT) return MapNode(CONTENT_IGNORE); return m_data[m_area.index(p)]; } MapNode & getNodeRef(v3s16 p) { emerge(p); if(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT) { dstream<<"EXCEPT: VoxelManipulator::getNode(): " <<"p=("<<p.X<<","<<p.Y<<","<<p.Z<<")" <<", index="<<m_area.index(p) <<", flags="<<(int)m_flags[m_area.index(p)] <<" is inexistent"<<std::endl; throw InvalidPositionException ("VoxelManipulator: getNode: inexistent"); } return m_data[m_area.index(p)]; } void setNode(v3s16 p, MapNode &n) { emerge(p); m_data[m_area.index(p)] = n; m_flags[m_area.index(p)] &= ~VOXELFLAG_INEXISTENT; m_flags[m_area.index(p)] &= ~VOXELFLAG_NOT_LOADED; } void setNodeNoRef(v3s16 p, MapNode n) { setNode(p, n); } /*void setExists(VoxelArea a) { emerge(a); for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++) for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++) for(s32 x=a.MinEdge.X; x<=a.MaxEdge.X; x++) { m_flags[m_area.index(x,y,z)] &= ~VOXELFLAG_INEXISTENT; } }*/ /*MapNode & operator[](v3s16 p) { //dstream<<"operator[] p=("<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl; if(isValidPosition(p) == false) emerge(VoxelArea(p)); return m_data[m_area.index(p)]; }*/ /* Set stuff if available without an emerge. Return false if failed. This is convenient but slower than playing around directly with the m_data table with indices. */ bool setNodeNoEmerge(v3s16 p, MapNode n) { if(m_area.contains(p) == false) return false; m_data[m_area.index(p)] = n; } bool setNodeNoEmerge(s32 i, MapNode n) { if(m_area.contains(i) == false) return false; m_data[i] = n; } /*bool setContentNoEmerge(v3s16 p, u8 c) { if(isValidPosition(p) == false) return false; m_data[m_area.index(p)].d = c; }*/ /* Control */ virtual void clear(); void print(std::ostream &o, VoxelPrintMode mode=VOXELPRINT_MATERIAL); void addArea(VoxelArea area); /* Copy data and set flags to 0 dst_area.getExtent() <= src_area.getExtent() */ void copyFrom(MapNode *src, VoxelArea src_area, v3s16 from_pos, v3s16 to_pos, v3s16 size); // Copy data void copyTo(MapNode *dst, VoxelArea dst_area, v3s16 dst_pos, v3s16 from_pos, v3s16 size); /* Algorithms */ void clearFlag(u8 flag); void unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight, core::map<v3s16, bool> & light_sources); void unspreadLight(enum LightBank bank, core::map<v3s16, u8> & from_nodes, core::map<v3s16, bool> & light_sources); void spreadLight(enum LightBank bank, v3s16 p); void spreadLight(enum LightBank bank, core::map<v3s16, bool> & from_nodes); /* Virtual functions */ /* Get the contents of the requested area from somewhere. Shall touch only nodes that have VOXELFLAG_NOT_LOADED Shall reset VOXELFLAG_NOT_LOADED If not found from source, add with VOXELFLAG_INEXISTENT */ virtual void emerge(VoxelArea a, s32 caller_id=-1) { //dstream<<"emerge p=("<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl; addArea(a); for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++) for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++) for(s32 x=a.MinEdge.X; x<=a.MaxEdge.X; x++) { s32 i = m_area.index(x,y,z); // Don't touch nodes that have already been loaded if(!(m_flags[i] & VOXELFLAG_NOT_LOADED)) continue; m_flags[i] = VOXELFLAG_INEXISTENT; } } /* Member variables */ /* The area that is stored in m_data. addInternalBox should not be used if getExtent() == v3s16(0,0,0) MaxEdge is 1 higher than maximum allowed position */ VoxelArea m_area; /* NULL if data size is 0 (extent (0,0,0)) Data is stored as [z*h*w + y*h + x] */ MapNode *m_data; /* Flags of all nodes */ u8 *m_flags; //TODO: Use these or remove them //TODO: Would these make any speed improvement? //bool m_pressure_route_valid; //v3s16 m_pressure_route_surface; /* Some settings */ //bool m_disable_water_climb; private: }; #endif