Написание плагинов

Grey83

не пишу плагины с весны 2022
Сообщения
7,254
Реакции
4,216
Вот так было бы вполне себе нормально:
C-подобный:
#pragma semicolon 1
#pragma newdecls required

#define BOOST_MULT    5.0    // множитель ускорения
#define BOOST_TIME    2.0    // время действия ускорения

bool bUsed[MAXPLAYERS+1];

public void OnPluginStart()
{
    RegConsoleCmd("sm_boost", Cmd_Boost);

    HookEvent("round_freeze_end", Event_Start, EventHookMode_PostNoCopy);    // с этого момента игроки могут двигаться
}

public void OnClientDisconnect(int client)
{
    bUsed[client] = false;
}

public void Event_Start(Event event, const char[] name, bool dontBroadcast)
{
    for(int i = 1; i <= MaxClients; i++) bUsed[i] = false;
}

public Action Cmd_Boost(int client, int args)
{
    if(!client || bUsed[client] || !IsClientInGame(client) || !IsPlayerAlive(client))
        return Plugin_Handled;

    bUsed[client] = true;
    SetEntPropFloat(client, Prop_Send, "m_flLaggedMovementValue", BOOST_MULT);
    CreateTimer(BOOST_TIME, Timer_End, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE);

    return Plugin_Handled;
}

public Action Timer_End(Handle hTimer, int client)
{
    if((client = GetClientOfUserId(client)) && IsClientInGame(client) && IsPlayerAlive(client))
        SetEntPropFloat(client, Prop_Send, "m_flLaggedMovementValue", 1.0);

    return Plugin_Stop;
}
Сообщения автоматически склеены:

Можно без него?
inSpeed[client] ^= true;
тут дело в том что значение зачем-то инвертируется, вместо того чтобы просто присвоить значение true или false
Ну и тут я так понял<можно по другому сделать

bool inSpeed[MAXPLAYERS+1];
int iLimitSpeed[MAXPLAYERS+1];
выше код поправленный предоставил

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

NeLifeASkazka

Участник
Сообщения
11
Реакции
0
Может кто подсказать, почему не отображается ентити?
Пробовал до этого создавать env_sprite и все работало
Так же почему-то не реагирует на SDKHook(ent, SDKHook_SetTransmit, Hook_SetTransmit);

C-подобный:
#pragma semicolon 1
#include <smlib>
#include <sourcemod>
#include <sdkhooks>

#pragma newdecls required

#define d_interval 0.5 //Интервал между созданием декалей (меньше 0.5 лучше не ставить)
#define d_clear 5.0 // Через сколько секунд удалять декали (слишком много времени лучше не ставить).
#define d_max 11 // d_clear(5.0) / d_interval(0.5) = 10 + 1 "на всякий" = 11

int
    i_speed[MAXPLAYERS+1],
    i_ground[MAXPLAYERS+1],
    count_ent[MAXPLAYERS+1],
    del_ent[MAXPLAYERS+1],
    step_ent[d_max];
Handle
    h_CDStep[MAXPLAYERS+1],
    h_ClearStep[MAXPLAYERS+1];
bool
    StepsClient[MAXPLAYERS+1];

public void OnPluginStart(){
    RegConsoleCmd("sm_test", cmd_test);
}
public void OnMapStart(){
    CreateTimer(0.1, GlobalTimer, _, 1);
    AddFileToDownloadsTable("materials/nlas/decals/arrow_step.vmt");
    AddFileToDownloadsTable("materials/nlas/decals/arrow_step.vtf");
    PrecacheDecal("nlas/decals/arrow_step.vmt", true);
}
public Action cmd_test(int client, int args){
    if(!StepsClient[client]) StepsClient[client] = true;
    else if(StepsClient[client]) StepsClient[client] = false;
    PrintToChat(client, "%s", StepsClient[client]?"+":"-");
    return Plugin_Handled;
}
public Action GlobalTimer(Handle timer){
    for(int client = 1; client <= MaxClients; client++)
    {
        if(IsValidClient(client) && IsPlayerAlive(client))
        {
            float vec[3]; GetEntPropVector(client, Prop_Data, "m_vecVelocity", vec);
            i_ground[client] = GetEntPropEnt(client, Prop_Send, "m_hGroundEntity");
            i_speed[client] = RoundToNearest(SquareRoot(vec[0] * vec[0] + vec[1] * vec[1]));
            PrintHintText(client, "%N\n%d\n%d\nCount: %d, Del: %d", client, i_speed[client], i_ground[client], count_ent[client], del_ent[client]);
            if(h_CDStep[client] == null)
            {
                if(i_speed[client]>110 && i_ground[client]!=-1)
                {
                    float pos[3]; GetClientAbsOrigin(client, pos);
                    float ang[3]; GetClientAbsAngles(client, ang);
                    count_ent[client]++;
                    if(count_ent[client] >= d_max) count_ent[client] = 0;
                    step_ent[count_ent[client]] = CreateEntityByName("info_projecteddecal");
                    if(step_ent[count_ent[client]]!=-1)
                    {
                        DispatchKeyValue(step_ent[count_ent[client]], "texture", "nlas/decals/arrow_step.vmt");
                        DispatchKeyValueVector(step_ent[count_ent[client]], "angles", ang);

                        DispatchKeyValue(step_ent[count_ent[client]], "Distance", "64");
                        DispatchSpawn(step_ent[count_ent[client]]);
                        TeleportEntity(step_ent[count_ent[client]], pos, NULL_VECTOR, NULL_VECTOR);

                        h_ClearStep[client] = CreateTimer(d_clear, ClearStep, client);
                        PrintToChatAll("_______________\nent: %d\n%.1f %.1f %.1f", step_ent[count_ent[client]], pos[0], pos[1], pos[2]);
                    }
                    SDKHook(ent, SDKHook_SetTransmit, Hook_SetTransmit);
                }
                h_CDStep[client] = CreateTimer(d_interval, CDStep, client);
            }
        }
    }
}
public Action Hook_SetTransmit(int entity, int client){
    return !StepsClient[client]? Plugin_Handled : Plugin_Continue;
}
public Action ClearStep(Handle timer, int client){
    del_ent[client]++;
    if(del_ent[client] >= d_max) del_ent[client] = 0;
    AcceptEntityInput(step_ent[del_ent[client]], "kill");
}
public Action CDStep(Handle timer, int client){
    h_CDStep[client] = null;
}
stock bool IsValidClient(int client){
    if(0 >= client || client > MaxClients || !IsClientInGame(client) || !IsClientConnected(client))
        return false;
    return true;
}

Суть плагина в том, чтобы за игроком создавался след в виде декали, который видят определенные игроки
 
Сверху Снизу