PDA

Просмотр полной версии : [Вопрос] AFK система



denis01
30.06.2014, 10:29
Помогите плиз
Добавил AFK систему вроде бы всё нормально пока не дойдёт до 10 минут время начинает идти так 10:1001

public OnGameModeInit()
{
SetTimer("CheckAFK", 1000, 1);
return 1;
}
public OnPlayerUpdate(playerid)
{
DeletePVar(playerid, "AFKTime");
return 1;
}
forward CheckAFK();
public CheckAFK()
{
for(new i = GetMaxPlayers() - 1; i != -1; i--)
{
if(!IsPlayerConnected(i) || IsPlayerNPC(i)) continue;
new afktime = GetPVarInt(i, "AFKTime");
SetPVarInt(i, "AFKTime", afktime + 1);
if(afktime >= 4)
{
new string[18];
if(afktime > 3599) return format(string, sizeof(string), "На паузе %d:%02d:%02d", floatround(afktime / 3600), floatround((afktime - 3600) / 60), afktime - 3600);
else if(afktime > 59) format(string, sizeof(string), "На паузе %d:%02d", floatround(afktime / 60), afktime - 60);
else format(string, sizeof(string), "На паузе %d сек.", afktime);
SetPlayerChatBubble(i, string, 0xFF0000FF, 10.0, 1000);
}
}
return 1;
}

Nurick
30.06.2014, 22:37
Где то видел данный код, случайно автор кода не OKStyle?

DeimoS
01.07.2014, 05:49
Pvar медленнее массивов и в подобной системе это будет гораздо заметнее, чем где-либо ещё
По поводу времени - формулы расчёта неверные. Вот исправление вашей проблемы:

else if(afktime > 59) format(string, sizeof(string), "На паузе %d:%02d", floatround(afktime / 60), floatround(afktime % 60));

OKStyle
01.07.2014, 08:02
Да, автор кода я, да, формула в этом коде неверная. А насчет Пваров - проблем тут с ними не было никогда.

DeimoS
01.07.2014, 08:19
Я и не говорю, что с ними будет проблема. Просто многие гоняются за миллисекундами, а о медленности pVar написано даже на офф.сайте (http://wiki.sa-mp.com/wiki/Per-player_variable_system). В общем, я просто предупредил :)

OKStyle
01.07.2014, 09:54
Конечно они медленнее, ведь обычная переменная УЖЕ содержит значение, а PVar постоянно получается в необходимый момент времени. А это, как минимум, ping * 2.

denis01
01.07.2014, 23:27
Лучше делать на переменных? если да на примере не могли бы показать

DeimoS
01.07.2014, 23:53
В интернете полно систем AFK на переменных

OKStyle
02.07.2014, 08:24
Pvar медленнее массивов и в подобной системе это будет гораздо заметнее, чем где-либо ещё
По поводу времени - формулы расчёта неверные. Вот исправление вашей проблемы:

else if(afktime > 59) format(string, sizeof(string), "На паузе %d:%02d", floatround(afktime / 60), floatround(afktime % 60));
Только смысл ещё теряется. Надо чтобы "сек." было, если время до минуты, и часы, если больше 60 минут.

DeimoS
02.07.2014, 11:15
В общем, можно сделать как-то так и не страдать

new afk_time[MAX_PLAYERS];

public OnGameModeInit()
{
SetTimer("CheckAFK", 1000, 1);
return 1;
}
public OnPlayerUpdate(playerid)
{
afk_time[playerid] = -1;
return 1;
}
forward CheckAFK();
public CheckAFK()
{
new string[18];
for(new i = GetMaxPlayers() - 1; i != -1; i--)
{
if(!IsPlayerConnected(i) || IsPlayerNPC(i)) continue;
if(++afk_time[i] > 0)
{
ConvertAfkSeconds(afk_time[i], string[0], string[1], string[2])
if(string[0]) format(string, sizeof(string), "На паузе %d:%02d:%02d", string[0], string[1], string[2]);
else if(string[1]) format(string, sizeof(string), "На паузе %d:%02d", string[1], string[2]);
else format(string, sizeof(string), "На паузе %d сек.", string[2]);
SetPlayerChatBubble(i, string, 0xFF0000FF, 10.0, 1000);
}
}
return 1;
}


stock ConvertAfkSeconds(conv_time, &conv_hour, &conv_minute, &conv_second)
{
if(conv_time <= 60) conv_hour = 0, conv_minute = 0, conv_second = conv_time;
else if(conv_time > 60 && conv_time < 3600)
{
conv_hour = 0;
conv_minute = conv_time / 60;
conv_second = floatround(conv_time % 60, floatround_tozero);
}
else if(conv_time == 3600) conv_hour = 1, conv_minute = 0, conv_second = 0;
else if(conv_time > 3600)
{
new conv_minute_int;
conv_hour = conv_time / 3600;
minutes_int = floatround(conv_time % 3600, floatround_tozero);
conv_minute = conv_minute_int / 60;
conv_second = floatround(conv_minute_int % 60, floatround_tozero);
}
return 1;
}
И stock потом использовать для других случаев, когда нужно конвертировать время из секунд (название ему и сами дать можете)

OKStyle
02.07.2014, 11:35
Использование стока недопустимо в данной задаче - слишком сложно.

Надо считать сразу в сообщениях, примерно:

if(afktime > 3599) return format(string, sizeof(string), "На паузе %d:%02d:%02d", afktime / 3600, floatround(afktime % 60), floatround(afktime/60) % 60);
else if(afktime > 59) format(string, sizeof(string), "На паузе %d:%02d", afktime / 60, floatround(afktime/60) % 60);
else format(string, sizeof(string), "На паузе %d сек.", afktime);

^_^
02.07.2014, 12:05
Использование стока недопустимо в данной задаче - слишком сложно.

Надо считать сразу в сообщениях, примерно:

if(afktime > 3599) return format(string, sizeof(string), "На паузе %d:%02d:%02d", afktime / 3600, floatround(afktime % 60), floatround(afktime/60) % 60);
else if(afktime > 59) format(string, sizeof(string), "На паузе %d:%02d", afktime / 60, floatround(afktime/60) % 60);
else format(string, sizeof(string), "На паузе %d сек.", afktime);
floatround(afktime % 60), floatround(afktime/60) % 60
:mda::mda:

DeimoS
02.07.2014, 12:11
Использование стока недопустимо в данной задаче - слишком сложно.

Надо считать сразу в сообщениях, примерно:

if(afktime > 3599) return format(string, sizeof(string), "На паузе %d:%02d:%02d", afktime / 3600, floatround(afktime % 60), floatround(afktime/60) % 60);
else if(afktime > 59) format(string, sizeof(string), "На паузе %d:%02d", afktime / 60, floatround(afktime/60) % 60);
else format(string, sizeof(string), "На паузе %d сек.", afktime);

Хмм, ну если для вас потеря пары сотых миллисекунд - существенная потеря, хорошо.
Тогда, во-первых, стоит убрать лишний возврат из первого условия.
Во-вторых, формулы должны выглядеть так:

if(afktime > 3599) format(string, sizeof(string), "На паузе %d:%02d:%02d", afktime / 3600, afktime % 3600/60, afktime % 3600 % 60);
else if(afktime > 59) format(string, sizeof(string), "На паузе %d:%02d", afktime / 60, afktime % 60);
else format(string, sizeof(string), "На паузе %d сек.", afktime);
Ибо чтоб, например, найти час, нужно число разделить на 3600. А чтоб найти минуты, нужно сначала найти остаток от прошлого деления, а потом уже из этого числа найти нужные нам минуты. Ну и так далее :)


new afk_time[MAX_PLAYERS];

public OnGameModeInit()
{
SetTimer("CheckAFK", 1000, 1);
return 1;
}
public OnPlayerUpdate(playerid)
{
afk_time[playerid] = -1;
return 1;
}
forward CheckAFK();
public CheckAFK()
{
new string[18];
for(new i = GetMaxPlayers() - 1; i != -1; i--)
{
if(!IsPlayerConnected(i) || IsPlayerNPC(i)) continue;
if(++afk_time[i] > 0)
{
ConvertAfkSeconds(afk_time[i], string[0], string[1], string[2])
if(afk_time[i] > 3599) format(string, sizeof(string), "На паузе %d:%02d:%02d", afk_time[i] / 3600, afk_time[i] % 3600/60, afk_time[i] % 3600 % 60);
else if(afk_time[i] > 59) format(string, sizeof(string), "На паузе %d:%02d", afk_time[i] / 60, afk_time[i] % 60);
else format(string, sizeof(string), "На паузе %d сек.", afk_time[i]);
SetPlayerChatBubble(i, string, 0xFF0000FF, 10.0, 1000);
}
}
return 1;
}
Вроде, ничего не забыл :crazy:

OKStyle
02.07.2014, 12:38
Мой код не претендует на идеал по части формул)) Я ж написал - примерно =)

^_^
02.07.2014, 13:21
Мой код не претендует на идеал по части формул)) Я ж написал - примерно =)
Не в формулах тут дело, а в ненужном использовании функции floatround.
Точный пример:
floatround(afktime % 60)
Итак, этапы которые будет выполнять машина:
1) afktime % 60 = целочисленный результат остатка от деления
2) тип _: целочисленного результата преобразовывает в Float:
3) округляет результат (x.0 в x.0, 50.0 в 50.0, 20.0 в 20.0 и т.д).
4) преобразовывает конечный результат в _: (integer)
5) возвращает результат (тот же что и в 1 пункте)
afktime % 60
1) целочисленный результат остатка от деления
Во втором случае - также.
Вот собственно и плюсы чтения книг и руководств...

DeimoS
02.07.2014, 13:52
http://ihost.pro-pawn.ru/image.php?di=QEZY

^_^
02.07.2014, 14:01
http://ihost.pro-pawn.ru/image.php?di=QEZY
Зачем цитировать меня, петушок? =)))

OKStyle
02.07.2014, 14:29
При чем тут руководства?)) Все и так знают, что делает floatround, и что бессмысленно его юзать на целых переменных :lol:

^_^
02.07.2014, 16:27
При чем тут руководства?)) Все и так знают, что делает floatround, и что бессмысленно его юзать на целых переменных :lol:
Однако тебе на это плевать и нарочно так делаешь?
http://breedpmnr.ru/i/4D47BB81

OKStyle
02.07.2014, 18:56
Я не парюсь на эту тему. Я сразу сказал, что формула там неверная. С другой стороны, если юзать округление - результат будет тот же. Не говоря о скоростях.

Seregamil
02.07.2014, 20:06
Я не парюсь на эту тему. Я сразу сказал, что формула там неверная. С другой стороны, если юзать округление - результат будет тот же. Не говоря о скоростях.

Стоят 2 разных магазина с одинаковой продукцией и разной ценой, судя по всему ты пойдешь в магазин, где цена выше.

Nurick
02.07.2014, 20:30
Вы чем спорить лучше предоставьте человеку готовый код, и там уже выеснится кто более умнее из вас. А щас тут пошол сыр бор.
Или вообще закройте тему.

Я давно замечал что у вас профессионалов между собой конфликт и каждый хочет показаться умнее!

DeimoS
02.07.2014, 20:32
Вы чем спорить лучше предоставьте человеку готовый код, и там уже выеснится кто более умнее из вас. А щас тут пошол сыр бор.
Или вообще закройте тему.

Я давно замечал что у вас профессионалов между собой конфликт и каждый хочет показаться умнее!

Готовый код уже дан (http://pro-pawn.ru/showthread.php?9499-AFK-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0&p=44076&viewfull=1#post44076) же

Nurick
02.07.2014, 20:33
Готовый код уже дан (http://pro-pawn.ru/showthread.php?9499-AFK-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0&p=44076&viewfull=1#post44076) же
Прости не заметил

- - - Добавлено - - -

Всё модераторы закрывайте тему!

OKStyle
02.07.2014, 20:34
Стоят 2 разных магазина с одинаковой продукцией и разной ценой, судя по всему ты пойдешь в магазин, где цена выше.
Если в дешёвом магазине будут китайские подделки, то да - я пойду в более дорогой магазин. Твоего участия тема не требует, иначе она опять перерастёт в один большой оффтоп.

Seregamil
02.07.2014, 21:28
Если в дешёвом магазине будут китайские подделки, то да - я пойду в более дорогой магазин. Твоего участия тема не требует, иначе она опять перерастёт в один большой оффтоп.

http://breedpmnr.ru/i/A769528E

DeimoS
02.07.2014, 21:34
http://breedpmnr.ru/i/A769528E

http://ihost.pro-pawn.ru/image.php?di=TCAY

OKStyle
02.07.2014, 22:10
iPhone в китае и в США - одинаковый товар, только начинка разная, да и делали люди другие. Ну и гарантия там... Но это слишком сложно для тебя, чувак :to_take_umbrage:

denis01
02.07.2014, 23:11
В общем, можно сделать как-то так и не страдать

new afk_time[MAX_PLAYERS];

public OnGameModeInit()
{
SetTimer("CheckAFK", 1000, 1);
return 1;
}
public OnPlayerUpdate(playerid)
{
afk_time[playerid] = -1;
return 1;
}
forward CheckAFK();
public CheckAFK()
{
new string[18];
for(new i = GetMaxPlayers() - 1; i != -1; i--)
{
if(!IsPlayerConnected(i) || IsPlayerNPC(i)) continue;
if(++afk_time[i] > 0)
{
ConvertAfkSeconds(afk_time[i], string[0], string[1], string[2])
if(string[0]) format(string, sizeof(string), "На паузе %d:%02d:%02d", string[0], string[1], string[2]);
else if(string[1]) format(string, sizeof(string), "На паузе %d:%02d", string[1], string[2]);
else format(string, sizeof(string), "На паузе %d сек.", string[2]);
SetPlayerChatBubble(i, string, 0xFF0000FF, 10.0, 1000);
}
}
return 1;
}


stock ConvertAfkSeconds(conv_time, &conv_hour, &conv_minute, &conv_second)
{
if(conv_time <= 60) conv_hour = 0, conv_minute = 0, conv_second = conv_time;
else if(conv_time > 60 && conv_time < 3600)
{
conv_hour = 0;
conv_minute = conv_time / 60;
conv_second = floatround(conv_time % 60, floatround_tozero);
}
else if(conv_time == 3600) conv_hour = 1, conv_minute = 0, conv_second = 0;
else if(conv_time > 3600)
{
new conv_minute_int;
conv_hour = conv_time / 3600;
minutes_int = floatround(conv_time % 3600, floatround_tozero);
conv_minute = conv_minute_int / 60;
conv_second = floatround(conv_minute_int % 60, floatround_tozero);
}
return 1;
}
И stock потом использовать для других случаев, когда нужно конвертировать время из секунд (название ему и сами дать можете)

http://i022.radikal.ru/1407/d9/da1c9fd0e537.png

DeimoS
02.07.2014, 23:14
Используйте этот код

new afk_time[MAX_PLAYERS];

public OnGameModeInit()
{
SetTimer("CheckAFK", 1000, 1);
return 1;
}
public OnPlayerUpdate(playerid)
{
afk_time[playerid] = -1;
return 1;
}
forward CheckAFK();
public CheckAFK()
{
new string[18];
for(new i = GetMaxPlayers() - 1; i != -1; i--)
{
if(!IsPlayerConnected(i) || IsPlayerNPC(i)) continue;
if(++afk_time[i] > 0)
{
if(afk_time[i] > 3599) format(string, sizeof(string), "На паузе %d:%02d:%02d", afk_time[i] / 3600, afk_time[i] % 3600/60, afk_time[i] % 3600 % 60);
else if(afk_time[i] > 59) format(string, sizeof(string), "На паузе %d:%02d", afk_time[i] / 60, afk_time[i] % 60);
else format(string, sizeof(string), "На паузе %d сек.", afk_time[i]);
SetPlayerChatBubble(i, string, 0xFF0000FF, 10.0, 1000);
}
}
return 1;
}

denis01
02.07.2014, 23:21
Используйте этот код

new afk_time[MAX_PLAYERS];

public OnGameModeInit()
{
SetTimer("CheckAFK", 1000, 1);
return 1;
}
public OnPlayerUpdate(playerid)
{
afk_time[playerid] = -1;
return 1;
}
forward CheckAFK();
public CheckAFK()
{
new string[18];
for(new i = GetMaxPlayers() - 1; i != -1; i--)
{
if(!IsPlayerConnected(i) || IsPlayerNPC(i)) continue;
if(++afk_time[i] > 0)
{
if(afk_time[i] > 3599) format(string, sizeof(string), "На паузе %d:%02d:%02d", afk_time[i] / 3600, afk_time[i] % 3600/60, afk_time[i] % 3600 % 60);
else if(afk_time[i] > 59) format(string, sizeof(string), "На паузе %d:%02d", afk_time[i] / 60, afk_time[i] % 60);
else format(string, sizeof(string), "На паузе %d сек.", afk_time[i]);
SetPlayerChatBubble(i, string, 0xFF0000FF, 10.0, 1000);
}
}
return 1;
}
Скомпилировалась без ошибок, пойду протестить

- - - Добавлено - - -

Всё хорошо но время каждую секунду прыгает, мерцает. Огромное спасибо DeiMos

OKStyle
03.07.2014, 09:43
Попробуй тут SetPlayerChatBubble(i, string, 0xFF0000FF, 10.0, 1000); увеличить значение до 1100, например.

Gressie
05.07.2014, 17:53
Скомпилировалась без ошибок, пойду протестить

- - - Добавлено - - -

Всё хорошо но время каждую секунду прыгает, мерцает. Огромное спасибо DeiMos


SetPlayerChatBubble(i, string, 0xFF0000FF, 10.0, 1500);