diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 9ee81e63f..4f1336d28 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -727,6 +727,17 @@ scene::IBillboardSceneNode* GenericCAO::getSpriteSceneNode() return m_spritenode; } +void GenericCAO::setChildrenVisible(bool toset) +{ + for (std::vector::iterator ci = m_children.begin(); + ci != m_children.end(); ci++) { + GenericCAO *obj = m_env->getGenericCAO(*ci); + if (obj) { + obj->setVisible(toset); + } + } +} + void GenericCAO::setAttachments() { updateAttachments(); @@ -1489,16 +1500,7 @@ void GenericCAO::updateBonePosition() void GenericCAO::updateAttachments() { - // localplayer itself can't be attached to localplayer - if (!m_is_local_player) - { - m_attached_to_local = getParent() != NULL && getParent()->isLocalPlayer(); - // Objects attached to the local player should always be hidden - m_is_visible = !m_attached_to_local; - } - - if(getParent() == NULL || m_attached_to_local) // Detach or don't attach - { + if (getParent() == NULL) { // Detach or don't attach scene::ISceneNode *node = getSceneNode(); if (node) { v3f old_position = node->getAbsolutePosition(); @@ -1667,14 +1669,26 @@ void GenericCAO::processMessage(const std::string &data) m_bone_position[bone] = core::vector2d(position, rotation); updateBonePosition(); - } - else if(cmd == GENERIC_CMD_SET_ATTACHMENT) { - m_env->m_attachements[getId()] = readS16(is); - m_children.push_back(m_env->m_attachements[getId()]); + } else if (cmd == GENERIC_CMD_SET_ATTACHMENT) { + u16 parentID = readS16(is); + m_env->m_attachements[getId()] = parentID; + GenericCAO *parentobj = m_env->getGenericCAO(parentID); + + if (parentobj) { + parentobj->m_children.push_back(getId()); + } + m_attachment_bone = deSerializeString(is); m_attachment_position = readV3F1000(is); m_attachment_rotation = readV3F1000(is); + // localplayer itself can't be attached to localplayer + if (!m_is_local_player) { + m_attached_to_local = getParent() != NULL && getParent()->isLocalPlayer(); + // Objects attached to the local player should be hidden by default + m_is_visible = !m_attached_to_local; + } + updateAttachments(); } else if(cmd == GENERIC_CMD_PUNCHED) { diff --git a/src/content_cao.h b/src/content_cao.h index 36245bd3b..813a41259 100644 --- a/src/content_cao.h +++ b/src/content_cao.h @@ -162,6 +162,8 @@ public: m_is_visible = toset; } + void setChildrenVisible(bool toset); + void setAttachments(); void removeFromScene(bool permanent); diff --git a/src/environment.cpp b/src/environment.cpp index dc18fd58f..7d80619bc 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -2400,6 +2400,15 @@ void ClientEnvironment::addSimpleObject(ClientSimpleObject *simple) m_simple_objects.push_back(simple); } +GenericCAO* ClientEnvironment::getGenericCAO(u16 id) +{ + ClientActiveObject *obj = getActiveObject(id); + if (obj && obj->getType() == ACTIVEOBJECT_TYPE_GENERIC) + return (GenericCAO*) obj; + else + return NULL; +} + ClientActiveObject* ClientEnvironment::getActiveObject(u16 id) { std::map::iterator n; diff --git a/src/environment.h b/src/environment.h index a25a12db3..983f09409 100644 --- a/src/environment.h +++ b/src/environment.h @@ -405,6 +405,8 @@ private: #ifndef SERVER #include "clientobject.h" +#include "content_cao.h" + class ClientSimpleObject; /* @@ -467,6 +469,7 @@ public: ActiveObjects */ + GenericCAO* getGenericCAO(u16 id); ClientActiveObject* getActiveObject(u16 id); /* diff --git a/src/game.cpp b/src/game.cpp index 903e4f85c..be4897d75 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3298,6 +3298,7 @@ void Game::updateCamera(VolatileRunFlags *flags, u32 busy_time, camera->toggleCameraMode(); playercao->setVisible(camera->getCameraMode() > CAMERA_MODE_FIRST); + playercao->setChildrenVisible(camera->getCameraMode() > CAMERA_MODE_FIRST); } float full_punch_interval = playeritem_toolcap.full_punch_interval;