Убийство АФК-КТ для jail

Тема в разделе "Программирование / Скриптинг", создана пользователем ilga80, 21 янв 2013.

  1. ilga80

    ilga80

    Сообщения:
    153
    Симпатии:
    827
    Помогите оптимизировать код и исправить ошибки
    PHP:
    #include <sourcemod>
    #include <sdktools_functions>

    new Handle:my_timer[MAXPLAYERS+1];

    new 
    Float:afk_timer 3.0,
    Float:afk_pos[MAXPLAYERS+1][3];

    public 
    OnPluginStart()
    {
    HookConVarChange(CreateConVar("afk_timer""5"), cvar_afk_timer);
    HookEvent("player_death"playerDeath);
    }

    public 
    cvar_afk_timer(Handle:convar, const String:oldValue[], const String:newValue[]) afk_timer float(EditValue(newValue));

    EditValue(const String:newValue[])
    {
    new 
    value StringToInt(newValue);
    if (
    value 1value 1;
    return 
    value;
    }

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

    public 
    OnClientPutInServer(client)
    {
    if (!
    IsFakeClient(client))
    {
    my_timer[client] = CreateTimer(afk_timerAFK_Timer_FuncclientTIMER_REPEAT);
    }
    }

    public 
    Action:AFK_Timer_Func(Handle:timerany:client)
    {
    //if (GetClientTeam(client) == 3 && !IsPlayerAlive(client)) return Plugin_Continue;
    // afk
    decl Float:x_vec[3];
    GetClientAbsOrigin(clientx_vec);
    if (
    GetClientTeam(client) == && !(GetUserFlagBits(client) & ADMFLAG_ROOT) && x_vec[0] == afk_pos[client][0] && x_vec[1] == afk_pos[client][1])
    {
    //if (GetClientTeam(client) == 3 && !IsPlayerAlive(client))
    my_timer[client] = INVALID_HANDLE;
    ForcePlayerSuicide(client);
    //PrintToChatAll("\x01\x05[AFK-CT]\x01 Игрок \x03%N\x01 убит!", client)
    return Plugin_Continue;
    }
    else
    {
    afk_pos[client][0] = x_vec[0];
    afk_pos[client][1] = x_vec[1];
    }
    return 
    Plugin_Continue;
    }

    public 
    Action:playerDeath(Handle:event, const String:name[], bool:dontBroadcast
    {
    new 
    client GetClientOfUserId(GetEventInt(event"userid"));
    if (
    GetClientTeam(client) == 3)
    {
    PrintToChatAll("\x01\x05[AFK-CT]\x01 Игрок \x03%N\x01 убит!"client)
    }
    }
    в public Action:AFK_Timer_Func(Handle:timer, any:client) закомментировал PrintToChatAll, потому что когда АФК-КТ умирает в чат бесконечно пишется текст что игрок убит (пока не начнется новый раунд.
    Сделал как то замудрено: HookEvent("player_death", playerDeath); и в нем PrintToChatAll теперь пишется 1 раз, чат не засирает, но меня напрягает громоздкий код и
    ошибки в логах
    Код:
    L 01/21/2013 - 23:11:36: [SM] Native "GetClientAbsOrigin" reported: Client 1 is not in game
    L 01/21/2013 - 23:11:36: [SM] Displaying call stack trace for plugin "AFKControl.smx":
    L 01/21/2013 - 23:11:36: [SM] [0] Line 55, AFKControl.sp::AFK_Timer_Func()
    L 01/21/2013 - 23:11:39: [SM] Native "GetClientAbsOrigin" reported: Client 1 is not in game
    L 01/21/2013 - 23:11:39: [SM] Displaying call stack trace for plugin "AFKControl.smx":
    L 01/21/2013 - 23:11:39: [SM] [0] Line 55, AFKControl.sp::AFK_Timer_Func()
    L 01/21/2013 - 23:11:42: [SM] Native "GetClientAbsOrigin" reported: Client 1 is not in game
    L 01/21/2013 - 23:11:42: [SM] Displaying call stack trace for plugin "AFKControl.smx":
    L 01/21/2013 - 23:11:42: [SM] [0] Line 55, AFKControl.sp::AFK_Timer_Func()
    L 01/21/2013 - 23:11:45: [SM] Native "GetClientAbsOrigin" reported: Client 1 is not in game
    L 01/21/2013 - 23:11:45: [SM] Displaying call stack trace for plugin "AFKControl.smx":
    L 01/21/2013 - 23:11:45: [SM] [0] Line 55, AFKControl.sp::AFK_Timer_Func()
    
     
    Последнее редактирование: 22 фев 2013
  2. AlmazON

    AlmazON деревянный © yand3xmail

    Сообщения:
    4.512
    Симпатии:
    1.963
    PHP:
    #include <sourcemod>
    #include <sdktools_functions>

    new Handle:my_timer[MAXPLAYERS+1];

    new 
    Float:afk_timer 3.0,
    Float:afk_pos[MAXPLAYERS+1][3];

    public 
    OnPluginStart()
    {
        
    HookConVarChange(CreateConVar("afk_timer""5"), cvar_afk_timer);
    }

    public 
    cvar_afk_timer(Handle:convar, const String:oldValue[], const String:newValue[]) afk_timer float(EditValue(newValue));

    EditValue(const String:newValue[])
    {
        new 
    value StringToInt(newValue);
        if (
    value 1value 1;
        return 
    value;
    }

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

    public 
    OnClientPutInServer(client)
    {
        if (!
    IsFakeClient(client))
        {
            
    my_timer[client] = CreateTimer(afk_timerAFK_Timer_FuncclientTIMER_REPEAT);
        }
    }

    public 
    Action:AFK_Timer_Func(Handle:timerany:client)
    {
        
    //if (GetClientTeam(client) == 3 && !IsPlayerAlive(client)) return Plugin_Continue;
        // afk
        
    decl Float:x_vec[3];
        
    GetClientAbsOrigin(clientx_vec);
        if (
    GetClientTeam(client) == && !IsPlayerAlive(client) && !(GetUserFlagBits(client) & ADMFLAG_ROOT) && x_vec[0] == afk_pos[client][0] && x_vec[1] == afk_pos[client][1])
        {
            
    my_timer[client] = INVALID_HANDLE;
            
    ForcePlayerSuicide(client);
            
    PrintToChatAll("\x01\x05[AFK-CT]\x01 Игрок \x03%N\x01 убит!"client)
            return 
    Plugin_Continue;
        }
        else
        {
            
    afk_pos[client][0] = x_vec[0];
            
    afk_pos[client][1] = x_vec[1];
        }
        return 
    Plugin_Continue;
    }

    /*
    public Action:Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
    {
        return Plugin_Continue;
    }
     */
    Не? :) Проверить не на чем... Но логи чисты по крайней мере от него.
     
  3. Impulse72

    Impulse72

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

    На счет того хука на смерть игрока. У тебя так при любом убийстве кт будет писаться :)

    PHP:
    #include <sourcemod>
    #include <sdktools_functions>

    new Handle:my_timer[MAXPLAYERS+1];
    new 
    Float:last_pos[MAXPLAYERS+1][3];
    new 
    Float:new_pos[MAXPLAYERS+1][3];
    new 
    Handle:cvarTimer INVALID_HANDLE;
    new 
    afktime[MAXPLAYERS+1];
    new 
    bool:need[MAXPLAYERS+1];


    public 
    OnPluginStart()
    {
        
    cvarTimer CreateConVar("afk_timer""20""kyky");
        
    HookEvent("player_team"jointeam);
        
    HookEvent("player_spawn"spawn);
    }

    public 
    spawn(Handle:event, const String:name[], bool:dontBroadcast)
     { 
         new 
    client GetClientOfUserId(GetEventInt(event"userid"));
        if (
    need[client])
        {
            
    afktime[client] = 0;
            
    my_timer[client] = CreateTimer(1.0AFK_Timer_FuncclientTIMER_REPEAT);
            
    need[client] = false;
        }
    }

    public 
    jointeam(Handle:event, const String:name[], bool:dontBroadcast)
     { 
         new 
    client GetClientOfUserId(GetEventInt(event"userid"));
         new 
    team GetEventInt(event"team");
        if (
    team == 3)
        {
            
    need[client] = true;
        }
        else 
    DelTimer(client);
     }

    public 
    OnClientDisconnect(client)
    {
        
    DelTimer(client);
    }

    DelTimer(client)
    {
        if (
    my_timer[client] != INVALID_HANDLE)
        {
            
    KillTimer(my_timer[client]);
            
    my_timer[client] = INVALID_HANDLE;
        }
    }

    public 
    Action:AFK_Timer_Func(Handle:timerany:client)
    {
        if (!
    IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client)) DelTimer(client);
        
        if (
    IsAfkClient(client))
        {
            
    afktime[client]++;
        }
        else 
    afktime[client] = 0;
        
        if (
    afktime[client] == GetConVarInt(cvarTimer))
        {
            
    ChangeClientTeam(client1);
            
    PrintToChatAll("\x01\x05[AFK-CT]\x01 Р˜РіСЂРѕРє \x03%N\x01 СѓР±РёС‚!"client);
            
    DelTimer(client);
        }
        return 
    Plugin_Continue;
    }

    bool:IsAfkClient(client)
    {
        
    GetClientAbsOrigin(clientnew_pos[client]);
        if (
    new_pos[client][0] == last_pos[client][0] && new_pos[client][1] == last_pos[client][1])
        {
            return 
    true;
        }
        else 
        {
            
    last_pos[client][0] = new_pos[client][0];
            
    last_pos[client][1] = new_pos[client][1];        
        }
        return 
    false;
    }

    Оффтоп
     
  4. Scarface_slv

    Scarface_slv

    Сообщения:
    228
    Симпатии:
    47
    Попробуй этот, я немного кривоват в написании плагинов поэтому, как умею так и сделал)
     

    Вложения:

    • Afk.sp
      Размер файла:
      2,7 КБ
      Просмотров:
      7
    Руслан Ахметшин нравится это.
  5. Scarface_slv

    Scarface_slv

    Сообщения:
    228
    Симпатии:
    47
    я забыл изменить еще if(player < 2) на if(player > 2)
    а насчет смерти и перестает перекидывать это я хз, потому что я тупо запрещаю считать
    afktime[client]++; если игроков меньше двух или если 60 секунд прошло

    Добавлено через 5 минут
    и попробуй в
    DelTimer(client)
    засунуть need[client] = true;
     
    Последнее редактирование: 22 янв 2013
  6. Impulse72

    Impulse72

    Сообщения:
    246
    Симпатии:
    170
    ilga80, вообще надо сразу условия говорить. Особенно не люблю когда при заказе в самом конце пишут доп. требования :)

    PHP:
    #include <sourcemod>
    #include <sdktools_functions>

    new Handle:my_timer[MAXPLAYERS+1];
    new 
    Handle:my_timertwo[MAXPLAYERS+1];
    new 
    Float:last_pos[MAXPLAYERS+1][3];
    new 
    Float:new_pos[MAXPLAYERS+1][3];
    new 
    Handle:cvarTimer INVALID_HANDLE;
    new 
    afktime[MAXPLAYERS+1];


    public 
    OnPluginStart()
    {
        
    cvarTimer CreateConVar("afk_timer""20""kyky");
        
    HookEvent("round_start"spawn);
    }

    public 
    spawn(Handle:event, const String:name[], bool:dontBroadcast)
     { 
         new 
    client GetClientOfUserId(GetEventInt(event"userid"));
        if (
    GetClientTeam(client) == && HavePlayers())
        {
            
    afktime[client] = 0;
            
    my_timer[client] = CreateTimer(1.0AFK_Timer_FuncclientTIMER_REPEAT);
            
    my_timertwo[client] = CreateTimer(60.0Endclient);
        }
    }

    bool:HavePlayers()
    {
        new 
    count 0;
        for (new 
    1i<MaxClientsi++)
        {
            if (
    IsClientConnected(i) && GetClientTeam(i) == 2)
            
    count++;
        }
        
        if (
    count >= 2)
            return 
    true;
        
        return 
    false;
    }

    public 
    Action:End(Handle:timerany:client)
    {
        
    DelTimer(client);
    }

    public 
    OnClientDisconnect(client)
    {
        
    DelTimer(client);
    }

    DelTimer(client)
    {
        if (
    my_timer[client] != INVALID_HANDLE)
        {
            
    KillTimer(my_timer[client]);
            
    my_timer[client] = INVALID_HANDLE;
        }
        if (
    my_timertwo[client] != INVALID_HANDLE)
        {
            
    KillTimer(my_timertwo[client]);
            
    my_timertwo[client] = INVALID_HANDLE;
        }
    }

    public 
    Action:AFK_Timer_Func(Handle:timerany:client)
    {
        if (!
    IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client)) DelTimer(client);
        
        if (
    IsAfkClient(client))
        {
            
    afktime[client]++;
        }
        else 
    afktime[client] = 0;
        
        if (
    afktime[client] == GetConVarInt(cvarTimer))
        {
            
    ChangeClientTeam(client1);
            
    PrintToChatAll("\x01\x05[AFK-CT]\x01 Р˜РіСЂРѕРє \x03%N\x01 СѓР±РёС‚!"client);
            
    DelTimer(client);
        }
        return 
    Plugin_Continue;
    }

    bool:IsAfkClient(client)
    {
        
    GetClientAbsOrigin(clientnew_pos[client]);
        if (
    new_pos[client][0] == last_pos[client][0] && new_pos[client][1] == last_pos[client][1])
        {
            return 
    true;
        }
        else 
        {
            
    last_pos[client][0] = new_pos[client][0];
            
    last_pos[client][1] = new_pos[client][1];        
        }
        return 
    false;
    }
     
  7. Impulse72

    Impulse72

    Сообщения:
    246
    Симпатии:
    170
    Ой, я забыл поменять. Там надо цикл использовать.

    Добавлено через 1 минуту
    Код:
    public spawn(Handle:event, const String:name[], bool:dontBroadcast)
     { 
     	for (new client = 1; client <= MaxClients; client++)
    	{
    		if (GetClientTeam(client) == 3 && HavePlayers())
    		{
    			afktime[client] = 0;
    			my_timer[client] = CreateTimer(1.0, AFK_Timer_Func, client, TIMER_REPEAT);
    			my_timertwo[client] = CreateTimer(60.0, End, client);
    		}
    	}
    }

    Поменяй на эту функцию.
     
    Последнее редактирование: 22 янв 2013
  8. Impulse72

    Impulse72

    Сообщения:
    246
    Симпатии:
    170
    в 22 строку доабвь IsClientConnected(client) чтобы получилось if (IsClientConnected(client) &&GetClientTeam(client) == 3 && HavePlayers())
     
  9. Impulse72

    Impulse72

    Сообщения:
    246
    Симпатии:
    170
    Client 3 is not in game
    Добавь просто проверок на онлайн. Странно, что там ошибка появилась. таймер же убивается если игрока нету в игре.
     
  10. Scarface_slv

    Scarface_slv

    Сообщения:
    228
    Симпатии:
    47
    В том в котором я скинул лучше изменить тут, что бы таймер удалился как только время закончится в 60 с, или если игроков мало... а то глупо сбрасывать на 0 это afktime[client]
    PHP:
    public Action:AFK_Timer_Func(Handle:timerany:client)
    {
        if (!
    IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client) || OffTimerDelTimer(client);
        
        if (
    IsAfkClient(client))
        {
            
    afktime[client]++;
        }
    .....
    в остальном вроде норм
     
  11. Impulse72

    Impulse72

    Сообщения:
    246
    Симпатии:
    170
    Ты знаешь за что отвечает массив afktime вообще? По ходу нет.
     
  12. Scarface_slv

    Scarface_slv

    Сообщения:
    228
    Симпатии:
    47
    эээ да, тупо прибавляется когда игрок стоит на месте.... если станет равен cvarTimerе убьет
    а ты знаешь что будет с твоим таймером если будет рестарт?=)
    Я же просто учусь опыта у меня не много, и пытаюсь помочь просто что бы самому набраться побольше опыта
     
  13. Impulse72

    Impulse72

    Сообщения:
    246
    Симпатии:
    170
    А на кой ты пишешь, что тупо его обнулять если игрок начал двигаться? Завершится мой таймер когда начнется рестарт.
     
  14. Scarface_slv

    Scarface_slv

    Сообщения:
    228
    Симпатии:
    47
    Имею виду зачем нужен таймер и подсчет, если прошло 60 секунд? Или если игроков меньше двух...

    Добавлено через 16 минут
    А где он завершается та в последнем коде? handle тупо перезапишится а тот таймер который был будет работать и ничего уже с ним не сделать....
     
    Последнее редактирование: 22 янв 2013
  15. Impulse72

    Impulse72

    Сообщения:
    246
    Симпатии:
    170
    беру исходник в посте 8 с правильной функцией из 10.

    HavePlayers - логическая функция, которая подсчитывает игроков из команды Т. Если их меньше = 2, то вернет ложь и таймеры не запустятся, так как условие выше не выполняется. Для оптимизации можно вообще в самое начало это запихать и если сразу ложь, то завершаем действие плагина не приступая к циклу. Но щас не об оптимизации.

    В той же функции кстати. Что делает этот таймер через 60 секунд?
    Ответ:
    Что делает функция DelTimer()?
    Ответ: Завершает все таймеры созданые этим плагином для этого плеера если такие существуют.
     
  16. Scarface_slv

    Scarface_slv

    Сообщения:
    228
    Симпатии:
    47
    смотри запустил ты таймер на 60 секунд, и если 60 секунд не прошло и будет рестарт или окончание раунда, таймер перезапишится
     
  17. Impulse72

    Impulse72

    Сообщения:
    246
    Симпатии:
    170
    if (!IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client)) DelTimer(client);

    Объяснить что это значит? Если клиент не приконектчен (интересное слово), если он не в игре, если он мертв что случится? Там я даже думаю лучше будет написать return Plugin_Stop. Но не суть. Так что будет если хотя бы одно условие не выполняется?
     
  18. Scarface_slv

    Scarface_slv

    Сообщения:
    228
    Симпатии:
    47
    я про 60 секунд а ты мне про 1 секунду)
    Да забей лучше, не хочу спорить и флудить...
     
  19. Impulse72

    Impulse72

    Сообщения:
    246
    Симпатии:
    170
    if (my_timer[client] != INVALID_HANDLE)
    {
    KillTimer(my_timer[client]);
    my_timer[client] = INVALID_HANDLE;
    }
    if (my_timertwo[client] != INVALID_HANDLE)
    {
    KillTimer(my_timertwo[client]);
    my_timertwo[client] = INVALID_HANDLE;
    }

    Скажи сколько тут таймеров выключается?

    Добавлено через 2 минуты
    Ты сам пишешь, что хочешь научиться. Но не пытаешься прочитать действия программы.
     
    Последнее редактирование: 23 янв 2013
  20. Scarface_slv

    Scarface_slv

    Сообщения:
    228
    Симпатии:
    47
    Кстати как тока написал, вспомнил что в удаление два таймера удаляется D