Заказать игровой сервер Контакты (заказать плагин/исправить ошибки/другое) Пожертвовать Поиск

[ вход ]
[ последние сообщения ]

  • Страница 1 из 2
  • 1
  • 2
  • »
Как узнать находится ли игрок на лестнице
Sunday Дата: Пятница, 25.01.2013, 00:14:12 | Сообщение # 1
Сообщений: 186
Репутация: 24 [ +/- ]
Парни, подскажите, возможно ли отловить событие когда игрок находится на лестнице и к примеру убить его? Дело в том что у меня один из серверов крутит одну карту и иногда некоторые игроки из команды висят на лестнице не давая другим подняться, когда нет админа на сервере, это сильно раздражает игроков. Вот я и подумал, может есть возможность как то это отловить и если игрок висит например больше 10 секунд то его убивает.
 
_wS_ Дата: Пятница, 25.01.2013, 00:30:12 | Сообщение # 2
Код
if (GetEntityMoveType(client) == MOVETYPE_LADDER)
{
      // Игрок на лестнице
}

Наверно, придется проверять это условие каждые 'x' сек (CreateTimer). Есть еще более сложный и неудобный вариант с env_player_surface_trigger (OnSurfaceChangedToTarget, OnSurfaceChangedFromTarget), который позволяет ловить момент, когда игрок, например, переходит с бетона на дерево - только неизвестно, какой именно игрок, и можно ли поймать этот момент с лестницей.
 
Sunday Дата: Пятница, 25.01.2013, 05:31:36 | Сообщение # 3
Сообщений: 186
Репутация: 24 [ +/- ]
Спасибо _wS_ за пример и подсказку, я сделал два варианта, если не затруднит, подскажите все ли верно и какой вариант будет менее нагружать сервер, меня очень сильно именно нагрузка на сервер волнует.

Вариант 1:
Код
#include <sourcemod>

public OnMapStart()
{
     CreateTimer(10.0, t_timer, INVALID_HANDLE, TIMER_REPEAT);
}

public Action:t_timer(Handle:timer)     
{
     for (new client = 1; client <= MaxClients; client++)
     {
      if (IsValidClient(client) && IsPlayerAlive(client))
      {
       if (GetEntityMoveType(client) == MOVETYPE_LADDER)
       {
        CreateTimer(10.0, t_PlayerKick, INVALID_HANDLE, TIMER_REPEAT);
        PrintToChat(client, "1");
       }
      }
     }

     return Plugin_Continue;
}

public Action:t_PlayerKick(Handle:timer)
{
     for (new client = 1; client <= MaxClients; client++)
     {
      if (IsValidClient(client) && IsPlayerAlive(client))
      {
       if (GetEntityMoveType(client) == MOVETYPE_LADDER)
       {
        KickClient(client);
       }
      }
     }

     return Plugin_Stop;
}

stock IsValidClient(client)
{
     if(IsClientConnected(client) && IsClientInGame(client) && !IsFakeClient(client))
      return true;
         
     return false;
}


Вариант 2:
Код
#include <sourcemod>

new Handle:t_timer[MAXPLAYERS+1];

public OnGameFrame()   
{
   for (new client=1; client <= MaxClients; client++)
   {
    if (IsValidClient(client) && IsPlayerAlive(client))
    {
     if (GetEntityMoveType(client) == MOVETYPE_LADDER)
     {
      t_timer [client]= CreateTimer(10.0, t_PlayerKick, client);
     }
    }
   }
}

public Action:t_PlayerKick(Handle:timer, any:client)
{
   t_timer [client]= INVALID_HANDLE;

   if (IsValidClient(client) && IsPlayerAlive(client))
   {
    if (GetEntityMoveType(client) == MOVETYPE_LADDER)
    {
     KickClient(client);
    }
   }

   return Plugin_Stop;
}

public OnClientDisconnect(client)
{
   if (t_timer [client]!= INVALID_HANDLE)
   {
    KillTimer(t_timer[client]);
    t_timer [client]= INVALID_HANDLE;
   }
}

stock IsValidClient(client)
{
   if(IsClientConnected(client) && IsClientInGame(client) && !IsFakeClient(client))
    return true;
     
   return false;
}


Добавлено (25.01.2013, 05:31:36)
---------------------------------------------
еще хотел узнать, как убить игрока? Получается только кикнуть, я пытался сделать через:
new String:clientname[255];
GetClientName(clientname, sizeof(clientname)
а дальше ступор. Если не затруднит, подскажите.


Сообщение отредактировал Sunday - Пятница, 25.01.2013, 05:51:38
 
scorpion2904 Дата: Пятница, 25.01.2013, 09:55:47 | Сообщение # 4
Сообщений: 68
Репутация: 5 [ +/- ]
Убить с помощью ForcePlayerSuicide(client); , но тогда нужно еще подключить sdktools_functions  (#include <sdktools_functions>)

Добавлено (25.01.2013, 09:50:36)
---------------------------------------------
Попробуй еще такой вариант :

Код
#include <sourcemod>
#include <sdktools>  
#include <sdktools_functions>

new Handle:Timer[MAXPLAYERS+1];

public OnPluginStart(){
    HookEvent("round_start", round_start)
}

public round_start(Handle:event, const String:name[], bool:dontBroadcast)  
{  
    new index = -1;  
    while ((index = FindEntityByClassname(index, "func_ladder")) > 0 || (index = FindEntityByClassname(index, "func_ladderendpoint") > 0))
    {  
       HookSingleEntityOutput(index, "OnStartTouch", OnStartTouch);
       HookSingleEntityOutput(index, "OnEndTouch", OnEndTouch);
    }
}

public OnStartTouch(const String:output[], ent, client, Float:delay)
{
    if (0 < client <= MaxClients && Timer [client]== INVALID_HANDLE)
    {
       Timer [client]= CreateTimer(10.0, TimerFunc, client, TIMER_REPEAT);
    }
}

public OnEndTouch(const String:output[], ent, client, Float:delay) StopTimer(client);
public OnClientDisconnect(client) StopTimer(client);

StopTimer(client)
{
    if (Timer [client]!= INVALID_HANDLE)
    {
       KillTimer(Timer[client]);
       Timer [client]= INVALID_HANDLE;
    }
}

public Action:TimerFunc(Handle:timer, any:client)
{
    ForcePlayerSuicide(client);
    Timer [client]= INVALID_HANDLE;
    return Plugin_Stop;
}

Добавлено (25.01.2013, 09:55:47)
---------------------------------------------
Если из твоих выбирать, то первый лучше. Только по-моему во всех случаях будет убивать и того кто стоит на лестнице и того кто не может из-за первого пройти

 
Sunday Дата: Пятница, 25.01.2013, 12:47:06 | Сообщение # 5
Сообщений: 186
Репутация: 24 [ +/- ]
scorpion2904 да, ведь на самом деле Вы правильно говорите, убивать будет обоих... А я и не подумал о таких важных моментах dumaem . Спасибо Вас большое, скрипт попробовал, идея хорошая но непонятно по каким причинам РаундСтарт не работает! Я попробовал в каждую функцию поставить PrintToChatAll("1") что бы проверить что активируется но ни одного сообщения не получил.
 
scorpion2904 Дата: Пятница, 25.01.2013, 16:34:28 | Сообщение # 6
Сообщений: 68
Репутация: 5 [ +/- ]
То есть даже

Код
public round_start(Handle:event, const String:name[], bool:dontBroadcast)   
{  
PrintToChatAll("1")
}


не работает?

Добавлено (25.01.2013, 16:34:28)
---------------------------------------------
Может быть сделать так, чтобы когда игрок находится на лестнице через него можно было пройти? SetEntProp(client, Prop_Data, "m_CollisionGroup", 2);

 
Sunday Дата: Суббота, 26.01.2013, 05:17:23 | Сообщение # 7
Сообщений: 186
Репутация: 24 [ +/- ]
Цитата (scorpion2904)
То есть даже

Код
public round_start(Handle:event, const String:name[], bool:dontBroadcast)
{
PrintToChatAll("1")
}

не работает?


да, не работает, я ни когда раунд старт не использовал, может быть надо брать индекс игрока в качестве эвента, может по этому не работает.

***
Цитата (scorpion2904)
Может быть сделать так, чтобы когда игрок находится на лестнице через него можно было пройти? SetEntProp(client, Prop_Data, "m_CollisionGroup", 2);


Ваша идея Великолепна! Ведь это на много лучше, спасибо за идею я именно так и буду делать, это ни кого не обидит и все довольны klas

Добавлено (26.01.2013, 05:17:23)
---------------------------------------------
Вот что получилось:

Код
#include <sourcemod>
#pragma semicolon 1

new Handle:h_Timer[MAXPLAYERS+1];

public OnMapStart() {
  CreateTimer(10.0, t_timer, INVALID_HANDLE, TIMER_REPEAT);
}

public Action:t_timer(Handle:timer)
{
  for (new client = 1; client <= MaxClients; client++) {
   if (IsValidClient(client) && IsPlayerAlive(client) && h_Timer[client] == INVALID_HANDLE) {
    if (GetEntityMoveType(client) == MOVETYPE_LADDER) {
     h_Timer[client] = CreateTimer(10.0, t_LadderNoclip, client);
    }
   }
  } return Plugin_Continue;
}

public Action:t_LadderNoclip(Handle:timer, any:client) {
  h_Timer[client] = INVALID_HANDLE;
   
  if (!IsClientInGame(client))
  return Plugin_Stop;

  if (IsValidClient(client) && IsPlayerAlive(client)) {
   if (GetEntityMoveType(client) == MOVETYPE_LADDER) {
    SetEntProp(client, Prop_Data, "m_CollisionGroup", 2);
   }
   else {
    SetEntProp(client, Prop_Data, "m_CollisionGroup", 0);
   }
  } return Plugin_Stop;
}

public OnClientDisconnect(client) {
  if (h_Timer[client] != INVALID_HANDLE) {
   KillTimer(h_Timer[client]);
   h_Timer[client] = INVALID_HANDLE;
  }
}

stock IsValidClient(client) {
  if(IsClientConnected(client) && IsClientInGame(client) && !IsFakeClient(client))
   return true;
  return false;
}


Все работает, буду признателен если укажите на ошибки, если они имеются. Хотелось бы добавить третью функцию, если запущен таймер и игрок уже не на лестнице, то таймер убивался, что то не пойму как это сделать с этими иф и элсе...


Сообщение отредактировал Sunday - Пятница, 25.01.2013, 21:45:03
 
scorpion2904 Дата: Суббота, 26.01.2013, 09:50:09 | Сообщение # 8
Сообщений: 68
Репутация: 5 [ +/- ]
В Вашем коде ошибок я не увидел, но есть ли смысл создавать таймер на игрока, если можно сразу дать ему ноу блок.

Код
#include <sourcemod>  
#pragma semicolon 1  

public OnMapStart() {  
   CreateTimer(10.0, t_timer, INVALID_HANDLE, TIMER_REPEAT);  
}  

public Action:t_timer(Handle:timer)  
{  
   for (new client = 1; client <= MaxClients; client++) {  
    if (IsValidClient(client) && IsPlayerAlive(client)) {  
     if (GetEntityMoveType(client) == MOVETYPE_LADDER) {  
      SetEntProp(client, Prop_Data, "m_CollisionGroup", 2);   
     }
    else{
     SetEntProp(client, Prop_Data, "m_CollisionGroup", 0);
    }
    }  
   } return Plugin_Continue;  
}  

stock IsValidClient(client) {  
   if(IsClientConnected(client) && IsClientInGame(client) && !IsFakeClient(client))  
    return true;  
   return false;  
}
 
Хотя по-моему мой вариант будет меньше нагружать сервер т.к. там можно обойтись без таймеров.Вы для Counter-Strike:Source делаете этот плагин?
 
Sunday Дата: Суббота, 26.01.2013, 20:50:32 | Сообщение # 9
Сообщений: 186
Репутация: 24 [ +/- ]
Цитата (scorpion2904)
В Вашем коде ошибок я не увидел, но есть ли смысл создавать таймер на игрока, если можно сразу дать ему ноу блок.

Код
#include <sourcemod>
#pragma semicolon 1

public OnMapStart() {
CreateTimer(10.0, t_timer, INVALID_HANDLE, TIMER_REPEAT);
}

public Action:t_timer(Handle:timer)
{
for (new client = 1; client <= MaxClients; client++) {
if (IsValidClient(client) && IsPlayerAlive(client)) {
if (GetEntityMoveType(client) == MOVETYPE_LADDER) {
SetEntProp(client, Prop_Data, "m_CollisionGroup", 2);
}
else{
SetEntProp(client, Prop_Data, "m_CollisionGroup", 0);
}
}
} return Plugin_Continue;
}

stock IsValidClient(client) {
if(IsClientConnected(client) && IsClientInGame(client) && !IsFakeClient(client))
return true;
return false;
}


Цитата (scorpion2904)
Хотя по-моему мой вариант будет меньше нагружать сервер т.к. там можно обойтись без таймеров.Вы для Counter-Strike:Source делаете этот плагин?


Спасибо scorpion2904, Вы в очередной раз оказались правы! Сейчас когда выспался хорошо, смотрю и думаю, а на самом деле зачем я создавал второй таймер dumaem klas . Еще раз спасибо scorpion2904 за поддержку и отличные идеи!

п.с. Плагин для half-life 2 Deathmatch, там есть популярная карта "РунОфф" и иногда на ней бывает, когда одна команда проигрывает, некоторые ... игроки переходят в другую команду и перекрывают проход на лестнице не давая пройти к основному оружию ну и собственно команда начинает проигрывать.

Добавлено (26.01.2013, 15:10:53)
---------------------------------------------
klas
http://world-source.ru/forum/129-3072-1

Добавлено (26.01.2013, 20:50:32)
---------------------------------------------
эх, почему из за m_CollisionGroup бывает сбой на карте и все предметы падают под карту... В чем может быть проблема парни?



Сообщение отредактировал Sunday - Суббота, 26.01.2013, 15:11:40
 
scorpion2904 Дата: Суббота, 26.01.2013, 20:57:56 | Сообщение # 10
Сообщений: 68
Репутация: 5 [ +/- ]
Всмысле сами игроки падают под карту?
 
scorpion2904 Дата: Суббота, 26.01.2013, 21:11:31 | Сообщение # 11
Сообщений: 68
Репутация: 5 [ +/- ]
Попробуй так еще:

Код
#include <sourcemod>  
#include <sdktools>   

public OnPluginStart() HookEvent("teamplay_round_start", round_start)  

public round_start(Handle:event, const String:name[], bool:dontBroadcast)   
{   
     new index = -1;   
     while ((index = FindEntityByClassname(index, "func_ladder") > 0) || (index = FindEntityByClassname(index, "func_ladderendpoint")) > 0 || (index = FindEntityByClassname(index, "func_useableladder") > 0))  
     {   
        HookSingleEntityOutput(index, "OnStartTouch", OnStartTouch);  
        HookSingleEntityOutput(index, "OnEndTouch", OnEndTouch);  
     }  
}  

public OnStartTouch(const String:output[], ent, client, Float:delay) SetEntProp(client, Prop_Data, "m_CollisionGroup", 2);

public OnEndTouch(const String:output[], ent, client, Float:delay) SetEntProp(client, Prop_Data, "m_CollisionGroup", 0);
Для half-life 2 Deathmatch должно работать.Может быть, так этого бага не будет.

Гости не могут скачивать файлы
 
Sunday Дата: Суббота, 26.01.2013, 21:22:07 | Сообщение # 12
Сообщений: 186
Репутация: 24 [ +/- ]
Цитата (scorpion2904)
Всмысле сами игроки падают под карту?


Предметы, вот и гадаю из за чего функция которая в обще не относится к предметам, влияет на них. Я ни раз замечал такой баг, с плагинами которые дают ноклип. Возможно это как то только в Халфлайф влияет.

И еще я вспомнил для чего я делал втротой таймер))))))) Для того что бы в момент проверки игрока сразу не кикнуло, первый таймер запускает проверку а второй время допустимое на лестнице и как я мог забыть. Так что надо будет его добавить, а то получается если игрок попадает в момент проверки но он сам находился на лестнице менее 10 секунд то он все равно кикается...

Спасибо scorpion2904, сейчас попробую!
************************************
Так тоже 0 эмоций.


Сообщение отредактировал Sunday - Суббота, 26.01.2013, 21:28:14
 
scorpion2904 Дата: Суббота, 26.01.2013, 21:32:57 | Сообщение # 13
Сообщений: 68
Репутация: 5 [ +/- ]
Тогда наверное лучше будет оставить твой вариант только вместо кика убивать (ForcePlayerSuicide(client);). Хотя щас еще попробую что-нибудь придумать

Добавлено (26.01.2013, 21:32:57)
---------------------------------------------
Ты начала раунда дождался при последнем тесте?

 
Sunday Дата: Суббота, 26.01.2013, 21:54:26 | Сообщение # 14
Сообщений: 186
Репутация: 24 [ +/- ]
Цитата (scorpion2904)
Ты начала раунда дождался при последнем тесте?


Да, в Халфлайф начало раунда сразу, то есть нет закупок и тому подобное как в контр страйк, там сразу как игрок появился или отреспамился или как зашел в игру то это уже и есть начало раунда. В принципе работает отлично, хотелось бы конечно не кикать а убивать игрока, не понятно из за чего не получается так сделать, сейчас буду штрудировать примеры, смотреть как и где это реализовано!

Вот что получилось: (осталось только понять как сделат не кик а килл)

Код
#include <sourcemod>
#pragma semicolon 1

public Plugin:myinfo =
{
    name = " [ASP]Ladder Nonblocking for DM RunOFF, (ver. 1.0.0 beta)",
    author = "Aurora [Russia], scorpion2904, _wS_",
    description = "NoBlock на лестнице",
    url = "http://world-source.ru"
};

new Handle:hTimer[MAXPLAYERS+1];

public OnMapStart() CreateTimer(10.0, t_timer, INVALID_HANDLE, TIMER_REPEAT);

public Action:t_timer(Handle:timer) {

    for (new client = 1; client <= MaxClients; client++) {
     if (IsValidClient(client) && IsPlayerAlive(client) && hTimer [client]== INVALID_HANDLE) {
      if (GetEntityMoveType(client) == MOVETYPE_LADDER) hTimer [client]= CreateTimer(10.0, aTimer, client);
      PrintToChatAll("На лестнице?");
     }
    }
    return Plugin_Continue;
}

public Action:aTimer(Handle:timer, any:client) {

    hTimer [client]= INVALID_HANDLE;

    if (!IsClientInGame(client))
     return Plugin_Stop;

    if (IsValidClient(client) && IsPlayerAlive(client)) {
     if (GetEntityMoveType(client) == MOVETYPE_LADDER) KickClient(client, "Вы Кикнуты за блокировку лестници!");
    }

    return Plugin_Stop;
}

public OnClientDisconnect(client) {
    if (hTimer [client]!= INVALID_HANDLE) {
     KillTimer(hTimer[client]);
     hTimer [client]= INVALID_HANDLE;
    }
}

stock IsValidClient(client) {
    if(IsClientConnected(client) && IsClientInGame(client) && !IsFakeClient(client)) return true;
    return false;
}

Гости не могут скачивать файлы


Сообщение отредактировал Sunday - Суббота, 26.01.2013, 21:57:41
 
scorpion2904 Дата: Суббота, 26.01.2013, 22:04:27 | Сообщение # 15
Сообщений: 68
Репутация: 5 [ +/- ]
Код
#include <sourcemod>  
#include <sdktools>  
#include <sdktools_functions>  
#pragma semicolon 1  

public Plugin:myinfo =  
{  
     name = " [ASP]Ladder Nonblocking for DM RunOFF, (ver. 1.0.0 beta)",  
     author = "Aurora [Russia], scorpion2904, _wS_",  
     description = "NoBlock на лестнице",  
     url = "http://world-source.ru"  
};  

new Handle:hTimer[MAXPLAYERS+1];  

public OnMapStart() CreateTimer(10.0, t_timer, INVALID_HANDLE, TIMER_REPEAT);  

public Action:t_timer(Handle:timer) {  

     for (new client = 1; client <= MaxClients; client++) {  
      if (IsValidClient(client) && IsPlayerAlive(client) && hTimer [client]== INVALID_HANDLE) {  
       if (GetEntityMoveType(client) == MOVETYPE_LADDER) hTimer [client]= CreateTimer(10.0, aTimer, client);  
       PrintToChatAll("На лестнице?");  
      }  
     }  
     return Plugin_Continue;  
}  

public Action:aTimer(Handle:timer, any:client) {  

     hTimer [client]= INVALID_HANDLE;  

     if (!IsClientInGame(client))  
      return Plugin_Stop;  

     if (IsValidClient(client) && IsPlayerAlive(client)) {  
      if (GetEntityMoveType(client) == MOVETYPE_LADDER) ForcePlayerSuicide(client);  
     }  

     return Plugin_Stop;  
}  

public OnClientDisconnect(client) {  
     if (hTimer [client]!= INVALID_HANDLE) {  
      KillTimer(hTimer[client]);  
      hTimer [client]= INVALID_HANDLE;  
     }  
}  

stock IsValidClient(client) {  
     if(IsClientConnected(client) && IsClientInGame(client) && !IsFakeClient(client)) return true;  
     return false;  
}

Так должно убивать.В zombie panic у меня так работало.
 
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск: