From 8eaf83fec0540649cddc4eb613226effff16e45d Mon Sep 17 00:00:00 2001 From: bruhmoent Date: Sun, 7 Jul 2024 19:59:49 +0200 Subject: [PATCH 1/5] Improve cloud particles --- src/object/cloud_particle_system.cpp | 215 ++++++++++++++++++++------- src/object/cloud_particle_system.hpp | 47 +++++- src/video/layer.hpp | 5 +- 3 files changed, 207 insertions(+), 60 deletions(-) diff --git a/src/object/cloud_particle_system.cpp b/src/object/cloud_particle_system.cpp index aafee814586..ac72d113c75 100644 --- a/src/object/cloud_particle_system.cpp +++ b/src/object/cloud_particle_system.cpp @@ -1,5 +1,6 @@ // SuperTux // Copyright (C) 2006 Matthias Braun +// Copyright (C) 2024 bruhmoent // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -29,13 +30,17 @@ #include "video/surface_batch.hpp" #include "video/video_system.hpp" #include "video/viewport.hpp" +#include "video/layer.hpp" CloudParticleSystem::CloudParticleSystem() : ParticleSystem(128), cloudimage(Surface::from_file("images/particles/cloud.png")), - m_current_speed(1.f), - m_target_speed(1.f), - m_speed_fade_time_remaining(0.f), + m_current_speed_x(1.f), + m_target_speed_x(1.f), + m_speed_fade_time_remaining_x(0.f), + m_current_speed_y(0.f), + m_target_speed_y(0.f), + m_speed_fade_time_remaining_y(0.f), m_current_amount(15), m_current_real_amount(0) { @@ -45,13 +50,18 @@ CloudParticleSystem::CloudParticleSystem() : CloudParticleSystem::CloudParticleSystem(const ReaderMapping& reader) : ParticleSystem(reader, 128), cloudimage(Surface::from_file("images/particles/cloud.png")), - m_current_speed(1.f), - m_target_speed(1.f), - m_speed_fade_time_remaining(0.f), + m_current_speed_x(1.f), + m_target_speed_x(1.f), + m_speed_fade_time_remaining_x(0.f), + m_current_speed_y(0.f), + m_target_speed_y(0.f), + m_speed_fade_time_remaining_y(0.f), m_current_amount(15), m_current_real_amount(0) { reader.get("intensity", m_current_amount); + reader.get("x_speed", m_current_speed_x); + reader.get("y_speed", m_current_speed_y); init(); } @@ -59,40 +69,87 @@ CloudParticleSystem::~CloudParticleSystem() { } -void CloudParticleSystem::init() +void +CloudParticleSystem::init() { - virtual_width = 2000.0; + virtual_width = 2000.f; // Create some random clouds. add_clouds(m_current_amount, 0.f); } +void +CloudParticleSystem::set_x_speed(float speed) +{ + m_current_speed_x = speed; +} + +float +CloudParticleSystem::get_x_speed() const +{ + return m_current_speed_x; +} + +void +CloudParticleSystem::set_y_speed(float speed) +{ + m_current_speed_y = speed; +} + +float +CloudParticleSystem::get_y_speed() const +{ + return m_current_speed_y; +} + ObjectSettings CloudParticleSystem::get_settings() { ObjectSettings result = ParticleSystem::get_settings(); result.add_int(_("Intensity"), &m_current_amount, "intensity", 15); + result.add_float(_("X Speed"), &m_current_speed_x, "x_speed", 1.f); + result.add_float(_("Y Speed"), &m_current_speed_y, "y_speed", 0.f); - result.reorder({"intensity", "enabled", "name"}); + result.reorder({ "intensity", "x_speed", "y_speed", "enabled", "name" }); return result; } - -void CloudParticleSystem::update(float dt_sec) +void +CloudParticleSystem::update(float dt_sec) { if (!enabled) return; - // Update speed. - if (m_speed_fade_time_remaining > 0.f) { - if (dt_sec >= m_speed_fade_time_remaining) { - m_current_speed = m_target_speed; - m_speed_fade_time_remaining = 0.f; - } else { - float amount = dt_sec / m_speed_fade_time_remaining; - m_current_speed += (m_target_speed - m_current_speed) * amount; - m_speed_fade_time_remaining -= dt_sec; + // Update X speed. + if (m_speed_fade_time_remaining_x > 0.f) + { + if (dt_sec >= m_speed_fade_time_remaining_x) + { + m_current_speed_x = m_target_speed_x; + m_speed_fade_time_remaining_x = 0.f; + } + else + { + float amount = dt_sec / m_speed_fade_time_remaining_x; + m_current_speed_x += (m_target_speed_x - m_current_speed_x) * amount; + m_speed_fade_time_remaining_x -= dt_sec; + } + } + + // Update Y speed. + if (m_speed_fade_time_remaining_y > 0.f) + { + if (dt_sec >= m_speed_fade_time_remaining_y) + { + m_current_speed_y = m_target_speed_y; + m_speed_fade_time_remaining_y = 0.f; + } + else + { + float amount = dt_sec / m_speed_fade_time_remaining_y; + m_current_speed_y += (m_target_speed_y - m_current_speed_y) * amount; + m_speed_fade_time_remaining_y -= dt_sec; } } @@ -101,11 +158,13 @@ void CloudParticleSystem::update(float dt_sec) auto screen_width = static_cast(SCREEN_WIDTH) / scale; auto screen_height = static_cast(SCREEN_HEIGHT) / scale; - for (auto& particle : particles) { + for (auto& particle : particles) + { auto cloudParticle = dynamic_cast(particle.get()); if (!cloudParticle) continue; - cloudParticle->pos.x += cloudParticle->speed * dt_sec * m_current_speed; + cloudParticle->pos.x += cloudParticle->speed * dt_sec * m_current_speed_x; + cloudParticle->pos.y += cloudParticle->speed * dt_sec * m_current_speed_y; while (cloudParticle->pos.x < cam.get_translation().x - static_cast(cloudParticle->texture->get_width())) cloudParticle->pos.x += screen_width + static_cast(cloudParticle->texture->get_width()) * 2.f; while (cloudParticle->pos.x > cam.get_translation().x + screen_width) @@ -116,15 +175,20 @@ void CloudParticleSystem::update(float dt_sec) cloudParticle->pos.y -= screen_height + static_cast(cloudParticle->texture->get_height()) * 2.f; // Update alpha. - if (cloudParticle->target_time_remaining > 0.f) { - if (dt_sec >= cloudParticle->target_time_remaining) { + if (cloudParticle->target_time_remaining > 0.f) + { + if (dt_sec >= cloudParticle->target_time_remaining) + { cloudParticle->alpha = cloudParticle->target_alpha; cloudParticle->target_time_remaining = 0.f; - if (cloudParticle->alpha == 0.f) { + if (cloudParticle->alpha == 0.f) + { // Remove this particle, but not at this point // as it would interfere with the iterator. } - } else { + } + else + { float amount = dt_sec / cloudParticle->target_time_remaining; cloudParticle->alpha += (cloudParticle->target_alpha - cloudParticle->alpha) * amount; cloudParticle->target_time_remaining -= dt_sec; @@ -135,15 +199,31 @@ void CloudParticleSystem::update(float dt_sec) // Clear dead clouds. // Iterate through the vector backwards to avoid affecting the index of elements // after removal, preventing buggy behavior. - for (int i = static_cast(particles.size()) - 1; i >= 0; --i) { + for (int i = static_cast(particles.size()) - 1; i >= 0; --i) + { auto particle = dynamic_cast(particles.at(i).get()); - + if (particle->target_alpha == 0.f && particle->target_time_remaining == 0.f) - particles.erase(particles.begin()+i); + particles.erase(particles.begin() + i); } } -int CloudParticleSystem::add_clouds(int amount, float fade_time) +void +CloudParticleSystem::apply_fog_effect(DrawingContext& context) +{ + float opacity = fog_max_value * (static_cast(m_current_amount) - static_cast(fog_start_amount)) / (static_cast(max_amount) - static_cast(fog_start_amount)); + opacity = std::clamp(opacity, 0.f, 1.f); + + context.push_transform(); + context.set_translation(Vector(0, 0)); + context.color().draw_filled_rect(context.get_rect(), + Color(0.3f, 0.38f, 0.4f, opacity), + LAYER_FOG); + context.pop_transform(); +} + +int +CloudParticleSystem::add_clouds(int amount, float fade_time) { int target_amount = m_current_real_amount + amount; @@ -152,7 +232,8 @@ int CloudParticleSystem::add_clouds(int amount, float fade_time) int amount_to_add = target_amount - m_current_real_amount; - for (int i = 0; i < amount_to_add; ++i) { + for (int i = 0; i < amount_to_add; ++i) + { auto particle = std::make_unique(); // Don't consider the camera, because the Sector might not exist yet // Instead, rely on update() to correct this when it will be called. @@ -171,7 +252,8 @@ int CloudParticleSystem::add_clouds(int amount, float fade_time) return m_current_real_amount; } -int CloudParticleSystem::remove_clouds(int amount, float fade_time) +int +CloudParticleSystem::remove_clouds(int amount, float fade_time) { int target_amount = m_current_real_amount - amount; @@ -181,13 +263,17 @@ int CloudParticleSystem::remove_clouds(int amount, float fade_time) int amount_to_remove = m_current_real_amount - target_amount; int i = 0; - for (; i < amount_to_remove && i < static_cast(particles.size()); ++i) { - + for (; i < amount_to_remove && i < static_cast(particles.size()); ++i) + { + auto particle = dynamic_cast(particles.at(i).get()); - if (particle->target_alpha != 1.f || particle->target_time_remaining != 0.f) { + if (particle->target_alpha != 1.f || particle->target_time_remaining != 0.f) + { // Skip that one, it doesn't count. --i; - } else { + } + else + { particle->target_alpha = 0.f; particle->target_time_remaining = fade_time; } @@ -196,21 +282,27 @@ int CloudParticleSystem::remove_clouds(int amount, float fade_time) return i; } -void CloudParticleSystem::fade_speed(float new_speed, float fade_time) +void +CloudParticleSystem::fade_speed(float new_speed_x, float new_speed_y, float fade_time) { // No check for enabled; change the fading even if it's disabled. // If fade_time is 0 or smaller, update() will never change m_current_speed. if (fade_time <= 0.f) { - m_current_speed = new_speed; + m_current_speed_x = new_speed_x; + m_current_speed_y = new_speed_y; } - - m_target_speed = new_speed; - m_speed_fade_time_remaining = fade_time; + + m_target_speed_x = new_speed_x; + m_speed_fade_time_remaining_x = fade_time; + + m_target_speed_y = new_speed_y; + m_speed_fade_time_remaining_y = fade_time; } -void CloudParticleSystem::fade_amount(int new_amount, float fade_time, float time_between) +void +CloudParticleSystem::fade_amount(int new_amount, float fade_time, float time_between) { // No check for enabled; change the fading even if it's disabled. @@ -232,8 +324,8 @@ CloudParticleSystem::set_amount(int amount, float time) fade_amount(amount, time, 0.f); } - -void CloudParticleSystem::draw(DrawingContext& context) +void +CloudParticleSystem::draw(DrawingContext& context) { if (!enabled) return; @@ -243,32 +335,39 @@ void CloudParticleSystem::draw(DrawingContext& context) context.push_transform(); std::unordered_map batches; - for (const auto& particle : particles) { + for (const auto& particle : particles) + { - if(!region.contains(particle->pos)) + if (!region.contains(particle->pos)) continue; - if (particle->alpha != 1.f) { + if (particle->alpha != 1.f) + { const auto& batch_it = batches.emplace( - particle->texture->clone(), - SurfaceBatch( - particle->texture, - Color(1.f, 1.f, 1.f, particle->alpha) - )); + particle->texture->clone(), + SurfaceBatch( + particle->texture, + Color(1.f, 1.f, 1.f, particle->alpha) + )); batch_it.first->second.draw(particle->pos, particle->angle); - } else { + } + else + { auto it = batches.find(particle->texture); if (it == batches.end()) { const auto& batch_it = batches.emplace(particle->texture, SurfaceBatch(particle->texture)); batch_it.first->second.draw(particle->pos, particle->angle); - } else { + } + else + { it->second.draw(particle->pos, particle->angle); } } } - for(auto& it : batches) { + for (auto& it : batches) + { auto& surface = it.first; auto& batch = it.second; // FIXME: What is the colour used for? @@ -277,10 +376,10 @@ void CloudParticleSystem::draw(DrawingContext& context) batch.move_dstrects(), batch.move_angles(), batch.get_color(), z_pos); } + apply_fog_effect(context); context.pop_transform(); } - void CloudParticleSystem::register_class(ssq::VM& vm) { @@ -289,6 +388,10 @@ CloudParticleSystem::register_class(ssq::VM& vm) cls.addFunc("fade_speed", &CloudParticleSystem::fade_speed); cls.addFunc("fade_amount", &CloudParticleSystem::fade_amount); cls.addFunc("set_amount", &CloudParticleSystem::set_amount); + cls.addFunc("set_x_speed", &CloudParticleSystem::set_x_speed); + cls.addFunc("get_x_speed", &CloudParticleSystem::get_x_speed); + cls.addFunc("set_y_speed", &CloudParticleSystem::set_y_speed); + cls.addFunc("get_y_speed", &CloudParticleSystem::get_y_speed); } /* EOF */ diff --git a/src/object/cloud_particle_system.hpp b/src/object/cloud_particle_system.hpp index 81b49cc6c46..f81f87260f1 100644 --- a/src/object/cloud_particle_system.hpp +++ b/src/object/cloud_particle_system.hpp @@ -1,5 +1,6 @@ // SuperTux // Copyright (C) 2006 Matthias Braun +// Copyright (C) 2024 bruhmoent // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -58,11 +59,12 @@ class CloudParticleSystem final : public ParticleSystem /** * @scripting - * @description Smoothly changes the rain speed to the given value in ""time"" seconds. - * @param float $speed + * @description Smoothly changes the clouds' X and Y speed to the given value in ""time"" seconds. + * @param float $speed_x + * @param float $speed_y * @param float $time */ - void fade_speed(float speed, float time); + void fade_speed(float speed_x, float speed_y, float time); /** * @scripting * @description Smoothly changes the amount of particles to the given value in ""time"" seconds. @@ -83,6 +85,31 @@ class CloudParticleSystem final : public ParticleSystem static int constexpr const max_amount = 500; static int constexpr const min_amount = 0; + /** + * @scripting + * @description Sets the horizontal speed of the cloud particles. + * @param float $speed + */ + void set_x_speed(float speed); + /** + * @scripting + * @description Gets the horizontal speed of the cloud particles. + * @return float + */ + float get_x_speed() const; + /** + * @scripting + * @description Sets the vertical speed of the cloud particles. + * @param float $speed + */ + void set_y_speed(float speed); + /** + * @scripting + * @description Gets the vertical speed of the cloud particles. + * @return float + */ + float get_y_speed() const; + private: /** Returns the amount that got inserted (In case max_amount got hit) */ int add_clouds(int amount, float fade_time); @@ -90,6 +117,9 @@ class CloudParticleSystem final : public ParticleSystem /** Returns the amount that got removed (In case min_amount got hit) */ int remove_clouds(int amount, float fade_time); + /** Applies the fog effect based on the intensity */ + void apply_fog_effect(DrawingContext& context); + private: class CloudParticle : public Particle { @@ -111,9 +141,20 @@ class CloudParticleSystem final : public ParticleSystem float m_target_speed; float m_speed_fade_time_remaining; + float m_current_speed_x; + float m_target_speed_x; + float m_speed_fade_time_remaining_x; + + float m_current_speed_y; + float m_target_speed_y; + float m_speed_fade_time_remaining_y; + int m_current_amount; int m_current_real_amount; + const float fog_max_value = 1.0f; + const float fog_start_amount = 10.0f; + private: CloudParticleSystem(const CloudParticleSystem&) = delete; CloudParticleSystem& operator=(const CloudParticleSystem&) = delete; diff --git a/src/video/layer.hpp b/src/video/layer.hpp index af5e7717129..80ae32703f7 100644 --- a/src/video/layer.hpp +++ b/src/video/layer.hpp @@ -41,12 +41,15 @@ enum { LAYER_LIGHTMAP = 450, + // Used for the fog created by particles + LAYER_FOG = 199, + // Hitpoints, time, coins, etc. LAYER_HUD = 500, // Menus, mouse, console etc. LAYER_GUI = 600, - //make sure all get_light requests are handled last. + // Make sure all get_light requests are handled last. LAYER_GETPIXEL = LAYER_GUI }; From c291b7eb29f166c48ca73143dd1d81e92a1881b6 Mon Sep 17 00:00:00 2001 From: bruhmoent <69918580+bruhmoent@users.noreply.github.com> Date: Sun, 7 Jul 2024 20:08:35 +0200 Subject: [PATCH 2/5] Remove leftovers --- src/object/cloud_particle_system.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/object/cloud_particle_system.hpp b/src/object/cloud_particle_system.hpp index f81f87260f1..339ee01c6f0 100644 --- a/src/object/cloud_particle_system.hpp +++ b/src/object/cloud_particle_system.hpp @@ -137,10 +137,6 @@ class CloudParticleSystem final : public ParticleSystem SurfacePtr cloudimage; - float m_current_speed; - float m_target_speed; - float m_speed_fade_time_remaining; - float m_current_speed_x; float m_target_speed_x; float m_speed_fade_time_remaining_x; From 01f11157f303d1a2b1d949fea4cb1d4816f43d2f Mon Sep 17 00:00:00 2001 From: bruhmoent Date: Wed, 16 Oct 2024 16:49:33 +0200 Subject: [PATCH 3/5] Refresh builds From 6a8e85310eaaa574feee2c11c195d0779aa01104 Mon Sep 17 00:00:00 2001 From: bruhmoent Date: Fri, 25 Oct 2024 19:34:25 +0200 Subject: [PATCH 4/5] Separate the fog + code-style improvements --- src/object/cloud_particle_system.cpp | 119 ++++++++++++++------------- src/object/cloud_particle_system.hpp | 19 ++++- 2 files changed, 78 insertions(+), 60 deletions(-) diff --git a/src/object/cloud_particle_system.cpp b/src/object/cloud_particle_system.cpp index ac72d113c75..1b7c0826fbe 100644 --- a/src/object/cloud_particle_system.cpp +++ b/src/object/cloud_particle_system.cpp @@ -34,7 +34,7 @@ CloudParticleSystem::CloudParticleSystem() : ParticleSystem(128), - cloudimage(Surface::from_file("images/particles/cloud.png")), + cloud_image(Surface::from_file("images/particles/cloud.png")), m_current_speed_x(1.f), m_target_speed_x(1.f), m_speed_fade_time_remaining_x(0.f), @@ -42,14 +42,15 @@ CloudParticleSystem::CloudParticleSystem() : m_target_speed_y(0.f), m_speed_fade_time_remaining_y(0.f), m_current_amount(15), - m_current_real_amount(0) + m_current_real_amount(0), + m_fog_opacity(0.f) { init(); } CloudParticleSystem::CloudParticleSystem(const ReaderMapping& reader) : ParticleSystem(reader, 128), - cloudimage(Surface::from_file("images/particles/cloud.png")), + cloud_image(Surface::from_file("images/particles/cloud.png")), m_current_speed_x(1.f), m_target_speed_x(1.f), m_speed_fade_time_remaining_x(0.f), @@ -57,17 +58,17 @@ CloudParticleSystem::CloudParticleSystem(const ReaderMapping& reader) : m_target_speed_y(0.f), m_speed_fade_time_remaining_y(0.f), m_current_amount(15), - m_current_real_amount(0) + m_current_real_amount(0), + m_fog_opacity(0.f) { reader.get("intensity", m_current_amount); + reader.get("fog_opacity", m_fog_opacity); reader.get("x_speed", m_current_speed_x); reader.get("y_speed", m_current_speed_y); init(); } -CloudParticleSystem::~CloudParticleSystem() -{ -} +CloudParticleSystem::~CloudParticleSystem() {} void CloudParticleSystem::init() @@ -102,15 +103,29 @@ CloudParticleSystem::get_y_speed() const return m_current_speed_y; } -ObjectSettings CloudParticleSystem::get_settings() +void +CloudParticleSystem::set_fog_opacity(float opacity) +{ + m_fog_opacity = std::clamp(opacity, 0.f, 100.f); +} + +float +CloudParticleSystem::get_fog_opacity() const +{ + return m_fog_opacity; +} + +ObjectSettings +CloudParticleSystem::get_settings() { ObjectSettings result = ParticleSystem::get_settings(); - result.add_int(_("Intensity"), &m_current_amount, "intensity", 15); + result.add_int(_("Amount"), &m_current_amount, "intensity", 15); + result.add_float(_("Fog Opacity"), &m_fog_opacity, "fog_opacity", 0.f); result.add_float(_("X Speed"), &m_current_speed_x, "x_speed", 1.f); result.add_float(_("Y Speed"), &m_current_speed_y, "y_speed", 0.f); - result.reorder({ "intensity", "x_speed", "y_speed", "enabled", "name" }); + result.reorder({ "intensity", "fog_opacity", "x_speed", "y_speed", "enabled", "name" }); return result; } @@ -160,38 +175,42 @@ CloudParticleSystem::update(float dt_sec) for (auto& particle : particles) { - auto cloudParticle = dynamic_cast(particle.get()); - if (!cloudParticle) + auto cloud_particle = dynamic_cast(particle.get()); + + if (!cloud_particle) continue; - cloudParticle->pos.x += cloudParticle->speed * dt_sec * m_current_speed_x; - cloudParticle->pos.y += cloudParticle->speed * dt_sec * m_current_speed_y; - while (cloudParticle->pos.x < cam.get_translation().x - static_cast(cloudParticle->texture->get_width())) - cloudParticle->pos.x += screen_width + static_cast(cloudParticle->texture->get_width()) * 2.f; - while (cloudParticle->pos.x > cam.get_translation().x + screen_width) - cloudParticle->pos.x -= screen_width + static_cast(cloudParticle->texture->get_width()) * 2.f; - while (cloudParticle->pos.y < cam.get_translation().y - static_cast(cloudParticle->texture->get_height())) - cloudParticle->pos.y += screen_height + static_cast(cloudParticle->texture->get_height()) * 2.f; - while (cloudParticle->pos.y > cam.get_translation().y + screen_height) - cloudParticle->pos.y -= screen_height + static_cast(cloudParticle->texture->get_height()) * 2.f; + + cloud_particle->pos.x += cloud_particle->speed * dt_sec * m_current_speed_x; + cloud_particle->pos.y += cloud_particle->speed * dt_sec * m_current_speed_y; + + float texture_height = static_cast(cloud_particle->texture->get_height()); + float texture_width = static_cast(cloud_particle->texture->get_width()); + + while (cloud_particle->pos.x < cam.get_translation().x - texture_width) + cloud_particle->pos.x += screen_width + texture_width * 2.f; + + while (cloud_particle->pos.x > cam.get_translation().x + screen_width) + cloud_particle->pos.x -= screen_width + texture_width * 2.f; + + while (cloud_particle->pos.y < cam.get_translation().y - texture_height) + cloud_particle->pos.y += screen_height + texture_height * 2.f; + + while (cloud_particle->pos.y > cam.get_translation().y + screen_height) + cloud_particle->pos.y -= screen_height + texture_height * 2.f; // Update alpha. - if (cloudParticle->target_time_remaining > 0.f) + if (cloud_particle->target_time_remaining > 0.f) { - if (dt_sec >= cloudParticle->target_time_remaining) + if (dt_sec >= cloud_particle->target_time_remaining) { - cloudParticle->alpha = cloudParticle->target_alpha; - cloudParticle->target_time_remaining = 0.f; - if (cloudParticle->alpha == 0.f) - { - // Remove this particle, but not at this point - // as it would interfere with the iterator. - } + cloud_particle->alpha = cloud_particle->target_alpha; + cloud_particle->target_time_remaining = 0.f; } else { - float amount = dt_sec / cloudParticle->target_time_remaining; - cloudParticle->alpha += (cloudParticle->target_alpha - cloudParticle->alpha) * amount; - cloudParticle->target_time_remaining -= dt_sec; + float amount = dt_sec / cloud_particle->target_time_remaining; + cloud_particle->alpha += (cloud_particle->target_alpha - cloud_particle->alpha) * amount; + cloud_particle->target_time_remaining -= dt_sec; } } } @@ -211,8 +230,7 @@ CloudParticleSystem::update(float dt_sec) void CloudParticleSystem::apply_fog_effect(DrawingContext& context) { - float opacity = fog_max_value * (static_cast(m_current_amount) - static_cast(fog_start_amount)) / (static_cast(max_amount) - static_cast(fog_start_amount)); - opacity = std::clamp(opacity, 0.f, 1.f); + float opacity = m_fog_opacity / 100.0f; context.push_transform(); context.set_translation(Vector(0, 0)); @@ -225,11 +243,7 @@ CloudParticleSystem::apply_fog_effect(DrawingContext& context) int CloudParticleSystem::add_clouds(int amount, float fade_time) { - int target_amount = m_current_real_amount + amount; - - if (target_amount > max_amount) - target_amount = max_amount; - + int target_amount = std::clamp(m_current_real_amount + amount, min_amount, max_amount); int amount_to_add = target_amount - m_current_real_amount; for (int i = 0; i < amount_to_add; ++i) @@ -239,7 +253,7 @@ CloudParticleSystem::add_clouds(int amount, float fade_time) // Instead, rely on update() to correct this when it will be called. particle->pos.x = graphicsRandom.randf(virtual_width); particle->pos.y = graphicsRandom.randf(virtual_height); - particle->texture = cloudimage; + particle->texture = cloud_image; particle->speed = -graphicsRandom.randf(25.0, 54.0); particle->alpha = (fade_time == 0.f) ? 1.f : 0.f; particle->target_alpha = 1.f; @@ -255,11 +269,7 @@ CloudParticleSystem::add_clouds(int amount, float fade_time) int CloudParticleSystem::remove_clouds(int amount, float fade_time) { - int target_amount = m_current_real_amount - amount; - - if (target_amount < min_amount) - target_amount = min_amount; - + int target_amount = std::clamp(m_current_real_amount - amount, min_amount, max_amount); int amount_to_remove = m_current_real_amount - target_amount; int i = 0; @@ -267,9 +277,8 @@ CloudParticleSystem::remove_clouds(int amount, float fade_time) { auto particle = dynamic_cast(particles.at(i).get()); - if (particle->target_alpha != 1.f || particle->target_time_remaining != 0.f) + if (particle->target_alpha != 1.f || particle->target_time_remaining != 0.f) // Invalid particle. { - // Skip that one, it doesn't count. --i; } else @@ -286,8 +295,8 @@ void CloudParticleSystem::fade_speed(float new_speed_x, float new_speed_y, float fade_time) { // No check for enabled; change the fading even if it's disabled. - // If fade_time is 0 or smaller, update() will never change m_current_speed. + if (fade_time <= 0.f) { m_current_speed_x = new_speed_x; @@ -295,10 +304,8 @@ CloudParticleSystem::fade_speed(float new_speed_x, float new_speed_y, float fade } m_target_speed_x = new_speed_x; - m_speed_fade_time_remaining_x = fade_time; - m_target_speed_y = new_speed_y; - m_speed_fade_time_remaining_y = fade_time; + m_speed_fade_time_remaining_x = m_speed_fade_time_remaining_y = fade_time; } void @@ -315,7 +322,7 @@ CloudParticleSystem::fade_amount(int new_amount, float fade_time, float time_bet else if (delta > 0) { add_clouds(delta, fade_time); - } // If delta is zero, there is nothing to do. + } } void @@ -370,8 +377,6 @@ CloudParticleSystem::draw(DrawingContext& context) { auto& surface = it.first; auto& batch = it.second; - // FIXME: What is the colour used for? - // RESOLVED : That's the tint and the alpha. context.color().draw_surface_batch(surface, batch.move_srcrects(), batch.move_dstrects(), batch.move_angles(), batch.get_color(), z_pos); } @@ -392,6 +397,8 @@ CloudParticleSystem::register_class(ssq::VM& vm) cls.addFunc("get_x_speed", &CloudParticleSystem::get_x_speed); cls.addFunc("set_y_speed", &CloudParticleSystem::set_y_speed); cls.addFunc("get_y_speed", &CloudParticleSystem::get_y_speed); + cls.addFunc("set_fog_opacity", &CloudParticleSystem::set_fog_opacity); + cls.addFunc("get_fog_opacity", &CloudParticleSystem::get_fog_opacity); } /* EOF */ diff --git a/src/object/cloud_particle_system.hpp b/src/object/cloud_particle_system.hpp index 339ee01c6f0..4637c05a277 100644 --- a/src/object/cloud_particle_system.hpp +++ b/src/object/cloud_particle_system.hpp @@ -109,6 +109,18 @@ class CloudParticleSystem final : public ParticleSystem * @return float */ float get_y_speed() const; + /** + * @scripting + * @description Sets the fog's opacity. + * @param float opacity + */ + void set_fog_opacity(float opacity); + /** + * @scripting + * @description Gets the fog's opacity. + * @return float + */ + float get_fog_opacity() const; private: /** Returns the amount that got inserted (In case max_amount got hit) */ @@ -135,7 +147,7 @@ class CloudParticleSystem final : public ParticleSystem {} }; - SurfacePtr cloudimage; + SurfacePtr cloud_image; float m_current_speed_x; float m_target_speed_x; @@ -145,12 +157,11 @@ class CloudParticleSystem final : public ParticleSystem float m_target_speed_y; float m_speed_fade_time_remaining_y; + float m_fog_opacity; + int m_current_amount; int m_current_real_amount; - const float fog_max_value = 1.0f; - const float fog_start_amount = 10.0f; - private: CloudParticleSystem(const CloudParticleSystem&) = delete; CloudParticleSystem& operator=(const CloudParticleSystem&) = delete; From a03cd2fcdbdc94e3baee797e55b684c78d123c73 Mon Sep 17 00:00:00 2001 From: bruhmoent Date: Fri, 25 Oct 2024 19:45:35 +0200 Subject: [PATCH 5/5] Fix ordering warning --- src/object/cloud_particle_system.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/object/cloud_particle_system.hpp b/src/object/cloud_particle_system.hpp index 4637c05a277..fc1cd0006f8 100644 --- a/src/object/cloud_particle_system.hpp +++ b/src/object/cloud_particle_system.hpp @@ -157,11 +157,10 @@ class CloudParticleSystem final : public ParticleSystem float m_target_speed_y; float m_speed_fade_time_remaining_y; - float m_fog_opacity; - int m_current_amount; int m_current_real_amount; + float m_fog_opacity; private: CloudParticleSystem(const CloudParticleSystem&) = delete; CloudParticleSystem& operator=(const CloudParticleSystem&) = delete;