Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Гайд Particle Manager

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
1 Авг 2024
Сообщения
65
Реакции
2
вот кому надо вот вам Particle Manager
1 трейсера
2 map Particle

сами эффекты, Ashes, Snow, Stars

кидать эфекты сюда Counter-Strike Global Offensive\game\csgo\bin

1765631358440.png


ParticleManager.cpp:
Expand Collapse Copy
constexpr const char* EMBER_EFFECT_PATH = "bin/falling_ember1.vpcf";
constexpr const char* EMBER_EFFECT2_PATH = "bin/falling_ember2.vpcf";
constexpr const char* SNOW_EFFECT_PATH = "bin/falling_snow1.vpcf";
constexpr const char* STARS_EFFECT_PATH = "bin/nomove_stars.vpcf";
constexpr const char* RAIN_EFFECT_PATH = "bin/rain.vpcf";


struct TracerStartInfo
{
    Vector vEyePos;
    float flTime;
};
std::unordered_map<CCSPlayerController*, TracerStartInfo> m_mapTracerStartCache;


void CParticleMgr::OnEvent(CGameEvent* pEvent)
{
    CCSPlayerController* pController = reinterpret_cast<CCSPlayerController*>(pEvent->GetPlayerController(X("userid")));
    C_CSPlayerPawn* pPawn = reinterpret_cast<C_CSPlayerPawn*>(pEvent->GetPlayerPawn(X("userid")));
    if (!pController || !pPawn)
        return;

    Vector vecImpactPosition = Vector(pEvent->GetFloat(X("x")), pEvent->GetFloat(X("y")), pEvent->GetFloat(X("z")));
    if (vecImpactPosition.IsZero())
        return;

    float currentTime = Interfaces::m_pGlobalVariables->m_flCurrentTime;

    if (pController->m_bIsLocalPlayerController())
    {
        if (Config::b(g_Variables.m_WorldEffects.m_bDrawImpacts))
        {
            Interfaces::m_pClient->GetDebugOverlay()->RenderWithoutDots(true);
            Interfaces::m_pClient->GetDebugOverlay()->AddBoxOverlay(
                vecImpactPosition,
                Vector(-1.f, -1.f, -1.f),
                Vector(1.f, 1.f, 1.f),
                QAngle(0.0f, 0.0f, 0.0f),
                Config::c(g_Variables.m_WorldEffects.m_colDrawImpactsColor),
                Config::i(g_Variables.m_Visuals.m_nHitEffectsDurration)
            );
        }

        if (Config::b(g_Variables.m_WorldEffects.m_bLocalBulletTracers))
        {
            TracerStartInfo& info = m_mapTracerStartCache[pController];

            
            info.vEyePos = Globals::m_pLocalPlayerPawn->GetEyePosition(true);
            info.flTime = currentTime;

            if (Config::b(g_Variables.m_WorldEffects.m_bLocalBulletTracersGradient))
            {
                this->AddParticle2PointGradient(
                    X("particles/entity/spectator_utility_trail.vpcf"),
                    info.vEyePos,
                    vecImpactPosition,
                    Config::c(g_Variables.m_WorldEffects.m_colLocalBulletTracers),
                    Config::c(g_Variables.m_WorldEffects.m_colLocalBulletTracersGradient),
                    Config::i(g_Variables.m_Visuals.m_nHitEffectsDurration),
                    false
                );
            }
            else
            {
                this->AddParticle2Point(
                    X("particles/entity/spectator_utility_trail.vpcf"),
                    info.vEyePos,
                    vecImpactPosition,
                    Config::c(g_Variables.m_WorldEffects.m_colLocalBulletTracers),
                    Config::i(g_Variables.m_Visuals.m_nHitEffectsDurration),
                    false
                );
            }
        }
    }

    else if (pPawn->IsEnemy(Globals::m_pLocalPlayerPawn))
    {
        if (Config::b(g_Variables.m_WorldEffects.m_bEnemyBulletTracers))
        {
            TracerStartInfo& info = m_mapTracerStartCache[pController];

            if (currentTime - info.flTime > 0.1f)
            {
                info.vEyePos = pPawn->GetEyePosition();
                info.flTime = currentTime;
            }

            this->AddParticle2Point(
                X("particles/entity/spectator_utility_trail.vpcf"),
                info.vEyePos,
                vecImpactPosition,
                Config::c(g_Variables.m_WorldEffects.m_colEnemyBulletTracers),
                Config::i(g_Variables.m_Visuals.m_nHitEffectsDurration),
                false
            );
        }
    }
}

void CParticleMgr::AddParticlePoints(const char* szParticlePath, std::vector<Vector> vecPoints, Color colColor, float flTime, bool bCustom)
{
    CBeamInfo objParticleInfo = CBeamInfo();

    if (bCustom)
    {
        CBufferString objParticleName(szParticlePath, 'fcpv');
        Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&objParticleName, "");
    }

    Interfaces::m_pParticleManager->CreateParticleEffect(&objParticleInfo.m_nEffectIndex, szParticlePath);
    CParticleColor tColor = CParticleColor(static_cast<float>(colColor.Get<COLOR_R>()), static_cast<float>(colColor.Get<COLOR_G>()), static_cast<float>(colColor.Get<COLOR_B>()));
    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_COLOR, &tColor);

    for (int i = 0; i < vecPoints.size(); i++)
    {

        CParticleInformation particle_info{};
        particle_info.m_flTime = flTime;
        particle_info.m_flWidth = 0.5f;
        particle_info.m_flAlpha = 1.f;

        Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_INFO, &particle_info);

        objParticleInfo.m_vecPositions = new Vector[i + 1];
        objParticleInfo.m_flTimes = new float[i + 1];

        for (int j{}; j < i + 1; j++) {
            objParticleInfo.m_vecPositions[j] = vecPoints[j];
            objParticleInfo.m_flTimes[j] = INTERVAL_PER_TICK * float(j);
        }
        objParticleInfo.m_ParticleData.m_vecPosition = objParticleInfo.m_vecPositions;
        objParticleInfo.m_ParticleData.m_flTimes2 = objParticleInfo.m_flTimes;

        Interfaces::m_pParticleSystemMgr->CreateSnapshot(&objParticleInfo.m_hSnapsotParticle);

        Interfaces::m_pParticleManager->UnknownFunction(objParticleInfo.m_nEffectIndex, 0, &objParticleInfo.m_hSnapsotParticle);

        objParticleInfo.m_hSnapsotParticle->Draw(i + 1, &objParticleInfo.m_ParticleData);

        delete[] objParticleInfo.m_vecPositions;
        delete[] objParticleInfo.m_flTimes;
    }

    m_deqPointParticlesAdded.push_back({ objParticleInfo.m_nEffectIndex , Interfaces::m_pGlobalVariables->m_flCurrentTime, flTime });
}

void CParticleMgr::AddParticle2Point(const char* szParticlePath, Vector vStart, Vector vEnd, Color colColor, float flTime, bool bCustom)
{
    CBeamInfo objParticleInfo = CBeamInfo();

    if (bCustom)
    {
        CBufferString objParticleName(szParticlePath, 'fcpv');
        Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&objParticleName, "");
    }

    Interfaces::m_pParticleManager->CreateParticleEffect(&objParticleInfo.m_nEffectIndex, szParticlePath);

    CParticleColor tColor = CParticleColor(static_cast<float>(colColor.Get<COLOR_R>()), static_cast<float>(colColor.Get<COLOR_G>()), static_cast<float>(colColor.Get<COLOR_B>()));
    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_COLOR, &tColor);

    objParticleInfo.m_ParticleData = CParticleData();
    Vector vDirection = (vEnd - vStart);
    Vector vMiddle = vStart + (vDirection * 0.5f);

    CParticleInformation  particleInfo = CParticleInformation();
    particleInfo.m_flWidth = 0.5f;
    particleInfo.m_flTime = flTime;
    particleInfo.m_flAlpha = colColor.a() / 255.f;
    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_INFO, &particleInfo);

    const int totalPoints = 5;
    std::vector<Vector> vecPositions;
    vecPositions.reserve(totalPoints);

    vecPositions.push_back(vStart);
    vecPositions.push_back(vStart.Lerp(vMiddle, 0.05f));

    vecPositions.push_back(vMiddle);
    vecPositions.push_back(vMiddle.Lerp(vEnd, 0.95f));
    vecPositions.push_back(vEnd);

    objParticleInfo.m_ParticleData.m_vecPosition = vecPositions.data();

    Interfaces::m_pParticleSystemMgr->CreateSnapshot(&objParticleInfo.m_hSnapsotParticle);

    Interfaces::m_pParticleManager->UnknownFunction(objParticleInfo.m_nEffectIndex, 0, &objParticleInfo.m_hSnapsotParticle);

    objParticleInfo.m_hSnapsotParticle->Draw(vecPositions.size(), &objParticleInfo.m_ParticleData);

    m_deqPointParticlesAdded.push_back({ objParticleInfo.m_nEffectIndex , Interfaces::m_pGlobalVariables->m_flCurrentTime, flTime });
}

void CParticleMgr::AddParticle2PointGradient(const char* szParticlePath, Vector vStart, Vector vEnd, Color colStart, Color colEnd, float flTime, bool bCustom)
{
    CBeamInfo objParticleInfo = CBeamInfo();

    if (bCustom)
    {
        CBufferString objParticleName(szParticlePath, 'fcpv');
        Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&objParticleName, "");
    }

    Interfaces::m_pParticleManager->CreateParticleEffect(&objParticleInfo.m_nEffectIndex, szParticlePath);

    objParticleInfo.m_ParticleData = CParticleData();
    Vector vDirection = (vEnd - vStart);
    Vector vMiddle = vStart + (vDirection * 0.5f);

    const int totalPoints = 5;
    std::vector<Vector> vecPositions;
    vecPositions.reserve(totalPoints);

    vecPositions.push_back(vStart);
    vecPositions.push_back(vStart.Lerp(vMiddle, 0.05f));
    vecPositions.push_back(vMiddle);
    vecPositions.push_back(vMiddle.Lerp(vEnd, 0.95f));
    vecPositions.push_back(vEnd);

    for (int i = 0; i < totalPoints - 1; i++)
    {
        float t = static_cast<float>(i) / static_cast<float>(totalPoints - 1);
        float tNext = static_cast<float>(i + 1) / static_cast<float>(totalPoints - 1);
        
        Color segColor(
            static_cast<int>(colStart.r() + (colEnd.r() - colStart.r()) * t),
            static_cast<int>(colStart.g() + (colEnd.g() - colStart.g()) * t),
            static_cast<int>(colStart.b() + (colEnd.b() - colStart.b()) * t),
            static_cast<int>(colStart.a() + (colEnd.a() - colStart.a()) * t)
        );

        CParticleColor tColor = CParticleColor(static_cast<float>(segColor.Get<COLOR_R>()), static_cast<float>(segColor.Get<COLOR_G>()), static_cast<float>(segColor.Get<COLOR_B>()));
        Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_COLOR, &tColor);

        CParticleInformation particleInfo = CParticleInformation();
        particleInfo.m_flWidth = 0.5f;
        particleInfo.m_flTime = flTime;
        particleInfo.m_flAlpha = segColor.a() / 255.f;
        Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_INFO, &particleInfo);

        Vector segPositions[2] = { vecPositions[i], vecPositions[i + 1] };
        objParticleInfo.m_ParticleData.m_vecPosition = segPositions;

        Interfaces::m_pParticleSystemMgr->CreateSnapshot(&objParticleInfo.m_hSnapsotParticle);
        Interfaces::m_pParticleManager->UnknownFunction(objParticleInfo.m_nEffectIndex, 0, &objParticleInfo.m_hSnapsotParticle);
        objParticleInfo.m_hSnapsotParticle->Draw(2, &objParticleInfo.m_ParticleData);
    }

    m_deqPointParticlesAdded.push_back({ objParticleInfo.m_nEffectIndex , Interfaces::m_pGlobalVariables->m_flCurrentTime, flTime });
}

void CParticleMgr::AddParticle1Point(const char* szParticlePath, Vector vPosition, Color colColor, float flTime, bool bCustom)
{
    CBeamInfo objParticleInfo = CBeamInfo();

    if (bCustom)
    {
        CBufferString objParticleName(szParticlePath, 'fcpv');
        Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&objParticleName, "");
    }

    Interfaces::m_pParticleManager->CreateParticleEffect(&objParticleInfo.m_nEffectIndex, szParticlePath);

    CParticleColor tColor = CParticleColor(static_cast<float>(colColor.Get<COLOR_R>()), static_cast<float>(colColor.Get<COLOR_G>()), static_cast<float>(colColor.Get<COLOR_B>()));
    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_COLOR, &tColor);

    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_POSITION, &vPosition);

    m_deqPointParticlesAdded.push_back({ objParticleInfo.m_nEffectIndex, Interfaces::m_pGlobalVariables->m_flCurrentTime, flTime });
}

void CParticleMgr::CreateParticle(unsigned int& nEffectIndex, const char* szParticlePath)
{
    if (!szParticlePath || !Interfaces::m_pResourceSystem || !Interfaces::m_pParticleManager)
        return;

    CBufferString emberName(szParticlePath, 'fcpv');
    Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&emberName, "");

    unsigned int uEffectIndex = 0;
    Interfaces::m_pParticleManager->CreateParticleEffect(&uEffectIndex, szParticlePath);

    if (uEffectIndex != 0)
    {
        m_vecEffectIndexes.push_back(uEffectIndex);
        nEffectIndex = uEffectIndex;
    }
}

void CParticleMgr::ReleaseParticles()
{
    if (!Interfaces::m_pParticleManager)
        return;

    for (unsigned int& uEffectIndex : m_vecEffectIndexes)
    {
        if (uEffectIndex != 0)
        {
            Interfaces::m_pParticleManager->DestroyParticle(uEffectIndex, true, true);
            Interfaces::m_pParticleManager->ReleaseParticleIndex(uEffectIndex);
        }
    }

    if (!m_vecEffectIndexes.empty())
        m_vecEffectIndexes.clear();
}

void CParticleMgr::UpdateParticles()
{
    if (!Globals::m_pLocalPlayerPawn || !Interfaces::m_pGameRules || !Interfaces::m_pParticleManager)
        return;

    if (!m_deqPointParticlesAdded.empty())
    {
        float flCurrentTime = Interfaces::m_pGlobalVariables->m_flCurrentTime;
        
        for (std::deque<PointParticle_t>::iterator it = m_deqPointParticlesAdded.begin(); it != m_deqPointParticlesAdded.end(); )
        {

            if (it == m_deqPointParticlesAdded.end())
                break;
                
            if (it->m_flParticleTimeBeforeDelete + it->m_flCurrentTimeGlobal < flCurrentTime)
            {
                if (it->m_uiEffectIndex != 0)
            {
                Interfaces::m_pParticleManager->DestroyParticle(it->m_uiEffectIndex, 1, 1);
                Interfaces::m_pParticleManager->ReleaseParticleIndex(it->m_uiEffectIndex);
                }
                it = m_deqPointParticlesAdded.erase(it);
            }
            else
            {
                ++it;
            }
        }
    }


    int iSelectedEffect = Config::i(g_Variables.m_WorldEffects.m_iSelectedCustomWorldParticles);

    if (iSelectedEffect == WORLD_PARTICLES_NONE)
    {
        this->ReleaseParticles();
        return;
    }

    float flCurrentRoundStartTime = Interfaces::m_pGameRules->m_fRoundStartTime();

    if (iSelectedEffect != m_iLastEffectCached || flCurrentRoundStartTime != m_flLastReloadTime)
    {
        this->ReleaseParticles();

        m_iLastEffectCached = iSelectedEffect;
        m_flLastReloadTime = flCurrentRoundStartTime;

        unsigned int uEffectIndex1 = 0;
        unsigned int uEffectIndex2 = 0;
        switch (iSelectedEffect) {
        case ECustomWorldParticles::WORLD_PARTICLES_ASHES:
            this->CreateParticle(uEffectIndex1, EMBER_EFFECT_PATH);
            this->CreateParticle(uEffectIndex2, EMBER_EFFECT2_PATH);
            break;
        case ECustomWorldParticles::WORLD_PARTICLES_SNOW:
            this->CreateParticle(uEffectIndex1, SNOW_EFFECT_PATH);
            break;
        case ECustomWorldParticles::WORLD_PARTICLES_STARS:
            this->CreateParticle(uEffectIndex1, STARS_EFFECT_PATH);
            break;
        case ECustomWorldParticles::WORLD_PARTICLES_RAIN:
            this->CreateParticle(uEffectIndex1, RAIN_EFFECT_PATH);
            break;
        }
    }

    Vector vDensity(Config::i(g_Variables.m_WorldEffects.m_iSelectedCustomWorldParticleDensity), 0, 0);
    for (const unsigned int& uEffectIndex : m_vecEffectIndexes)
    {
        if (uEffectIndex != 0)
        {
            Interfaces::m_pParticleManager->SetParticleSetting(
                uEffectIndex,
                EParticleSetting::PARTICLE_SETTING_POSITION,
                &Globals::m_pLocalPlayerPawn->m_pGameSceneNode()->m_vecAbsOrigin()
            );

            Interfaces::m_pParticleManager->SetParticleSetting(
                uEffectIndex,
                EParticleSetting::PARTICLE_SETTING_DENSITY,
                &vDensity
            );
        }
    }
}


ParticleManager.h:
Expand Collapse Copy
#pragma once

enum EParticleSetting : unsigned int
{
    PARTICLE_SETTING_POSITION = 0,
    PARTICLE_SETTING_DENSITY = 2,
    PARTICLE_SETTING_INFO = 3,
    PARTICLE_SETTING_COLOR = 16
};

class CParticleMgr
{
private:
    struct PointParticle_t
    {
        unsigned int m_uiEffectIndex;
        float m_flCurrentTimeGlobal;
        float m_flParticleTimeBeforeDelete;
    };
private:
    std::vector<unsigned int> m_vecEffectIndexes;
    int8_t m_iLastEffectCached;
    float m_flLastReloadTime;
    std::deque<PointParticle_t> m_deqPointParticlesAdded;
public:
    void OnEvent(CGameEvent* pEvent);
    void AddParticlePoints(const char* szParticlePath, std::vector<Vector> vecPoints, Color colColor, float flTime, bool bCustom = false);
    void AddParticle2Point(const char* szParticlePath, Vector vStart, Vector vEnd, Color colColor, float flTime, bool bCustom = false);
    void AddParticle2PointGradient(const char* szParticlePath, Vector vStart, Vector vEnd, Color colStart, Color colEnd, float flTime, bool bCustom = false);
    void AddParticle1Point(const char* szParticlePath, Vector vPosition, Color colColor, float flTime, bool bCustom = false);

    void CreateParticle(unsigned int& nEffectIndex, const char* szParticlePath);
    void ReleaseParticles();
    void UpdateParticles();
};
inline auto g_ParticleMgr = std::make_unique<CParticleMgr>();
 

Вложения

вот кому надо вот вам Particle Manager
1 трейсера
2 map Particle

сами эффекты, Ashes, Snow, Stars

кидать эфекты сюда Counter-Strike Global Offensive\game\csgo\bin

Посмотреть вложение 321927

ParticleManager.cpp:
Expand Collapse Copy
constexpr const char* EMBER_EFFECT_PATH = "bin/falling_ember1.vpcf";
constexpr const char* EMBER_EFFECT2_PATH = "bin/falling_ember2.vpcf";
constexpr const char* SNOW_EFFECT_PATH = "bin/falling_snow1.vpcf";
constexpr const char* STARS_EFFECT_PATH = "bin/nomove_stars.vpcf";
constexpr const char* RAIN_EFFECT_PATH = "bin/rain.vpcf";


struct TracerStartInfo
{
    Vector vEyePos;
    float flTime;
};
std::unordered_map<CCSPlayerController*, TracerStartInfo> m_mapTracerStartCache;


void CParticleMgr::OnEvent(CGameEvent* pEvent)
{
    CCSPlayerController* pController = reinterpret_cast<CCSPlayerController*>(pEvent->GetPlayerController(X("userid")));
    C_CSPlayerPawn* pPawn = reinterpret_cast<C_CSPlayerPawn*>(pEvent->GetPlayerPawn(X("userid")));
    if (!pController || !pPawn)
        return;

    Vector vecImpactPosition = Vector(pEvent->GetFloat(X("x")), pEvent->GetFloat(X("y")), pEvent->GetFloat(X("z")));
    if (vecImpactPosition.IsZero())
        return;

    float currentTime = Interfaces::m_pGlobalVariables->m_flCurrentTime;

    if (pController->m_bIsLocalPlayerController())
    {
        if (Config::b(g_Variables.m_WorldEffects.m_bDrawImpacts))
        {
            Interfaces::m_pClient->GetDebugOverlay()->RenderWithoutDots(true);
            Interfaces::m_pClient->GetDebugOverlay()->AddBoxOverlay(
                vecImpactPosition,
                Vector(-1.f, -1.f, -1.f),
                Vector(1.f, 1.f, 1.f),
                QAngle(0.0f, 0.0f, 0.0f),
                Config::c(g_Variables.m_WorldEffects.m_colDrawImpactsColor),
                Config::i(g_Variables.m_Visuals.m_nHitEffectsDurration)
            );
        }

        if (Config::b(g_Variables.m_WorldEffects.m_bLocalBulletTracers))
        {
            TracerStartInfo& info = m_mapTracerStartCache[pController];

           
            info.vEyePos = Globals::m_pLocalPlayerPawn->GetEyePosition(true);
            info.flTime = currentTime;

            if (Config::b(g_Variables.m_WorldEffects.m_bLocalBulletTracersGradient))
            {
                this->AddParticle2PointGradient(
                    X("particles/entity/spectator_utility_trail.vpcf"),
                    info.vEyePos,
                    vecImpactPosition,
                    Config::c(g_Variables.m_WorldEffects.m_colLocalBulletTracers),
                    Config::c(g_Variables.m_WorldEffects.m_colLocalBulletTracersGradient),
                    Config::i(g_Variables.m_Visuals.m_nHitEffectsDurration),
                    false
                );
            }
            else
            {
                this->AddParticle2Point(
                    X("particles/entity/spectator_utility_trail.vpcf"),
                    info.vEyePos,
                    vecImpactPosition,
                    Config::c(g_Variables.m_WorldEffects.m_colLocalBulletTracers),
                    Config::i(g_Variables.m_Visuals.m_nHitEffectsDurration),
                    false
                );
            }
        }
    }

    else if (pPawn->IsEnemy(Globals::m_pLocalPlayerPawn))
    {
        if (Config::b(g_Variables.m_WorldEffects.m_bEnemyBulletTracers))
        {
            TracerStartInfo& info = m_mapTracerStartCache[pController];

            if (currentTime - info.flTime > 0.1f)
            {
                info.vEyePos = pPawn->GetEyePosition();
                info.flTime = currentTime;
            }

            this->AddParticle2Point(
                X("particles/entity/spectator_utility_trail.vpcf"),
                info.vEyePos,
                vecImpactPosition,
                Config::c(g_Variables.m_WorldEffects.m_colEnemyBulletTracers),
                Config::i(g_Variables.m_Visuals.m_nHitEffectsDurration),
                false
            );
        }
    }
}

void CParticleMgr::AddParticlePoints(const char* szParticlePath, std::vector<Vector> vecPoints, Color colColor, float flTime, bool bCustom)
{
    CBeamInfo objParticleInfo = CBeamInfo();

    if (bCustom)
    {
        CBufferString objParticleName(szParticlePath, 'fcpv');
        Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&objParticleName, "");
    }

    Interfaces::m_pParticleManager->CreateParticleEffect(&objParticleInfo.m_nEffectIndex, szParticlePath);
    CParticleColor tColor = CParticleColor(static_cast<float>(colColor.Get<COLOR_R>()), static_cast<float>(colColor.Get<COLOR_G>()), static_cast<float>(colColor.Get<COLOR_B>()));
    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_COLOR, &tColor);

    for (int i = 0; i < vecPoints.size(); i++)
    {

        CParticleInformation particle_info{};
        particle_info.m_flTime = flTime;
        particle_info.m_flWidth = 0.5f;
        particle_info.m_flAlpha = 1.f;

        Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_INFO, &particle_info);

        objParticleInfo.m_vecPositions = new Vector[i + 1];
        objParticleInfo.m_flTimes = new float[i + 1];

        for (int j{}; j < i + 1; j++) {
            objParticleInfo.m_vecPositions[j] = vecPoints[j];
            objParticleInfo.m_flTimes[j] = INTERVAL_PER_TICK * float(j);
        }
        objParticleInfo.m_ParticleData.m_vecPosition = objParticleInfo.m_vecPositions;
        objParticleInfo.m_ParticleData.m_flTimes2 = objParticleInfo.m_flTimes;

        Interfaces::m_pParticleSystemMgr->CreateSnapshot(&objParticleInfo.m_hSnapsotParticle);

        Interfaces::m_pParticleManager->UnknownFunction(objParticleInfo.m_nEffectIndex, 0, &objParticleInfo.m_hSnapsotParticle);

        objParticleInfo.m_hSnapsotParticle->Draw(i + 1, &objParticleInfo.m_ParticleData);

        delete[] objParticleInfo.m_vecPositions;
        delete[] objParticleInfo.m_flTimes;
    }

    m_deqPointParticlesAdded.push_back({ objParticleInfo.m_nEffectIndex , Interfaces::m_pGlobalVariables->m_flCurrentTime, flTime });
}

void CParticleMgr::AddParticle2Point(const char* szParticlePath, Vector vStart, Vector vEnd, Color colColor, float flTime, bool bCustom)
{
    CBeamInfo objParticleInfo = CBeamInfo();

    if (bCustom)
    {
        CBufferString objParticleName(szParticlePath, 'fcpv');
        Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&objParticleName, "");
    }

    Interfaces::m_pParticleManager->CreateParticleEffect(&objParticleInfo.m_nEffectIndex, szParticlePath);

    CParticleColor tColor = CParticleColor(static_cast<float>(colColor.Get<COLOR_R>()), static_cast<float>(colColor.Get<COLOR_G>()), static_cast<float>(colColor.Get<COLOR_B>()));
    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_COLOR, &tColor);

    objParticleInfo.m_ParticleData = CParticleData();
    Vector vDirection = (vEnd - vStart);
    Vector vMiddle = vStart + (vDirection * 0.5f);

    CParticleInformation  particleInfo = CParticleInformation();
    particleInfo.m_flWidth = 0.5f;
    particleInfo.m_flTime = flTime;
    particleInfo.m_flAlpha = colColor.a() / 255.f;
    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_INFO, &particleInfo);

    const int totalPoints = 5;
    std::vector<Vector> vecPositions;
    vecPositions.reserve(totalPoints);

    vecPositions.push_back(vStart);
    vecPositions.push_back(vStart.Lerp(vMiddle, 0.05f));

    vecPositions.push_back(vMiddle);
    vecPositions.push_back(vMiddle.Lerp(vEnd, 0.95f));
    vecPositions.push_back(vEnd);

    objParticleInfo.m_ParticleData.m_vecPosition = vecPositions.data();

    Interfaces::m_pParticleSystemMgr->CreateSnapshot(&objParticleInfo.m_hSnapsotParticle);

    Interfaces::m_pParticleManager->UnknownFunction(objParticleInfo.m_nEffectIndex, 0, &objParticleInfo.m_hSnapsotParticle);

    objParticleInfo.m_hSnapsotParticle->Draw(vecPositions.size(), &objParticleInfo.m_ParticleData);

    m_deqPointParticlesAdded.push_back({ objParticleInfo.m_nEffectIndex , Interfaces::m_pGlobalVariables->m_flCurrentTime, flTime });
}

void CParticleMgr::AddParticle2PointGradient(const char* szParticlePath, Vector vStart, Vector vEnd, Color colStart, Color colEnd, float flTime, bool bCustom)
{
    CBeamInfo objParticleInfo = CBeamInfo();

    if (bCustom)
    {
        CBufferString objParticleName(szParticlePath, 'fcpv');
        Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&objParticleName, "");
    }

    Interfaces::m_pParticleManager->CreateParticleEffect(&objParticleInfo.m_nEffectIndex, szParticlePath);

    objParticleInfo.m_ParticleData = CParticleData();
    Vector vDirection = (vEnd - vStart);
    Vector vMiddle = vStart + (vDirection * 0.5f);

    const int totalPoints = 5;
    std::vector<Vector> vecPositions;
    vecPositions.reserve(totalPoints);

    vecPositions.push_back(vStart);
    vecPositions.push_back(vStart.Lerp(vMiddle, 0.05f));
    vecPositions.push_back(vMiddle);
    vecPositions.push_back(vMiddle.Lerp(vEnd, 0.95f));
    vecPositions.push_back(vEnd);

    for (int i = 0; i < totalPoints - 1; i++)
    {
        float t = static_cast<float>(i) / static_cast<float>(totalPoints - 1);
        float tNext = static_cast<float>(i + 1) / static_cast<float>(totalPoints - 1);
       
        Color segColor(
            static_cast<int>(colStart.r() + (colEnd.r() - colStart.r()) * t),
            static_cast<int>(colStart.g() + (colEnd.g() - colStart.g()) * t),
            static_cast<int>(colStart.b() + (colEnd.b() - colStart.b()) * t),
            static_cast<int>(colStart.a() + (colEnd.a() - colStart.a()) * t)
        );

        CParticleColor tColor = CParticleColor(static_cast<float>(segColor.Get<COLOR_R>()), static_cast<float>(segColor.Get<COLOR_G>()), static_cast<float>(segColor.Get<COLOR_B>()));
        Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_COLOR, &tColor);

        CParticleInformation particleInfo = CParticleInformation();
        particleInfo.m_flWidth = 0.5f;
        particleInfo.m_flTime = flTime;
        particleInfo.m_flAlpha = segColor.a() / 255.f;
        Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_INFO, &particleInfo);

        Vector segPositions[2] = { vecPositions[i], vecPositions[i + 1] };
        objParticleInfo.m_ParticleData.m_vecPosition = segPositions;

        Interfaces::m_pParticleSystemMgr->CreateSnapshot(&objParticleInfo.m_hSnapsotParticle);
        Interfaces::m_pParticleManager->UnknownFunction(objParticleInfo.m_nEffectIndex, 0, &objParticleInfo.m_hSnapsotParticle);
        objParticleInfo.m_hSnapsotParticle->Draw(2, &objParticleInfo.m_ParticleData);
    }

    m_deqPointParticlesAdded.push_back({ objParticleInfo.m_nEffectIndex , Interfaces::m_pGlobalVariables->m_flCurrentTime, flTime });
}

void CParticleMgr::AddParticle1Point(const char* szParticlePath, Vector vPosition, Color colColor, float flTime, bool bCustom)
{
    CBeamInfo objParticleInfo = CBeamInfo();

    if (bCustom)
    {
        CBufferString objParticleName(szParticlePath, 'fcpv');
        Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&objParticleName, "");
    }

    Interfaces::m_pParticleManager->CreateParticleEffect(&objParticleInfo.m_nEffectIndex, szParticlePath);

    CParticleColor tColor = CParticleColor(static_cast<float>(colColor.Get<COLOR_R>()), static_cast<float>(colColor.Get<COLOR_G>()), static_cast<float>(colColor.Get<COLOR_B>()));
    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_COLOR, &tColor);

    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_POSITION, &vPosition);

    m_deqPointParticlesAdded.push_back({ objParticleInfo.m_nEffectIndex, Interfaces::m_pGlobalVariables->m_flCurrentTime, flTime });
}

void CParticleMgr::CreateParticle(unsigned int& nEffectIndex, const char* szParticlePath)
{
    if (!szParticlePath || !Interfaces::m_pResourceSystem || !Interfaces::m_pParticleManager)
        return;

    CBufferString emberName(szParticlePath, 'fcpv');
    Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&emberName, "");

    unsigned int uEffectIndex = 0;
    Interfaces::m_pParticleManager->CreateParticleEffect(&uEffectIndex, szParticlePath);

    if (uEffectIndex != 0)
    {
        m_vecEffectIndexes.push_back(uEffectIndex);
        nEffectIndex = uEffectIndex;
    }
}

void CParticleMgr::ReleaseParticles()
{
    if (!Interfaces::m_pParticleManager)
        return;

    for (unsigned int& uEffectIndex : m_vecEffectIndexes)
    {
        if (uEffectIndex != 0)
        {
            Interfaces::m_pParticleManager->DestroyParticle(uEffectIndex, true, true);
            Interfaces::m_pParticleManager->ReleaseParticleIndex(uEffectIndex);
        }
    }

    if (!m_vecEffectIndexes.empty())
        m_vecEffectIndexes.clear();
}

void CParticleMgr::UpdateParticles()
{
    if (!Globals::m_pLocalPlayerPawn || !Interfaces::m_pGameRules || !Interfaces::m_pParticleManager)
        return;

    if (!m_deqPointParticlesAdded.empty())
    {
        float flCurrentTime = Interfaces::m_pGlobalVariables->m_flCurrentTime;
       
        for (std::deque<PointParticle_t>::iterator it = m_deqPointParticlesAdded.begin(); it != m_deqPointParticlesAdded.end(); )
        {

            if (it == m_deqPointParticlesAdded.end())
                break;
               
            if (it->m_flParticleTimeBeforeDelete + it->m_flCurrentTimeGlobal < flCurrentTime)
            {
                if (it->m_uiEffectIndex != 0)
            {
                Interfaces::m_pParticleManager->DestroyParticle(it->m_uiEffectIndex, 1, 1);
                Interfaces::m_pParticleManager->ReleaseParticleIndex(it->m_uiEffectIndex);
                }
                it = m_deqPointParticlesAdded.erase(it);
            }
            else
            {
                ++it;
            }
        }
    }


    int iSelectedEffect = Config::i(g_Variables.m_WorldEffects.m_iSelectedCustomWorldParticles);

    if (iSelectedEffect == WORLD_PARTICLES_NONE)
    {
        this->ReleaseParticles();
        return;
    }

    float flCurrentRoundStartTime = Interfaces::m_pGameRules->m_fRoundStartTime();

    if (iSelectedEffect != m_iLastEffectCached || flCurrentRoundStartTime != m_flLastReloadTime)
    {
        this->ReleaseParticles();

        m_iLastEffectCached = iSelectedEffect;
        m_flLastReloadTime = flCurrentRoundStartTime;

        unsigned int uEffectIndex1 = 0;
        unsigned int uEffectIndex2 = 0;
        switch (iSelectedEffect) {
        case ECustomWorldParticles::WORLD_PARTICLES_ASHES:
            this->CreateParticle(uEffectIndex1, EMBER_EFFECT_PATH);
            this->CreateParticle(uEffectIndex2, EMBER_EFFECT2_PATH);
            break;
        case ECustomWorldParticles::WORLD_PARTICLES_SNOW:
            this->CreateParticle(uEffectIndex1, SNOW_EFFECT_PATH);
            break;
        case ECustomWorldParticles::WORLD_PARTICLES_STARS:
            this->CreateParticle(uEffectIndex1, STARS_EFFECT_PATH);
            break;
        case ECustomWorldParticles::WORLD_PARTICLES_RAIN:
            this->CreateParticle(uEffectIndex1, RAIN_EFFECT_PATH);
            break;
        }
    }

    Vector vDensity(Config::i(g_Variables.m_WorldEffects.m_iSelectedCustomWorldParticleDensity), 0, 0);
    for (const unsigned int& uEffectIndex : m_vecEffectIndexes)
    {
        if (uEffectIndex != 0)
        {
            Interfaces::m_pParticleManager->SetParticleSetting(
                uEffectIndex,
                EParticleSetting::PARTICLE_SETTING_POSITION,
                &Globals::m_pLocalPlayerPawn->m_pGameSceneNode()->m_vecAbsOrigin()
            );

            Interfaces::m_pParticleManager->SetParticleSetting(
                uEffectIndex,
                EParticleSetting::PARTICLE_SETTING_DENSITY,
                &vDensity
            );
        }
    }
}


ParticleManager.h:
Expand Collapse Copy
#pragma once

enum EParticleSetting : unsigned int
{
    PARTICLE_SETTING_POSITION = 0,
    PARTICLE_SETTING_DENSITY = 2,
    PARTICLE_SETTING_INFO = 3,
    PARTICLE_SETTING_COLOR = 16
};

class CParticleMgr
{
private:
    struct PointParticle_t
    {
        unsigned int m_uiEffectIndex;
        float m_flCurrentTimeGlobal;
        float m_flParticleTimeBeforeDelete;
    };
private:
    std::vector<unsigned int> m_vecEffectIndexes;
    int8_t m_iLastEffectCached;
    float m_flLastReloadTime;
    std::deque<PointParticle_t> m_deqPointParticlesAdded;
public:
    void OnEvent(CGameEvent* pEvent);
    void AddParticlePoints(const char* szParticlePath, std::vector<Vector> vecPoints, Color colColor, float flTime, bool bCustom = false);
    void AddParticle2Point(const char* szParticlePath, Vector vStart, Vector vEnd, Color colColor, float flTime, bool bCustom = false);
    void AddParticle2PointGradient(const char* szParticlePath, Vector vStart, Vector vEnd, Color colStart, Color colEnd, float flTime, bool bCustom = false);
    void AddParticle1Point(const char* szParticlePath, Vector vPosition, Color colColor, float flTime, bool bCustom = false);

    void CreateParticle(unsigned int& nEffectIndex, const char* szParticlePath);
    void ReleaseParticles();
    void UpdateParticles();
};
inline auto g_ParticleMgr = std::make_unique<CParticleMgr>();
прикольно, спасибо
 
вот кому надо вот вам Particle Manager
1 трейсера
2 map Particle

сами эффекты, Ashes, Snow, Stars

кидать эфекты сюда Counter-Strike Global Offensive\game\csgo\bin

Посмотреть вложение 321927

ParticleManager.cpp:
Expand Collapse Copy
constexpr const char* EMBER_EFFECT_PATH = "bin/falling_ember1.vpcf";
constexpr const char* EMBER_EFFECT2_PATH = "bin/falling_ember2.vpcf";
constexpr const char* SNOW_EFFECT_PATH = "bin/falling_snow1.vpcf";
constexpr const char* STARS_EFFECT_PATH = "bin/nomove_stars.vpcf";
constexpr const char* RAIN_EFFECT_PATH = "bin/rain.vpcf";


struct TracerStartInfo
{
    Vector vEyePos;
    float flTime;
};
std::unordered_map<CCSPlayerController*, TracerStartInfo> m_mapTracerStartCache;


void CParticleMgr::OnEvent(CGameEvent* pEvent)
{
    CCSPlayerController* pController = reinterpret_cast<CCSPlayerController*>(pEvent->GetPlayerController(X("userid")));
    C_CSPlayerPawn* pPawn = reinterpret_cast<C_CSPlayerPawn*>(pEvent->GetPlayerPawn(X("userid")));
    if (!pController || !pPawn)
        return;

    Vector vecImpactPosition = Vector(pEvent->GetFloat(X("x")), pEvent->GetFloat(X("y")), pEvent->GetFloat(X("z")));
    if (vecImpactPosition.IsZero())
        return;

    float currentTime = Interfaces::m_pGlobalVariables->m_flCurrentTime;

    if (pController->m_bIsLocalPlayerController())
    {
        if (Config::b(g_Variables.m_WorldEffects.m_bDrawImpacts))
        {
            Interfaces::m_pClient->GetDebugOverlay()->RenderWithoutDots(true);
            Interfaces::m_pClient->GetDebugOverlay()->AddBoxOverlay(
                vecImpactPosition,
                Vector(-1.f, -1.f, -1.f),
                Vector(1.f, 1.f, 1.f),
                QAngle(0.0f, 0.0f, 0.0f),
                Config::c(g_Variables.m_WorldEffects.m_colDrawImpactsColor),
                Config::i(g_Variables.m_Visuals.m_nHitEffectsDurration)
            );
        }

        if (Config::b(g_Variables.m_WorldEffects.m_bLocalBulletTracers))
        {
            TracerStartInfo& info = m_mapTracerStartCache[pController];

           
            info.vEyePos = Globals::m_pLocalPlayerPawn->GetEyePosition(true);
            info.flTime = currentTime;

            if (Config::b(g_Variables.m_WorldEffects.m_bLocalBulletTracersGradient))
            {
                this->AddParticle2PointGradient(
                    X("particles/entity/spectator_utility_trail.vpcf"),
                    info.vEyePos,
                    vecImpactPosition,
                    Config::c(g_Variables.m_WorldEffects.m_colLocalBulletTracers),
                    Config::c(g_Variables.m_WorldEffects.m_colLocalBulletTracersGradient),
                    Config::i(g_Variables.m_Visuals.m_nHitEffectsDurration),
                    false
                );
            }
            else
            {
                this->AddParticle2Point(
                    X("particles/entity/spectator_utility_trail.vpcf"),
                    info.vEyePos,
                    vecImpactPosition,
                    Config::c(g_Variables.m_WorldEffects.m_colLocalBulletTracers),
                    Config::i(g_Variables.m_Visuals.m_nHitEffectsDurration),
                    false
                );
            }
        }
    }

    else if (pPawn->IsEnemy(Globals::m_pLocalPlayerPawn))
    {
        if (Config::b(g_Variables.m_WorldEffects.m_bEnemyBulletTracers))
        {
            TracerStartInfo& info = m_mapTracerStartCache[pController];

            if (currentTime - info.flTime > 0.1f)
            {
                info.vEyePos = pPawn->GetEyePosition();
                info.flTime = currentTime;
            }

            this->AddParticle2Point(
                X("particles/entity/spectator_utility_trail.vpcf"),
                info.vEyePos,
                vecImpactPosition,
                Config::c(g_Variables.m_WorldEffects.m_colEnemyBulletTracers),
                Config::i(g_Variables.m_Visuals.m_nHitEffectsDurration),
                false
            );
        }
    }
}

void CParticleMgr::AddParticlePoints(const char* szParticlePath, std::vector<Vector> vecPoints, Color colColor, float flTime, bool bCustom)
{
    CBeamInfo objParticleInfo = CBeamInfo();

    if (bCustom)
    {
        CBufferString objParticleName(szParticlePath, 'fcpv');
        Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&objParticleName, "");
    }

    Interfaces::m_pParticleManager->CreateParticleEffect(&objParticleInfo.m_nEffectIndex, szParticlePath);
    CParticleColor tColor = CParticleColor(static_cast<float>(colColor.Get<COLOR_R>()), static_cast<float>(colColor.Get<COLOR_G>()), static_cast<float>(colColor.Get<COLOR_B>()));
    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_COLOR, &tColor);

    for (int i = 0; i < vecPoints.size(); i++)
    {

        CParticleInformation particle_info{};
        particle_info.m_flTime = flTime;
        particle_info.m_flWidth = 0.5f;
        particle_info.m_flAlpha = 1.f;

        Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_INFO, &particle_info);

        objParticleInfo.m_vecPositions = new Vector[i + 1];
        objParticleInfo.m_flTimes = new float[i + 1];

        for (int j{}; j < i + 1; j++) {
            objParticleInfo.m_vecPositions[j] = vecPoints[j];
            objParticleInfo.m_flTimes[j] = INTERVAL_PER_TICK * float(j);
        }
        objParticleInfo.m_ParticleData.m_vecPosition = objParticleInfo.m_vecPositions;
        objParticleInfo.m_ParticleData.m_flTimes2 = objParticleInfo.m_flTimes;

        Interfaces::m_pParticleSystemMgr->CreateSnapshot(&objParticleInfo.m_hSnapsotParticle);

        Interfaces::m_pParticleManager->UnknownFunction(objParticleInfo.m_nEffectIndex, 0, &objParticleInfo.m_hSnapsotParticle);

        objParticleInfo.m_hSnapsotParticle->Draw(i + 1, &objParticleInfo.m_ParticleData);

        delete[] objParticleInfo.m_vecPositions;
        delete[] objParticleInfo.m_flTimes;
    }

    m_deqPointParticlesAdded.push_back({ objParticleInfo.m_nEffectIndex , Interfaces::m_pGlobalVariables->m_flCurrentTime, flTime });
}

void CParticleMgr::AddParticle2Point(const char* szParticlePath, Vector vStart, Vector vEnd, Color colColor, float flTime, bool bCustom)
{
    CBeamInfo objParticleInfo = CBeamInfo();

    if (bCustom)
    {
        CBufferString objParticleName(szParticlePath, 'fcpv');
        Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&objParticleName, "");
    }

    Interfaces::m_pParticleManager->CreateParticleEffect(&objParticleInfo.m_nEffectIndex, szParticlePath);

    CParticleColor tColor = CParticleColor(static_cast<float>(colColor.Get<COLOR_R>()), static_cast<float>(colColor.Get<COLOR_G>()), static_cast<float>(colColor.Get<COLOR_B>()));
    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_COLOR, &tColor);

    objParticleInfo.m_ParticleData = CParticleData();
    Vector vDirection = (vEnd - vStart);
    Vector vMiddle = vStart + (vDirection * 0.5f);

    CParticleInformation  particleInfo = CParticleInformation();
    particleInfo.m_flWidth = 0.5f;
    particleInfo.m_flTime = flTime;
    particleInfo.m_flAlpha = colColor.a() / 255.f;
    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_INFO, &particleInfo);

    const int totalPoints = 5;
    std::vector<Vector> vecPositions;
    vecPositions.reserve(totalPoints);

    vecPositions.push_back(vStart);
    vecPositions.push_back(vStart.Lerp(vMiddle, 0.05f));

    vecPositions.push_back(vMiddle);
    vecPositions.push_back(vMiddle.Lerp(vEnd, 0.95f));
    vecPositions.push_back(vEnd);

    objParticleInfo.m_ParticleData.m_vecPosition = vecPositions.data();

    Interfaces::m_pParticleSystemMgr->CreateSnapshot(&objParticleInfo.m_hSnapsotParticle);

    Interfaces::m_pParticleManager->UnknownFunction(objParticleInfo.m_nEffectIndex, 0, &objParticleInfo.m_hSnapsotParticle);

    objParticleInfo.m_hSnapsotParticle->Draw(vecPositions.size(), &objParticleInfo.m_ParticleData);

    m_deqPointParticlesAdded.push_back({ objParticleInfo.m_nEffectIndex , Interfaces::m_pGlobalVariables->m_flCurrentTime, flTime });
}

void CParticleMgr::AddParticle2PointGradient(const char* szParticlePath, Vector vStart, Vector vEnd, Color colStart, Color colEnd, float flTime, bool bCustom)
{
    CBeamInfo objParticleInfo = CBeamInfo();

    if (bCustom)
    {
        CBufferString objParticleName(szParticlePath, 'fcpv');
        Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&objParticleName, "");
    }

    Interfaces::m_pParticleManager->CreateParticleEffect(&objParticleInfo.m_nEffectIndex, szParticlePath);

    objParticleInfo.m_ParticleData = CParticleData();
    Vector vDirection = (vEnd - vStart);
    Vector vMiddle = vStart + (vDirection * 0.5f);

    const int totalPoints = 5;
    std::vector<Vector> vecPositions;
    vecPositions.reserve(totalPoints);

    vecPositions.push_back(vStart);
    vecPositions.push_back(vStart.Lerp(vMiddle, 0.05f));
    vecPositions.push_back(vMiddle);
    vecPositions.push_back(vMiddle.Lerp(vEnd, 0.95f));
    vecPositions.push_back(vEnd);

    for (int i = 0; i < totalPoints - 1; i++)
    {
        float t = static_cast<float>(i) / static_cast<float>(totalPoints - 1);
        float tNext = static_cast<float>(i + 1) / static_cast<float>(totalPoints - 1);
       
        Color segColor(
            static_cast<int>(colStart.r() + (colEnd.r() - colStart.r()) * t),
            static_cast<int>(colStart.g() + (colEnd.g() - colStart.g()) * t),
            static_cast<int>(colStart.b() + (colEnd.b() - colStart.b()) * t),
            static_cast<int>(colStart.a() + (colEnd.a() - colStart.a()) * t)
        );

        CParticleColor tColor = CParticleColor(static_cast<float>(segColor.Get<COLOR_R>()), static_cast<float>(segColor.Get<COLOR_G>()), static_cast<float>(segColor.Get<COLOR_B>()));
        Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_COLOR, &tColor);

        CParticleInformation particleInfo = CParticleInformation();
        particleInfo.m_flWidth = 0.5f;
        particleInfo.m_flTime = flTime;
        particleInfo.m_flAlpha = segColor.a() / 255.f;
        Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_INFO, &particleInfo);

        Vector segPositions[2] = { vecPositions[i], vecPositions[i + 1] };
        objParticleInfo.m_ParticleData.m_vecPosition = segPositions;

        Interfaces::m_pParticleSystemMgr->CreateSnapshot(&objParticleInfo.m_hSnapsotParticle);
        Interfaces::m_pParticleManager->UnknownFunction(objParticleInfo.m_nEffectIndex, 0, &objParticleInfo.m_hSnapsotParticle);
        objParticleInfo.m_hSnapsotParticle->Draw(2, &objParticleInfo.m_ParticleData);
    }

    m_deqPointParticlesAdded.push_back({ objParticleInfo.m_nEffectIndex , Interfaces::m_pGlobalVariables->m_flCurrentTime, flTime });
}

void CParticleMgr::AddParticle1Point(const char* szParticlePath, Vector vPosition, Color colColor, float flTime, bool bCustom)
{
    CBeamInfo objParticleInfo = CBeamInfo();

    if (bCustom)
    {
        CBufferString objParticleName(szParticlePath, 'fcpv');
        Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&objParticleName, "");
    }

    Interfaces::m_pParticleManager->CreateParticleEffect(&objParticleInfo.m_nEffectIndex, szParticlePath);

    CParticleColor tColor = CParticleColor(static_cast<float>(colColor.Get<COLOR_R>()), static_cast<float>(colColor.Get<COLOR_G>()), static_cast<float>(colColor.Get<COLOR_B>()));
    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_COLOR, &tColor);

    Interfaces::m_pParticleManager->SetParticleSetting(objParticleInfo.m_nEffectIndex, EParticleSetting::PARTICLE_SETTING_POSITION, &vPosition);

    m_deqPointParticlesAdded.push_back({ objParticleInfo.m_nEffectIndex, Interfaces::m_pGlobalVariables->m_flCurrentTime, flTime });
}

void CParticleMgr::CreateParticle(unsigned int& nEffectIndex, const char* szParticlePath)
{
    if (!szParticlePath || !Interfaces::m_pResourceSystem || !Interfaces::m_pParticleManager)
        return;

    CBufferString emberName(szParticlePath, 'fcpv');
    Interfaces::m_pResourceSystem->BlockingLoadResourceByName(&emberName, "");

    unsigned int uEffectIndex = 0;
    Interfaces::m_pParticleManager->CreateParticleEffect(&uEffectIndex, szParticlePath);

    if (uEffectIndex != 0)
    {
        m_vecEffectIndexes.push_back(uEffectIndex);
        nEffectIndex = uEffectIndex;
    }
}

void CParticleMgr::ReleaseParticles()
{
    if (!Interfaces::m_pParticleManager)
        return;

    for (unsigned int& uEffectIndex : m_vecEffectIndexes)
    {
        if (uEffectIndex != 0)
        {
            Interfaces::m_pParticleManager->DestroyParticle(uEffectIndex, true, true);
            Interfaces::m_pParticleManager->ReleaseParticleIndex(uEffectIndex);
        }
    }

    if (!m_vecEffectIndexes.empty())
        m_vecEffectIndexes.clear();
}

void CParticleMgr::UpdateParticles()
{
    if (!Globals::m_pLocalPlayerPawn || !Interfaces::m_pGameRules || !Interfaces::m_pParticleManager)
        return;

    if (!m_deqPointParticlesAdded.empty())
    {
        float flCurrentTime = Interfaces::m_pGlobalVariables->m_flCurrentTime;
       
        for (std::deque<PointParticle_t>::iterator it = m_deqPointParticlesAdded.begin(); it != m_deqPointParticlesAdded.end(); )
        {

            if (it == m_deqPointParticlesAdded.end())
                break;
               
            if (it->m_flParticleTimeBeforeDelete + it->m_flCurrentTimeGlobal < flCurrentTime)
            {
                if (it->m_uiEffectIndex != 0)
            {
                Interfaces::m_pParticleManager->DestroyParticle(it->m_uiEffectIndex, 1, 1);
                Interfaces::m_pParticleManager->ReleaseParticleIndex(it->m_uiEffectIndex);
                }
                it = m_deqPointParticlesAdded.erase(it);
            }
            else
            {
                ++it;
            }
        }
    }


    int iSelectedEffect = Config::i(g_Variables.m_WorldEffects.m_iSelectedCustomWorldParticles);

    if (iSelectedEffect == WORLD_PARTICLES_NONE)
    {
        this->ReleaseParticles();
        return;
    }

    float flCurrentRoundStartTime = Interfaces::m_pGameRules->m_fRoundStartTime();

    if (iSelectedEffect != m_iLastEffectCached || flCurrentRoundStartTime != m_flLastReloadTime)
    {
        this->ReleaseParticles();

        m_iLastEffectCached = iSelectedEffect;
        m_flLastReloadTime = flCurrentRoundStartTime;

        unsigned int uEffectIndex1 = 0;
        unsigned int uEffectIndex2 = 0;
        switch (iSelectedEffect) {
        case ECustomWorldParticles::WORLD_PARTICLES_ASHES:
            this->CreateParticle(uEffectIndex1, EMBER_EFFECT_PATH);
            this->CreateParticle(uEffectIndex2, EMBER_EFFECT2_PATH);
            break;
        case ECustomWorldParticles::WORLD_PARTICLES_SNOW:
            this->CreateParticle(uEffectIndex1, SNOW_EFFECT_PATH);
            break;
        case ECustomWorldParticles::WORLD_PARTICLES_STARS:
            this->CreateParticle(uEffectIndex1, STARS_EFFECT_PATH);
            break;
        case ECustomWorldParticles::WORLD_PARTICLES_RAIN:
            this->CreateParticle(uEffectIndex1, RAIN_EFFECT_PATH);
            break;
        }
    }

    Vector vDensity(Config::i(g_Variables.m_WorldEffects.m_iSelectedCustomWorldParticleDensity), 0, 0);
    for (const unsigned int& uEffectIndex : m_vecEffectIndexes)
    {
        if (uEffectIndex != 0)
        {
            Interfaces::m_pParticleManager->SetParticleSetting(
                uEffectIndex,
                EParticleSetting::PARTICLE_SETTING_POSITION,
                &Globals::m_pLocalPlayerPawn->m_pGameSceneNode()->m_vecAbsOrigin()
            );

            Interfaces::m_pParticleManager->SetParticleSetting(
                uEffectIndex,
                EParticleSetting::PARTICLE_SETTING_DENSITY,
                &vDensity
            );
        }
    }
}


ParticleManager.h:
Expand Collapse Copy
#pragma once

enum EParticleSetting : unsigned int
{
    PARTICLE_SETTING_POSITION = 0,
    PARTICLE_SETTING_DENSITY = 2,
    PARTICLE_SETTING_INFO = 3,
    PARTICLE_SETTING_COLOR = 16
};

class CParticleMgr
{
private:
    struct PointParticle_t
    {
        unsigned int m_uiEffectIndex;
        float m_flCurrentTimeGlobal;
        float m_flParticleTimeBeforeDelete;
    };
private:
    std::vector<unsigned int> m_vecEffectIndexes;
    int8_t m_iLastEffectCached;
    float m_flLastReloadTime;
    std::deque<PointParticle_t> m_deqPointParticlesAdded;
public:
    void OnEvent(CGameEvent* pEvent);
    void AddParticlePoints(const char* szParticlePath, std::vector<Vector> vecPoints, Color colColor, float flTime, bool bCustom = false);
    void AddParticle2Point(const char* szParticlePath, Vector vStart, Vector vEnd, Color colColor, float flTime, bool bCustom = false);
    void AddParticle2PointGradient(const char* szParticlePath, Vector vStart, Vector vEnd, Color colStart, Color colEnd, float flTime, bool bCustom = false);
    void AddParticle1Point(const char* szParticlePath, Vector vPosition, Color colColor, float flTime, bool bCustom = false);

    void CreateParticle(unsigned int& nEffectIndex, const char* szParticlePath);
    void ReleaseParticles();
    void UpdateParticles();
};
inline auto g_ParticleMgr = std::make_unique<CParticleMgr>();
бля не работает, дай интерфейсы нужные еще
 
бля не работает, дай интерфейсы нужные еще

Interfaces.h:
Expand Collapse Copy
class IParticleSystemMgr;
class CGameParticleManager;
class CParticleCollection;

CGameParticleManager* GetGameParticleManager();


inline IParticleSystemMgr* m_pParticleSystemMgr = nullptr;
inline CGameParticleManager* m_pParticleManager = nullptr;
inline CParticleCollection* m_pParticleCollection = nullptr;


C++:
Expand Collapse Copy
CGameParticleManager* Interfaces::GetGameParticleManager()
{
    return *reinterpret_cast<CGameParticleManager**>(Memory::ResolveRelativeAddress(Memory::FindPattern(CLIENT_DLL, X("48 8B 0D ? ? ? ? 41 B8 ? ? ? ? F3 0F 11 74 24 ? 48 C7 44 24 ? ? ? ? ?")), 0x3, 0x7));
}

static CParticleCollection* GetParticleCollection()
{
    return *reinterpret_cast<CParticleCollection**>(Memory::FindPattern(PARTICLES_DLL, X(" 48 89 5C 24 ? 57 48 83 EC ? 0F 28 05")));
}

const auto pParticlesRegisterList = GetRegisterList(PARTICLES_DLL);
if (pParticlesRegisterList == nullptr)
    return false;

m_pParticleSystemMgr = Capture<IParticleSystemMgr>(pParticlesRegisterList, PARTICLE_SYSTEM_MANAGER);
bSuccess &= (m_pParticleSystemMgr != nullptr);

m_pParticleManager = GetGameParticleManager();
bSuccess &= (m_pParticleManager != nullptr);


Hooks.cpp:
Expand Collapse Copy
и тут в hkLevelInit вставь в конец это

Interfaces::m_pParticleManager = Interfaces::GetGameParticleManager();


IParticleSystem.h:
Expand Collapse Copy
#pragma once

class CParticleSnapshot
{
public:
    void Draw(int nCount, void* pData)
    {
        Memory::CallVFunc<void, 1U>(this, nCount, pData);
    }
};

class CParticleInformation
{
public:
    float m_flTime;
    float m_flWidth;
    float m_flAlpha;
};

class CParticleData
{
public:
    Vector* m_vecPosition;
    MEM_PAD(0x74);
    float* m_flTimes;
    MEM_PAD(0x28);
    float* m_flTimes2;
    MEM_PAD(0x98);
}; //Size: 0x0150

class CParticleName
{
    MEM_PAD(0x8);
    char** m_szParticleName;
};

class CParticleCollection
{
    MEM_PAD(0x18);
    CParticleName* m_pName;
};

struct CParticleColor
{
    float m_flRed;
    float m_flGreen;
    float m_flBlue;
};

class CBeamInfo
{
public:
    unsigned int m_nEffectIndex = 0;
    Vector* m_vecPositions = nullptr;
    float* m_flTimes = nullptr;
    CStrongHandle<CParticleSnapshot> m_hSnapsotParticle;
    CParticleData m_ParticleData;
};

class IParticleSystemMgr
{
public:
    void CreateSnapshot(CStrongHandle<CParticleSnapshot>* pOutParticleSnapshot)
    {
        __int64 unknown = 0;
        Memory::CallVFunc<void, 41>(this, pOutParticleSnapshot, &unknown);
    }

    void Draw(CStrongHandle<CParticleSnapshot>* pParticleSnapshot, int nCount, void* pData)
    {
        Memory::CallVFunc<void, 42>(this, pParticleSnapshot, nCount, pData);
    }
};

class CGameParticleManager
{
public:
    int* CreateParticleEffect(unsigned int* pEffectIndex, const char* szName)
    {
#ifdef CS_PARANOID
        CS_ASSERT(Functions::fnCacheParticleEffect != nullptr);
#endif

        return ReturnAddressSpoofer::SpoofCall(ReturnAddressSpoofGadgets::m_pClientGadet, Functions::fnCacheParticleEffect, this, pEffectIndex, szName, 2/*8*/, 0ll, 0ll, 0ll, 0);
    }

    bool SetParticleSetting(unsigned int nEffectIndex, int nUnknown, void* pData)
    {
#ifdef CS_PARANOID
        CS_ASSERT(Functions::fnCreateParticleEffect != nullptr);
#endif

        return ReturnAddressSpoofer::SpoofCall(ReturnAddressSpoofGadgets::m_pClientGadet, Functions::fnCreateParticleEffect, this, nEffectIndex, nUnknown, pData, 0);
    }

    bool UnknownFunction(int nEffectIndex, unsigned int nUnknown, const CStrongHandle<CParticleSnapshot>* pParticleSnapshot)
    {
#ifdef CS_PARANOID
        CS_ASSERT(Functions::fnUnknownParticleFunction != nullptr);
#endif

        return ReturnAddressSpoofer::SpoofCall(ReturnAddressSpoofGadgets::m_pClientGadet, Functions::fnUnknownParticleFunction, this, nEffectIndex, nUnknown, pParticleSnapshot);
    }

    void UnkFunc2(CStrongHandle<CParticleSnapshot>* pParticleSnapshot, int nCount, void* pData)
    {
        Memory::CallVFunc<void, 42>(this, pParticleSnapshot, nCount, pData);
    }

    void DestroyParticle(int iIndex, bool a1, bool a2)
    {
        using func_t = void(__fastcall*)(void*, int, char, char);
        static func_t fn = (func_t)Memory::FindPattern(CLIENT_DLL, X("83 FA ? 0F 84 ? ? ? ? 41 54"));
        return fn(this, iIndex, a1, a2);
    }

    void ReleaseParticleIndex(int iIndex)
    {
        return Memory::CallVFunc<void, 3U>(this, iIndex);
    }
};
 
Interfaces.h:
Expand Collapse Copy
class IParticleSystemMgr;
class CGameParticleManager;
class CParticleCollection;

CGameParticleManager* GetGameParticleManager();


inline IParticleSystemMgr* m_pParticleSystemMgr = nullptr;
inline CGameParticleManager* m_pParticleManager = nullptr;
inline CParticleCollection* m_pParticleCollection = nullptr;


C++:
Expand Collapse Copy
CGameParticleManager* Interfaces::GetGameParticleManager()
{
    return *reinterpret_cast<CGameParticleManager**>(Memory::ResolveRelativeAddress(Memory::FindPattern(CLIENT_DLL, X("48 8B 0D ? ? ? ? 41 B8 ? ? ? ? F3 0F 11 74 24 ? 48 C7 44 24 ? ? ? ? ?")), 0x3, 0x7));
}

static CParticleCollection* GetParticleCollection()
{
    return *reinterpret_cast<CParticleCollection**>(Memory::FindPattern(PARTICLES_DLL, X(" 48 89 5C 24 ? 57 48 83 EC ? 0F 28 05")));
}

const auto pParticlesRegisterList = GetRegisterList(PARTICLES_DLL);
if (pParticlesRegisterList == nullptr)
    return false;

m_pParticleSystemMgr = Capture<IParticleSystemMgr>(pParticlesRegisterList, PARTICLE_SYSTEM_MANAGER);
bSuccess &= (m_pParticleSystemMgr != nullptr);

m_pParticleManager = GetGameParticleManager();
bSuccess &= (m_pParticleManager != nullptr);


Hooks.cpp:
Expand Collapse Copy
и тут в hkLevelInit вставь в конец это

Interfaces::m_pParticleManager = Interfaces::GetGameParticleManager();


IParticleSystem.h:
Expand Collapse Copy
#pragma once

class CParticleSnapshot
{
public:
    void Draw(int nCount, void* pData)
    {
        Memory::CallVFunc<void, 1U>(this, nCount, pData);
    }
};

class CParticleInformation
{
public:
    float m_flTime;
    float m_flWidth;
    float m_flAlpha;
};

class CParticleData
{
public:
    Vector* m_vecPosition;
    MEM_PAD(0x74);
    float* m_flTimes;
    MEM_PAD(0x28);
    float* m_flTimes2;
    MEM_PAD(0x98);
}; //Size: 0x0150

class CParticleName
{
    MEM_PAD(0x8);
    char** m_szParticleName;
};

class CParticleCollection
{
    MEM_PAD(0x18);
    CParticleName* m_pName;
};

struct CParticleColor
{
    float m_flRed;
    float m_flGreen;
    float m_flBlue;
};

class CBeamInfo
{
public:
    unsigned int m_nEffectIndex = 0;
    Vector* m_vecPositions = nullptr;
    float* m_flTimes = nullptr;
    CStrongHandle<CParticleSnapshot> m_hSnapsotParticle;
    CParticleData m_ParticleData;
};

class IParticleSystemMgr
{
public:
    void CreateSnapshot(CStrongHandle<CParticleSnapshot>* pOutParticleSnapshot)
    {
        __int64 unknown = 0;
        Memory::CallVFunc<void, 41>(this, pOutParticleSnapshot, &unknown);
    }

    void Draw(CStrongHandle<CParticleSnapshot>* pParticleSnapshot, int nCount, void* pData)
    {
        Memory::CallVFunc<void, 42>(this, pParticleSnapshot, nCount, pData);
    }
};

class CGameParticleManager
{
public:
    int* CreateParticleEffect(unsigned int* pEffectIndex, const char* szName)
    {
#ifdef CS_PARANOID
        CS_ASSERT(Functions::fnCacheParticleEffect != nullptr);
#endif

        return ReturnAddressSpoofer::SpoofCall(ReturnAddressSpoofGadgets::m_pClientGadet, Functions::fnCacheParticleEffect, this, pEffectIndex, szName, 2/*8*/, 0ll, 0ll, 0ll, 0);
    }

    bool SetParticleSetting(unsigned int nEffectIndex, int nUnknown, void* pData)
    {
#ifdef CS_PARANOID
        CS_ASSERT(Functions::fnCreateParticleEffect != nullptr);
#endif

        return ReturnAddressSpoofer::SpoofCall(ReturnAddressSpoofGadgets::m_pClientGadet, Functions::fnCreateParticleEffect, this, nEffectIndex, nUnknown, pData, 0);
    }

    bool UnknownFunction(int nEffectIndex, unsigned int nUnknown, const CStrongHandle<CParticleSnapshot>* pParticleSnapshot)
    {
#ifdef CS_PARANOID
        CS_ASSERT(Functions::fnUnknownParticleFunction != nullptr);
#endif

        return ReturnAddressSpoofer::SpoofCall(ReturnAddressSpoofGadgets::m_pClientGadet, Functions::fnUnknownParticleFunction, this, nEffectIndex, nUnknown, pParticleSnapshot);
    }

    void UnkFunc2(CStrongHandle<CParticleSnapshot>* pParticleSnapshot, int nCount, void* pData)
    {
        Memory::CallVFunc<void, 42>(this, pParticleSnapshot, nCount, pData);
    }

    void DestroyParticle(int iIndex, bool a1, bool a2)
    {
        using func_t = void(__fastcall*)(void*, int, char, char);
        static func_t fn = (func_t)Memory::FindPattern(CLIENT_DLL, X("83 FA ? 0F 84 ? ? ? ? 41 54"));
        return fn(this, iIndex, a1, a2);
    }

    void ReleaseParticleIndex(int iIndex)
    {
        return Memory::CallVFunc<void, 3U>(this, iIndex);
    }
};
паттерны обновлены? дай строки из иды что бы я пообновлял
 
паттерны обновлены? дай строки из иды что бы я пообновлял

pattern:
Expand Collapse Copy
fnCreateParticleEffect 48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC ? F3 0F 10 1D ? ? ? ? 41 8B F8 8B DA 4C 8D 05 @client.dll
fnUnknownParticleFunction 48 89 74 24 ? 57 48 83 EC ? 4C 8B D9 49 8B F9 33 C9 41 8B F0 83 FA ? 0F 84 @client.dll
fnCacheParticleEffect 4C 8B DC 53 48 81 EC ? ? ? ? F2 0F 10 05 @client.dll
 
pattern:
Expand Collapse Copy
fnCreateParticleEffect 48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC ? F3 0F 10 1D ? ? ? ? 41 8B F8 8B DA 4C 8D 05 @client.dll
fnUnknownParticleFunction 48 89 74 24 ? 57 48 83 EC ? 4C 8B D9 49 8B F9 33 C9 41 8B F0 83 FA ? 0F 84 @client.dll
fnCacheParticleEffect 4C 8B DC 53 48 81 EC ? ? ? ? F2 0F 10 05 @client.dll
это новые которые?
 
это название просто функций и сигнатуры, это не строки из иды. строки из иды это то по чему можно перейти в функции
ну так я тебе дал актуальные паттерны а дальше сам
 
вкурсах что оно вообщем не заработает т.к структуры разные и вообщем стили
лично у меня работает а что бы и у тебя работало надо правельно переносить и делать под свою базу
 
Назад
Сверху Снизу