1
0
Fork 0
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:
sfan5 2024-08-12 15:32:18 +02:00 committed by GitHub
parent a0e33ba9ea
commit 85e717fcd1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 245 additions and 172 deletions

View file

@ -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();

View file

@ -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; }

View file

@ -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);
}

View file

@ -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;