From ac4884c3d677ef51bcce47f95ccd49d874022692 Mon Sep 17 00:00:00 2001 From: stujones11 Date: Thu, 24 Aug 2017 09:01:16 +0100 Subject: [PATCH] Make entity selection and collision boxes independently settable (#6218) * Make entity selection and collision boxes independently settable --- doc/lua_api.txt | 3 +++ src/content_cao.cpp | 9 ++++++--- src/content_sao.cpp | 14 ++++++++------ src/object_properties.cpp | 8 ++++++++ src/object_properties.h | 2 ++ src/script/common/c_content.cpp | 11 +++++++++++ 6 files changed, 38 insertions(+), 9 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 7af935056..32dab9d00 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -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", diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 8f6847bc0..c34b47d51 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -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()) diff --git a/src/content_sao.cpp b/src/content_sao.cpp index bc5fb164b..4debc354f 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -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; } diff --git a/src/object_properties.cpp b/src/object_properties.cpp index 5534db283..c9e134710 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -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 diff --git a/src/object_properties.h b/src/object_properties.h index 116921f7d..a18c8a1bb 100644 --- a/src/object_properties.h +++ b/src/object_properties.h @@ -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); diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 47443493b..4360f63bb 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -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());