Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions src/badguy/badguy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ static const float FADEOUT_TIME = 0.2f;
static const float X_OFFSCREEN_DISTANCE = 1280;
static const float Y_OFFSCREEN_DISTANCE = 800;

/** Ice physics constants (identical to player ice physics) */
static const float BADGUY_ICE_FRICTION_MULTIPLIER = 0.1f; // Same as player
static const float BADGUY_ICE_ACCELERATION_MULTIPLIER = 0.25f; // Same as player

BadGuy::BadGuy(const Vector& pos, const std::string& sprite_name, int layer,
const std::string& light_sprite_name, const std::string& ice_sprite_name,
const std::string& fire_sprite_name) :
Expand All @@ -67,6 +71,8 @@ BadGuy::BadGuy(const Vector& pos, Direction direction, const std::string& sprite
m_frozen(false),
m_ignited(false),
m_in_water(false),
m_on_ice(false),
m_ice_this_frame(false),
m_dead_script(),
m_melting_time(0),
m_lightsprite(SpriteManager::current()->create(light_sprite_name)),
Expand Down Expand Up @@ -120,6 +126,8 @@ BadGuy::BadGuy(const ReaderMapping& reader, const std::string& sprite_name,
m_frozen(false),
m_ignited(false),
m_in_water(false),
m_on_ice(false),
m_ice_this_frame(false),
m_dead_script(),
m_melting_time(0),
m_lightsprite(SpriteManager::current()->create(light_sprite_name)),
Expand Down Expand Up @@ -440,6 +448,12 @@ BadGuy::get_allowed_directions() const
void
BadGuy::active_update(float dt_sec)
{
// Manage ice state each frame
if (!m_ice_this_frame && on_ground()) {
m_on_ice = false;
}
m_ice_this_frame = false;

if (!is_grabbed())
{
if (is_in_water() && m_water_affected)
Expand All @@ -456,6 +470,9 @@ BadGuy::active_update(float dt_sec)
}
}

// Apply ice physics if on ice
apply_ice_physics();

if (m_frozen) {
m_sprite->stop_animation();
}
Expand All @@ -478,6 +495,11 @@ BadGuy::collision_tile(uint32_t tile_attributes)
SoundManager::current()->play("sounds/splash.ogg", get_pos());
}

if (tile_attributes & Tile::ICE) {
m_ice_this_frame = true;
m_on_ice = true;
}

if (tile_attributes & Tile::HURTS && is_hurtable())
{
Rectf hurtbox = get_bbox().grown(-6.f);
Expand Down Expand Up @@ -713,6 +735,23 @@ BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& hit)
}
}

void
BadGuy::apply_ice_physics()
{
if (!m_on_ice || !on_ground()) return;

float velx = m_physic.get_velocity_x();
// No artificial velocity threshold - let natural physics handle sliding

// Use same friction base as player (WALK_ACCELERATION_X = 300)
float friction = 300.0f * BADGUY_ICE_FRICTION_MULTIPLIER; // Base friction value
if (velx < 0) {
m_physic.set_acceleration_x(friction);
} else if (velx > 0) {
m_physic.set_acceleration_x(-friction);
}
}

void
BadGuy::kill_squished(GameObject& object)
{
Expand Down
5 changes: 5 additions & 0 deletions src/badguy/badguy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ class BadGuy : public MovingSprite,
collision_solid. */
bool on_ground() const;

/** Apply ice physics to reduce friction when on ice */
void apply_ice_physics();

/** Returns floor normal stored the last time when
update_on_ground_flag was called and we touched something solid
from above. */
Expand Down Expand Up @@ -299,6 +302,8 @@ class BadGuy : public MovingSprite,
bool m_frozen;
bool m_ignited; /**< true if this badguy is currently on fire */
bool m_in_water; /** < true if the badguy is currently in water */
bool m_on_ice; /**< true if the badguy is currently on ice */
bool m_ice_this_frame; /**< true if the badguy touched ice this frame */

std::string m_dead_script; /**< script to execute when badguy is killed */

Expand Down
9 changes: 7 additions & 2 deletions src/badguy/walking_badguy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

#include "sprite/sprite.hpp"

// Ice physics constant (identical to player ice physics)
static const float BADGUY_ICE_ACCELERATION_MULTIPLIER = 0.25f;

WalkingBadguy::WalkingBadguy(const Vector& pos,
const std::string& sprite_name_,
const std::string& walk_left_action_,
Expand Down Expand Up @@ -145,15 +148,17 @@ WalkingBadguy::active_update(float dt_sec, float dest_x_velocity, float modifier
{
/* acceleration == walk-speed => it will take one second to get from zero
* to full speed. */
m_physic.set_acceleration_x (dest_x_velocity * modifier);
float ice_multiplier = (m_on_ice && on_ground()) ? BADGUY_ICE_ACCELERATION_MULTIPLIER : 1.0f;
m_physic.set_acceleration_x (dest_x_velocity * modifier * ice_multiplier);
}
/* Check if we're going too fast */
else if (((dest_x_velocity <= 0.0f) && (current_x_velocity < dest_x_velocity)) ||
((dest_x_velocity > 0.0f) && (current_x_velocity > dest_x_velocity)))
{
/* acceleration == walk-speed => it will take one second to get twice the
* speed to normal speed. */
m_physic.set_acceleration_x ((-1.f) * dest_x_velocity);
float ice_multiplier = (m_on_ice && on_ground()) ? BADGUY_ICE_ACCELERATION_MULTIPLIER : 1.0f;
m_physic.set_acceleration_x ((-1.f) * dest_x_velocity * ice_multiplier);
}
else
{
Expand Down
Loading