mirror of
https://github.com/luanti-org/luanti.git
synced 2025-10-05 19:31:04 +00:00
Rework object attachment handling to fix bugs (#14825)
This commit is contained in:
parent
a0e33ba9ea
commit
85e717fcd1
17 changed files with 245 additions and 172 deletions
|
@ -368,7 +368,7 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
|
|||
void ClientEnvironment::removeActiveObject(u16 id)
|
||||
{
|
||||
// Get current attachment childs to detach them visually
|
||||
std::unordered_set<int> attachment_childs;
|
||||
std::unordered_set<ClientActiveObject::object_t> attachment_childs;
|
||||
if (auto *obj = getActiveObject(id))
|
||||
attachment_childs = obj->getAttachmentChildIds();
|
||||
|
||||
|
|
|
@ -57,8 +57,8 @@ public:
|
|||
virtual bool isLocalPlayer() const { return false; }
|
||||
|
||||
virtual ClientActiveObject *getParent() const { return nullptr; };
|
||||
virtual const std::unordered_set<int> &getAttachmentChildIds() const
|
||||
{ static std::unordered_set<int> rv; return rv; }
|
||||
virtual const std::unordered_set<object_t> &getAttachmentChildIds() const
|
||||
{ static std::unordered_set<object_t> rv; return rv; }
|
||||
virtual void updateAttachments() {};
|
||||
|
||||
virtual bool doShowSelectionBox() { return true; }
|
||||
|
|
|
@ -465,7 +465,7 @@ scene::IAnimatedMeshSceneNode *GenericCAO::getAnimatedMeshSceneNode() const
|
|||
|
||||
void GenericCAO::setChildrenVisible(bool toset)
|
||||
{
|
||||
for (u16 cao_id : m_attachment_child_ids) {
|
||||
for (object_t cao_id : m_attachment_child_ids) {
|
||||
GenericCAO *obj = m_env->getGenericCAO(cao_id);
|
||||
if (obj) {
|
||||
// Check if the entity is forced to appear in first person.
|
||||
|
@ -474,10 +474,10 @@ void GenericCAO::setChildrenVisible(bool toset)
|
|||
}
|
||||
}
|
||||
|
||||
void GenericCAO::setAttachment(int parent_id, const std::string &bone,
|
||||
void GenericCAO::setAttachment(object_t parent_id, const std::string &bone,
|
||||
v3f position, v3f rotation, bool force_visible)
|
||||
{
|
||||
int old_parent = m_attachment_parent_id;
|
||||
const auto old_parent = m_attachment_parent_id;
|
||||
m_attachment_parent_id = parent_id;
|
||||
m_attachment_bone = bone;
|
||||
m_attachment_position = position;
|
||||
|
@ -509,7 +509,7 @@ void GenericCAO::setAttachment(int parent_id, const std::string &bone,
|
|||
}
|
||||
}
|
||||
|
||||
void GenericCAO::getAttachment(int *parent_id, std::string *bone, v3f *position,
|
||||
void GenericCAO::getAttachment(object_t *parent_id, std::string *bone, v3f *position,
|
||||
v3f *rotation, bool *force_visible) const
|
||||
{
|
||||
*parent_id = m_attachment_parent_id;
|
||||
|
@ -523,29 +523,21 @@ void GenericCAO::clearChildAttachments()
|
|||
{
|
||||
// Cannot use for-loop here: setAttachment() modifies 'm_attachment_child_ids'!
|
||||
while (!m_attachment_child_ids.empty()) {
|
||||
int child_id = *m_attachment_child_ids.begin();
|
||||
const auto child_id = *m_attachment_child_ids.begin();
|
||||
|
||||
if (ClientActiveObject *child = m_env->getActiveObject(child_id))
|
||||
child->setAttachment(0, "", v3f(), v3f(), false);
|
||||
|
||||
removeAttachmentChild(child_id);
|
||||
if (auto *child = m_env->getActiveObject(child_id))
|
||||
child->clearParentAttachment();
|
||||
else
|
||||
removeAttachmentChild(child_id);
|
||||
}
|
||||
}
|
||||
|
||||
void GenericCAO::clearParentAttachment()
|
||||
{
|
||||
if (m_attachment_parent_id)
|
||||
setAttachment(0, "", m_attachment_position, m_attachment_rotation, false);
|
||||
else
|
||||
setAttachment(0, "", v3f(), v3f(), false);
|
||||
}
|
||||
|
||||
void GenericCAO::addAttachmentChild(int child_id)
|
||||
void GenericCAO::addAttachmentChild(object_t child_id)
|
||||
{
|
||||
m_attachment_child_ids.insert(child_id);
|
||||
}
|
||||
|
||||
void GenericCAO::removeAttachmentChild(int child_id)
|
||||
void GenericCAO::removeAttachmentChild(object_t child_id)
|
||||
{
|
||||
m_attachment_child_ids.erase(child_id);
|
||||
}
|
||||
|
|
|
@ -106,8 +106,8 @@ private:
|
|||
// stores position and rotation for each bone name
|
||||
BoneOverrideMap m_bone_override;
|
||||
|
||||
int m_attachment_parent_id = 0;
|
||||
std::unordered_set<int> m_attachment_child_ids;
|
||||
object_t m_attachment_parent_id = 0;
|
||||
std::unordered_set<object_t> m_attachment_child_ids;
|
||||
std::string m_attachment_bone = "";
|
||||
v3f m_attachment_position;
|
||||
v3f m_attachment_rotation;
|
||||
|
@ -226,16 +226,15 @@ public:
|
|||
}
|
||||
|
||||
void setChildrenVisible(bool toset);
|
||||
void setAttachment(int parent_id, const std::string &bone, v3f position,
|
||||
void setAttachment(object_t parent_id, const std::string &bone, v3f position,
|
||||
v3f rotation, bool force_visible) override;
|
||||
void getAttachment(int *parent_id, std::string *bone, v3f *position,
|
||||
void getAttachment(object_t *parent_id, std::string *bone, v3f *position,
|
||||
v3f *rotation, bool *force_visible) const override;
|
||||
void clearChildAttachments() override;
|
||||
void clearParentAttachment() override;
|
||||
void addAttachmentChild(int child_id) override;
|
||||
void removeAttachmentChild(int child_id) override;
|
||||
void addAttachmentChild(object_t child_id) override;
|
||||
void removeAttachmentChild(object_t child_id) override;
|
||||
ClientActiveObject *getParent() const override;
|
||||
const std::unordered_set<int> &getAttachmentChildIds() const override
|
||||
const std::unordered_set<object_t> &getAttachmentChildIds() const override
|
||||
{ return m_attachment_child_ids; }
|
||||
void updateAttachments() override;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue