[Sourcemod] Несколько фичей, так-же есть и для CS:GO

inklesspen

Не пишу модули под LSD :с
Сообщения
1,775
Реакции
966
Я тут по-находил кучу фичей, решил с вами поделиться, а так-же рассказать про некоторые вещи

Фейковый евент, без хука от сервера
Например фейковый запуск евента (Сервер не регистрирует евент, но игроки его получают)
При обычном Fire() сервер регистрирует фейковый евент и не всегда получается хорошо.
PHP:
// Автоматически закрывает Handle
stock void FakeEventFire(Handle event)
{
    Event curevent = view_as<Event>(event)
    for(int i = 1;i<MAXPLAYERS;i++)    {
        if(IsClientInGame(i) && !IsFakeClient(i))    curevent.FireToClient(i)
    }
    event.Close()
}
PHP:
void FakeClientDeath(int client)
{
    Event event = CreateEvent("player_death")
    event.SetInt("userid", GetClientUserId(client))
    FakeEventFire(event)
}

// Автоматически закрывает Handle
stock void FakeEventFire(Handle event)
{
    Event curevent = view_as<Event>(event)
    for(int i = 1;i<=MAXPLAYERS;i++)    {
        if(IsClientInGame(i) && !IsFakeClient(i))    curevent.FireToClient(i)
    }
    event.Close()
}

Блокировка разминки в CS:GO
PHP:
#include <cstrike>
public Action CS_OnTerminateRound(float &delay, CSRoundEndReason &reason)
{
    if(reason == CSRoundEnd_GameStart)
    {
        reason = CSRoundEnd_Draw
        return Plugin_Changed
    }
    return Plugin_Continue
}
В начале игры идёт доп.конец раунда с причиной CSRoundEnd_GameStart, после, если игра видит эту причину, запускает разминку.
Плагин меняет причину и разминка не запускается

След. фича для CS:GO и возможно для CSS
Отключение остановки звуков в начале раунда, так-же проигрывание музыки отдельно, если есть CS_TerminateRound (например в зм):
PHP:
// Раскомментировать, если есть плагины, завершающие раунд через CS_TerminateRound
// Ибо при этой функции round_end срабатывает в любом случае
#define FOR_ROUNDEND_MUSIC_AND_ZM

public void OnPluginStart()
{
    HookEvent("round_start", RoundEventPre, EventHookMode_Pre)
    HookEvent("round_end", RoundEventPre, EventHookMode_Pre)
    #if defined FOR_ROUNDEND_MUSIC_AND_ZM
    HookEvent("round_end", RoundEnd, EventHookMode_PostNoCopy)
    #endif
}

public Action RoundEventPre(Event event, const char[] name, bool dbc)
{
    event.BroadcastDisabled = true
    return Plugin_Continue
}

#if defined FOR_ROUNDEND_MUSIC_AND_ZM
public void RoundEnd(Event event, const char[] name, bool dbc)
{
    Event event = CreateEvent("round_start")
    for(int i = 1;i<=MAXPLAYERS;i++)
        if(IsClientInGame(i) && !IsFakeClient(i))
            event.FireToClient(i)
    RequestFrame(RoundEnd_PostFrame, 0)
}

public void RoundEnd_PostFrame(int data)
{
    for(int i = 1;i<=MAXPLAYERS;i++)
    {
        if(IsClientInGame(i) && !IsFakeClient(i))
        {
            ClientCommand("play */path/to/music.mp3")
        }
    }
}
#endif
Суть: Игроку не говорят, что раунд закончился или начался
Полезно использовать, когда хотите, чтобы музыка в конце раунда продолжала идти и в след. раунде
Но панелька с победителем не выводится, так-что не помешали бы какие-нибудь эффекты

Отлов конца матча CS:GO
Частенько сталкиваюсь с такими проблемами, как отлов конца матча, самого такое бесило. Благодаря запросу madwayz я нашёл способ
Этот код я не тестил, но по сути должен работать :D
PHP:
#include <sdktools>

Handle gTimer
ConVar mp_timelimit
ConVar mp_maxrounds

public void OnPluginStart()
{
    mp_maxrounds = FindConVar("mp_maxrounds")
    mp_timelimit = FindConVar("mp_timelimit")
 
    HookEvent("round_start", RoundStart)
    HookEvent("round_end", RoundEnd)
}

public void RoundEnd(Event event, const char[] name, bool dbc)
{
    if(mp_maxrounds.IntValue != 0)
        RequestFrame(PostFrameCheckMatchEnd, 0)
}
public void PostFrameCheckMatchEnd(int data)
{
    if(IsMatchEnd())
        OnMatchEnd()
}

public void RoundStart(Event event, const char[] name, bool dbc)
{
    if(gTimer)
    {
        KillTimer(gTimer)
        gTimer = INVALID_HANDLE
    }
    if(mp_maxrounds.IntValue == 0)
        gTimer = CreateTimer(mp_timelimit.FloatValue*60.0-GetGameTime()+GameRules_GetPropFloat("m_flGameStartTime"), OnMatchEndTimer, _, TIMER_FLAG_NO_MAPCHANGE)
}

public Action OnMatchEndTimer(Handle timer)
{
    if(mp_maxrounds.IntValue != 0)
        RequestFrame(PostFrameCheckMatchEnd, 0)
    gTimer = INVALID_HANDLE
}

public void OnMapStart()
{
    gTimer = INVALID_HANDLE
}

stock bool IsMatchEnd()
{
    return (GameRules_GetProp("m_gamePhase") == 5)
}

void OnMatchEnd()
{
    // do anything... for example
    PrintToChatAll("Match end")
}
[/SIZE]


..Однако с визуальным оформлением у меня беда
Если нашли тоже какие-нибудь фичи, не стесняйтесь - выкладывайте
Я не закинул те проблемы и баги, которые уже давно известны и решены тем же @Черная вдова, которые можно увидеть здесь
 
Последнее редактирование:
Сверху Снизу