Particle Control Point

Сообщения
18
Реакции
3
Как установить начальные и конечные координаты PARTICLE?
А по сути как прицепить particle эффект например медика в играе TF2 ??..
Почитал немного статей на сайте https://developer.valvesoftware.com/wiki/Control_Point_(particles) я так понял что для установки координат нужно использовать Control point, но как установить Control point на Sourcemod??
 
Последнее редактирование:

SourceGod

Участник
Сообщения
47
Реакции
0
Сергей Мироненко, вроде у вс есть на форуме есть плагин smoke redactor или что то вроде этого. Попробуй оттуда взять что нибудь
 

Reiko1231

AlexTheRegent
Сообщения
508
Реакции
1,335
Particle задаются через info_particle_system. Примеров использования в сети достаточно (например гугл, запрос: sourcemod info_particle_system, первая ссылка).
 
Сообщения
18
Реакции
3
вроде у вс есть на форуме есть плагин smoke redactor или что то вроде этого. Попробуй оттуда взять что нибудь

плагин smoke redactor использует env_smokestack а мне нужно кое-что иное info_particle_system
 
Сообщения
18
Реакции
3
Particle задаются через info_particle_system. Примеров использования в сети достаточно (например гугл, запрос: sourcemod info_particle_system, первая ссылка).
на Google первая ссылка там указано как заспавнить info_particle_system
спавнить слава богу я умею)) меня интересует позиции ..
Вот код как спавню я но ничего не спавнится((
C-подобный:
#pragma semicolon 1
#pragma tabsize 0
#include <sourcemod>
#include <cstrike>
#include <sdktools>
#include <sdkhooks>

#define PARTICLE "locust"
#define EFFECT_TIMER 5.0

public OnPluginStart()
{
    HookEvent("player_hurt",            Event_PlayerHurt);
}

public Event_PlayerHurt(Handle:event, const String:name[], bool:dontBroadcast) 
{ 
    new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
    decl Float:location[3];
    if(attacker)
    {
        GetClientAbsOrigin(attacker,location);
    }
    else
    {
        return;
    }
    decl Float:location2[3];
    new victim = GetClientOfUserId(GetEventInt(event, "userid"));
    if(victim)
    {
        GetClientAbsOrigin(victim,location2);
    }
    else
    {
        return;
    }

    location2[2]+=70;
    ShowParticle(victim, location2, attacker, location);
}



public OnMapStart()
{
    AddFileToDownloadsTable("materials/particle/roach/roach.vtf");
    AddFileToDownloadsTable("materials/particle/roach/roach.vmt");
    PrecacheModel("materials/particle/roach/roach.vtf", true);
    PrecacheModel("materials/particle/roach/roach.vmt", true);
    
    AddFileToDownloadsTable("particles/locust.pcf");
    PrecacheGeneric("particles/locust.pcf",true);
    PrecacheParticle("locust");
}

PrecacheParticle(const String:ParticleName[],any:...)
{
    new Particle = CreateEntityByName("info_particle_system");
    DispatchKeyValue(Particle, "effect_name", ParticleName);
    DispatchSpawn(Particle);
    ActivateEntity(Particle);
    AcceptEntityInput(Particle, "start");
    Particle = EntIndexToEntRef(Particle);
    SetVariantString("OnUser1 !self:Kill::0.1:-1");
    AcceptEntityInput(Particle, "AddOutput");
    AcceptEntityInput(Particle, "FireUser1");
}

ShowParticle(client, Float:originPos[3], target, Float: targetPos[3])
{  
    new String:Start[32];    
    Start = CreateControlPoint(client, targetPos);
    
    new String:End[32];
    End = CreateControlPoint(target, targetPos);
    
    new particle = CreateEntityByName("info_particle_system");
    DispatchKeyValue(particle, "effect_name", PARTICLE);
    DispatchKeyValue(particle, "cpoint0", End);
    DispatchKeyValue(particle, "cpoint1", Start);
    DispatchSpawn(particle);
    ActivateEntity(particle); 
    TeleportEntity(particle, originPos, NULL_VECTOR, NULL_VECTOR);
    AcceptEntityInput(particle, "start");    
    
    ModifyEntityAttach(particle, client);
    ModifyEntityAddDeathTimer(particle, EFFECT_TIMER);
}

String:CreateControlPoint(entity, Float:spawnPos[3])
{
    decl String:temp[32];
    //new target = CreateEntityByName("info_particle_target");
    new target = CreateEntityByName("info_target");
    Format(temp, 32, "cptarget%d", target);
    DispatchKeyValue(target, "targetname", temp);    
    TeleportEntity(target, spawnPos, NULL_VECTOR, NULL_VECTOR); 
    ActivateEntity(target); 
    DispatchSpawn(target); 
    
    ModifyEntityAttach(target, entity);
    ModifyEntityAddDeathTimer(target, EFFECT_TIMER);
    return temp;
}

stock ModifyEntityAttach(const entityIndex, const otherEntityIndex, const String:attachTo[]="")
{    
    if (IsValidEdict(entityIndex))
    {
        SetVariantString("!activator");
        AcceptEntityInput(entityIndex, "SetParent", otherEntityIndex, entityIndex, 0);
        
        if (!StrEqual(attachTo, ""))
        {
            SetVariantString(attachTo);
            AcceptEntityInput(entityIndex, "SetParentAttachment", entityIndex, entityIndex, 0);
        }
    }
}

stock ModifyEntityAddDeathTimer(const entityIndex, const Float:lifetime)
{
    if (IsValidEdict(entityIndex))
    {
        decl String:variantString[60];
        Format(variantString, sizeof(variantString), "OnUser1 !self:Kill::%f:-1", lifetime);
   
        SetVariantString(variantString);
        AcceptEntityInput(entityIndex, "AddOutput");
        AcceptEntityInput(entityIndex, "FireUser1");
    }
}
 

Вложения

  • part.rar
    6.2 КБ · Просмотры: 27

Reiko1231

AlexTheRegent
Сообщения
508
Реакции
1,335
Свой партикль добавить нельзя, он не проходит прехеши. Создатели wcs пытались это обойти, им удалось прехешировать модель на стороне сервера, а на клиенте так и не получилось, в результате чего такие партикли просто крашили клиента.
А задать координаты партикли тоже самое, что и задать координаты предмета - TeleportEntity. Не нужно создавать никакие info_target, нужно лишь создать info_particle_system, а затем с помощью TeleportEntity() перенести её туда, куда нужно. Но еще раз повторю - можно создать лишь ту партикль, которая есть по умолчанию в клиенте ксс. Свои добавить не получится.
 
Сообщения
18
Реакции
3
Свой партикль добавить нельзя, он не проходит прехеши. Создатели wcs пытались это обойти, им удалось прехешировать модель на стороне сервера, а на клиенте так и не получилось, в результате чего такие партикли просто крашили клиента.
А задать координаты партикли тоже самое, что и задать координаты предмета - TeleportEntity. Не нужно создавать никакие info_target, нужно лишь создать info_particle_system, а затем с помощью TeleportEntity() перенести её туда, куда нужно. Но еще раз повторю - можно создать лишь ту партикль, которая есть по умолчанию в клиенте ксс. Свои добавить не получится.
у меня великолепно всё получается! только вот с партиклями проблемы какие то, спавнить могу! а вот 1 2 10 20 позицию которую требует партиклл не ззнаю как уазать ((( в прочем я об етом говорил что нужно использовать Control Point.. но как я не пойму
 

Reiko1231

AlexTheRegent
Сообщения
508
Реакции
1,335
Я не понимаю, что вам нужно. Вернемся к самому началу:
Как установить начальные и конечные координаты PARTICLE?
А по сути как прицепить particle эффект например медика в играе TF2 ??..
У партикля нет конечных координат, это не линия. Это своеобразная модель, гиф анимация. У неё есть координата, в которой расположен её центр.
Для того, чтобы прицепить любую entity к другой, необходимо использовать SetParent input (если он поддерживается сущностью). При этом не нужно никаких дополнительных сущностей.

C-подобный:
public OnPluginStart() 
{
	RegConsoleCmd("sm_test", Command_Test);
}

public Action:Command_Test(iClient, iArgc)
{
	new iParticle = CreateEntityByName("info_particle_system");

	new Float:vOrigin[3];
	GetEntPropVector(iClient, Prop_Send, "m_vecOrigin", vOrigin);

	TeleportEntity(iParticle, vOrigin, NULL_VECTOR, NULL_VECTOR);
	DispatchKeyValue(iParticle, "effect_name", "water_splash_02_animated");
	DispatchSpawn(iParticle);

	ActivateEntity(iParticle);
	AcceptEntityInput(iParticle, "Start");
	CreateTimer(3.0, stop_effect, EntIndexToEntRef(iParticle));
	
	// прикрепление партикля к клиенту
	decl String:sTargetName[32]; 
	FormatEx(sTargetName, sizeof(sTargetName), "client%d", iClient);
	DispatchKeyValue(iClient, "targetname", sTargetName);
	SetVariantString(sTargetName);
	AcceptEntityInput(iParticle, "SetParent");  
	// конец прикрепления партикля
	
	return Plugin_Handled;
}


public Action:stop_effect(Handle:timer, any:iParticleRef)
{
	new iParticle = EntRefToEntIndex(iParticleRef);
	if (iParticle > MaxClients)
	{
		AcceptEntityInput(iParticle, "Stop");
		AcceptEntityInput(iParticle, "Kill");
	}
}
Вот пример, который прикрепляет сущность партикля к игроку. Если закоментировать код между "прикрепление партикля к клиенту" и "конец прикрепления партикля", то тогда будет создан объект, который будет находиться на одном месте, независимо от передвижения игрока.

Оффтоп
 
Сообщения
18
Реакции
3
Reiko1231, я написал код для того чтобы заспавнить не линии! а партикли стандартные, из ксс!
C-подобный:
#pragma semicolon 1
#pragma tabsize 0
#include <sourcemod>
#include <sdktools_stringtables> 
#include <halflife>
#include <clients>
#include <sdktools_functions>
#include <sdktools_entinput>
#include <sdktools_engine>
#include <sdktools_trace>
    
new String:NEED_CONTROL_POINT_PARTICLE_NAME[][] ={"blood_impact_synth_01_arc","blood_impact_synth_01_arc2","blood_impact_synth_01_arc3","blood_impact_synth_01_arc4","blood_impact_synth_01_arc_parents","muzzle_autorifles","muzzle_machinegun","muzzle_pistols","muzzle_rifles","muzzle_shotguns"};

new String:NEED_CENTER_POSITION_PARTICLE_NAME[][] ={"embers_small_01","env_fire_small_coverage_base","env_fire_small_coverage_base_smoke","water_splash_02_continuous"};



#define IsValidPlayer(%1)        (1 <= %1 <= MaxClients && IsClientInGame(%1))

new NumTexture[MAXPLAYERS+1];

public Plugin:myinfo = 
{
    name = "Particle TEST Spawner",
    author = "SeReGa_M",
    version = "1.0",
    url = "skype:serega123152"
};

public OnMapStart()
{
    PrecacheGeneric("particles/AMBIENT.PCF"            ,true);
    PrecacheGeneric("particles/EXPLOSIONS_FX.PCF"    ,true);    
    PrecacheGeneric("particles/LIGHTING.pcf"        ,true);
    PrecacheGeneric("particles/INFERNO_FX.pcf"        ,true);
    PrecacheGeneric("particles/WATER_IMPACT.pcf"    ,true);
    PrecacheGeneric("particles/CS_OFFICE.pcf"        ,true);    
    
    
    
    PrecacheGeneric("particles/error.pcf"            ,true);    
    PrecacheGeneric("particles/antlion_blood.pcf"    ,true);    
    PrecacheGeneric("particles/blood_impact.pcf"    ,true);    
    PrecacheGeneric("particles/water_impact.pcf"    ,true);    
    PrecacheGeneric("particles/fire_01.pcf"            ,true);    
    PrecacheGeneric("particles/burning_fx.pcf"        ,true);    
    PrecacheGeneric("particles/combineball.pcf"        ,true);    
    PrecacheGeneric("particles/vortigaunt_fx.pcf"    ,true);    
    PrecacheGeneric("particles/rocket_fx.pcf"        ,true);    
}

public OnPluginStart()
{
    RegConsoleCmd("t_menu",    ParticleMenu);    
    RegConsoleCmd("menu_setnum", ParticleMenuSetnum);
}

public Action:ParticleMenu(client, args)
{
    if (client)        Particle_Menu(client);    
    return Plugin_Handled;
}


public Action:ParticleMenuSetnum(client, args)
{      
    if (args < 1)    PrintToConsole(client,"Используйте: menu_setnum <номер>  - Устанавливаем номер");
    
    new String:arg1[32];
    GetCmdArg(1, arg1, sizeof(arg1));
    NumTexture[client] = StringToInt(arg1);
    Particle_Menu(client);
    return Plugin_Handled;
}

Particle_Menu(client)
{    
    if(NumTexture[client]>=9) NumTexture[client]=0;
    
    PrintToChat(client,"%d",NumTexture[client]);
    new Handle:Particles_Menu = CreateMenu(HandlerMenu);
    decl String:In[128];
    SetMenuTitle(Particles_Menu,                                "Particl под номером [%d]\n\n",NumTexture[client]+1);
    Format(In, sizeof(In),                                    "Показать\n");
    AddMenuItem(Particles_Menu,                                "ShowEffect", In);

    Format(In, sizeof(In),                                    "След\n");
    AddMenuItem(Particles_Menu,                                "NextEffect", In);

    Format(In, sizeof(In),                                    "Пред.Показать\n");
    AddMenuItem(Particles_Menu,                                "PreviousEffect", In);

    Format(In, sizeof(In),                                     "Узнать Имя");
    AddMenuItem(Particles_Menu,                                "show", In);
    
    Format(In, sizeof(In),                                     "чтобы переместится используте \n\n   menu_setnum <№>");
    AddMenuItem(Particles_Menu,                                "", In,ITEMDRAW_DISABLED);
    

    DisplayMenu(Particles_Menu, client, MENU_TIME_FOREVER);
}

public HandlerMenu(Handle:Particles_Menu, MenuAction:action, client, param2)
{
    if(action==MenuAction_Select)
    {
        decl String:info[32];

        GetMenuItem(Particles_Menu, param2, info, sizeof(info));
        if(IsValidPlayer(client))
        {
    
            if(StrEqual(info,        "ShowEffect"))
            {    
                AttachParticle(client, NEED_CONTROL_POINT_PARTICLE_NAME[NumTexture[client]],10.0);
            }
        
            else if(StrEqual(info,        "NextEffect"))
            {
                NumTexture[client]++;
                AttachParticle(client, NEED_CONTROL_POINT_PARTICLE_NAME[NumTexture[client]],10.0);
                
            }
            else if(StrEqual(info,        "PreviousEffect"))
            {
                NumTexture[client]--;
                AttachParticle(client, NEED_CONTROL_POINT_PARTICLE_NAME[NumTexture[client]],10.0);
                
            }
        
            
            if(StrEqual(info,        "show"))
            {
                PrintToChat(client," PArticle NAME \x04\"\x01%s\x04\"",NEED_CONTROL_POINT_PARTICLE_NAME[NumTexture[client]]);
                AttachParticle(client, NEED_CONTROL_POINT_PARTICLE_NAME[NumTexture[client]],10.0);
            }            
    
        }
        
        Particle_Menu(client);
        
    }
    else if(action == MenuAction_Cancel)
    {
        if(param2 == MenuCancel_ExitBack)
        {
        }    
    }
    else if(action==MenuAction_End)
    {
        CloseHandle(Particles_Menu);
    }
}
public OnClientPostAdminCheck(client)
{
    NumTexture[client] = 0;
}

public OnClientDisconnect(client)
{
    NumTexture[client] = 0;
}

GetLookPos(client, Float:Pos[3])
{ 
    decl Float:EyePosition[3], Float:EyeAngles[3], Handle:h_trace; 
    GetClientEyePosition(client, EyePosition); 
    GetClientEyeAngles(client, EyeAngles); 
    h_trace = TR_TraceRayFilterEx(EyePosition, EyeAngles, MASK_SOLID, RayType_Infinite, GetLookPos_Filter, client); 
    TR_GetEndPosition(Pos, h_trace); 
    CloseHandle(h_trace); 
}
public bool:GetLookPos_Filter(ent, mask, any:client)
{ 
    return client != ent; 
}

AttachParticle(client, String:particleType[], Float:time)
{
    decl String:tName[64];
    new particle = CreateEntityByName("info_particle_system");
    if (IsValidEdict(particle))
    {
        new Float:pos[3];
        GetLookPos(client, pos);
        pos[2]+=30.0;
        TeleportEntity(particle, pos, NULL_VECTOR, NULL_VECTOR);
        GetEntPropString(client, Prop_Data, "m_iName", tName, sizeof(tName));
        DispatchKeyValue(particle, "targetname", "particle");    // was tf2particle
        DispatchKeyValue(particle, "parentname", tName);
        DispatchKeyValue(particle, "effect_name", particleType);
        DispatchSpawn(particle);
        SetVariantString(tName);
        AcceptEntityInput(particle, "SetParent", particle, particle, 0);
        ActivateEntity(particle);
        AcceptEntityInput(particle, "start");
        CreateTimer(time, DeleteParticles, particle);
    }
}


public Action:DeleteParticles(Handle:timer, any:particleRef)
{
    DeleteParticle(particleRef);
    return Plugin_Stop;
}

stock DeleteParticle(particleRef)
{
    new particle = EntRefToEntIndex(particleRef);
    if (particle > 0 && IsValidEntity(particle))
    {
        AcceptEntityInput(particle, "stop");
        RemoveEdict(particle);
    }
}

протестируй и посмотри что получится!

это не линия, это партикл но как мне указать конечные координаты? если начальные я указал и они у меня есть, а конечные 0 0 0 как изменить?
 
Последнее редактирование:

Reiko1231

AlexTheRegent
Сообщения
508
Реакции
1,335
https://forums.alliedmods.net/showthread.php?t=90658
Задается через
DispatchKeyValue(particle, "cpoint1", entity_targetname);
полей cpointX 64, т.е. можно писать cpoint1, cpoint2, cpoint3, если нужно соединить с несколькими сущностями, если это требуется для партикля.
А последние партикли (по коду, muzzle_*) работают прекрасно и без этого.
 

Саша Шеин

Кому костылей?
Сообщения
1,697
Реакции
621
Сергей Мироненко, это тот плагин о котором я подумал?:)
 

SourceGod

Участник
Сообщения
47
Реакции
0
Сергей Мироненко, попробуй через повторяющи. Таймер
 
Сообщения
18
Реакции
3
DispatchKeyValue(particle, "cpoint1", entity_targetname);
Хмм большое спасибо)) я наверное не очень правильно делаю targetname(( большое спасибо) за уточнение .
P.S. ещё хотел задать вопрос, а возможно ли сменить Например LifeTime или цвет particle RGBA?? или ещё что нибудь?

это тот плагин о котором я подумал?
Да несомненно это тот плагнин что я тебе пару месяцев назад показывал НО я там использовал кастомные текстуры,те об которых говорил
Свой партикль добавить нельзя, он не проходит прехеши. Создатели wcs пытались это обойти, им удалось перехешировать модель на стороне сервера, а на клиенте так и не получилось, в результате чего такие партикли просто крашили клиента.
,а тут я использую некую малость стандартных из Counter Strike:Source! кстати в Source есть малось партиклей из Half-Life 2 они упакованные в VPK файлы они тоже смотрятся великолепно))

попробуй через повторяющи. Таймер
Спасибо)) но это не то)) , но идея хороша ,красивей выглядит если показать пару раз)

Reiko1231,тк а как сделать TARGETNAME на CONTROL_POINT 1 2 3......???
 
Последнее редактирование:
Сверху Снизу