diff --git a/src/badguy/badguy.cpp b/src/badguy/badguy.cpp index 92848605eb7..223fd2f17d2 100644 --- a/src/badguy/badguy.cpp +++ b/src/badguy/badguy.cpp @@ -635,7 +635,7 @@ BadGuy::kill_fall() // Set the badguy layer to be the foremost, so that // this does not reveal secret tilemaps: - m_layer = Sector::get().get_foremost_layer() + 1; + m_layer = Sector::get().get_foremost_opaque_layer() + 1; // Start the dead-script. run_dead_script(); } diff --git a/src/badguy/corrupted_granito_big.cpp b/src/badguy/corrupted_granito_big.cpp index 3c4a2a4f197..9c126a63014 100644 --- a/src/badguy/corrupted_granito_big.cpp +++ b/src/badguy/corrupted_granito_big.cpp @@ -132,7 +132,7 @@ CorruptedGranitoBig::crack() else if (!m_crack_timer.started()) m_crack_timer.start(CRACK_TIME); - float progress = m_crack_timer.get_timegone() / m_crack_timer.get_period(); + float progress = m_crack_timer.get_progress(); if (m_state == STATE_CRACK1 && progress >= 0.5f) { diff --git a/src/badguy/igel.cpp b/src/badguy/igel.cpp index 84504784bee..e36c483f184 100644 --- a/src/badguy/igel.cpp +++ b/src/badguy/igel.cpp @@ -75,7 +75,7 @@ Igel::active_update(float dt_sec) if (m_ease_timer.started()) { - float progress = m_ease_timer.get_timegone() / m_ease_timer.get_period(); + float progress = m_ease_timer.get_progress(); float vel = (static_cast(SineEaseOut(static_cast(progress))) * (ROLL_SPEED - get_normal_walk_speed())) + get_normal_walk_speed(); set_walk_speed(vel); m_physic.set_velocity_x(vel * (m_dir == Direction::LEFT ? -1 : 1)); @@ -106,7 +106,7 @@ Igel::active_update(float dt_sec) if (m_ease_timer.started()) { - float progress = m_ease_timer.get_timegone() / m_ease_timer.get_period(); + float progress = m_ease_timer.get_progress(); float vel = (static_cast(SineEaseIn(static_cast(progress))) * (get_normal_walk_speed() - ROLL_SPEED)) + ROLL_SPEED; set_walk_speed(vel); m_physic.set_velocity_x(vel * (m_dir == Direction::LEFT ? -1 : 1)); diff --git a/src/badguy/yeti.cpp b/src/badguy/yeti.cpp index 14c61ba70a8..2bc4d7ef3c1 100644 --- a/src/badguy/yeti.cpp +++ b/src/badguy/yeti.cpp @@ -263,7 +263,7 @@ void Yeti::take_hit(Player& ) // Set the badguy layer to be above the foremost, so that // this does not reveal secret tilemaps: - m_layer = Sector::get().get_foremost_layer() + 1; + m_layer = Sector::get().get_foremost_opaque_layer() + 1; m_state = SQUISHED; m_state_timer.start(YETI_SQUISH_TIME); set_colgroup_active(COLGROUP_MOVING_ONLY_STATIC); @@ -394,7 +394,7 @@ Yeti::SnowExplosionParticle::SnowExplosionParticle(const Vector& pos, const Vect m_physic.set_velocity(velocity); m_physic.enable_gravity(true); set_state(STATE_FALLING); - m_layer = Sector::get().get_foremost_layer() + 1; + m_layer = Sector::get().get_foremost_opaque_layer() + 1; } std::vector diff --git a/src/object/background.cpp b/src/object/background.cpp index a2b189195b1..66ba9657ac1 100644 --- a/src/object/background.cpp +++ b/src/object/background.cpp @@ -229,7 +229,7 @@ Background::update(float dt_sec) } else if (m_timer_color.started()) { - float progress = m_timer_color.get_timegone() / m_timer_color.get_period(); + float progress = m_timer_color.get_progress(); m_color = (m_src_color + (m_dst_color - m_src_color) * progress).validate(); } diff --git a/src/object/decal.cpp b/src/object/decal.cpp index da144b823ad..b72d9b39c80 100644 --- a/src/object/decal.cpp +++ b/src/object/decal.cpp @@ -116,7 +116,7 @@ Decal::update(float) else { // Square root makes the background stay at fairly constant color/transparency - float new_alpha = sqrtf(m_sprite_timer.get_timegone() / m_sprite_timer.get_period()); + float new_alpha = sqrtf(m_sprite_timer.get_progress()); float old_alpha = sqrtf(m_sprite_timer.get_timeleft() / m_sprite_timer.get_period()); m_sprite.get()->set_alpha(new_alpha); m_fade_sprite.get()->set_alpha(old_alpha); @@ -136,7 +136,7 @@ Decal::update(float) else { float alpha; - if (m_visible) alpha = m_fade_timer.get_timegone() / m_fade_timer.get_period(); + if (m_visible) alpha = m_fade_timer.get_progress(); else alpha = m_fade_timer.get_timeleft() / m_fade_timer.get_period(); m_sprite.get()->set_alpha(alpha); } diff --git a/src/object/player.cpp b/src/object/player.cpp index aa35eafb31a..11ddf2566a6 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -2206,7 +2206,7 @@ Player::draw(DrawingContext& context) } // don't draw Tux else if (m_dying) - m_sprite->draw(context.color(), get_pos(), Sector::get().get_foremost_layer() + 1); + m_sprite->draw(context.color(), get_pos(), Sector::get().get_foremost_opaque_layer() + 1); else m_sprite->draw(context.color(), get_pos(), LAYER_OBJECTS + 1); diff --git a/src/object/thunderstorm.cpp b/src/object/thunderstorm.cpp index 436481678b4..4d891e86a24 100644 --- a/src/object/thunderstorm.cpp +++ b/src/object/thunderstorm.cpp @@ -18,6 +18,7 @@ #include "audio/sound_manager.hpp" #include "editor/editor.hpp" +#include "object/background.hpp" #include "object/electrifier.hpp" #include "supertux/level.hpp" #include "supertux/sector.hpp" @@ -30,9 +31,8 @@ namespace { const float LIGHTNING_DELAY = 2.0f; -const float FLASH_DISPLAY_TIME = 0.1f; +const float FLASH_DISPLAY_TIME = 1.3f; const float ELECTRIFY_TIME = 0.5f; - } // namespace Thunderstorm::Thunderstorm(const ReaderMapping& reader) : @@ -45,7 +45,8 @@ Thunderstorm::Thunderstorm(const ReaderMapping& reader) : time_to_thunder(), time_to_lightning(), flash_display_timer(), - changing_tiles(TileManager::current()->get_tileset(Level::current()->get_tileset())->m_thunderstorm_tiles) + changing_tiles(TileManager::current()->get_tileset(Level::current()->get_tileset())->m_thunderstorm_tiles), + m_flash_color() { reader.get("running", running); reader.get("interval", interval); @@ -94,6 +95,27 @@ Thunderstorm::update(float ) lightning(); time_to_thunder.start(interval); } + + if(flash_display_timer.started()) + { + float alpha = 0.9f; + if(flash_display_timer.get_timegone() > 0.1f) + { + auto progress = flash_display_timer.get_timegone() / flash_display_timer.get_timeleft() - 0.1f; + if(progress < 0.0f) + progress = 0.0f; + + alpha = 0.9f - progress; + } + + if(alpha < 0.0f) + { + flash_display_timer.stop(); + return; + } + + m_flash_color = Color(alpha, alpha, alpha, 1.0); + } } void @@ -101,12 +123,11 @@ Thunderstorm::draw(DrawingContext& context) { if (!flash_display_timer.started()) return; - float alpha = 0.33f; context.push_transform(); context.set_translation(Vector(0, 0)); - context.color().draw_filled_rect(context.get_rect(), Color(1, 1, 1, alpha), layer); + context.transform().scale = 1.f; + context.color().draw_gradient(m_flash_color, m_flash_color, 500, GradientDirection::HORIZONTAL, context.get_rect(), Blend::ADD); context.pop_transform(); - } void @@ -131,6 +152,7 @@ void Thunderstorm::thunder() { SoundManager::current()->play("sounds/thunder.wav"); + change_background_colors(false); } void @@ -141,6 +163,8 @@ Thunderstorm::lightning() if (!m_strike_script.empty()) { Sector::get().run_script(m_strike_script, "strike-script"); } + + change_background_colors(true); } void @@ -156,4 +180,16 @@ Thunderstorm::electrify() Sector::get().add(changing_tiles, ELECTRIFY_TIME); } +void +Thunderstorm::change_background_colors(bool is_lightning) +{ + auto factor = is_lightning ? (1.0f / 0.7f) : 0.7f; + auto backgrounds = Sector::current()->get_objects_by_type(); + for(auto& background : backgrounds) + { + auto new_color = background.get_color() * factor; + background.fade_color(new_color.validate(), 0.1f); + } +} + /* EOF */ diff --git a/src/object/thunderstorm.hpp b/src/object/thunderstorm.hpp index 3845db928db..111a6034ffa 100644 --- a/src/object/thunderstorm.hpp +++ b/src/object/thunderstorm.hpp @@ -70,11 +70,14 @@ class Thunderstorm final : public GameObject, /** @} */ +private: + void change_background_colors(bool is_lightning); + private: bool running; /**< whether we currently automatically trigger lightnings */ float interval; /**< time between two lightnings */ int layer; /**< layer, where flash will be painted */ - + std::string m_strike_script; Timer time_to_thunder; /**< counts down until next thunder */ @@ -82,6 +85,7 @@ class Thunderstorm final : public GameObject, Timer flash_display_timer; /**< counts down while flash is displayed */ std::map changing_tiles; /**< preserves the tiles which an electrocution should change */ + Color m_flash_color; private: Thunderstorm(const Thunderstorm&) = delete; diff --git a/src/supertux/sector.cpp b/src/supertux/sector.cpp index 91c9f3cef89..45eb0ff49e8 100644 --- a/src/supertux/sector.cpp +++ b/src/supertux/sector.cpp @@ -65,6 +65,7 @@ Sector::Sector(Level& parent) : m_level(parent), m_fully_constructed(false), m_foremost_layer(), + m_foremost_opaque_layer(), m_gravity(10.0f), m_collision_system(new CollisionSystem(*this)), m_text_object(add("Text")) @@ -154,7 +155,8 @@ Sector::finish_construction(bool editable) m_initialized = false; flush_game_objects(); - m_foremost_layer = calculate_foremost_layer(); + m_foremost_layer = calculate_foremost_layer(false); + m_foremost_opaque_layer = calculate_foremost_layer(); process_resolve_requests(); @@ -300,14 +302,14 @@ Sector::get_active_region() const } int -Sector::calculate_foremost_layer() const +Sector::calculate_foremost_layer(bool including_transparent) const { int layer = LAYER_BACKGROUND0; for (auto& tm : get_objects_by_type()) { if (tm.get_layer() > layer) { - if ( (tm.get_alpha() < 1.0f) ) + if ( including_transparent && tm.get_alpha() < 1.0f ) { layer = tm.get_layer() - 1; } @@ -321,6 +323,12 @@ Sector::calculate_foremost_layer() const return layer; } +int +Sector::get_foremost_opaque_layer() const +{ + return m_foremost_opaque_layer; +} + int Sector::get_foremost_layer() const { diff --git a/src/supertux/sector.hpp b/src/supertux/sector.hpp index 8591283fa90..80d0c56183f 100644 --- a/src/supertux/sector.hpp +++ b/src/supertux/sector.hpp @@ -130,6 +130,7 @@ class Sector final : public Base::Sector Rectf get_active_region() const; + int get_foremost_opaque_layer() const; int get_foremost_layer() const; /** returns the editor size (in tiles) of a sector */ @@ -156,7 +157,7 @@ class Sector final : public Base::Sector virtual bool before_object_add(GameObject& object) override; virtual void before_object_remove(GameObject& object) override; - int calculate_foremost_layer() const; + int calculate_foremost_layer(bool including_transparent = true) const; /** Convert tiles into their corresponding GameObjects (e.g. bonusblocks, add light to lava tiles) */ @@ -167,6 +168,7 @@ class Sector final : public Base::Sector bool m_fully_constructed; int m_foremost_layer; + int m_foremost_opaque_layer; float m_gravity; diff --git a/src/supertux/timer.hpp b/src/supertux/timer.hpp index 7374b79ba30..b0102180a5e 100644 --- a/src/supertux/timer.hpp +++ b/src/supertux/timer.hpp @@ -46,8 +46,9 @@ class Timer final /** returns the period of the timer or 0 if it isn't started */ float get_period() const { return m_period; } - float get_timeleft() const{ return m_period - (g_game_time - m_cycle_start); } + float get_timeleft() const { return m_period - (g_game_time - m_cycle_start); } float get_timegone() const { return g_game_time - m_cycle_start; } + float get_progress() const { return get_timegone() / get_period(); } bool started() const { return (m_period != 0 && get_timeleft() > 0); } bool paused() const { return m_cycle_pause != 0; }