Leveled nodebox
authorproller <proller@github.com>
Sat, 13 Jul 2013 17:48:14 +0000 (21:48 +0400)
committerproller <proller@github.com>
Sat, 13 Jul 2013 18:13:24 +0000 (22:13 +0400)
src/mapnode.cpp
src/mapnode.h
src/nodedef.cpp
src/nodedef.h
src/script/common/c_content.cpp
src/script/cpp_api/s_node.cpp

index f9323118770a11178bb8d0357f201174b5489690..33644cf5cc84f671d4df1f9385e5c5ceb47b9a22 100644 (file)
@@ -163,7 +163,7 @@ static std::vector<aabb3f> transformNodeBox(const MapNode &n,
                const NodeBox &nodebox, INodeDefManager *nodemgr)
 {
        std::vector<aabb3f> boxes;
-       if(nodebox.type == NODEBOX_FIXED)
+       if(nodebox.type == NODEBOX_FIXED || nodebox.type == NODEBOX_LEVELED)
        {
                const std::vector<aabb3f> &fixed = nodebox.fixed;
                int facedir = n.getFaceDir(nodemgr);
@@ -174,6 +174,11 @@ static std::vector<aabb3f> transformNodeBox(const MapNode &n,
                                i != fixed.end(); i++)
                {
                        aabb3f box = *i;
+
+                       if (nodebox.type == NODEBOX_LEVELED) {
+                               box.MaxEdge.Y = -BS/2 + BS*((float)1/LEVELED_MAX) * n.getLevel(nodemgr);
+                       }
+
                        switch (axisdir)
                        {
                        case 0:
@@ -354,6 +359,24 @@ std::vector<aabb3f> MapNode::getSelectionBoxes(INodeDefManager *nodemgr) const
        return transformNodeBox(*this, f.selection_box, nodemgr);
 }
 
+u8 MapNode::getLevel(INodeDefManager *nodemgr) const
+{
+       const ContentFeatures &f = nodemgr->get(*this);
+       if(f.liquid_type == LIQUID_SOURCE)
+               return LIQUID_LEVEL_SOURCE;
+       if (f.param_type_2 == CPT2_FLOWINGLIQUID)
+               return getParam2() & LIQUID_LEVEL_MASK;
+       if(f.liquid_type == LIQUID_FLOWING) // can remove if all param_type_2 setted
+               return getParam2() & LIQUID_LEVEL_MASK;
+       if(f.leveled || f.param_type_2 == CPT2_LEVELED) {
+                u8 level = getParam2() & LEVELED_MASK;
+                if(level) return level;
+                if(f.leveled > LEVELED_MAX) return LEVELED_MAX;
+                return f.leveled; //default
+       }
+       return 0;
+}
+
 u32 MapNode::serializedLength(u8 version)
 {
        if(!ser_ver_supported(version))
index 60211b87cae1ec7d450811e9d3292e82e5d56a44..53e36b670e892ff779297d65e65273df286c44f7 100644 (file)
@@ -87,6 +87,10 @@ enum Rotation {
 
 #define LIQUID_INFINITY_MASK 0x80 //0b10000000
 
+// mask for param2, now as for liquid
+#define LEVELED_MASK 0x07
+#define LEVELED_MAX LEVELED_MASK
+
 /*
        This is the stuff what the whole world consists of.
 */
@@ -206,6 +210,9 @@ struct MapNode
        */
        std::vector<aabb3f> getSelectionBoxes(INodeDefManager *nodemgr) const;
 
+       /* Liquid helpers */
+       u8 getLevel(INodeDefManager *nodemgr) const;
+
        /*
                Serialization functions
        */
index 13e7e99585b5cb4d9c33dbd0d970856ba15cbde8..4b2fe1643b1111fe5eb149193584dd060b0676df 100644 (file)
@@ -50,7 +50,7 @@ void NodeBox::serialize(std::ostream &os) const
        writeU8(os, 1); // version
        writeU8(os, type);
 
-       if(type == NODEBOX_FIXED)
+       if(type == NODEBOX_FIXED || type == NODEBOX_LEVELED)
        {
                writeU16(os, fixed.size());
                for(std::vector<aabb3f>::const_iterator
@@ -82,7 +82,7 @@ void NodeBox::deSerialize(std::istream &is)
 
        type = (enum NodeBoxType)readU8(is);
 
-       if(type == NODEBOX_FIXED)
+       if(type == NODEBOX_FIXED || type == NODEBOX_LEVELED)
        {
                u16 fixed_count = readU16(is);
                while(fixed_count--)
@@ -206,6 +206,7 @@ void ContentFeatures::reset()
        climbable = false;
        buildable_to = false;
        rightclickable = true;
+       leveled = 0;
        liquid_type = LIQUID_NONE;
        liquid_alternative_flowing = "";
        liquid_alternative_source = "";
@@ -281,6 +282,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version)
        // Stuff below should be moved to correct place in a version that otherwise changes
        // the protocol version
        writeU8(os, drowning);
+       writeU8(os, leveled);
 }
 
 void ContentFeatures::deSerialize(std::istream &is)
@@ -346,6 +348,7 @@ void ContentFeatures::deSerialize(std::istream &is)
                // Stuff below should be moved to correct place in a version that
                // otherwise changes the protocol version
                drowning = readU8(is);
+               leveled = readU8(is);
        }catch(SerializationError &e) {};
 }
 
index 665a5ddc23d062205a911f99ce779a2e8e5f8cc5..7505cc12d1353ad2a7afe05240e935c6e28e4f9d 100644 (file)
@@ -56,13 +56,15 @@ enum ContentParamType2
        CPT2_FACEDIR,
        // Direction for signs, torches and such
        CPT2_WALLMOUNTED,
+       // Block level like FLOWINGLIQUID
+       CPT2_LEVELED,
 };
 
 enum LiquidType
 {
        LIQUID_NONE,
        LIQUID_FLOWING,
-       LIQUID_SOURCE
+       LIQUID_SOURCE,
 };
 
 enum NodeBoxType
@@ -70,6 +72,7 @@ enum NodeBoxType
        NODEBOX_REGULAR, // Regular block; allows buildable_to
        NODEBOX_FIXED, // Static separately defined box(es)
        NODEBOX_WALLMOUNTED, // Box for wall mounted nodes; (top, bottom, side)
+       NODEBOX_LEVELED, // Same as fixed, but with dynamic height from param2. for snow, ...
 };
 
 struct NodeBox
@@ -207,6 +210,8 @@ struct ContentFeatures
        bool buildable_to;
        // Player cannot build to these (placement prediction disabled)
        bool rightclickable;
+       // Flowing liquid or snow, value = default level
+       u8 leveled;
        // Whether the node is non-liquid, source liquid or flowing liquid
        enum LiquidType liquid_type;
        // If the content is liquid, this is the flowing version of the liquid.
index 4ea296523172fee6407bdd1d54b178ffdcd32f89..11f74916013960a12ac2ad273d50bf4880d4fb4a 100644 (file)
@@ -389,6 +389,8 @@ ContentFeatures read_content_features(lua_State *L, int index)
        // the slowest possible
        f.liquid_viscosity = getintfield_default(L, index,
                        "liquid_viscosity", f.liquid_viscosity);
+       f.leveled = getintfield_default(L, index, "leveled", f.leveled);
+
        getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
        getboolfield(L, index, "drowning", f.drowning);
        // Amount of light the node emits
index 969e2f4d92bfc05ffb820f8b5a5fbf85a07fe506..49a825cacb690b40c583ef7905800e57500ea0ba 100644 (file)
@@ -50,6 +50,7 @@ struct EnumString ScriptApiNode::es_ContentParamType2[] =
                {CPT2_FLOWINGLIQUID, "flowingliquid"},
                {CPT2_FACEDIR, "facedir"},
                {CPT2_WALLMOUNTED, "wallmounted"},
+               {CPT2_LEVELED, "leveled"},
                {0, NULL},
        };
 
@@ -73,6 +74,7 @@ struct EnumString ScriptApiNode::es_NodeBoxType[] =
                {NODEBOX_REGULAR, "regular"},
                {NODEBOX_FIXED, "fixed"},
                {NODEBOX_WALLMOUNTED, "wallmounted"},
+               {NODEBOX_LEVELED, "leveled"},
                {0, NULL},
        };