Make entity selection and collision boxes independently settable (#6218)
authorstujones11 <stujones111@gmail.com>
Thu, 24 Aug 2017 08:01:16 +0000 (09:01 +0100)
committerLoïc Blot <nerzhul@users.noreply.github.com>
Thu, 24 Aug 2017 08:01:16 +0000 (10:01 +0200)
* Make entity selection and collision boxes independently settable

doc/lua_api.txt
src/content_cao.cpp
src/content_sao.cpp
src/object_properties.cpp
src/object_properties.h
src/script/common/c_content.cpp

index 7af935056e146a7a67687e254da7b79e45c872cf..32dab9d00ee7d2eccec697aa710b43abe8375f17 100644 (file)
@@ -3986,6 +3986,9 @@ Definition tables
         collide_with_objects = true, -- collide with other objects if physical = true
         weight = 5,
         collisionbox = {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5},
+        selectionbox = {-0.5, 0.0, -0.5, 0.5, 1.0, 0.5},
+    --  ^ Default, uses collision box dimensions when not set
+        pointable = true, -- overrides selection box when false
         visual = "cube" / "sprite" / "upright_sprite" / "mesh" / "wielditem",
         visual_size = {x = 1, y = 1},
         mesh = "model",
index 8f6847bc055cb04a48ede87f181f1df374516d10..c34b47d51df0fd64b89e4a0b892cbcb198fe52a0 100644 (file)
@@ -346,7 +346,7 @@ GenericCAO::~GenericCAO()
 bool GenericCAO::getSelectionBox(aabb3f *toset) const
 {
        if (!m_prop.is_visible || !m_is_visible || m_is_local_player
-                       || getParent() != NULL){
+                       || !m_prop.pointable || getParent() != NULL) {
                return false;
        }
        *toset = m_selection_box;
@@ -1226,7 +1226,7 @@ void GenericCAO::processMessage(const std::string &data)
        if (cmd == GENERIC_CMD_SET_PROPERTIES) {
                m_prop = gob_read_set_properties(is);
 
-               m_selection_box = m_prop.collisionbox;
+               m_selection_box = m_prop.selectionbox;
                m_selection_box.MinEdge *= BS;
                m_selection_box.MaxEdge *= BS;
 
@@ -1240,7 +1240,10 @@ void GenericCAO::processMessage(const std::string &data)
                if (m_is_local_player) {
                        LocalPlayer *player = m_env->getLocalPlayer();
                        player->makes_footstep_sound = m_prop.makes_footstep_sound;
-                       player->setCollisionbox(m_selection_box);
+                       aabb3f collision_box = m_prop.collisionbox;
+                       collision_box.MinEdge *= BS;
+                       collision_box.MaxEdge *= BS;
+                       player->setCollisionbox(collision_box);
                }
 
                if ((m_is_player && !m_is_local_player) && m_prop.nametag.empty())
index bc5fb164b4c2183976d25173a21db41dbb01deb7..4debc354f15154a9966a355abc3f98ebe88a0e42 100644 (file)
@@ -752,12 +752,12 @@ bool LuaEntitySAO::getCollisionBox(aabb3f *toset) const
 
 bool LuaEntitySAO::getSelectionBox(aabb3f *toset) const
 {
-       if (!m_prop.is_visible) {
+       if (!m_prop.is_visible || !m_prop.pointable) {
                return false;
        }
 
-       toset->MinEdge = m_prop.collisionbox.MinEdge * BS;
-       toset->MaxEdge = m_prop.collisionbox.MaxEdge * BS;
+       toset->MinEdge = m_prop.selectionbox.MinEdge * BS;
+       toset->MaxEdge = m_prop.selectionbox.MaxEdge * BS;
 
        return true;
 }
@@ -786,6 +786,8 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id
        m_prop.physical = false;
        m_prop.weight = 75;
        m_prop.collisionbox = aabb3f(-0.3f, 0.0f, -0.3f, 0.3f, 1.77f, 0.3f);
+       m_prop.selectionbox = aabb3f(-0.3f, 0.0f, -0.3f, 0.3f, 1.77f, 0.3f);
+       m_prop.pointable = true;
        // start of default appearance, this should be overwritten by LUA
        m_prop.visual = "upright_sprite";
        m_prop.visual_size = v2f(1, 2);
@@ -1426,12 +1428,12 @@ bool PlayerSAO::getCollisionBox(aabb3f *toset) const
 
 bool PlayerSAO::getSelectionBox(aabb3f *toset) const
 {
-       if (!m_prop.is_visible) {
+       if (!m_prop.is_visible || !m_prop.pointable) {
                return false;
        }
 
-       toset->MinEdge = m_prop.collisionbox.MinEdge * BS;
-       toset->MaxEdge = m_prop.collisionbox.MaxEdge * BS;
+       toset->MinEdge = m_prop.selectionbox.MinEdge * BS;
+       toset->MaxEdge = m_prop.selectionbox.MaxEdge * BS;
 
        return true;
 }
index 5534db283c64388a7e469ed12d86cf0cae4849a0..c9e13471058c8aa8c622936822803d5e21171ee1 100644 (file)
@@ -61,6 +61,8 @@ std::string ObjectProperties::dump()
        os << ", nametag=" << nametag;
        os << ", nametag_color=" << "\"" << nametag_color.getAlpha() << "," << nametag_color.getRed()
                        << "," << nametag_color.getGreen() << "," << nametag_color.getBlue() << "\" ";
+       os << ", selectionbox=" << PP(selectionbox.MinEdge) << "," << PP(selectionbox.MaxEdge);
+       os << ", pointable=" << pointable;
        return os.str();
 }
 
@@ -99,6 +101,9 @@ void ObjectProperties::serialize(std::ostream &os) const
        writeF1000(os, automatic_face_movement_max_rotation_per_sec);
        os << serializeString(infotext);
        os << serializeString(wield_item);
+       writeV3F1000(os, selectionbox.MinEdge);
+       writeV3F1000(os, selectionbox.MaxEdge);
+       writeU8(os, pointable);
 
        // Add stuff only at the bottom.
        // Never remove anything, because we don't want new versions of this
@@ -142,6 +147,9 @@ void ObjectProperties::deSerialize(std::istream &is)
                        automatic_face_movement_max_rotation_per_sec = readF1000(is);
                        infotext = deSerializeString(is);
                        wield_item = deSerializeString(is);
+                       selectionbox.MinEdge = readV3F1000(is);
+                       selectionbox.MaxEdge = readV3F1000(is);
+                       pointable = readU8(is);
                }catch(SerializationError &e){}
        }
        else
index 116921f7d075f805fb5e2c7b03476e34b7bf3246..a18c8a1bb3e1fad56009f53cbb2d6184261f6812 100644 (file)
@@ -33,6 +33,8 @@ struct ObjectProperties
        bool collideWithObjects = true;
        float weight = 5.0f;
        aabb3f collisionbox = aabb3f(-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f);
+       aabb3f selectionbox = aabb3f(-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f);
+       bool pointable = true;
        std::string visual = "sprite";
        std::string mesh = "";
        v2f visual_size = v2f(1, 1);
index 47443493b8a751129adc5e6599674b0502a896a4..4360f63bbb715d126118dcca7fef95a33e365e06 100644 (file)
@@ -197,6 +197,13 @@ void read_object_properties(lua_State *L, int index,
                prop->collisionbox = read_aabb3f(L, -1, 1.0);
        lua_pop(L, 1);
 
+       lua_getfield(L, -1, "selectionbox");
+       if (lua_istable(L, -1))
+               prop->selectionbox = read_aabb3f(L, -1, 1.0);
+       else
+               prop->selectionbox = prop->collisionbox;
+       lua_pop(L, 1);
+       getboolfield(L, -1, "pointable", prop->pointable);
        getstringfield(L, -1, "visual", prop->visual);
 
        getstringfield(L, -1, "mesh", prop->mesh);
@@ -296,6 +303,10 @@ void push_object_properties(lua_State *L, ObjectProperties *prop)
        lua_setfield(L, -2, "weight");
        push_aabb3f(L, prop->collisionbox);
        lua_setfield(L, -2, "collisionbox");
+       push_aabb3f(L, prop->selectionbox);
+       lua_setfield(L, -2, "selectionbox");
+       lua_pushboolean(L, prop->pointable);
+       lua_setfield(L, -2, "pointable");
        lua_pushlstring(L, prop->visual.c_str(), prop->visual.size());
        lua_setfield(L, -2, "visual");
        lua_pushlstring(L, prop->mesh.c_str(), prop->mesh.size());