PDA

Просмотр полной версии : [Function] SetPlayerTimeSkin - скин на время



Alanchick
25.04.2016, 21:17
Доброго времени суток, Ув. пользователи Pro-Pawn.Ru!
На досуге пришла идея реализовать функцию, которая будет выдавать скин игроку на время.
Собственно, не долго думая, я решил это сделать.

SetPlayerTimeSkin(playerid, skinid, time);
playerid - id игрока;
skinid - id скина;
time - время(в секундах);

Код функции:



stock SetPlayerTimeSkin(playerid, skin, time)
{
// умножаем time на 1000, т.е.
// переводим в секунды
time = time*1000;
// в переменную old_skin записываем
// нынешний id скина (дабы его потом вернуть игроку)
new old_skin = GetPlayerSkin(playerid);
// таймер
SetTimerEx("OnTimeToSkinFinished", time, false, "ii", playerid, old_skin);
// в итоге выдаем указанному игроку
// указанный скин
return SetPlayerSkin(playerid, skin);
}

forward OnTimeToSkinFinished(playerid, old_skin);
public OnTimeToSkinFinished(playerid, old_skin)
{
// спустя указанное время - возвращаем
// игроку старый скин
SetPlayerSkin(playerid, old_skin);
}


Пример использования (команда /setskin):



CMD:setskin(playerid, params[])
{
new targetid, // переменная ID игрока
skin, // переменная ID нового скина
time; // переменная времени
// если не введен один из параметров - выводится текст
if(sscanf(params, "ddd", targetid, skin, time))
return SendClientMessage(playerid, -1,
!"Введите: /setskin [ID игрока] [ID скина] [время в секундах]");
// в итоге выдаем указанному игроку указанный скин на указанное время.
SetPlayerTimeSkin(targetid, skin, time);
return true;
}




Жду адекватной критики.
Автор: Alanchick.
Большое спасибо за помощь в реализации: Untonyst (http://pro-pawn.ru/member.php?4123-Untonyst).

wAx
25.04.2016, 21:35
stock SetPlayerTempSkin(playerid, skin, time)
{
// таймер
SetTimerEx("OnTimeToSkinFinished", time*1000, false, "ii", playerid, GetPlayerSkin(playerid));
return SetPlayerSkin(playerid, skin);
}

заменил time, на сокращенное temporary (временный)

Alanchick
25.04.2016, 21:44
stock SetPlayerTempSkin(playerid, skin, time)
{
// таймер
SetTimerEx("OnTimeToSkinFinished", time*1000, false, "ii", playerid, GetPlayerSkin(playerid));
return SetPlayerSkin(playerid, skin);
}

заменил time, на сокращенное temporary (временный)

По поводу самой функции что можешь сказать?

wAx
25.04.2016, 21:46
SetPlayerSkin(playerid, skinid, time);
playerid - id игрока;
skinid - id скина;
time - время(в секундах);
поменяй вот здесь вот название стандартной функции на свою.

Desulaid
25.04.2016, 22:05
Смысла в объявлении переменной old_skin нет. Ты используешь функцию один раз.

Иван Бубнов
26.04.2016, 14:37
А что если так:
У игрока до смены скина с помощью /setskin был ид 73, а затем после /setskin купил другой скин (ид 99), а затем ему дали снова новый скин через /setskin.

По этому предлагаю:


/*
Пример использования:
CMD:setskin(playerid, params[])
{
new targetid, // переменная ID игрока
skin, // переменная ID нового скина
time; // переменная времени
// если не введен один из параметров - выводится текст
if(sscanf(params, "ddd", targetid, skin, time))
return SendClientMessage(playerid, -1,
!"Введите: /setskin [ID игрока] [ID скина] [время в секундах]");
// в итоге выдаем указанному игроку указанный скин на указанное время.
SetPlayerSkin(targetid, skin, time);
return true;
}
*/
new timerskins[MAX_PLAYERS];

stock SetPlayerTimeSkin(playerid, skin, time = 0)
{
if(!(0 <= playerid <= MAX_PLAYERS))
return 1;
if(0 == IsPlayerConnected(playerid))
return 1;
if(time != 0)
{
if(timerskins[playerid] != -2)
KillTimer(timerskins[playerid]);
timerskins = SetTimerEx("OnTimeToSkinFinished", time * 1000, false, "ii", playerid, skin);
SetPlayerSkin(playerid, skin);
}
SetPlayerSkin(playerid, skin);

return 1;
}
#if defined _ALS_SetPlayerSkin // Перехватчик
#undef SetPlayerSkin
#else
#define SetPlayerTimeSkin
#endif
#define SetPlayerSkin SetPlayerTimeSkin

public OnPlayerConnect(playerid)
{
timerskins[playerid] = -2;
return 1;
}

public OnPlayerDisconnect(playerid)
{
timerskins[playerid] = -2;
return 1;
}

forward OnTimeToSkinFinished(playerid, old_skin);
public OnTimeToSkinFinished(playerid, old_skin)
{
if(0 == IsPlayerConnected(playerid))
return 1;
SetPlayerSkin(playerid, old_skin);
return 1;
}

DeimoS
26.04.2016, 15:05
// умножаем time на 1000, т.е.
// переводим в секунды
time = time*1000;
// в переменную old_skin записываем
// нынешний id скина (дабы его потом вернуть игроку)
new old_skin = GetPlayerSkin(playerid);

https://pp.vk.me/c543107/v543107995/1015f/uZfmpfEO1_E.jpg

Nexius_Tailer
26.04.2016, 15:56
// умножаем time на 1000, т.е.
// переводим в секунды
time = time*1000;
// в переменную old_skin записываем
// нынешний id скина (дабы его потом вернуть игроку)
new old_skin = GetPlayerSkin(playerid);

https://pp.vk.me/c543107/v543107995/1015f/uZfmpfEO1_E.jpg
Что зачем? Время переводить, или скин запоминать?
Первое, очевидно, для удобства. Нет смысла ставить скин на 200 мс. А без второго это работать не будет. Если конечно не имеется в виду объявление переменной, но про это уже написали.

Дополню:

А что если так:
У игрока до смены скина с помощью /setskin был ид 73, а затем после /setskin купил другой скин (ид 99), а затем ему дали снова новый скин через /setskin.

По этому предлагаю:


/*
Пример использования:
CMD:setskin(playerid, params[])
{
new targetid, // переменная ID игрока
skin, // переменная ID нового скина
time; // переменная времени
// если не введен один из параметров - выводится текст
if(sscanf(params, "ddd", targetid, skin, time))
return SendClientMessage(playerid, -1,
!"Введите: /setskin [ID игрока] [ID скина] [время в секундах]");
// в итоге выдаем указанному игроку указанный скин на указанное время.
SetPlayerSkin(targetid, skin, time);
return true;
}
*/
new timerskins[MAX_PLAYERS];

stock SetPlayerTimeSkin(playerid, skin, time = 0)
{
if(time == 0)
{
if(timerskins[playerid] != 0)
KillTimer(timerskins[playerid]);
timerskins = SetTimerEx("OnTimeToSkinFinished", time * 1000, false, "ii", playerid, skin);
SetPlayerSkin(playerid, skin);
}
SetPlayerSkin(playerid, skin);
return 1;
}
#if defined _ALS_SetPlayerSkin // Перехватчик
#undef SetPlayerSkin
#else
#define SetPlayerTimeSkin
#endif
#define SetPlayerSkin SetPlayerTimeSkin

public OnPlayerConnect(playerid)
{
timerskins[playerid] = 0;
return 1;
}

public OnPlayerDisconnect(playerid)
{
timerskins[playerid] = 0;
return 1;
}

forward OnTimeToSkinFinished(playerid, old_skin);
public OnTimeToSkinFinished(playerid, old_skin)
{
if(0 == IsPlayerConnected(playerid))
return 1;
SetPlayerSkin(playerid, old_skin);
return 1;
}

Этот вариант вообще по моему не нужен, ибо должна существовать простая функция, которая будет ставить его без ограничений по времени. Да и к тому же, если ввести 0 в аргумент time, то это работать не будет вообще (скорее всего в проверке "time == 0" подразумевалось "time != 0").
И да, таймеры начинаются с нуля, поэтому, ещё одно: массиву "timerskins" нужно присваивать -1 и сверять в "if(timerskins[playerid] != 0)" не с 0, а с -1.

А, и ещё вдогонку. При создании функций, которые заменяют стандартные, проверяйте вводные данные (параметры) на валидность! Я же могу просто ввести, например, в качестве playerid'а 59869546 и хорошо от этого уже не будет.

DeimoS
26.04.2016, 16:38
Что зачем? Время переводить, или скин запоминать?
Первое, очевидно, для удобства. Нет смысла ставить скин на 200 мс. А без второго это работать не будет. Если конечно не имеется в виду объявление переменной, но про это уже написали.

Как про переменную, так и про вынос перемножения в отдельное действие. Либо ты просто обращаешься к значению переменной и потом умножаешь это значение на 1000, либо ты сначала обращаешься к значению переменной, умножаешь его на 1000, сохраняешь и потом опять обращаешься к значению переменной... "Слышу звон, да не знаю где он"

Nexius_Tailer
26.04.2016, 16:47
Как про переменную, так и про вынос перемножения в отдельное действие. Либо ты просто обращаешься к значению переменной и потом умножаешь это значение на 1000, либо ты сначала обращаешься к значению переменной, умножаешь его на 1000, сохраняешь и потом опять обращаешься к значению переменной... "Слышу звон, да не знаю где он"
Ну это мелочи уже. И поговорка здесь не к месту

Иван Бубнов
26.04.2016, 18:21
Что зачем? Время переводить, или скин запоминать?
Первое, очевидно, для удобства. Нет смысла ставить скин на 200 мс. А без второго это работать не будет. Если конечно не имеется в виду объявление переменной, но про это уже написали.

Дополню:

Этот вариант вообще по моему не нужен, ибо должна существовать простая функция, которая будет ставить его без ограничений по времени. Да и к тому же, если ввести 0 в аргумент time, то это работать не будет вообще (скорее всего в проверке "time == 0" подразумевалось "time != 0").
И да, таймеры начинаются с нуля, поэтому, ещё одно: массиву "timerskins" нужно присваивать -1 и сверять в "if(timerskins[playerid] != 0)" не с 0, а с -1.

А, и ещё вдогонку. При создании функций, которые заменяют стандартные, проверяйте вводные данные (параметры) на валидность! Я же могу просто ввести, например, в качестве playerid'а 59869546 и хорошо от этого уже не будет.

Пускай делают 59869546. Для того кто держит сервер, это не понадобится. А на счет таймеров, я был более чем уверен, что у этих таймеров не будет ид 0 :3 Ибо у нынешних серверов обязательно найдется таймер, который уже занял ИД 0. На счет тайма вы не ошиблись.

Однако уже все сделал как надо) Спс

DeimoS
26.04.2016, 18:52
Ну это мелочи уже. И поговорка здесь не к месту

Ну тогда забыл объявитьмассив на 1000 ячеек и цикл в 5 миллиардов итераций сделать. Мелочь, а приятно

Nexius_Tailer
26.04.2016, 19:08
Ну тогда забыл объявитьмассив на 1000 ячеек и цикл в 5 миллиардов итераций сделать. Мелочь, а приятно
"Раздувать из мухи слона". Есть некие объективные границы между мелочью и обратному ей, по моему даже подсознательно это должно быть понятно.


Пускай делают 59869546. Для того кто держит сервер, это не понадобится.
В любом случае, это делать не сложно, и это уж точно того стоит.

Вот пример, как проверять все параметры на валидность сразу в подменяемой функции:

stock SetPlayerTimeSkin(playerid, skin, time = 0)
{
if(!SetPlayerSkin(playerid, skin)) return 0; //Обычная функция проверит всё за нас, заодно и выполним её
if(time != 0)
{
if(timerskins[playerid] != -2)
KillTimer(timerskins[playerid]);
timerskins = SetTimerEx("OnTimeToSkinFinished", time * 1000, false, "ii", playerid, skin);
SetPlayerSkin(playerid, skin);
}
return 1;
}

#if defined _ALS_SetPlayerSkin
#undef SetPlayerSkin
#else
#define SetPlayerTimeSkin
#endif
#define SetPlayerSkin SetPlayerTimeSkin

$continue$
27.04.2016, 00:00
Зачем из мс в секунды переводить?

https://pp.vk.me/c543107/v543107995/1015f/uZfmpfEO1_E.jpg

Nexius_Tailer
27.04.2016, 00:11
Зачем из мс в секунды переводить?

https://pp.vk.me/c543107/v543107995/1015f/uZfmpfEO1_E.jpg

Зачем ставить скин на миллисекунды?

https://pp.vk.me/c543107/v543107995/1015f/uZfmpfEO1_E.jpg

$continue$
27.04.2016, 00:22
Потому что это стандартная мера измерения для таймера? -_-

Зачем ставить скин на миллисекунды?

https://pp.vk.me/c543107/v543107995/1015f/uZfmpfEO1_E.jpg

Desulaid
27.04.2016, 14:35
Потому что это стандартная мера измерения для таймера? -_-

Господи, разве это так принципиально? В чем профит писать, например, /skin 11 5 1800000?

$continue$
27.04.2016, 18:45
Да. Найдите где таймеры запускаются в секундном интервале. Сниму шляпу.

Господи, разве это так принципиально? В чем профит писать, например, /skin 11 5 1800000?

Daniel_Cortez
27.04.2016, 19:45
Господи, разве это так принципиально? В чем профит писать, например, /skin 11 5 1800000?
Перевод из секунд в миллисикунды можно сделать и в команде, а не в самой функции.

Desulaid
27.04.2016, 23:02
Перевод из секунд в миллисикунды можно сделать и в команде, а не в самой функции.

Вот в чем срач. Я-то думал, что все дело в переводе времени сразу, а не как часть параметра функции (глупо). Согласен.