diff --git a/src/badguy/badguy.cpp b/src/badguy/badguy.cpp index dabf82453ef..92848605eb7 100644 --- a/src/badguy/badguy.cpp +++ b/src/badguy/badguy.cpp @@ -775,7 +775,9 @@ BadGuy::might_fall(int height) const x1 = m_col.m_bbox.get_right(); x2 = m_col.m_bbox.get_right() + 1; } - return Sector::get().is_free_of_statics(Rectf(x1, y1, x2, y2)); + const Rectf rect = Rectf(x1, y1, x2, y2); + + return Sector::get().is_free_of_statics(rect) && Sector::get().is_free_of_specifically_movingstatics(rect); } Player* diff --git a/src/collision/collision_system.cpp b/src/collision/collision_system.cpp index ca51c89004e..ebe5691f6b1 100644 --- a/src/collision/collision_system.cpp +++ b/src/collision/collision_system.cpp @@ -714,6 +714,22 @@ CollisionSystem::is_free_of_movingstatics(const Rectf& rect, const CollisionObje return true; } +bool +CollisionSystem::is_free_of_specifically_movingstatics(const Rectf& rect, const CollisionObject* ignore_object) const +{ + using namespace collision; + + for (const auto& object : m_objects) { + if (object == ignore_object) continue; + if (!object->is_valid()) continue; + if ((object->get_group() == COLGROUP_MOVING_STATIC) + && (intersects(rect, object->get_bbox()))) + return false; + } + + return true; +} + CollisionSystem::RaycastResult CollisionSystem::get_first_line_intersection(const Vector& line_start, const Vector& line_end, diff --git a/src/collision/collision_system.hpp b/src/collision/collision_system.hpp index 559c1b6bea6..9a7fcf40aed 100644 --- a/src/collision/collision_system.hpp +++ b/src/collision/collision_system.hpp @@ -65,6 +65,7 @@ class CollisionSystem final bool is_free_of_tiles(const Rectf& rect, const bool ignoreUnisolid = false, uint32_t tiletype = Tile::SOLID) const; bool is_free_of_statics(const Rectf& rect, const CollisionObject* ignore_object, const bool ignoreUnisolid) const; bool is_free_of_movingstatics(const Rectf& rect, const CollisionObject* ignore_object) const; + bool is_free_of_specifically_movingstatics(const Rectf& rect, const CollisionObject* ignore_object) const; RaycastResult get_first_line_intersection(const Vector& line_start, diff --git a/src/supertux/sector.cpp b/src/supertux/sector.cpp index 63f103fefad..747c1e25230 100644 --- a/src/supertux/sector.cpp +++ b/src/supertux/sector.cpp @@ -497,6 +497,13 @@ Sector::is_free_of_movingstatics(const Rectf& rect, const MovingObject* ignore_o ignore_object ? ignore_object->get_collision_object() : nullptr); } +bool +Sector::is_free_of_specifically_movingstatics(const Rectf& rect, const MovingObject* ignore_object) const +{ + return m_collision_system->is_free_of_specifically_movingstatics(rect, + ignore_object ? ignore_object->get_collision_object() : nullptr); +} + CollisionSystem::RaycastResult Sector::get_first_line_intersection(const Vector& line_start, const Vector& line_end, diff --git a/src/supertux/sector.hpp b/src/supertux/sector.hpp index 3d1898f72ef..6df95d15252 100644 --- a/src/supertux/sector.hpp +++ b/src/supertux/sector.hpp @@ -109,6 +109,10 @@ class Sector final : public Base::Sector This includes badguys and players. */ bool is_free_of_movingstatics(const Rectf& rect, const MovingObject* ignore_object = nullptr) const; + /** Checks if the specified rectangle is free of MovingObjects in COLGROUP_MOVINGSTATIC. + Note that this does not include moving badguys, or players */ + bool is_free_of_specifically_movingstatics(const Rectf& rect, const MovingObject* ignore_object = nullptr) const; + CollisionSystem::RaycastResult get_first_line_intersection(const Vector& line_start, const Vector& line_end, bool ignore_objects,