+class UnitSAO: public ServerActiveObject
+{
+public:
+ UnitSAO(ServerEnvironment *env, v3f pos);
+ virtual ~UnitSAO() = default;
+
+ void setRotation(v3f rotation) { m_rotation = rotation; }
+ const v3f &getRotation() const { return m_rotation; }
+ v3f getRadRotation() { return m_rotation * core::DEGTORAD; }
+
+ // Deprecated
+ f32 getRadYawDep() const { return (m_rotation.Y + 90.) * core::DEGTORAD; }
+
+ u16 getHP() const { return m_hp; }
+ // Use a function, if isDead can be defined by other conditions
+ bool isDead() const { return m_hp == 0; }
+
+ inline bool isAttached() const
+ { return getParent(); }
+
+ inline bool isImmortal() const
+ { return itemgroup_get(getArmorGroups(), "immortal"); }
+
+ void setArmorGroups(const ItemGroupList &armor_groups);
+ const ItemGroupList &getArmorGroups() const;
+ void setAnimation(v2f frame_range, float frame_speed, float frame_blend, bool frame_loop);
+ void getAnimation(v2f *frame_range, float *frame_speed, float *frame_blend, bool *frame_loop);
+ void setAnimationSpeed(float frame_speed);
+ void setBonePosition(const std::string &bone, v3f position, v3f rotation);
+ 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) const;
+ void clearChildAttachments();
+ void clearParentAttachment();
+ void addAttachmentChild(int child_id);
+ void removeAttachmentChild(int child_id);
+ const std::unordered_set<int> &getAttachmentChildIds() const;
+ ServerActiveObject *getParent() const;
+ ObjectProperties* accessObjectProperties();
+ void notifyObjectPropertiesModified();
+protected:
+ u16 m_hp = 1;
+
+ v3f m_rotation;
+
+ bool m_properties_sent = true;
+ ObjectProperties m_prop;
+
+ ItemGroupList m_armor_groups;
+ bool m_armor_groups_sent = false;
+
+ v2f m_animation_range;
+ float m_animation_speed = 0.0f;
+ float m_animation_blend = 0.0f;
+ bool m_animation_loop = true;
+ bool m_animation_sent = false;
+ bool m_animation_speed_sent = false;
+
+ // Stores position and rotation for each bone name
+ std::unordered_map<std::string, core::vector2d<v3f>> m_bone_position;
+ bool m_bone_position_sent = false;
+
+ int m_attachment_parent_id = 0;
+ std::unordered_set<int> m_attachment_child_ids;
+ std::string m_attachment_bone = "";
+ v3f m_attachment_position;
+ v3f m_attachment_rotation;
+ bool m_attachment_sent = false;
+private:
+ void onAttach(int parent_id);
+ void onDetach(int parent_id);
+};