-
-
Notifications
You must be signed in to change notification settings - Fork 545
Fix issue #3321 where Granitos would sink into the ground if a rock was dropped on top of them. #3412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Fix issue #3321 where Granitos would sink into the ground if a rock was dropped on top of them. #3412
Conversation
Granito’s collision handling was updated to prevent rocks from propagating movement into the granito, which previously caused granito to be forced downward when a rock landed on its head. A new check ensures that rocks do not trigger movement propagation. - Added rock-specific guard in Granito::collision to block propagation Closes SuperTux#3321
After the initial fix for rocks pushing granito into the floor, a new bug appeared when a rock remained on granito’s head and the player jumped on top. Granito would forget the rock and begin sinking again. To resolve this, a new state flag (m_has_rock_on_top) was introduced and checked in both collision and update. Granito now consistently tracks whether a rock is present above its head across frames, preventing the sinking bug while still allowing players to ride granito correctly. - Added m_has_rock_on_top flag to Granito - Updated collision to set flag when rock detected - Added update logic to probe bounding box and clear flag when rock removed
When a big granito carried a smaller granito, dropping a rock on the smaller one caused both to sink into the ground. This happened because rock-on-top logic was applied even while the granito was in a carried state, leaking movement propagation into the carrier. To resolve this, collision handling was updated to eject the small granito when a rock lands while it is carried, reset its physics, and restore it to a standing state. This ensures rocks no longer propagate movement through carried granitos and prevents both entities from sinking. - Added eject + reset logic when rock hits a carried granito - Ensured carried granito transitions back to STATE_STAND - Blocked propagation when rock is present on carried granito
Cleaned up collision handling by removing unnecessary state assignments
(STAND and original state) after ejecting a carried granito. The eject
logic already resets physics and restores a neutral state, so these
extra lines were redundant.
- Deleted redundant m_state/m_original_state assignments
- Deleted redundant set_action("stand", m_dir) call
- Use const reference in Rock iteration loop - Remove newline in collision check
|
Thank you! I've triggered another build. |
Hi! All checks have passed — is there anything else I should update before this can be merged ? Also regarding the original issue: a comment mentioned that lanterns might have the same bug, but I tested them and they seem to behave correctly. |
I want someone else to at least review this as well before merging. |
Hypernoot
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested in game, works.
Frostwithasideofsalt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Walking granitos turn into standing granitos if a rock is placed on them, this shouldn't happen as it can softlock levels.
Prevent walking granitos from turning into standing when a rock is placed on top - Removed update logic that forced STATE_STAND when m_has_rock_on_top cleared - Changed collision handling: small granitos now enter STATE_LOOKUP when a rock lands - Added m_has_rock_on_top flag, treated like m_stepped_on, to restore original state cleanly - Ensures walking granitos no longer softlock into standing state under rocks
Override Granitobig collision handling to separate it from small granitos - Added virtual HitResponse collision(MovingObject&, const CollisionHit&) override - Prevented GranitoBig from triggering small granitos' collision logic - Makes big vs small granito collision paths cleaner and easier to debug
Granitobig propagate movement to objects on top - In update(), added m_col.propagate_movement(m_physic.get_movement(dt_sec)) - Ensures rocks, lanterns, and players ride correctly on big granitos - Matches expected behavior: big granitos carry objects above them
Rock abort collision handling when colliding with GranitoBig - Added dynamic_cast check in Rock::collision - Return ABORT_MOVE when colliding with GranitoBig - Calls collision() but skips handling, as per collision_hit.hpp comment - Allows rocks to propagate with big granitos without sinking them
Thanks for pointing this out I have adjusted the behaviour so walking granitos no longer incorrectly switch to standing when a rock is placed on them.
|
swagtoy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Frankly, speaking, what happens when you drop a rock on other objects? Is this a granito specific issue?
|
The logic for a rock being dropped on the second granito doesn't seem right anyway. I feel like we shouldn't mess with the sprite state. It looks weird. EDIT: This is what @Frostwithasideofsalt was claiming |
Just to clarify your comment when you say “the second granito” are you referring to: the small granito, the big granito, or the case where a small granito is riding on top of a big granito (being carried)? I want to make sure I understand the context correctly before adjusting the behaviour. |
Fix code style in rock.cpp
- Rename granitoBig to granito to match the dynamic cast in granito.cpp
- Add a space after the If ")" and "{"
- Make sure to follow the style of lines 222->225 in rock.cpp
Remove redundant m_has_rock_on_top flag - Rename m_stepped_on → m_has_entity_on_top to better reflect usage - m_has_entity_on_top now indicates whether any entity (player or rock) was on top of the granito in the last frame
|
I’ve committed the requested style fixes and also unified the flags (m_stepped_on → m_has_entity_on_top) as mentioned. Regarding this comment:
This part still remains, and I need to understand it a bit more before I can adjust the behaviour properly. Apologies if my work has required extra requests this is my first open source contribution, so I’m still learning the workflow. Any further feedback is appreciated. |
Update declaration of 'granito' in rock.cpp to use a pointer-to-const - Resolves the cppcheck style warning src/object/rock.cpp:227:10: style: Variable 'granito' can be declared as pointer to const [constVariablePointer] - Improves const correctness by ensuring 'granito' is only used for read-only access, preventing accidental modification of the underlying object and aligning with project coding standards.
2273d79 to
cd564ee
Compare
Summary
This PR fixes issue #3321 where Granitos would sink into the ground if a rock was dropped on top of them.
Changes
Reproduction Steps
Expected Behavior
Issue Reference
Closes #3321
Demo Video
Fix.mp4