diff --git a/src/badguy/crusher.cpp b/src/badguy/crusher.cpp index 0dfb20407ad..9e378b3e87d 100644 --- a/src/badguy/crusher.cpp +++ b/src/badguy/crusher.cpp @@ -123,31 +123,37 @@ HitResponse Crusher::collision(GameObject& other, const CollisionHit& hit) { auto* player = dynamic_cast(&other); + bool crushed_bottom = m_state == CRUSHING && !m_sideways && hit.bottom; + bool crushed_sideways = m_state == CRUSHING && m_sideways && + ((hit.left && m_physic.get_velocity_x() < 0.f) || + (hit.right && m_physic.get_velocity_x() > 0.f)); + bool is_crushing = crushed_bottom || crushed_sideways; // If the other object is the player, and the collision is at the // bottom of the crusher, hurt the player. - if (player && hit.bottom && player->on_ground() && m_state == CRUSHING) { + if (player && is_crushing && + ((crushed_bottom && player->on_ground()) || crushed_sideways)) + { SoundManager::current()->play("sounds/brick.wav", get_pos()); set_state(RECOVERING); + if (player->is_invincible()) { return ABORT_MOVE; } + player->kill(false); + return FORCE_MOVE; } auto* badguy = dynamic_cast(&other); - 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))))) + if (badguy && is_crushing) { badguy->kill_fall(); } auto* rock = dynamic_cast(&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))))) + if (rock && !rock->is_grabbed() && is_crushing) { SoundManager::current()->play("sounds/brick.wav", get_pos()); m_physic.reset(); @@ -226,14 +232,20 @@ Crusher::collision_solid(const CollisionHit& hit) } } } - if (hit.bottom) - spawn_roots(Direction::DOWN); - else if (hit.top) - spawn_roots(Direction::UP); - else if (hit.left) - spawn_roots(Direction::LEFT); - else if (hit.right) - spawn_roots(Direction::RIGHT); + if(m_sideways) + { + if (hit.left) + spawn_roots(Direction::LEFT); + else if (hit.right) + spawn_roots(Direction::RIGHT); + } + else + { + if (hit.bottom) + spawn_roots(Direction::DOWN); + else if (hit.top) + spawn_roots(Direction::UP); + } break; default: log_debug << "Crusher in invalid state" << std::endl; @@ -637,18 +649,27 @@ Crusher::eye_position(bool right) const } break; case RECOVERING: + { + // Amplitude dependent on size. + auto amplitude = static_cast(m_sprite->get_width()) / 64.0f * 2.0f; + + //Phase factor due to cooldown timer. + auto cooldown_phase_factor = (m_ic_size == NORMAL ? RECOVER_SPEED_NORMAL : RECOVER_SPEED_LARGE) + m_cooldown_timer * 13.0f; + + // Phase factor due to y position. + auto y_position_phase_factor = !m_sideways ? get_pos().y / 13 : get_pos().x / 13; + + auto phase_factor = y_position_phase_factor - cooldown_phase_factor; + // Eyes spin while crusher is recovering, giving a dazed impression. return Vector(sinf((right ? 1 : -1) * // X motion of each eye is opposite of the other. - ((!m_sideways ? get_pos().y / 13 : get_pos().x / 13) - // Phase factor due to y position. - (m_ic_size == NORMAL ? RECOVER_SPEED_NORMAL : RECOVER_SPEED_LARGE) + m_cooldown_timer * 13.0f)) * //Phase factor due to cooldown timer. - static_cast(m_sprite->get_width()) / 64.0f * 2.0f - (right ? 1 : -1) * // Amplitude dependent on size. - static_cast(m_sprite->get_width()) / 64.0f * 2.0f, // Offset to keep eyes visible. + phase_factor) * amplitude - (right ? 1 : -1) * + amplitude, // Offset to keep eyes visible. cosf((right ? 3.1415f : 0.0f) + // Eyes spin out of phase of eachother. - (!m_sideways ? get_pos().y / 13 : get_pos().x / 13) - // Phase factor due to y position. - (m_ic_size == NORMAL ? RECOVER_SPEED_NORMAL : RECOVER_SPEED_LARGE) + m_cooldown_timer * 13.0f) * //Phase factor due to cooldown timer. - static_cast(m_sprite->get_width()) / 64.0f * 2.0f - // Amplitude dependent on size. - static_cast(m_sprite->get_width()) / 64.0f * 2.0f); // Offset to keep eyes visible. + phase_factor) * amplitude - + amplitude); // Offset to keep eyes visible. + } default: log_debug << "Crusher in invalid state" << std::endl; break; diff --git a/src/object/player.cpp b/src/object/player.cpp index 168a2a35244..5c2f878e641 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -2322,14 +2322,8 @@ Player::collision_solid(const CollisionHit& hit) m_physic.set_velocity_x(0); } - // crushed? - if (hit.crush) { - if (hit.left || hit.right) { - kill(true); - } else if (hit.top || hit.bottom) { - kill(false); - } - } + if (hit.crush) + kill(false); if ((hit.left && m_boost < 0.f) || (hit.right && m_boost > 0.f)) m_boost = 0.f;