Указать на ошибки

Тема в разделе "Программирование / Скриптинг", создана пользователем Hejter, 11 дек 2015.

  1. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Делаю голод для паблика. Оффтоп
    Хотелось бы узнать чего не хватает в моем коде или сделано не так. Вообщем оптимизировать его.
    PHP:
    #pragma semicolon 1

    #include <sdktools>

    /* Спасибо Zipcore - макросы */
    #define LoopIngameClients(%1) for(int %1=1;%1<=MaxClients;++%1)\
    if(IsClientInGame(%1))

    #define start_hunger 100 // Сколько давать ед. голода при спавне?
    #define minus_hunger 2 // Кол-во ед. снятия голода

    new p_hunger[MAXPLAYERS 1]; // Голод -+
    new bool:b_hunger[MAXPLAYERS 1]; // Голод true/false

    Handle g_hHunger null;
    ConVar g_cvCheckHunger;
    new 
    Float:g_fCheckHunger;

    public 
    OnPluginStart(){
        
    HookEvent("player_spawn"PlayerSpawn);
        
    HookEvent("player_death"PlayerDeath);
        
        
    g_cvCheckHunger CreateConVar("sm_check_hunger""5.0""Отрезок времени через которое игроку будет отнимать голод.");
        
    HookConVarChange(g_cvCheckHungerConVar_Callback);
        
    g_fCheckHunger GetConVarFloat(g_cvCheckHunger);
        
        
    HookEvent("round_start"RoundStart);
        
    HookEvent("round_end"RoundEnd);
    }

    public 
    ConVar_Callback(Handle:cvar, const String:oldVal[], const String:newVal[])
    {
        if (
    cvar == g_cvCheckHunger)
        {
            
    g_fCheckHunger GetConVarFloat(g_cvCheckHunger);
            
            if(
    g_hHunger != null)
                
    CloseHandle(g_hHunger);
            
            
    g_hHunger CreateTimer(g_fCheckHungerTimer_CheckHunger0TIMER_REPEAT);
        }
    }

    public 
    RoundStart(Handle:event, const String:name[], bool:dontBroadcast){
        
    g_hHunger CreateTimer(g_fCheckHungerTimer_CheckHunger0TIMER_REPEAT);
    }

    public 
    RoundEnd(Handle:event, const String:name[], bool:dontBroadcast){
        if(
    g_hHunger != null)
        {
            
    KillTimer(g_hHunger);
            
    g_hHunger null;
        }
    }

    public 
    Action:Timer_CheckHunger(Handle:timer)
    {
        
    CheckHunger();
        
        return 
    Plugin_Continue;
    }

    CheckHunger()
    {
        
    LoopIngameClients(client)
        {        
            
    Hunger(client);
        }
    }

    Hunger(client)
    {
        if (
    IsClientInGame(client) && IsPlayerAlive(client) && b_hunger[client])
        {
            if (
    b_hunger[client] == true)
            {
                if (
    p_hunger[client] > 0)
                {
                    
    p_hunger[client] -= minus_hunger;
                    
    PrintHintText(client"Голод %d"p_hunger[client]);
                }
                else if (
    p_hunger[client] <= 0)
                {
                    
    ForcePlayerSuicide(client);
                    
    b_hunger[client] = false;
                }
            }    
        }
    }

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

    /* Спасибо AlmazON - убиваем глобальный таймер, если все игроки вышли с сервера */
    public OnClientDisconnect_Post(client)
    {
        for (new 
    1<= MaxClients; ++i)
        {
            if (
    IsClientInGame(i)) return;
        }
        if(
    g_hHunger != null)
        {
            
    KillTimer(g_hHunger);
            
    g_hHunger null;
        }
    }

    public 
    Info(client){
        
    p_hunger[client] = 0;
        
    b_hunger[client] = false;
    }

    public 
    PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast){
        new 
    client GetClientOfUserId(GetEventInt(event"userid"));
        
        if(
    IsClientInGame(client) && !IsFakeClient(client))
        {
            
    p_hunger[client] = 0;
            
    b_hunger[client] = false;
        }
    }

    public 
    PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast){
        new 
    client GetClientOfUserId(GetEventInt(event"userid")); 
        
        if(
    IsClientInGame(client) && IsPlayerAlive(client))
        {
            
    p_hunger[client] = start_hunger;
            
    b_hunger[client] = true;
            
    /* if (p_hunger[client] == start_hunger)
            {
                HungerTimer[client] = CreateTimer(minus_hunger_timer, hunger_timer, GetClientUserId(client), TIMER_REPEAT);
                b_hunger[client] = true;
            } */
        
    }
    }
     
    Последнее редактирование: 11 дек 2015
  2. Черная вдова

    Черная вдова

    Сообщения:
    1.621
    Симпатии:
    234
    У тебя фугкция Info используется 1 раз ? Или я не заметил, вобщем если 1 раз тогда незачем делать ее
    На спавне и смерти игрока надо использовать ид игрока который соспавнился/умер а не цикл по всем игрокам
    В конце 2 раза чекаешь hunger причем в 2 оформлениях

    Добавлено через 1 минуту
    О ты код обновил

    Добавлено через 3 минуты
    Ну вот ты исправил про цикл, а вот таймер как всегда на 1 игрока :D
     
    Последнее редактирование: 11 дек 2015
  3. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Запостил старую версию, которая более менее работала.


    Уже поправил эту ошибку. Сейчас таймер под циклом.
     
    Последнее редактирование: 11 дек 2015
  4. AlmazON

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

    Сообщения:
    4.514
    Симпатии:
    1.968
    PHP:
    #pragma semicolon 1

    #include <sdktools>

    #define start_hunger 100 // Сколько давать ед. голода при спавне?
    #define minus_hunger 2 // Кол-во ед. снятия голода
    #define minus_hunger_timer 5.0 // Промежуток снятие голода

    new p_hunger[MAXPLAYERS 1];
    new 
    bool:b_hunger[MAXPLAYERS 1];

    new 
    Handle:HungerTimer[MAXPLAYERS 1];

    public 
    OnPluginStart(){
        
    HookEvent("player_spawn"PlayerSpawn);
        
    HookEvent("player_death"PlayerDeath);
    }

    public 
    OnClientDisconnect(client){
        
    p_hunger[client] = 0;
        
    b_hunger[client] = false;
        
    func_killtimer(client);
    }

    public 
    PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast){
        
    OnClientDisconnect(GetClientOfUserId(GetEventInt(event"userid")));
    }

    public 
    PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast){
        new 
    client GetClientOfUserId(GetEventInt(event"userid"));
        
    func_killtimer(client);
        
    p_hunger[client] = start_hunger;
        
    HungerTimer[client] = CreateTimer(minus_hunger_timerhunger_timerclientTIMER_REPEAT);
        
    b_hunger[client] = true;
    }

    public 
    Action:hunger_timer(Handle:timerany:client){
       if (
    b_hunger[client])
        {
            if (
    b_hunger[client] == true)
            {
                if (
    p_hunger[client] > 0)
                {
                    
    p_hunger[client] -= minus_hunger;
                    
    PrintHintText(client"Голод %d"p_hunger[client]);
                }
                else if (
    p_hunger[client] <= 0)
                {
                    
    ForcePlayerSuicide(client);
                    
    b_hunger[client] = false;
                }
                return 
    Plugin_Continue;
            }
            
            
    HungerTimer[client] = INVALID_HANDLE;
        } 
        return 
    Plugin_Stop;
    }

    func_killtimer(client){
        if(
    HungerTimer[client]) 
        { 
            
    KillTimer(HungerTimer[client]); 
            
    HungerTimer[client] = INVALID_HANDLE
        }
    }
    Глобальные переменные вообще не нужны в данный момент... Короче, как будет "голодоутоляющее", тогда и стоит думать о них.
    В целом, код ни о чём... Не успел возродиться - уже голод через несколько секунд. Глупо.
     
  5. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Уже есть. Просто пока что они не используются здесь, они пишутся в другом плагине, потом перенесу в этот. Оффтоп
    Пост обновил первый.
     
  6. Черная вдова

    Черная вдова

    Сообщения:
    1.621
    Симпатии:
    234
    Ну ты пади хочешь раунды по 3 часа что бы голод не сразу был
     
  7. The End Is Near...

    The End Is Near... Russian Roulette

    Сообщения:
    893
    Симпатии:
    659
    глянул мельком.. может игрок умереть не на севере? а быть мертвым при спавне?

    3. p_hunger[client] = start_hunger;
    if (p_hunger[client] == start_hunger) О_О

    4. таймер можно не глобально заюзать, наверное, если игрок мертв, не пройдет проверку, стопнится в конце - хотя хз, см п. 6

    5. else if (p_hunger[client] <= 0) лишнее, else достаточно

    6. а если игрок выжил в раунде? таймер не остановится, так? причем запустится новый

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

    алмазон, тута все ок?)
    PHP:
    public Action:hunger_timer(Handle:timerany:client){
       if (
    b_hunger[client])
        {
            if (
    b_hunger[client] == true)
            {
                if (
    p_hunger[client] > 0)
                {
                    
    p_hunger[client] -= minus_hunger;
                    
    PrintHintText(client"Голод %d"p_hunger[client]);
                }
                else if (
    p_hunger[client] <= 0)
                {
                    
    ForcePlayerSuicide(client);
                    
    b_hunger[client] = false;
                }
                return 
    Plugin_Continue;
            }
            
            
    HungerTimer[client] = INVALID_HANDLE;
        } 
        return 
    Plugin_Stop;
    }

    upd. зачем вообще переменная b_hunger??
     
  8. AlmazON

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

    Сообщения:
    4.514
    Симпатии:
    1.968
    Попробуй поиграть с таким голодом. Да с ним и взрыва бомбы не дождёшься, все перемрут!
    Я потом забил, так как:
     
  9. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Конкретно голод будет отнимать опр. кол-во ед. в X секунд.
    Это лишь сейчас минимум времени стоит.
    И плагин не конкретно для паблик серверов, а для всех, вообще расчитывал на Hunger Games мод.

    И можно ведь добавить Если игрок убил кого-то то +X ед. к голоду.

    Я в оффтопе писал, что код мусорка и возможно кому то нужен будет.

    Добавлено через 2 минуты
    И как мне тогда его убивать? Если таймер глобальный.

    Добавлено через 3 минуты
    Они уже нужны. Т.к после голода я начну писать инвентарь или условие получение голода.
    Кроме голода будет и жажда.
     
    Последнее редактирование: 11 дек 2015
  10. The End Is Near...

    The End Is Near... Russian Roulette

    Сообщения:
    893
    Симпатии:
    659
    как, как, также, как и обычный

    upd. знаешь самую главную свою ошибку? ты стараешься сделать все сразу, с использованием всяких переменных, типа вот, плагин получился большой, осталось за малым, но тебе это мешает, мешает в каком плане, первое, это отвлекает, второе, ты просто путаешься, не можешь уследить, где, что изменилось, ну это на мой взгляд
     
  11. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Планировал что она будет отвечать за отключение голода.
     
  12. The End Is Near...

    The End Is Near... Russian Roulette

    Сообщения:
    893
    Симпатии:
    659
    если ты таймер оставишь глобальный, то получается, когда он работает - "голод" отнимается, или другая логика нужна?
     
  13. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Ну да такая логика.

    Добавлено через 46 секунд
    В точку.
     
    Последнее редактирование: 11 дек 2015
  14. The End Is Near...

    The End Is Near... Russian Roulette

    Сообщения:
    893
    Симпатии:
    659
    тогда просто проверяешь, работает ли таймер, переменная b_blblbalba не пригодится
     
  15. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Вот проверять работает или нет, не умею.
     
  16. The End Is Near...

    The End Is Near... Russian Roulette

    Сообщения:
    893
    Симпатии:
    659
    если работает, значит Таймер != INVALID_HANDLE, ведь после окончания таймер делаем = INVALID_HANDLE, останется проверить, везде ли все ок, везде ли переменные на своих местах, ну и тому подобное
     
  17. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Чем отличается != null от != INVALID_HANDLE?
    Глянь первый пост темы (код). Там таймер вроде как убивается
    PHP:
    if(g_hTimer != null)
                
    CloseHandle(g_hTimer);
    Добавлено через 12 минут
    Не вижу смысла это делать. А если игрок умирает, мне что таймер придется убивать? Проще уж тогда булем.
     
    Последнее редактирование: 11 дек 2015
  18. AlmazON

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

    Сообщения:
    4.514
    Симпатии:
    1.968
    Это значит - работает. Всё уже есть.
    Новый/старый синтаксис.
     
  19. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    У меня вот вопросик.
    Если я буду запускать таймер каждый новый раунд и убивать его в конце раунда, будут ли ошибки?
     
  20. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.975
    Симпатии:
    2.981
    Hejter, с чего бы им взяться ?