Skip to content

Commit

Permalink
Fix crusher issues (#2854)
Browse files Browse the repository at this point in the history
* Fix weird crusher offset

* Rocks no longer push down crusher

* Rocks no longer pushed under terrain by crusher

* More changes

* Only crush rock and badguy under sensible conditions

* fix these little things [ci skip]

* improve if statement readability

* For mrkubax

---------

Co-authored-by: MatusGuy <[email protected]>
  • Loading branch information
weluvgoatz and MatusGuy authored Apr 21, 2024
1 parent b778105 commit 24087de
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 13 deletions.
27 changes: 22 additions & 5 deletions src/badguy/crusher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "object/camera.hpp"
#include "object/particles.hpp"
#include "object/player.hpp"
#include "object/rock.hpp"
#include "sprite/sprite.hpp"
#include "sprite/sprite_manager.hpp"
#include "supertux/flip_level_transformer.hpp"
Expand Down Expand Up @@ -136,10 +137,24 @@ Crusher::collision(GameObject& other, const CollisionHit& hit)
}

auto* badguy = dynamic_cast<BadGuy*>(&other);
if (badguy && m_state == CRUSHING) {
if (badguy && m_state == CRUSHING && ((!m_sideways && hit.bottom) ||
(m_sideways && ((hit.left && m_physic.get_velocity_x() < 0.f) ||
(hit.right && m_physic.get_velocity_x() > 0.f)))))
{
badguy->kill_fall();
}

auto* rock = dynamic_cast<Rock*>(&other);
if (rock && !rock->is_grabbed() && m_state == CRUSHING && ((!m_sideways && hit.bottom) ||
(m_sideways && ((hit.left && m_physic.get_velocity_x() < 0.f) ||
(hit.right && m_physic.get_velocity_x() > 0.f)))))
{
SoundManager::current()->play("sounds/brick.wav", get_pos());
m_physic.reset();
set_state(RECOVERING);
return ABORT_MOVE;
}

const auto* heavy_coin = dynamic_cast<HeavyCoin*>(&other);
if (heavy_coin) {
return ABORT_MOVE;
Expand Down Expand Up @@ -328,7 +343,7 @@ Crusher::update(float dt_sec)
switch (m_state)
{
case IDLE:
m_start_position = get_pos();
//m_start_position = get_pos();
if (found_victim())
{
set_state(CRUSHING);
Expand Down Expand Up @@ -360,9 +375,11 @@ Crusher::update(float dt_sec)
case RECOVERING:
if (returned_down || returned_up || returned_left || returned_right)
{
set_pos(Vector(m_sideways ? m_start_position.x : get_pos().x,
m_sideways ? get_pos().y : m_start_position.y));
m_physic.set_velocity(0.f, 0.f);
m_physic.reset();
// we have to offset the crusher when we bring it back to its original position because otherwise it will gain an ugly offset. #JustPhysicErrorThings
set_pos(Vector(m_sideways ? m_start_position.x + (2.6f * (m_side_dir == Direction::LEFT ? -1.f : 1.f)) : get_pos().x,
m_sideways ? get_pos().y : m_start_position.y + (2.6f * (m_flip ? -1.f : 1.f))));

if (m_ic_size == LARGE)
m_cooldown_timer = PAUSE_TIME_LARGE;
else
Expand Down
14 changes: 11 additions & 3 deletions src/collision/collision_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
namespace {

const float MAX_SPEED = 16.0f;
static const float FORGIVENESS = 256.f; // 16.f * 16.f - half a tile by half a tile.

} // namespace

Expand Down Expand Up @@ -419,6 +420,13 @@ CollisionSystem::collision_static(collision::Constraints* constraints,
// Collision with other (static) objects.
for (auto* static_object : m_objects)
{
const float static_size = static_object->get_bbox().get_width() * static_object->get_bbox().get_height();
const float object_size = object.get_bbox().get_width() * object.get_bbox().get_height();
// let's skip this if two colgroup_moving_static's connect and our object is somewhat larger than the static object.
if ((object.get_group() == COLGROUP_MOVING_STATIC && static_object->get_group() == COLGROUP_MOVING_STATIC) &&
(object_size > static_size + FORGIVENESS)) {
return;
}
if ((
static_object->get_group() == COLGROUP_STATIC ||
static_object->get_group() == COLGROUP_MOVING_STATIC
Expand Down Expand Up @@ -639,9 +647,9 @@ CollisionSystem::update()
{
auto object = *i;

if ((object->get_group() != COLGROUP_MOVING
&& object->get_group() != COLGROUP_MOVING_STATIC)
|| !object->is_valid())
if (!object->is_valid() ||
(object->get_group() != COLGROUP_MOVING &&
object->get_group() != COLGROUP_MOVING_STATIC))
continue;

for (auto i2 = i+1; i2 != m_objects.end(); ++i2) {
Expand Down
6 changes: 1 addition & 5 deletions src/object/rock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,7 @@ Rock::collision(GameObject& other, const CollisionHit& hit)

auto crusher = dynamic_cast<Crusher*> (&other);
if (crusher) {
auto state = crusher->get_state();
if(state == Crusher::CrusherState::RECOVERING ||
state == Crusher::CrusherState::IDLE) {
return ABORT_MOVE;
}
return FORCE_MOVE;
}

// Don't fall further if we are on a rock which is on the ground.
Expand Down

0 comments on commit 24087de

Please sign in to comment.