Nimbin[12]?SDL & Graphics / sdl_runtime_compiler / src/systems/celebration_system.cpp

sdl_runtime_compiler git · main

SDL3 game for running and compiling code at runtime

sdl3 c++ compiler dlopen cmake · first commit 2026-04-19 · last commit 2026-07-03 (3 months ago) · synced 3 days ago · upstream: git.ide3.de/hsnr/sdl-runtime-compiler

C++ 72.3% C 26.2%
git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gz
src/systems/celebration_system.cpp 2.9 KB · 118 lines raw
#include "celebration_system.hpp"
#include "entities/camera.hpp"
#include "entities/world.hpp"
#include "systems/particle_system.hpp"

namespace
Nimbin
{

void
CelebrationSystem::start(const Camera& cam, double& glyph_yaw)
{
    _active     = true;
    _t          = 0.0;
    _next_burst = 0.0;

    const double ws     = World::get_BoxScale<double>();
    const double floor  = World::get_FloorY<double>();
    const double margin = 1.0;

    Vec3 banner_pos {
        cam.pos.x + cam.fwd.x * 10.0,
        cam.pos.y + cam.fwd.y * 10.0,
        cam.pos.z + cam.fwd.z * 10.0,
    };

    auto clamp = [](double v, double lo, double hi) {
        return v < lo ? lo : (v > hi ? hi : v);
    };

    banner_pos.x = clamp(banner_pos.x, -ws + margin, ws - margin);
    banner_pos.z = clamp(banner_pos.z, -ws + margin, ws - margin);
    banner_pos.y = clamp(banner_pos.y, floor + 1.0,  ws - margin);

    _banner = Text::make_Token("Success",
                          Text::Token::depth_floor * 2.0f,
                          0.012f, banner_pos,
                          Config::Color::white);
    _banner->yaw       = static_cast<float>(glyph_yaw);
    _banner->body.mode = PhysicsMode::Static;
}


void
CelebrationSystem::tick(double dt, ParticleSystem& particle_sys)
{
    if (!_active) return;

    _t += dt;

    if (_banner)
        _banner->yaw += static_cast<float>(dt * 0.6);

    if (_t >= _next_burst &&
        _t <  _duration - 0.3) {
        const double ws = World::get_BoxScale<double>();
        const double margin = 3.0;
        auto rnd = []() {
            return Random::unit();
        };

        Vec3 center {
            (rnd() * 2.0 - 1.0) * (ws - margin),
            rnd() * (ws - margin),
            (rnd() * 2.0 - 1.0) * (ws - margin),
        };

        double h = rnd() * 6.0;
        int    i = static_cast<int>(h);
        double f = h - i;
        float r=0, g=0, b=0;
        switch (i % 6) {
            case 0: r=1;     g=(float)f; b=0;            break;
            case 1: r=(float)(1-f); g=1; b=0;            break;
            case 2: r=0;     g=1;        b=(float)f;     break;
            case 3: r=0;     g=(float)(1-f); b=1;        break;
            case 4: r=(float)f; g=0;     b=1;            break;
            case 5: r=1;     g=0;        b=(float)(1-f); break;
        }

        particle_sys.emit_FireworkBurst(center, SDL_FColor{r, g, b, 1.0f}, 80);

        _next_burst = _t + 0.5 + rnd() * 0.5;
    }
}


void
CelebrationSystem::finish(ParticleSystem& particle_sys)
{
    _active = false;
    _banner.     reset();
    particle_sys.clear();
}


bool
CelebrationSystem::is_Active() const
{
    return _active;
}


double
CelebrationSystem::get_Progress() const
{
    return (_duration > 0.0) ? (_t / _duration) : 1.0;
}


void
CelebrationSystem::draw(GlRenderer& gl, const Camera& cam, const Light& light) const
{
    if (!_active || !_banner) return;
    _banner->draw(gl, cam, light);
}

} // namespace Nimbin