Also, use a better distance calculation for 'collide with objects'.
Fixes the issue of a vehicle occasionally colliding with its own driver,
causing one of the velocity components to be set to zero.
virtual scene::ISceneNode *getSceneNode() { return NULL; }
virtual scene::IAnimatedMeshSceneNode *getAnimatedMeshSceneNode() { return NULL; }
virtual bool isLocalPlayer() const {return false;}
+ virtual ClientActiveObject *getParent() const { return nullptr; };
virtual void setAttachments() {}
virtual bool doShowSelectionBox(){return true;}
#ifndef SERVER
ClientEnvironment *c_env = dynamic_cast<ClientEnvironment*>(env);
if (c_env != 0) {
- f32 distance = speed_f->getLength();
+ // Calculate distance by speed, add own extent and 1.5m of tolerance
+ f32 distance = speed_f->getLength() * dtime +
+ box_0.getExtent().getLength() + 1.5f * BS;
std::vector<DistanceSortedActiveObject> clientobjects;
- c_env->getActiveObjects(*pos_f, distance * 1.5f, clientobjects);
+ c_env->getActiveObjects(*pos_f, distance, clientobjects);
+
for (auto &clientobject : clientobjects) {
- if (!self || (self != clientobject.obj)) {
+ // Do collide with everything but itself and the parent CAO
+ if (!self || (self != clientobject.obj &&
+ self != clientobject.obj->getParent())) {
objects.push_back((ActiveObject*) clientobject.obj);
}
}
{
ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env);
if (s_env != NULL) {
- f32 distance = speed_f->getLength();
+ // Calculate distance by speed, add own extent and 1.5m of tolerance
+ f32 distance = speed_f->getLength() * dtime +
+ box_0.getExtent().getLength() + 1.5f * BS;
std::vector<u16> s_objects;
- s_env->getObjectsInsideRadius(s_objects, *pos_f, distance * 1.5f);
+ s_env->getObjectsInsideRadius(s_objects, *pos_f, distance);
+
for (u16 obj_id : s_objects) {
ServerActiveObject *current = s_env->getActiveObject(obj_id);
- if (!self || (self != current)) {
+
+ if (!self || (self != current &&
+ self != current->getParent())) {
objects.push_back((ActiveObject*)current);
}
}
void processInitData(const std::string &data);
- ClientActiveObject *getParent() const;
-
bool getCollisionBox(aabb3f *toset) const;
bool collideWithObjects() const;
void setChildrenVisible(bool toset);
+ ClientActiveObject *getParent() const;
+
void setAttachments();
void removeFromScene(bool permanent);
m_armor_groups["fleshy"] = 100;
}
-bool UnitSAO::isAttached() const
+ServerActiveObject *UnitSAO::getParent() const
{
if (!m_attachment_parent_id)
- return false;
+ return nullptr;
// Check if the parent still exists
ServerActiveObject *obj = m_env->getActiveObject(m_attachment_parent_id);
- if (obj)
- return true;
- return false;
+
+ return obj;
}
void UnitSAO::setArmorGroups(const ItemGroupList &armor_groups)
// Use a function, if isDead can be defined by other conditions
bool isDead() const { return m_hp == 0; }
- bool isAttached() const;
+ inline bool isAttached() const
+ { return getParent(); }
+
void setArmorGroups(const ItemGroupList &armor_groups);
const ItemGroupList &getArmorGroups();
void setAnimation(v2f frame_range, float frame_speed, float frame_blend, bool frame_loop);
void addAttachmentChild(int child_id);
void removeAttachmentChild(int child_id);
const std::unordered_set<int> &getAttachmentChildIds();
+ ServerActiveObject *getParent() const;
ObjectProperties* accessObjectProperties();
void notifyObjectPropertiesModified();
protected:
{}
virtual const std::unordered_set<int> &getAttachmentChildIds()
{ static const std::unordered_set<int> rv; return rv; }
+ virtual ServerActiveObject *getParent() const { return nullptr; }
virtual ObjectProperties* accessObjectProperties()
{ return NULL; }
virtual void notifyObjectPropertiesModified()