From c5e6274ac414a262801c514863bf633ed6c960b4 Mon Sep 17 00:00:00 2001 From: Baltazar Reis Date: Thu, 26 Mar 2026 15:42:10 +0000 Subject: [PATCH 1/3] Fix #3685: Prevent coin collection through solid weak blocks --- src/object/coin.cpp | 16 ++++++++++++++++ src/object/weak_block.hpp | 3 +++ 2 files changed, 19 insertions(+) diff --git a/src/object/coin.cpp b/src/object/coin.cpp index 8c7db8bea4a..1cd8aba9661 100644 --- a/src/object/coin.cpp +++ b/src/object/coin.cpp @@ -22,6 +22,7 @@ #include "object/bouncy_coin.hpp" #include "object/player.hpp" #include "object/tilemap.hpp" +#include "object/weak_block.hpp" #include "supertux/flip_level_transformer.hpp" #include "supertux/level.hpp" #include "supertux/sector.hpp" @@ -242,6 +243,21 @@ Coin::collision(MovingObject& other, const CollisionHit& ) auto player = dynamic_cast(&other); if (player == nullptr) return ABORT_MOVE; + + // Check if this coin is trapped inside an active WeakBlock + Vector coin_center = m_col.m_bbox.get_middle(); + for (auto& weak_block : Sector::get().get_objects_by_type()) { + if (weak_block.is_solid_block()) { + const Rectf& block_bbox = weak_block.get_bbox(); + if (coin_center.x >= block_bbox.get_left() && + coin_center.x <= block_bbox.get_right() && + coin_center.y >= block_bbox.get_top() && + coin_center.y <= block_bbox.get_bottom()) { + return ABORT_MOVE; + } + } + } + if (m_col.get_bbox().overlaps(player->get_bbox().grown(-0.1f))) collect(); return ABORT_MOVE; diff --git a/src/object/weak_block.hpp b/src/object/weak_block.hpp index d7c7b0b819b..0fb3165028e 100644 --- a/src/object/weak_block.hpp +++ b/src/object/weak_block.hpp @@ -46,6 +46,9 @@ class WeakBlock final : public MovingSprite virtual void on_flip(float height) override; void startBurning(); + + /** Check if this block is still solid (not destroyed) and blocking objects */ + inline bool is_solid_block() const { return state != STATE_DISINTEGRATING; } private: virtual HitResponse collision_bullet(Bullet& bullet, const CollisionHit& hit); From e2d0451428e55d203521bf45d2709395d5632b3d Mon Sep 17 00:00:00 2001 From: Baltazar Reis Date: Fri, 19 Jun 2026 16:36:43 +0100 Subject: [PATCH 2/3] Update src/object/coin.cpp Co-authored-by: MatusGuy <85036874+MatusGuy@users.noreply.github.com> --- src/object/coin.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/object/coin.cpp b/src/object/coin.cpp index 1cd8aba9661..0a5f51c21aa 100644 --- a/src/object/coin.cpp +++ b/src/object/coin.cpp @@ -247,15 +247,11 @@ Coin::collision(MovingObject& other, const CollisionHit& ) // Check if this coin is trapped inside an active WeakBlock Vector coin_center = m_col.m_bbox.get_middle(); for (auto& weak_block : Sector::get().get_objects_by_type()) { - if (weak_block.is_solid_block()) { - const Rectf& block_bbox = weak_block.get_bbox(); - if (coin_center.x >= block_bbox.get_left() && - coin_center.x <= block_bbox.get_right() && - coin_center.y >= block_bbox.get_top() && - coin_center.y <= block_bbox.get_bottom()) { - return ABORT_MOVE; - } - } + if (weak_block.get_group() == COLGROUP_DISABLED) + continue; + + if (weak_block.get_bbox().contains(coin_center)) + return ABORT_MOVE; } if (m_col.get_bbox().overlaps(player->get_bbox().grown(-0.1f))) From 9cba23b926abd1161aa1b65bef41750ff541a542 Mon Sep 17 00:00:00 2001 From: Baltazar Reis Date: Fri, 19 Jun 2026 16:36:53 +0100 Subject: [PATCH 3/3] Update src/object/weak_block.hpp Co-authored-by: MatusGuy <85036874+MatusGuy@users.noreply.github.com> --- src/object/weak_block.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/object/weak_block.hpp b/src/object/weak_block.hpp index 0fb3165028e..d7c7b0b819b 100644 --- a/src/object/weak_block.hpp +++ b/src/object/weak_block.hpp @@ -46,9 +46,6 @@ class WeakBlock final : public MovingSprite virtual void on_flip(float height) override; void startBurning(); - - /** Check if this block is still solid (not destroyed) and blocking objects */ - inline bool is_solid_block() const { return state != STATE_DISINTEGRATING; } private: virtual HitResponse collision_bullet(Bullet& bullet, const CollisionHit& hit);