Иконка ресурса

Easy Spawn Protector 2.0

d4Ck

Урегулированный
Сообщения
730
Реакции
562
  • Автор ресурса
  • #1
Пользователь jasmine разместил новый ресурс:

Eazy Spawn Protector - Простой плагин защиты игроков в начале раунда.

Простой плагин защиты игроков в начале раунда.

Защита забирается у всех одновременно, вне зависимости от времени спавна.

Узнать больше об этом ресурсе...
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
  • Команда форума
  • #2
PHP:
public OnClientPostAdminCheck(int client)
{
    SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage); 
}
Есть вероятность того, что это событие никогда не вызовется, если какой-то плагин пытается вручную хандлить авторизации админов.

И можно вообще без хуков.
PHP:
#include <sourcemod>

#pragma newdecls required
#pragma semicolon 1

#define ForPlayer(%0)   for (int %0 = MaxClients; %0 != 0; --%0) if (IsClientInGame(%0))
#define IntToFloat(%0)  (%0 * 1.0)

/**
 * from shareddefs.h
 */
enum {
    No          = 0,    /**< Block any damage */
    EventsOnly  = 1,    /**< Block any damage, but call damage functions */
    Yes         = 2,    /**< Do not block damage */
    AIM         = 3     /**< ??? */
}

/**
 * @section Global variables
 */
int     g_iProtectTime;
Handle  g_hProtectTime;

/**
 * @section Plugin information
 */
public Plugin myinfo = {
    description = "Simple plugin for protect clients from any damage after round start",
    version     = "1.0",
    author      = "CrazyHackGUT aka Kruzya",
    name        = "Spawn Protection",
    url         = "https://kruzefag.ru/"
};

/**
 * @section SourceMod core events
 */
public void OnPluginStart() {
    HookConVarChange((g_hProtectTime = CreateConVar("sm_spawnprotect_time", "7", "Protect time")), OnCvarChanged);
    HookEvent("round_start", OnRoundStart, EventHookMode_Post);
}

public void OnConfigsExecuted() {
    g_iProtectTime = GetConVarInt(g_hProtectTime);
}

/**
 * @section ConVar hook
 */
public void OnCvarChanged(Handle hCvar, const char[] szOV, const char[] szNV) {
    g_iProtectTime = GetConVarInt(g_hProtectTime);
}

/**
 * @section Game events hooks
 */
public void OnRoundStart(Handle hEvent, const char[] szEventName, bool bDontBroadcast) {
    ForPlayer(iClient) {
        SetEntProp(iClient, Prop_Data, "m_takedamage", No, 1);
        PrintToChat(iClient, " \x04[SpawnProtection] \x01Now you protected from any damage on \x04%i \x01sec.", g_iProtectTime);
    }

    CreateTimer(IntToFloat(g_iProtectTime), OnDisableProtect, _, TIMER_FLAG_NO_MAPCHANGE);
}

/**
 * @section Timers
 */
public Action OnDisableProtect(Handle hTimer) {
    ForPlayer(iClient) {
        SetEntProp(iClient, Prop_Data, "m_takedamage", Yes, 1);
        PrintToChat(iClient, " \x04[SpawnProtection] \x01Protection from any damage \x04disabled\x01.");
    }
}
 

diman1000w

Участник
Сообщения
422
Реакции
24
вот так
sm_spawnprotect_time "10"
на 10 секунд
в server.cfg
--- Добавлено позже ---
А можно сделать если ты двигаться начинаешь время сбрасывается. Это я хочу сделать кто стоит афк.
 
Последнее редактирование:

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@jasmine, вот так ещё проще, кмк
только я не уверен что событие спавна происходит точно после начала раунда
PHP:
#include <sdktools>

float fProtectTime;

public Plugin myinfo =
{
    name        = "EazySpawnProtector",
    description    = "Spawn protection",
    author        = "DUCK (vk.com/geliydaun)",
    version        = "1.0.1",
    url            = "http://crystals.pw/"
};

public void OnPluginStart()
{
    ConVar cvar;
    (cvar = CreateConVar("sm_spawnprotect_time", "7", "Время защиты с начала раунда, сек.", FCVAR_NOTIFY, true, _)).AddChangeHook(CVarChanged_ProtectTime);
    fProtectTime = cvar.FloatValue;

    HookEvent("round_start", Event_RoundStart, EventHookMode_Pre)
}

public void CVarChanged_ProtectTime(ConVar cvar, char[] oldValue, char[] newValue)
{
    fProtectTime = cvar.FloatValue;
}

public void Event_RoundStart(Handle hEvent, char[] name, bool dbc)
{
    if(!fProtectTime) return;

    HookEvent("player_spawn", Event_PlayerSpawn);
    PrintToChatAll(" \x04[SpawnProtection] \x01Все игроки защищены от урона на\x04 %i \x01сек.", fProtectTime);
    CreateTimer(fProtectTime, StopProtectTimer, _, TIMER_FLAG_NO_MAPCHANGE);
}

public Action StopProtectTimer(Handle timer)
{
    UnhookEvent("player_spawn", Event_PlayerSpawn);
    PrintToChatAll(" \x04[SpawnProtection] \x01Защита от урона снята!");
    for(int i = 1; i <= MaxClients; i++) if(IsClientInGame(i) && IsPlayerAlive(i)) SetEntProp(i, Prop_Data, "m_takedamage", 2);

}

public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast)
{
    static int client;
    if((client = GetClientOfUserId(event.GetInt("userid")))) SetEntProp(client, Prop_Data, "m_takedamage", 0);
}
 

Вложения

  • EasySpawnProtector 1.0.1.sp
    1.6 КБ · Просмотры: 4
  • EasySpawnProtector 1.0.1.smx
    5.2 КБ · Просмотры: 3

d4Ck

Урегулированный
Сообщения
730
Реакции
562
  • Автор ресурса
  • #5
@jasmine, вот так ещё проще, кмк
только я не уверен что событие спавна происходит точно после начала раунда
PHP:
#include <sdktools>

float fProtectTime;

public Plugin myinfo =
{
    name        = "EazySpawnProtector",
    description    = "Spawn protection",
    author        = "DUCK (vk.com/geliydaun)",
    version        = "1.0.1",
    url            = "http://crystals.pw/"
};

public void OnPluginStart()
{
    ConVar cvar;
    (cvar = CreateConVar("sm_spawnprotect_time", "7", "Время защиты с начала раунда, сек.", FCVAR_NOTIFY, true, _)).AddChangeHook(CVarChanged_ProtectTime);
    fProtectTime = cvar.FloatValue;

    HookEvent("round_start", Event_RoundStart, EventHookMode_Pre)
}

public void CVarChanged_ProtectTime(ConVar cvar, char[] oldValue, char[] newValue)
{
    fProtectTime = cvar.FloatValue;
}

public void Event_RoundStart(Handle hEvent, char[] name, bool dbc)
{
    if(!fProtectTime) return;

    HookEvent("player_spawn", Event_PlayerSpawn);
    PrintToChatAll(" \x04[SpawnProtection] \x01Все игроки защищены от урона на\x04 %i \x01сек.", fProtectTime);
    CreateTimer(fProtectTime, StopProtectTimer, _, TIMER_FLAG_NO_MAPCHANGE);
}

public Action StopProtectTimer(Handle timer)
{
    UnhookEvent("player_spawn", Event_PlayerSpawn);
    PrintToChatAll(" \x04[SpawnProtection] \x01Защита от урона снята!");
    for(int i = 1; i <= MaxClients; i++) if(IsClientInGame(i) && IsPlayerAlive(i)) SetEntProp(i, Prop_Data, "m_takedamage", 2);

}

public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast)
{
    static int client;
    if((client = GetClientOfUserId(event.GetInt("userid")))) SetEntProp(client, Prop_Data, "m_takedamage", 0);
}
Где-то читал, что сначала спавн игроков, а потом начало раунда.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@jasmine, ну тогда надо ещё окончание раунда отлавливать и после него включать режим бессмертия
а после начала раунда запускать таймер для отключения бессмертия
PHP:
#include <sdktools>

float fProtectTime;
bool bHooked;

public Plugin myinfo =
{
    name        = "EazySpawnProtector",
    description    = "Spawn protection",
    author        = "DUCK (vk.com/geliydaun)",
    version        = "1.0.2",
    url            = "http://crystals.pw/"
};

public void OnPluginStart()
{
    ConVar cvar;
    (cvar = CreateConVar("sm_spawnprotect_time", "7", "Время защиты с начала раунда, сек.", FCVAR_NOTIFY, true, _)).AddChangeHook(CVarChanged_ProtectTime);
    fProtectTime = cvar.FloatValue;

    HookEvent("round_start", Event_RoundStart)
    HookEvent("round_end", Event_RoundEnd)
}

public void CVarChanged_ProtectTime(ConVar cvar, char[] oldValue, char[] newValue)
{
    fProtectTime = cvar.FloatValue;
}

public void OnMapStart()
{
    if(fProtectTime) bHooked = HookEventEx("player_spawn", Event_PlayerSpawn);
}

public void OnMapEnd()
{
    if(bHooked) UnhookEvent("player_spawn", Event_PlayerSpawn);
    bHooked = false;
}

public void Event_RoundStart(Handle hEvent, char[] name, bool dbc)
{
    if(!fProtectTime || !bHooked) return;

    PrintToChatAll(" \x04[SpawnProtection] \x01Все игроки защищены от урона на\x04 %i \x01сек.", fProtectTime);
    CreateTimer(fProtectTime, StopProtectTimer, _, TIMER_FLAG_NO_MAPCHANGE);
}

public Action StopProtectTimer(Handle timer)
{
    UnhookEvent("player_spawn", Event_PlayerSpawn);
    PrintToChatAll(" \x04[SpawnProtection] \x01Защита от урона снята!");
    for(int i = 1; i <= MaxClients; i++) if(IsClientInGame(i) && IsPlayerAlive(i)) SetEntProp(i, Prop_Data, "m_takedamage", 2);
}

public void Event_RoundEnd(Handle hEvent, char[] name, bool dbc)
{
    if(fProtectTime) bHooked = HookEventEx("player_spawn", Event_PlayerSpawn);
}

public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast)
{
    static int client;
    if((client = GetClientOfUserId(event.GetInt("userid")))) SetEntProp(client, Prop_Data, "m_takedamage", 0);
}
 

Вложения

  • EasySpawnProtector 1.0.2.smx
    5.5 КБ · Просмотры: 5
  • EasySpawnProtector 1.0.2.sp
    1.9 КБ · Просмотры: 7
Последнее редактирование:
  • Мне нравится
Реакции: d4Ck

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
  • Команда форума
  • #7
@Grey83, где-то читал, да и сам неоднократно сталкивался, что хук изменения переменной не вызывается, если эта переменная вбита в server.cfg или автоконфиг самого плагина. Потому в идеале нужен ещё OnConfigsExecuted()
 
  • Мне нравится
Реакции: d4Ck

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@Kr1kuzya, м/б это если переменная меняется в конфиге, а не через консоль?
Кстати, только что заметил:
PrintToChatAll(" \x04[SpawnProtection] \x01Все игроки защищены от урона на\x04 %i \x01сек.", fProtectTime);
нужно заменить на
PrintToChatAll(" \x04[SpawnProtection] \x01Все игроки защищены от урона на\x04 %i \x01сек.", RoundToNearest(fProtectTime));
 

Vit_ amin

Добрая душа
Сообщения
1,504
Реакции
660
Вообще лучше создавать переменные типа integer, и потом их уже через view_as<float>(...) вставлять как надо. Все же CPU лучше работают с Integer значениями
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@Vit_ amin, ну ок
PHP:
#include <sdktools>

int iProtectTime;
bool bHooked;

public Plugin myinfo =
{
    name        = "EazySpawnProtector",
    description    = "Spawn protection",
    author        = "DUCK (vk.com/geliydaun)",
    version        = "1.0.3",
    url            = "http://crystals.pw/"
};

public void OnPluginStart()
{
    ConVar cvar;
    (cvar = CreateConVar("sm_spawnprotect_time", "7", "Время защиты с начала раунда, сек.", FCVAR_NOTIFY, true, _)).AddChangeHook(CVarChanged_ProtectTime);
    iProtectTime = cvar.IntValue;

    HookEvent("round_start", Event_RoundStart)
    HookEvent("round_end", Event_RoundEnd)
}

public void CVarChanged_ProtectTime(ConVar cvar, char[] oldValue, char[] newValue)
{
    iProtectTime = cvar.IntValue;
}

public void OnMapStart()
{
    if(iProtectTime) bHooked = HookEventEx("player_spawn", Event_PlayerSpawn);
}

public void OnMapEnd()
{
    if(bHooked) UnhookEvent("player_spawn", Event_PlayerSpawn);
    bHooked = false;
}

public void Event_RoundStart(Handle hEvent, char[] name, bool dbc)
{
    if(!iProtectTime || !bHooked) return;

    PrintToChatAll(" \x04[SpawnProtection] \x01Все игроки защищены от урона на\x04 %i \x01сек.", iProtectTime);
    CreateTimer(view_as<float>(iProtectTime), StopProtectTimer, _, TIMER_FLAG_NO_MAPCHANGE);
}

public Action StopProtectTimer(Handle timer)
{
    UnhookEvent("player_spawn", Event_PlayerSpawn);
    PrintToChatAll(" \x04[SpawnProtection] \x01Защита от урона снята!");
    for(int i = 1; i <= MaxClients; i++) if(IsClientInGame(i) && IsPlayerAlive(i)) SetEntProp(i, Prop_Data, "m_takedamage", 2);
}

public void Event_RoundEnd(Handle hEvent, char[] name, bool dbc)
{
    if(iProtectTime) bHooked = HookEventEx("player_spawn", Event_PlayerSpawn);
}

public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast)
{
    static int client;
    if((client = GetClientOfUserId(event.GetInt("userid")))) SetEntProp(client, Prop_Data, "m_takedamage", 0);
}
 

Вложения

  • EasySpawnProtector 1.0.3.sp
    1.9 КБ · Просмотры: 9
  • EasySpawnProtector 1.0.3.smx
    5.4 КБ · Просмотры: 8

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
  • Команда форума
  • #11
Вообще лучше создавать переменные типа integer, и потом их уже через view_as<float>(...) вставлять как надо.
Это ничем хорошим не закончится, как минимум потому что Pawn хранит обычный инт в 4 байта, а float - в 8 байт.
0CZBkEZ.png
 

Vit_ amin

Добрая душа
Сообщения
1,504
Реакции
660
Не знаю, все плагины так делаю, все нормально, и по дампам памяти и по частоте процессора
--- Добавлено позже ---
Естественно не все возможно так делать (я имею в виду), только что позволяется
 

Snake

Участник
Сообщения
124
Реакции
30
Плагин в чат информацию пишет, но защиту не выдает.
Логи чистые, SM - 1.9.0.6225, cs go.
 

sPonso™

Участник
Сообщения
169
Реакции
48
В него можно добавить функцию, что если игрок произвёл выстрел из оружия, нанёс урон ножом, начал дефузить бомбу - защита спадала?
 

Emptyc

Участник
Сообщения
509
Реакции
96
Плагин невероятно много жрёт оперативки.
 

d4Ck

Урегулированный
Сообщения
730
Реакции
562
  • Автор ресурса
  • #19
Последнее редактирование:
Сверху Снизу