Welcome to hackvshack.net Forum!
Download Free HvH CS2/CS:GO Cheats, CFG, LUA/JS Scripts, and More!
Register

C++ Cheat 3d particles without patterns

signalud

Rookie HvHer
User ID:
152185
Messages:
90
Reactions:
35
Badges:
11
REP:
−0/0+
Level:
90
so this method uses w2s to do 3d particles without hooking particle system works externally and internally

particles.h
Code:
Expand Collapse Copy
#pragma once

#include <vector>

#include <chrono>

#include <random>

#include <algorithm>

#include "../sdk/structs.h"

#include "../sdk/globals.h"

#include "../imgui/imgui.h"



struct ash_particle_3d_t {

    Vector3 pos;

    Vector3 vel;

    float size;

    float life;

    float max_life;

    float brightness;

    float stretch;

    float rotation;

    float rot_speed;

    float flicker_phase;

    float turbulence_phase;

    float star_radius;

    float wind_angle;

    float tumble;

    int   type;

};



class c_ash_particles {

public:

    void update_and_draw(ash_config_t& cfg);



    void reset() {

        m_particles.clear();

        m_last_time = {};

        m_elapsed = 0.f;

    }



private:

    std::vector<ash_particle_3d_t> m_particles;

    std::chrono::steady_clock::time_point m_last_time{};

    float m_elapsed{ 0.f };

    int   m_last_particle_type{ -1 };

    std::mt19937 m_rng{ std::random_device{}() };



    float rf(float a, float b) {

        std::uniform_real_distribution<float> d(a, b);

        return d(m_rng);

    }



    void spawn_particle(ash_config_t& cfg, const Vector3& origin, const Vector3& forward);

};



namespace features {

    inline c_ash_particles particles;

}



[/ICODE]



particles.cpp

[ICODE]

#define NOMINMAX

#include "particles.h"

#include "../sdk/offsets.h"

#include <algorithm>



void c_ash_particles::spawn_particle(ash_config_t& cfg, const Vector3& origin, const Vector3& forward) {

    ash_particle_3d_t p{};



 

    Vector3 side = { -forward.y, forward.x, 0.f };

  

 

    float fwdDist = rf(-cfg.radius * 0.2f, cfg.radius * 1.8f);

    float sideDist = rf(-cfg.radius, cfg.radius) * (fwdDist / (cfg.radius * 1.8f) + 0.2f);



    p.pos.x = origin.x + forward.x * fwdDist + side.x * sideDist;

    p.pos.y = origin.y + forward.y * fwdDist + side.y * sideDist;

    p.pos.z = origin.z + rf(cfg.height_min, cfg.height_max);



    p.life = 1.0f;

    p.brightness = rf(0.6f, 1.0f);

    p.flicker_phase = rf(0.f, 6.28f);

    p.turbulence_phase = rf(0.f, 6.28f);

    p.rotation = rf(0.f, 6.28f);

    p.star_radius = 0.f;



    switch (cfg.particle_type)

    {

    case 0:

    {

        p.type = (rf(0.f, 1.f) < 0.75f) ? 0 : 1;

        if (p.type == 0) {

            p.vel = { rf(-6.f, 6.f), rf(-6.f, 6.f), rf(3.f, 12.f) };

            p.size = rf(1.5f, 4.f);

            p.max_life = rf(5.f, 12.f);

            p.stretch = rf(1.2f, 3.0f);

            p.rot_speed = rf(-3.f, 3.f);

        }

        else {

            p.vel = { rf(-5.f, 5.f), rf(-5.f, 5.f), rf(10.f, 25.f) };

            p.size = rf(1.8f, 4.0f);

            p.max_life = rf(3.f, 7.f);

            p.stretch = 1.f;

            p.rot_speed = 0.f;

        }

        break;

    }

    case 1:

    {

        p.type = 0;

        p.vel = { rf(-3.f, 3.f), rf(-3.f, 3.f), rf(-15.f, -5.f) };

        p.size = rf(1.5f, 5.f);

        p.max_life = rf(6.f, 14.f);

        p.stretch = 1.f;

        p.rot_speed = rf(-1.f, 1.f);

        break;

    }

    case 2:

    {

        p.type = 0;

        p.vel = { rf(-2.f, 2.f) + cfg.wind_x * 0.2f, rf(-2.f, 2.f) + cfg.wind_y * 0.2f, rf(-120.f, -80.f) };

        p.size = rf(0.8f, 1.6f);

        p.max_life = rf(0.8f, 2.0f);

        p.stretch = 1.f;

        p.rot_speed = 0.f;

        p.rotation = 0.f;

        break;

    }

    case 3:

    {

        p.type = 0;

        p.vel = { rf(-0.5f, 0.5f), rf(-0.5f, 0.5f), rf(-0.3f, 0.3f) };

        p.size = rf(1.f, 3.5f);

        p.max_life = rf(12.f, 25.f);

        p.stretch = 1.f;

        p.rot_speed = rf(-0.4f, 0.4f);

        p.star_radius = rf(2.5f, 5.5f);

        break;

    }

    case 4:

    {

        p.type = 0;

        p.vel = { rf(-8.f, 8.f) + cfg.wind_x * 0.3f, rf(-8.f, 8.f) + cfg.wind_y * 0.3f, rf(-18.f, -6.f) };

        p.size = rf(4.f, 19.f);

        p.max_life = rf(5.f, 12.f);

        p.stretch = 1.f;

        p.rot_speed = rf(-3.f, 3.f);

        p.wind_angle = rf(0.f, 6.28f);

        p.tumble = rf(0.f, 6.28f);

        break;

    }

    }



    m_particles.push_back(p);

}



void c_ash_particles::update_and_draw(ash_config_t& cfg) {

    if (!cfg.enabled) {

        if (!m_particles.empty()) reset();

        return;

    }



    if (cfg.particle_type != m_last_particle_type) {

        reset();

        m_last_particle_type = cfg.particle_type;

    }



    uintptr_t clientBase = (uintptr_t)GetModuleHandleA("client.dll");

    if (!clientBase) return;



    uintptr_t localPawn = *(uintptr_t*)(clientBase + offsets::dwLocalPlayerPawn);

    if (!localPawn) return;



    int health = *(int*)(localPawn + offsets::m_iHealth);

    if (health <= 0) return;



    uintptr_t sceneNode = *(uintptr_t*)(localPawn + offsets::m_pGameSceneNode);

    if (!sceneNode) return;



    Vector3 player_origin = *(Vector3*)(sceneNode + offsets::m_vecAbsOrigin);

    Vector3 viewAngles = *(Vector3*)(localPawn + offsets::m_angEyeAngles);



    view_matrix_t viewMatrix;

    memcpy(&viewMatrix, (void*)(clientBase + offsets::dwViewMatrix), sizeof(viewMatrix));



    auto now = std::chrono::steady_clock::now();

    if (m_last_time.time_since_epoch().count() == 0) {

        m_last_time = now;

        return;

    }



    float dt = std::chrono::duration<float>(now - m_last_time).count();

    m_last_time = now;

    m_elapsed += dt;

    if (dt > 0.1f) dt = 0.1f;



 

    float yaw = viewAngles.y * (3.14159265f / 180.f);

    Vector3 forward = { std::cos(yaw), std::sin(yaw), 0.f };



    while (static_cast<int>(m_particles.size()) < cfg.count)

        spawn_particle(cfg, player_origin, forward);



    auto* dl = ImGui::GetBackgroundDrawList();

    ImVec2 ds = ImGui::GetIO().DisplaySize;



    for (int i = static_cast<int>(m_particles.size()) - 1; i >= 0; i--) {

        auto& p = m_particles[i];

        p.life -= dt / p.max_life;



        Vector3 delta = p.pos - player_origin;

        float dist_sq = delta.x * delta.x + delta.y * delta.y + delta.z * delta.z;



      

        if (p.life <= 0.f || dist_sq > cfg.radius * cfg.radius * 9.f) {

            m_particles[i] = m_particles.back();

            m_particles.pop_back();

            continue;

        }



        float tx = std::sin(m_elapsed * 1.3f + p.turbulence_phase) * cfg.turbulence * 10.f;

        float ty = std::cos(m_elapsed * 1.1f + p.turbulence_phase * 0.7f) * cfg.turbulence * 10.f;

        float tz = std::sin(m_elapsed * 0.8f + p.turbulence_phase * 1.3f) * cfg.turbulence * 5.f;

        float gust = std::sin(m_elapsed * 0.25f + p.turbulence_phase * 0.4f) * 0.4f + 1.0f;



        p.pos.x += (p.vel.x + cfg.wind_x * gust + tx) * cfg.speed * dt;

        p.pos.y += (p.vel.y + cfg.wind_y * gust + ty) * cfg.speed * dt;

        p.pos.z += (p.vel.z + cfg.wind_z + tz) * cfg.speed * dt;



        p.rotation += p.rot_speed * dt;



        Vector2 screen;

        if (!WorldToScreen(p.pos, screen, viewMatrix, (int)ds.x, (int)ds.y))

            continue;



        float dist = std::sqrt(dist_sq);

        float perspective = 250.f / (dist + 60.f);



        float alpha_life = (p.life > 0.9f) ? (1.0f - p.life) * 10.f : (p.life < 0.2f ? p.life / 0.2f : 1.0f);

        float dist_fade = 1.0f - std::clamp(dist / (cfg.radius * 2.5f), 0.f, 1.f);

        dist_fade *= dist_fade;



        float alpha = alpha_life * p.brightness * dist_fade;

        if (alpha < 0.01f) continue;



        ImVec2 sp(screen.x, screen.y);



        switch (cfg.particle_type)

        {

        case 0:

            if (p.type == 0) {

                float sz = (std::clamp)(p.size * perspective, 0.4f, 8.f);

                float sx = sz * p.stretch, sy = sz;

                float c = std::cos(p.rotation), s = std::sin(p.rotation);

                ImVec2 pts[4];

                float hx = sx * 0.5f, hy = sy * 0.5f;

                pts[0] = { sp.x + (-hx*c - -hy*s), sp.y + (-hx*s + -hy*c) };

                pts[1] = { sp.x + ( hx*c - -hy*s), sp.y + ( hx*s + -hy*c) };

                pts[2] = { sp.x + ( hx*c -  hy*s), sp.y + ( hx*s +  hy*c) };

                pts[3] = { sp.x + (-hx*c -  hy*s), sp.y + (-hx*s +  hy*c) };

                dl->AddConvexPolyFilled(pts, 4, IM_COL32(cfg.debris_color.r, cfg.debris_color.g, cfg.debris_color.b, (int)(alpha * cfg.debris_color.a)));

            } else {

                float sz = (std::clamp)(p.size * perspective * 0.7f, 0.3f, 6.f);

                float flicker = 0.6f + 0.4f * std::sin(m_elapsed * 10.f + p.flicker_phase);

                float ea = alpha * flicker;

                if (ea * 0.3f * cfg.glow_intensity > 0.01f)

                    dl->AddCircleFilled(sp, sz * 4.f, IM_COL32(cfg.ember_glow.r, cfg.ember_glow.g, cfg.ember_glow.b, (int)(ea * 0.3f * cfg.glow_intensity * 100.f)), 8);

                dl->AddCircleFilled(sp, sz * 2.f, IM_COL32(cfg.ember_glow.r, cfg.ember_glow.g, cfg.ember_glow.b, (int)(ea * 120.f)), 8);

                dl->AddCircleFilled(sp, sz, IM_COL32(cfg.ember_core.r, cfg.ember_core.g, cfg.ember_core.b, (int)((std::min)(ea * cfg.glow_intensity, 1.f) * 255.f)), 6);

            }

            break;

        case 1:

        {

            float sz = (std::clamp)(p.size * perspective, 0.4f, 9.f);

            int base_a = (int)(alpha * cfg.snow_color.a);

            dl->AddCircleFilled(sp, sz * 2.2f, IM_COL32(cfg.snow_color.r, cfg.snow_color.g, cfg.snow_color.b, base_a / 6), 12);

            dl->AddCircleFilled(sp, sz * 1.4f, IM_COL32(cfg.snow_color.r, cfg.snow_color.g, cfg.snow_color.b, base_a / 3), 12);

            dl->AddCircleFilled(sp, sz, IM_COL32(cfg.snow_color.r, cfg.snow_color.g, cfg.snow_color.b, base_a), 10);

            break;

        }

        case 2:

        {

            float sz = (std::clamp)(p.size * perspective, 0.4f, 4.f);

            Vector3 tail_world = p.pos - p.vel * (cfg.speed * 0.035f);

            Vector2 tail_screen;

            if (!WorldToScreen(tail_world, tail_screen, viewMatrix, (int)ds.x, (int)ds.y)) continue;

            ImVec2 tail(tail_screen.x, tail_screen.y);

          

            float dx = sp.x - tail.x, dy = sp.y - tail.y;

            float slen = std::sqrt(dx*dx + dy*dy);

            if (slen > 40.f) { float scale = 40.f / slen; tail = { sp.x - dx * scale, sp.y - dy * scale }; }

            if (slen < 1.0f) continue;



            int ra = (int)(alpha * cfg.rain_color.a);

          

            dl->AddLine(tail, sp, IM_COL32(cfg.rain_color.r, cfg.rain_color.g, cfg.rain_color.b, ra / 8), sz * 3.0f);

          

            dl->AddLine(tail, sp, IM_COL32(cfg.rain_color.r, cfg.rain_color.g, cfg.rain_color.b, ra / 2), sz * 1.5f);

        

            dl->AddLine(tail, sp, IM_COL32(255, 255, 255, (int)(alpha * 200)), (std::max)(sz * 0.4f, 0.5f));

          

            if (p.pos.z < player_origin.z - 20.f && rf(0.f, 1.f) < 0.1f) {

                 dl->AddCircle(sp, sz * 3.f * (1.0f - p.life), IM_COL32(200, 220, 255, ra / 4), 8, 1.0f);

            }

            break;

        }

        case 3:

        {

            float sz = (std::clamp)(p.size * perspective, 0.5f, 7.f);

            float twinkle = 0.55f + 0.45f * std::sin(m_elapsed * 2.5f + p.flicker_phase);

            float ea = alpha * twinkle * cfg.glow_intensity;

            if (ea < 0.02f) continue;

            int sa = (int)((std::min)(ea, 1.f) * 255.f);

            float gr = (std::min)(sz * 5.5f * p.star_radius * 0.35f, 28.f);

            if (gr > 1.f) {

                dl->AddCircleFilled(sp, gr, IM_COL32(cfg.star_glow.r, cfg.star_glow.g, cfg.star_glow.b, (int)(ea * 0.10f * cfg.star_glow.a)), 16);

                dl->AddCircleFilled(sp, gr * 0.5f, IM_COL32(cfg.star_glow.r, cfg.star_glow.g, cfg.star_glow.b, (int)(ea * 0.22f * cfg.star_glow.a)), 12);

                dl->AddCircleFilled(sp, gr * 0.2f, IM_COL32(cfg.star_color.r, cfg.star_color.g, cfg.star_color.b, (int)(ea * 0.42f * cfg.star_glow.a)), 8);

            }

            constexpr int PTS = 10; constexpr float TWO_PI = 6.28318530f;

            float outer_r = sz * 2.0f, inner_r = sz * 0.80f, base_a = p.rotation - (TWO_PI / 4.f);

            ImVec2 v[PTS]; for (int k = 0; k < PTS; ++k) { float r = (k % 2 == 0) ? outer_r : inner_r; float ang = base_a + (TWO_PI * k) / PTS; v[k] = { sp.x + std::cos(ang) * r, sp.y + std::sin(ang) * r }; }

            ImU32 col = IM_COL32(cfg.star_color.r, cfg.star_color.g, cfg.star_color.b, sa);

            if (sz > 1.5f) {

                ImVec2 gv[PTS]; for (int k = 0; k < PTS; ++k) { float r = ((k % 2 == 0) ? outer_r : inner_r) * 1.4f; float ang = base_a + (TWO_PI * k) / PTS; gv[k] = { sp.x + std::cos(ang) * r, sp.y + std::sin(ang) * r }; }

                for (int k = 0; k < PTS; ++k) dl->AddTriangleFilled(sp, gv[k], gv[(k+1)%PTS], IM_COL32(cfg.star_color.r, cfg.star_color.g, cfg.star_color.b, sa / 5));

            }

            for (int k = 0; k < PTS; ++k) dl->AddTriangleFilled(sp, v[k], v[(k+1)%PTS], col);

            dl->AddCircleFilled(sp, sz * 0.4f, IM_COL32(255, 255, 255, sa), 5);

            break;

        }

        case 4:

        {

            float sz = 15.f * perspective;

            p.tumble += p.rot_speed * dt;

            float tumble_scale = std::abs(std::cos(p.tumble));

            float sx = sz, sy = sz * (0.15f + 0.85f * tumble_scale);

            ash_color_t lc = (p.flicker_phase / 6.28f < 0.33f) ? cfg.leaf_color_a : (p.flicker_phase / 6.28f < 0.66f ? cfg.leaf_color_b : cfg.leaf_color_c);

            float c = std::cos(p.rotation), s = std::sin(p.rotation);

            float hx = sx * 0.5f, hy = sy * 0.5f;

            ImVec2 pts[4];

            pts[0] = { sp.x + (-hx*c - -hy*s), sp.y + (-hx*s + -hy*c) };

            pts[1] = { sp.x + ( hx*c - -hy*s), sp.y + ( hx*s + -hy*c) };

            pts[2] = { sp.x + ( hx*c -  hy*s), sp.y + ( hx*s +  hy*c) };

            pts[3] = { sp.x + (-hx*c -  hy*s), sp.y + (-hx*s +  hy*c) };

            dl->AddConvexPolyFilled(pts, 4, IM_COL32(lc.r, lc.g, lc.b, (int)(alpha * lc.a)));

            break;

        }

        }

    }

}
 
Last edited by a moderator:
  • Like
Reactions: kazkoks
so this method uses w2s to do 3d particles without hooking particle system works externally and internally

particles.h
Code:
Expand Collapse Copy
#pragma once

#include <vector>

#include <chrono>

#include <random>

#include <algorithm>

#include "../sdk/structs.h"

#include "../sdk/globals.h"

#include "../imgui/imgui.h"



struct ash_particle_3d_t {

    Vector3 pos;

    Vector3 vel;

    float size;

    float life;

    float max_life;

    float brightness;

    float stretch;

    float rotation;

    float rot_speed;

    float flicker_phase;

    float turbulence_phase;

    float star_radius;

    float wind_angle;

    float tumble;

    int   type;

};



class c_ash_particles {

public:

    void update_and_draw(ash_config_t& cfg);



    void reset() {

        m_particles.clear();

        m_last_time = {};

        m_elapsed = 0.f;

    }



private:

    std::vector<ash_particle_3d_t> m_particles;

    std::chrono::steady_clock::time_point m_last_time{};

    float m_elapsed{ 0.f };

    int   m_last_particle_type{ -1 };

    std::mt19937 m_rng{ std::random_device{}() };



    float rf(float a, float b) {

        std::uniform_real_distribution<float> d(a, b);

        return d(m_rng);

    }



    void spawn_particle(ash_config_t& cfg, const Vector3& origin, const Vector3& forward);

};



namespace features {

    inline c_ash_particles particles;

}



[/ICODE]



particles.cpp

[ICODE]

#define NOMINMAX

#include "particles.h"

#include "../sdk/offsets.h"

#include <algorithm>



void c_ash_particles::spawn_particle(ash_config_t& cfg, const Vector3& origin, const Vector3& forward) {

    ash_particle_3d_t p{};



 

    Vector3 side = { -forward.y, forward.x, 0.f };

 

 

    float fwdDist = rf(-cfg.radius * 0.2f, cfg.radius * 1.8f);

    float sideDist = rf(-cfg.radius, cfg.radius) * (fwdDist / (cfg.radius * 1.8f) + 0.2f);



    p.pos.x = origin.x + forward.x * fwdDist + side.x * sideDist;

    p.pos.y = origin.y + forward.y * fwdDist + side.y * sideDist;

    p.pos.z = origin.z + rf(cfg.height_min, cfg.height_max);



    p.life = 1.0f;

    p.brightness = rf(0.6f, 1.0f);

    p.flicker_phase = rf(0.f, 6.28f);

    p.turbulence_phase = rf(0.f, 6.28f);

    p.rotation = rf(0.f, 6.28f);

    p.star_radius = 0.f;



    switch (cfg.particle_type)

    {

    case 0:

    {

        p.type = (rf(0.f, 1.f) < 0.75f) ? 0 : 1;

        if (p.type == 0) {

            p.vel = { rf(-6.f, 6.f), rf(-6.f, 6.f), rf(3.f, 12.f) };

            p.size = rf(1.5f, 4.f);

            p.max_life = rf(5.f, 12.f);

            p.stretch = rf(1.2f, 3.0f);

            p.rot_speed = rf(-3.f, 3.f);

        }

        else {

            p.vel = { rf(-5.f, 5.f), rf(-5.f, 5.f), rf(10.f, 25.f) };

            p.size = rf(1.8f, 4.0f);

            p.max_life = rf(3.f, 7.f);

            p.stretch = 1.f;

            p.rot_speed = 0.f;

        }

        break;

    }

    case 1:

    {

        p.type = 0;

        p.vel = { rf(-3.f, 3.f), rf(-3.f, 3.f), rf(-15.f, -5.f) };

        p.size = rf(1.5f, 5.f);

        p.max_life = rf(6.f, 14.f);

        p.stretch = 1.f;

        p.rot_speed = rf(-1.f, 1.f);

        break;

    }

    case 2:

    {

        p.type = 0;

        p.vel = { rf(-2.f, 2.f) + cfg.wind_x * 0.2f, rf(-2.f, 2.f) + cfg.wind_y * 0.2f, rf(-120.f, -80.f) };

        p.size = rf(0.8f, 1.6f);

        p.max_life = rf(0.8f, 2.0f);

        p.stretch = 1.f;

        p.rot_speed = 0.f;

        p.rotation = 0.f;

        break;

    }

    case 3:

    {

        p.type = 0;

        p.vel = { rf(-0.5f, 0.5f), rf(-0.5f, 0.5f), rf(-0.3f, 0.3f) };

        p.size = rf(1.f, 3.5f);

        p.max_life = rf(12.f, 25.f);

        p.stretch = 1.f;

        p.rot_speed = rf(-0.4f, 0.4f);

        p.star_radius = rf(2.5f, 5.5f);

        break;

    }

    case 4:

    {

        p.type = 0;

        p.vel = { rf(-8.f, 8.f) + cfg.wind_x * 0.3f, rf(-8.f, 8.f) + cfg.wind_y * 0.3f, rf(-18.f, -6.f) };

        p.size = rf(4.f, 19.f);

        p.max_life = rf(5.f, 12.f);

        p.stretch = 1.f;

        p.rot_speed = rf(-3.f, 3.f);

        p.wind_angle = rf(0.f, 6.28f);

        p.tumble = rf(0.f, 6.28f);

        break;

    }

    }



    m_particles.push_back(p);

}



void c_ash_particles::update_and_draw(ash_config_t& cfg) {

    if (!cfg.enabled) {

        if (!m_particles.empty()) reset();

        return;

    }



    if (cfg.particle_type != m_last_particle_type) {

        reset();

        m_last_particle_type = cfg.particle_type;

    }



    uintptr_t clientBase = (uintptr_t)GetModuleHandleA("client.dll");

    if (!clientBase) return;



    uintptr_t localPawn = *(uintptr_t*)(clientBase + offsets::dwLocalPlayerPawn);

    if (!localPawn) return;



    int health = *(int*)(localPawn + offsets::m_iHealth);

    if (health <= 0) return;



    uintptr_t sceneNode = *(uintptr_t*)(localPawn + offsets::m_pGameSceneNode);

    if (!sceneNode) return;



    Vector3 player_origin = *(Vector3*)(sceneNode + offsets::m_vecAbsOrigin);

    Vector3 viewAngles = *(Vector3*)(localPawn + offsets::m_angEyeAngles);



    view_matrix_t viewMatrix;

    memcpy(&viewMatrix, (void*)(clientBase + offsets::dwViewMatrix), sizeof(viewMatrix));



    auto now = std::chrono::steady_clock::now();

    if (m_last_time.time_since_epoch().count() == 0) {

        m_last_time = now;

        return;

    }



    float dt = std::chrono::duration<float>(now - m_last_time).count();

    m_last_time = now;

    m_elapsed += dt;

    if (dt > 0.1f) dt = 0.1f;



 

    float yaw = viewAngles.y * (3.14159265f / 180.f);

    Vector3 forward = { std::cos(yaw), std::sin(yaw), 0.f };



    while (static_cast<int>(m_particles.size()) < cfg.count)

        spawn_particle(cfg, player_origin, forward);



    auto* dl = ImGui::GetBackgroundDrawList();

    ImVec2 ds = ImGui::GetIO().DisplaySize;



    for (int i = static_cast<int>(m_particles.size()) - 1; i >= 0; i--) {

        auto& p = m_particles[i];

        p.life -= dt / p.max_life;



        Vector3 delta = p.pos - player_origin;

        float dist_sq = delta.x * delta.x + delta.y * delta.y + delta.z * delta.z;



     

        if (p.life <= 0.f || dist_sq > cfg.radius * cfg.radius * 9.f) {

            m_particles[i] = m_particles.back();

            m_particles.pop_back();

            continue;

        }



        float tx = std::sin(m_elapsed * 1.3f + p.turbulence_phase) * cfg.turbulence * 10.f;

        float ty = std::cos(m_elapsed * 1.1f + p.turbulence_phase * 0.7f) * cfg.turbulence * 10.f;

        float tz = std::sin(m_elapsed * 0.8f + p.turbulence_phase * 1.3f) * cfg.turbulence * 5.f;

        float gust = std::sin(m_elapsed * 0.25f + p.turbulence_phase * 0.4f) * 0.4f + 1.0f;



        p.pos.x += (p.vel.x + cfg.wind_x * gust + tx) * cfg.speed * dt;

        p.pos.y += (p.vel.y + cfg.wind_y * gust + ty) * cfg.speed * dt;

        p.pos.z += (p.vel.z + cfg.wind_z + tz) * cfg.speed * dt;



        p.rotation += p.rot_speed * dt;



        Vector2 screen;

        if (!WorldToScreen(p.pos, screen, viewMatrix, (int)ds.x, (int)ds.y))

            continue;



        float dist = std::sqrt(dist_sq);

        float perspective = 250.f / (dist + 60.f);



        float alpha_life = (p.life > 0.9f) ? (1.0f - p.life) * 10.f : (p.life < 0.2f ? p.life / 0.2f : 1.0f);

        float dist_fade = 1.0f - std::clamp(dist / (cfg.radius * 2.5f), 0.f, 1.f);

        dist_fade *= dist_fade;



        float alpha = alpha_life * p.brightness * dist_fade;

        if (alpha < 0.01f) continue;



        ImVec2 sp(screen.x, screen.y);



        switch (cfg.particle_type)

        {

        case 0:

            if (p.type == 0) {

                float sz = (std::clamp)(p.size * perspective, 0.4f, 8.f);

                float sx = sz * p.stretch, sy = sz;

                float c = std::cos(p.rotation), s = std::sin(p.rotation);

                ImVec2 pts[4];

                float hx = sx * 0.5f, hy = sy * 0.5f;

                pts[0] = { sp.x + (-hx*c - -hy*s), sp.y + (-hx*s + -hy*c) };

                pts[1] = { sp.x + ( hx*c - -hy*s), sp.y + ( hx*s + -hy*c) };

                pts[2] = { sp.x + ( hx*c -  hy*s), sp.y + ( hx*s +  hy*c) };

                pts[3] = { sp.x + (-hx*c -  hy*s), sp.y + (-hx*s +  hy*c) };

                dl->AddConvexPolyFilled(pts, 4, IM_COL32(cfg.debris_color.r, cfg.debris_color.g, cfg.debris_color.b, (int)(alpha * cfg.debris_color.a)));

            } else {

                float sz = (std::clamp)(p.size * perspective * 0.7f, 0.3f, 6.f);

                float flicker = 0.6f + 0.4f * std::sin(m_elapsed * 10.f + p.flicker_phase);

                float ea = alpha * flicker;

                if (ea * 0.3f * cfg.glow_intensity > 0.01f)

                    dl->AddCircleFilled(sp, sz * 4.f, IM_COL32(cfg.ember_glow.r, cfg.ember_glow.g, cfg.ember_glow.b, (int)(ea * 0.3f * cfg.glow_intensity * 100.f)), 8);

                dl->AddCircleFilled(sp, sz * 2.f, IM_COL32(cfg.ember_glow.r, cfg.ember_glow.g, cfg.ember_glow.b, (int)(ea * 120.f)), 8);

                dl->AddCircleFilled(sp, sz, IM_COL32(cfg.ember_core.r, cfg.ember_core.g, cfg.ember_core.b, (int)((std::min)(ea * cfg.glow_intensity, 1.f) * 255.f)), 6);

            }

            break;

        case 1:

        {

            float sz = (std::clamp)(p.size * perspective, 0.4f, 9.f);

            int base_a = (int)(alpha * cfg.snow_color.a);

            dl->AddCircleFilled(sp, sz * 2.2f, IM_COL32(cfg.snow_color.r, cfg.snow_color.g, cfg.snow_color.b, base_a / 6), 12);

            dl->AddCircleFilled(sp, sz * 1.4f, IM_COL32(cfg.snow_color.r, cfg.snow_color.g, cfg.snow_color.b, base_a / 3), 12);

            dl->AddCircleFilled(sp, sz, IM_COL32(cfg.snow_color.r, cfg.snow_color.g, cfg.snow_color.b, base_a), 10);

            break;

        }

        case 2:

        {

            float sz = (std::clamp)(p.size * perspective, 0.4f, 4.f);

            Vector3 tail_world = p.pos - p.vel * (cfg.speed * 0.035f);

            Vector2 tail_screen;

            if (!WorldToScreen(tail_world, tail_screen, viewMatrix, (int)ds.x, (int)ds.y)) continue;

            ImVec2 tail(tail_screen.x, tail_screen.y);

         

            float dx = sp.x - tail.x, dy = sp.y - tail.y;

            float slen = std::sqrt(dx*dx + dy*dy);

            if (slen > 40.f) { float scale = 40.f / slen; tail = { sp.x - dx * scale, sp.y - dy * scale }; }

            if (slen < 1.0f) continue;



            int ra = (int)(alpha * cfg.rain_color.a);

         

            dl->AddLine(tail, sp, IM_COL32(cfg.rain_color.r, cfg.rain_color.g, cfg.rain_color.b, ra / 8), sz * 3.0f);

         

            dl->AddLine(tail, sp, IM_COL32(cfg.rain_color.r, cfg.rain_color.g, cfg.rain_color.b, ra / 2), sz * 1.5f);

       

            dl->AddLine(tail, sp, IM_COL32(255, 255, 255, (int)(alpha * 200)), (std::max)(sz * 0.4f, 0.5f));

         

            if (p.pos.z < player_origin.z - 20.f && rf(0.f, 1.f) < 0.1f) {

                 dl->AddCircle(sp, sz * 3.f * (1.0f - p.life), IM_COL32(200, 220, 255, ra / 4), 8, 1.0f);

            }

            break;

        }

        case 3:

        {

            float sz = (std::clamp)(p.size * perspective, 0.5f, 7.f);

            float twinkle = 0.55f + 0.45f * std::sin(m_elapsed * 2.5f + p.flicker_phase);

            float ea = alpha * twinkle * cfg.glow_intensity;

            if (ea < 0.02f) continue;

            int sa = (int)((std::min)(ea, 1.f) * 255.f);

            float gr = (std::min)(sz * 5.5f * p.star_radius * 0.35f, 28.f);

            if (gr > 1.f) {

                dl->AddCircleFilled(sp, gr, IM_COL32(cfg.star_glow.r, cfg.star_glow.g, cfg.star_glow.b, (int)(ea * 0.10f * cfg.star_glow.a)), 16);

                dl->AddCircleFilled(sp, gr * 0.5f, IM_COL32(cfg.star_glow.r, cfg.star_glow.g, cfg.star_glow.b, (int)(ea * 0.22f * cfg.star_glow.a)), 12);

                dl->AddCircleFilled(sp, gr * 0.2f, IM_COL32(cfg.star_color.r, cfg.star_color.g, cfg.star_color.b, (int)(ea * 0.42f * cfg.star_glow.a)), 8);

            }

            constexpr int PTS = 10; constexpr float TWO_PI = 6.28318530f;

            float outer_r = sz * 2.0f, inner_r = sz * 0.80f, base_a = p.rotation - (TWO_PI / 4.f);

            ImVec2 v[PTS]; for (int k = 0; k < PTS; ++k) { float r = (k % 2 == 0) ? outer_r : inner_r; float ang = base_a + (TWO_PI * k) / PTS; v[k] = { sp.x + std::cos(ang) * r, sp.y + std::sin(ang) * r }; }

            ImU32 col = IM_COL32(cfg.star_color.r, cfg.star_color.g, cfg.star_color.b, sa);

            if (sz > 1.5f) {

                ImVec2 gv[PTS]; for (int k = 0; k < PTS; ++k) { float r = ((k % 2 == 0) ? outer_r : inner_r) * 1.4f; float ang = base_a + (TWO_PI * k) / PTS; gv[k] = { sp.x + std::cos(ang) * r, sp.y + std::sin(ang) * r }; }

                for (int k = 0; k < PTS; ++k) dl->AddTriangleFilled(sp, gv[k], gv[(k+1)%PTS], IM_COL32(cfg.star_color.r, cfg.star_color.g, cfg.star_color.b, sa / 5));

            }

            for (int k = 0; k < PTS; ++k) dl->AddTriangleFilled(sp, v[k], v[(k+1)%PTS], col);

            dl->AddCircleFilled(sp, sz * 0.4f, IM_COL32(255, 255, 255, sa), 5);

            break;

        }

        case 4:

        {

            float sz = 15.f * perspective;

            p.tumble += p.rot_speed * dt;

            float tumble_scale = std::abs(std::cos(p.tumble));

            float sx = sz, sy = sz * (0.15f + 0.85f * tumble_scale);

            ash_color_t lc = (p.flicker_phase / 6.28f < 0.33f) ? cfg.leaf_color_a : (p.flicker_phase / 6.28f < 0.66f ? cfg.leaf_color_b : cfg.leaf_color_c);

            float c = std::cos(p.rotation), s = std::sin(p.rotation);

            float hx = sx * 0.5f, hy = sy * 0.5f;

            ImVec2 pts[4];

            pts[0] = { sp.x + (-hx*c - -hy*s), sp.y + (-hx*s + -hy*c) };

            pts[1] = { sp.x + ( hx*c - -hy*s), sp.y + ( hx*s + -hy*c) };

            pts[2] = { sp.x + ( hx*c -  hy*s), sp.y + ( hx*s +  hy*c) };

            pts[3] = { sp.x + (-hx*c -  hy*s), sp.y + (-hx*s +  hy*c) };

            dl->AddConvexPolyFilled(pts, 4, IM_COL32(lc.r, lc.g, lc.b, (int)(alpha * lc.a)));

            break;

        }

        }

    }

}
Good boy
 
why would you ever want to use this when internal? I understand external but this just seems to be a waste when the cs2 particle system is so optimised and easy.
 
why would you ever want to use this when internal? I understand external but this just seems to be a waste when the cs2 particle system is so optimised and easy.
this is optimised and its only for externals idk why anyone would use this in an internal
 

Who has read this thread (Total: 1) in last 1 hours View details