• 0
NO2037

[закрыто] Добавления надписи при выходе с AFK через функцию SetPlayerChatBubble

Вопросы

Здравствуйте. Есть система AFK. При нажатии ESC выводит текст над головой [AFK: n секунд] через функцию SetPlayerChatBubble. Когда выйдет допустим с afk, как ему показать текст [Вышел с AFK]? Пробовал в OnPlayerUpdate че то делать, то надпись просто зависала, то еще чего... Пол дня сижу и не могу додумать как реализовать).

new PlayerAFK[MAX_PLAYERS];

public OnGameModeInit()
{
    SetTimer("second_timer"1000true);

    return 1;
}

public OnPlayerUpdate(playerid)
{
    PlayerAFK[playerid] = 0;
    
    return 1;
}

callback: second_timer()
{
    foreach(new i : logged_players)
    {
        PlayerAFK[i]++;
        if(PlayerAFK[i] > 1)
        {
            new afk_text[100];
            format(afk_text, sizeof(afk_text), "[AFK: %d секунд]", PlayerAFK[i]);
            SetPlayerChatBubble(i, afk_text, -150.01200);
        }
    }

    return 1;
}

 

Поделиться сообщением


Ссылка на сообщение

14 ответов на этот вопрос

  • 0

@NO2037, для начала рассмотрим возможность перехода на индивидуальные секундные таймеры. Как вы понимаете, если будет большое количество игроков и весьма "тяжелый" код в second_timer, таймер может не успевать обрабатывать все за секунду, откуда будут расти проблемы. В этом плане эффективнее на каждого игрока создавать собственный таймер. К тому же, возможно, проблема растет из того, что ваш глобальный таймер для игрока начинает вызываться раньше, чем игрок успел появиться на карте, в результате чего время его авторизации/регистрации может идти в секунды AFK (ибо, насколько я помню, в режиме наблюдения OnPlayerUpdate вызывается крайне редко). В любом случае попробуйте, а там будет видно.

 

Спойлер

new gSecondTimer[MAX_PLAYERS] = {-1};

public OnPlayerConnect(playerid) {
    gSecondTimer[playerid] = SetTimerEx("@SecondTimer"1 * 1000true"i", playerid); // создаем индивидуальный таймер
}

public OnPlayerDisconnect(playerid) {
    if (gSecondTimer[playerid] != -1) {
        KillTimer(gSecondTimer[playerid]); // удаляем индивидуальный таймер
        gSecondTimer[playerid] = -1// сбрасываем значение переменной
    }
}

@SecondTimer(playerid);
@SecondTimer(playerid) {
    // этот таймер будет вызываться только для тех игроков, которые подключены (~1 раз в секунду)
    // и теперь здесь не нужны циклы

    // пока игрока нет на карте, возможно, OnPlayerUpdate вызывается крайне редко
    // поэтому проверим, чтобы игрок был на карте, и только в этом случае будем считать AFK секунды
    new playerState = GetPlayerState(playerid);
    switch (playerState) {
        case PLAYER_STATE_ONFOOT, PLAYER_STATE_DRIVER, PLAYER_STATE_PASSENGER, PLAYER_STATE_SPAWNED: {
            PlayerAFK[playerid]++;
            
            // на всякий случай пока что 2 секунды AFK - это минимум
            if (PlayerAFK[playerid] >= 2) {
                // отображаем текст над головой
            }
        }
    }
}

public OnPlayerUpdate(playerid) {
    if (PlayerAFK[playerid] >= 2) {
        // отображаем текст "Вышел из АФК"
        PlayerAFK[playerid] = 0;
    }
}

 

 

Отредактировано пользователем Cawfee

Поделиться сообщением


Ссылка на сообщение
  • 0

@NO2037, а что-нибудь такое?

public OnPlayerUpdate(playerid) {

    if (PlayerAFK[playerid] != 0) {
        SetPlayerChatBubble(i, "[Вышел из AFK]", -150.01200);
        PlayerAFK[playerid] = 0;
    }
    
    return 1;
}

 

Поделиться сообщением


Ссылка на сообщение
  • 0

@Cawfee Такое пробовал. Так же зависает не заходя даже в AFK. https://imgur.com/a/ZbSb4ci

Поделиться сообщением


Ссылка на сообщение
  • 0

@NO2037, а если добавить вывод переменной PlayerAFK[playerid] в OnPlayerUpdate в логи сервера? В эту ветку вообще не должно было быть попадание, поэтому появляются сомнения, что PlayerAFK принимает корректное значение.

Поделиться сообщением


Ссылка на сообщение
  • 0

@Cawfee 

public OnPlayerUpdate(playerid)
{
    if(PlayerAFK[playerid] != 0)
    {
        SetPlayerChatBubble(playerid, "[Выход с AFK]", -150.01200);
        PlayerAFK[playerid] = 0;
    }
    
    printf("PlayerAFK[playerid] = ", PlayerAFK[playerid]);
    
    return 1;
}

https://imgur.com/a/G8g6ZOW

Отредактировано пользователем NO2037

Поделиться сообщением


Ссылка на сообщение
  • 0

@NO2037, спецификатор забыли добавить.

printf("PlayerAFK[playerid] = %d", PlayerAFK[playerid]);

 

Поделиться сообщением


Ссылка на сообщение
  • 0

@Cawfee Ой, не заметил.) https://imgur.com/a/c5KNBlB

Поделиться сообщением


Ссылка на сообщение
  • 0

@NO2037, я тоже кое-что не заметил вовремя. Вы, получается, выводите всегда значение переменной после ее обнуления. Повторите попытку, используя следующий кусок:

public OnPlayerUpdate(playerid)
{
    if(PlayerAFK[playerid] != 0) {
        printf("PlayerAFK = ", PlayerAFK[playerid]);

        SetPlayerChatBubble(playerid, "[Выход с AFK]", -150.01200);
        PlayerAFK[playerid] = 0;
    }
    
    return 1;
}

 

Поделиться сообщением


Ссылка на сообщение
  • 0

@Cawfee Получается так: https://imgur.com/a/vf2Fhg2

Поделиться сообщением


Ссылка на сообщение
  • 0

@Cawfee Вот так теперь просто чередуется https://imgur.com/a/6iMn48A

 

Видимо очень сложно наверное такое реализовать)

Поделиться сообщением


Ссылка на сообщение
  • 0

@NO2037, сама реализация корректная. Остается лишь пробовать увеличивать минимальное время для отображения текста про AFK над головой (скажем, не 1-2 секунды, 3).

Поделиться сообщением


Ссылка на сообщение
  • 0

@Cawfee Пробую увеличивать, но все равно как-то не так по моему работает. Все равно, даже если игрок не в АФК, высвечивается надпись [AFK: n секунд], проходит 2 сек [Вышел с AFK] и так чередуется. Не могу понять с чем связано. Просто сейчас такая же ситуация была как и с моей реализацией, только иначе...

Отредактировано пользователем NO2037

Поделиться сообщением


Ссылка на сообщение
  • 0

Все заработало. Чутка правда пришлось переделать, спасибо за помощь.

Поделиться сообщением


Ссылка на сообщение
  • 0

@NO2037, было бы здорово, если бы поделились решением – возможно, кому-нибудь будет полезно.

Поделиться сообщением


Ссылка на сообщение
Гость
Эта тема закрыта для публикации ответов.
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

  • Похожий контент

    • nazpol9
      От nazpol9
      Привет всем.

      У меня имеется мод для самп сервера и VPS с Ubuntu, на котором я пытаюсь его запустить.

      В чем суть проблемы: при запуске samp03svr, сервер запускается, но на версии 0.3.DL R-1. Когда я пытаюсь запустить этот же мод локально на Windows, сервер работает на версии 0.3.7 и я могу зайти на него без клиента 0.3.DL.

      Для решения этой проблемы я уже пробовал заменять инклуды и исполнительные файлы теми, что есть в архивах на официальном сайте сампа, перекомпилировал мод, и ничего не изменилось.
       
      #include <a_samp> #include <a_mysql> #include <foreach> #include <Pawn.RakNet> #include <streamer> #include <sscanf2> #include <float2> #include <crashdetect> #include <fmt> #include <a_http> #include <Pawn.CMD> #include <Pawn.Regex> #include <requests> #include <callbacks> #include <MD5> #include <mxdate> #include <TOTP> #include <gvar> #include <md-sort> #include <nex-ac> #include <weapon-config> #include <discord-connector> #include <3DTryg> #include <textdraw-streamer>  
      plugins crashdetect.so streamer.so textdraw-streamer.so sscanf.so pawnraknet.so pawncmd.so mysql.so requests.so profiler.so pawnregex.so TOTP.so gvar.so discord-connector.so

      Если у кого-то будут какие-либо догадки, прошу ими поделиться, если понадобится больше информации - я постараюсь её предоставить.