Custom collision boxes node property.
authorRealBadAngel <maciej.kasatkin@o2.pl>
Sat, 18 Oct 2014 16:46:16 +0000 (18:46 +0200)
committerRealBadAngel <maciej.kasatkin@o2.pl>
Sun, 19 Oct 2014 18:48:21 +0000 (20:48 +0200)
doc/lua_api.txt
src/collision.cpp
src/mapnode.cpp
src/mapnode.h
src/nodedef.cpp
src/nodedef.h
src/script/common/c_content.cpp

index 8f77366f7f4bee61a36a2c7f564c757193c53bc1..ff2143cc841ba07b6fd93075201317bae1e05cae 100644 (file)
@@ -408,8 +408,16 @@ param2 is reserved for the engine when any of these are used:
     0 = y+    1 = z+    2 = z-    3 = x+    4 = x-    5 = y-
     facedir's two less significant bits are rotation around the axis
   paramtype2 == "leveled"
-  ^ The drawn node level is read from param2, like flowingliquid
-
+  collision_box = {
+       type = "fixed",
+       fixed = {
+                       {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
+                       },
+  },
+  ^ defines list of collision boxes for the node. If empty, collision boxes
+       will be the same as nodeboxes, in case of any other nodes will be full cube
+       as in the example above.
+                       
 Nodes can also contain extra data. See "Node Metadata".
 
 Node drawtypes
index 76696e90db7deb8db0fd431f1a17b35d19c39743..edbee40b9599d802e793341822ef50b2935d8739 100644 (file)
@@ -259,7 +259,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
                                continue;
                        int n_bouncy_value = itemgroup_get(f.groups, "bouncy");
 
-                       std::vector<aabb3f> nodeboxes = n.getNodeBoxes(gamedef->ndef());
+                       std::vector<aabb3f> nodeboxes = n.getCollisionBoxes(gamedef->ndef());
                        for(std::vector<aabb3f>::iterator
                                        i = nodeboxes.begin();
                                        i != nodeboxes.end(); i++)
index d52677be07540def4fc0a15b8b3e0022c6887b4f..786224240a5e302a6f5cb13ed5b359e26f05d3de 100644 (file)
@@ -354,6 +354,15 @@ std::vector<aabb3f> MapNode::getNodeBoxes(INodeDefManager *nodemgr) const
        return transformNodeBox(*this, f.node_box, nodemgr);
 }
 
+std::vector<aabb3f> MapNode::getCollisionBoxes(INodeDefManager *nodemgr) const
+{
+       const ContentFeatures &f = nodemgr->get(*this);
+       if (f.collision_box.fixed.empty())
+               return transformNodeBox(*this, f.node_box, nodemgr);
+       else
+               return transformNodeBox(*this, f.collision_box, nodemgr);
+}
+
 std::vector<aabb3f> MapNode::getSelectionBoxes(INodeDefManager *nodemgr) const
 {
        const ContentFeatures &f = nodemgr->get(*this);
index f19885d87614f6e38e04254ce59bf06c2a94b3d2..d0b949e6ff60b257f838e107a4fd56db8383fbfc 100644 (file)
@@ -217,8 +217,7 @@ struct MapNode
        void rotateAlongYAxis(INodeDefManager *nodemgr, Rotation rot);
 
        /*
-               Gets list of node boxes (used for rendering (NDT_NODEBOX)
-               and collision)
+               Gets list of node boxes (used for rendering (NDT_NODEBOX))
        */
        std::vector<aabb3f> getNodeBoxes(INodeDefManager *nodemgr) const;
 
@@ -227,6 +226,11 @@ struct MapNode
        */
        std::vector<aabb3f> getSelectionBoxes(INodeDefManager *nodemgr) const;
 
+       /*
+               Gets list of collision boxes
+       */
+       std::vector<aabb3f> getCollisionBoxes(INodeDefManager *nodemgr) const;
+
        /* Liquid helpers */
        u8 getMaxLevel(INodeDefManager *nodemgr) const;
        u8 getLevel(INodeDefManager *nodemgr) const;
index ef61d0722a5b34314f14017ea80ae8b8bb127f74..5735ef91465406dc99919c6c485b8ece14b61688 100644 (file)
@@ -233,6 +233,7 @@ void ContentFeatures::reset()
        damage_per_second = 0;
        node_box = NodeBox();
        selection_box = NodeBox();
+       collision_box = NodeBox();
        waving = 0;
        legacy_facedir_simple = false;
        legacy_wallmounted = false;
@@ -303,6 +304,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
        os<<serializeString(mesh);
+       collision_box.serialize(os, protocol_version);
 }
 
 void ContentFeatures::deSerialize(std::istream &is)
@@ -372,6 +374,7 @@ void ContentFeatures::deSerialize(std::istream &is)
                // Stuff below should be moved to correct place in a version that
                // otherwise changes the protocol version
        mesh = deSerializeString(is);
+       collision_box.deSerialize(is);
        }catch(SerializationError &e) {};
 }
 
index 2400f5f7330646d501703d88a27d81eeb12b59c3..27d67b481198748086a9457e415a9910a773ccb9 100644 (file)
@@ -244,6 +244,7 @@ struct ContentFeatures
        u32 damage_per_second;
        NodeBox node_box;
        NodeBox selection_box;
+       NodeBox collision_box;
        // Used for waving leaves/plants
        u8 waving;
        // Compatibility with old maps
index 4737f19933916e513272abf7af5894175d359ad0..58d8c473ee8a925761ce7e5b58d4e7744bffc45d 100644 (file)
@@ -432,6 +432,11 @@ ContentFeatures read_content_features(lua_State *L, int index)
                f.selection_box = read_nodebox(L, -1);
        lua_pop(L, 1);
 
+       lua_getfield(L, index, "collision_box");
+       if(lua_istable(L, -1))
+               f.collision_box = read_nodebox(L, -1);
+       lua_pop(L, 1);
+
        f.waving = getintfield_default(L, index,
                        "waving", f.waving);