diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 386b7e07..eab1e627 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -591,6 +591,21 @@ void LuaEntitySAO::getAttachment(int *parent_id, std::string *bone, v3f *positio *rotation = m_attachment_rotation; } +void LuaEntitySAO::addAttachmentChild(int child_id) +{ + m_attachment_child_ids.insert(child_id); +} + +void LuaEntitySAO::removeAttachmentChild(int child_id) +{ + m_attachment_child_ids.erase(child_id); +} + +std::set LuaEntitySAO::getAttachmentChildIds() +{ + return m_attachment_child_ids; +} + ObjectProperties* LuaEntitySAO::accessObjectProperties() { return &m_prop; @@ -1231,6 +1246,21 @@ void PlayerSAO::getAttachment(int *parent_id, std::string *bone, v3f *position, *rotation = m_attachment_rotation; } +void PlayerSAO::addAttachmentChild(int child_id) +{ + m_attachment_child_ids.insert(child_id); +} + +void PlayerSAO::removeAttachmentChild(int child_id) +{ + m_attachment_child_ids.erase(child_id); +} + +std::set PlayerSAO::getAttachmentChildIds() +{ + return m_attachment_child_ids; +} + ObjectProperties* PlayerSAO::accessObjectProperties() { return &m_prop; diff --git a/src/content_sao.h b/src/content_sao.h index f6156666..1f0a68cd 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -65,6 +65,9 @@ public: void getBonePosition(const std::string &bone, v3f *position, v3f *rotation); void setAttachment(int parent_id, const std::string &bone, v3f position, v3f rotation); void getAttachment(int *parent_id, std::string *bone, v3f *position, v3f *rotation); + void addAttachmentChild(int child_id); + void removeAttachmentChild(int child_id); + std::set getAttachmentChildIds(); ObjectProperties* accessObjectProperties(); void notifyObjectPropertiesModified(); /* LuaEntitySAO-specific */ @@ -113,6 +116,7 @@ private: bool m_bone_position_sent; int m_attachment_parent_id; + std::set m_attachment_child_ids; std::string m_attachment_bone; v3f m_attachment_position; v3f m_attachment_rotation; @@ -204,6 +208,9 @@ public: void getBonePosition(const std::string &bone, v3f *position, v3f *rotation); void setAttachment(int parent_id, const std::string &bone, v3f position, v3f rotation); void getAttachment(int *parent_id, std::string *bone, v3f *position, v3f *rotation); + void addAttachmentChild(int child_id); + void removeAttachmentChild(int child_id); + std::set getAttachmentChildIds(); ObjectProperties* accessObjectProperties(); void notifyObjectPropertiesModified(); void setNametagColor(video::SColor color); @@ -320,6 +327,7 @@ private: bool m_bone_position_sent; int m_attachment_parent_id; + std::set m_attachment_child_ids; std::string m_attachment_bone; v3f m_attachment_position; v3f m_attachment_rotation; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index e407ef16..96fb0c57 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -132,10 +132,22 @@ int ObjectRef::gc_object(lua_State *L) { int ObjectRef::l_remove(lua_State *L) { NO_MAP_LOCK_REQUIRED; + GET_ENV_PTR; + ObjectRef *ref = checkobject(L, 1); ServerActiveObject *co = getobject(ref); - if(co == NULL) return 0; - if(co->getType() == ACTIVEOBJECT_TYPE_PLAYER) return 0; + if (co == NULL) + return 0; + if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER) + return 0; + + std::set child_ids = co->getAttachmentChildIds(); + std::set::iterator it; + for (it = child_ids.begin(); it != child_ids.end(); ++it) { + ServerActiveObject *child = env->getActiveObject(*it); + child->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0)); + } + verbosestream<<"ObjectRef::l_remove(): id="<getId()<m_removed = true; return 0; @@ -630,23 +642,38 @@ int ObjectRef::l_get_bone_position(lua_State *L) int ObjectRef::l_set_attach(lua_State *L) { NO_MAP_LOCK_REQUIRED; + GET_ENV_PTR; + ObjectRef *ref = checkobject(L, 1); ObjectRef *parent_ref = checkobject(L, 2); ServerActiveObject *co = getobject(ref); ServerActiveObject *parent = getobject(parent_ref); - if(co == NULL) return 0; - if(parent == NULL) return 0; + if (co == NULL) + return 0; + if (parent == NULL) + return 0; // Do it + int parent_id = 0; std::string bone = ""; - if(!lua_isnil(L, 3)) - bone = lua_tostring(L, 3); v3f position = v3f(0, 0, 0); - if(!lua_isnil(L, 4)) - position = read_v3f(L, 4); v3f rotation = v3f(0, 0, 0); - if(!lua_isnil(L, 5)) + co->getAttachment(&parent_id, &bone, &position, &rotation); + if (parent_id) { + ServerActiveObject *old_parent = env->getActiveObject(parent_id); + old_parent->removeAttachmentChild(co->getId()); + } + + bone = ""; + if (!lua_isnil(L, 3)) + bone = lua_tostring(L, 3); + position = v3f(0, 0, 0); + if (!lua_isnil(L, 4)) + position = read_v3f(L, 4); + rotation = v3f(0, 0, 0); + if (!lua_isnil(L, 5)) rotation = read_v3f(L, 5); co->setAttachment(parent->getId(), bone, position, rotation); + parent->addAttachmentChild(co->getId()); return 0; } @@ -682,11 +709,26 @@ int ObjectRef::l_get_attach(lua_State *L) int ObjectRef::l_set_detach(lua_State *L) { NO_MAP_LOCK_REQUIRED; + GET_ENV_PTR; + ObjectRef *ref = checkobject(L, 1); ServerActiveObject *co = getobject(ref); - if(co == NULL) return 0; + if (co == NULL) + return 0; + + int parent_id = 0; + std::string bone = ""; + v3f position; + v3f rotation; + co->getAttachment(&parent_id, &bone, &position, &rotation); + ServerActiveObject *parent = NULL; + if (parent_id) + parent = env->getActiveObject(parent_id); + // Do it co->setAttachment(0, "", v3f(0,0,0), v3f(0,0,0)); + if (parent != NULL) + parent->removeAttachmentChild(co->getId()); return 0; } diff --git a/src/serverobject.h b/src/serverobject.h index 7204fe3a..597eb63a 100644 --- a/src/serverobject.h +++ b/src/serverobject.h @@ -163,6 +163,12 @@ public: {} virtual void getAttachment(int *parent_id, std::string *bone, v3f *position, v3f *rotation) {} + virtual void addAttachmentChild(int child_id) + {} + virtual void removeAttachmentChild(int child_id) + {} + virtual std::set getAttachmentChildIds() + { return std::set(); } virtual ObjectProperties* accessObjectProperties() { return NULL; } virtual void notifyObjectPropertiesModified()