PDA

Просмотр полной версии : [Include] MasPickups



MassonNN
03.06.2020, 19:22
MasPickups

Удобнее, функциональнее, проще




Описание:

Данный инклуд писался мной давно для своих личных целей, я не заметил похожих библиотек, разве что некоторые другие подобия, которые мне показались не достаточно удобными и функциональным да и их поддержка уже закончилась, поэтому я решил заняться этим. Инклуд находится в данный момент в режиме тестирования, обо всех багах прошу сообщать мне на гитхаб или в эту тему, постараюсь фиксить оперативно.


Зависимости:
Streamer


Совместим с:
YSF
ePickups
YSI




Функции:



PickupCreate(pick_Function[23], pick_Model, pick_Type, Float:pick_X, Float:pick_Y, Float:pick_Z, pick_VirtualWorld = 0, pick_Interior = 0, pick_Playerid = 0, Float:streamdistance = STREAMER_PICKUP_SD)
Создает динамический пикап, все аргументы, кроме pick_Function, взяты именно с функции создания пикапов, поэтому их объяснять не буду.
pick_Function - функция, которая будет вызвана при взятии пикапа.
Возвращает: id созданного пикапа



Пример:


PickupCreate("testPickup", 19197, 23, 0.0, 0.0, 0.0, 0);

* Примечание Функцию, которую Вы укажете при создании пикапа нужно использовать следующим образом:


new PolicePickup;
OnGamemodeInit() {
PolicePickup = PickupCreate("dynPoliceDetective", 19197, 23, 2545.0198, -2114.5449, 11.0047, 0);
PickupSetAntiFlood(PolicePickup, 10);

return 1;
}

Pickup:dynPoliceDetective(playerid, pickupid) { // указывать Pickup: обязательно
return 1;
}



DeletePickup(id)
Удаляет пикап
id - id пикапа
Возвращает: 0, если пикап не был найден, в остальных случаях 1




PickupSetAntiFlood(id, interval)
Устанавливает антифлуд для пикапа
id - id пикапа
interval - количество времени в секундах для действия антифлуда после подбора пикапа
Возвращает: в любом случае 1


Пример:



new test = PickupCreate("testPickup", 19197, 23, 0.0, 0.0, 0.0, 0);
PickupSetAntiFlood(test , 3);



GetPickupTypeEx(id)
Узнает тип пикапа
id - id пикапа
Возвращает: id типа пикапа


Пример:



new test = PickupCreate("testPickup", 19197, 23, 0.0, 0.0, 0.0, 0);
new model = GetPickupTypeEx(test); // в данном случае 23




GetPickupVirtualWorldEx(id)
Узнает виртуальный мир пикапа
id - id пикапа
Возвращает: id виртуального мира


Пример:



new test = PickupCreate("testPickup", 19197, 23, 0.0, 0.0, 0.0, 0);
new vw = GetPickupVirtualWorldEx(test ); // в данном случае 0




GetPickupPlayerid(id)
Узнает id игрока для которого был создан пикап
id - id пикапа
Возвращает: id игрока


Пример:



new test = PickupCreate("testPickup", 19197, 23, 0.0, 0.0, 0.0, 0);
new playerid = GetPickupPlayerid(test ); // в данном случае 0



PickupEmitate(playerid, id)
Эмитирует взятие пикапа игроком
playerid - id игрока
id - id пикапа
Возвращает: 0, если функция не была найдена


Пример:



new test = PickupCreate("testPickup", 19197, 23, 0.0, 0.0, 0.0, 0);
PickupEmitate(playerid, test );



SetPickupModel(&id, model)
Устанавливает пикапу новую модель
id - пикап
model - модель
Возвращает: всегда 1



SetPickupType(&id, type)
Устанавливает пикапу новый тип
id - пикап
type - тип
Возвращает: всегда 1



SetPickupVirtualWorld(&id, world)
Устанавливает пикапу новый мир
id - пикап
world - мир
Возвращает: всегда 1



SetPickupInterior(&id, interior)
Устанавливает пикапу новый интерьер
id - пикап
interior - тип
Возвращает: всегда 1



PickupSetTag(bool:is_on_key = false, antiflood = 0, sync = INVALID_PICKUP)
Устанавливает последнему созданному пикапу определенные значения для работы
is_on_key - пикап на кнопку или нет,
antiflood - секунд антифлуда,
sync - синхронизация с другим пикапом
Возвращает: всегда 1





Теперь переходим к интересному:



Синхронизания двух пикапов
Нужно для пикапов входа и выхода из здания/в здание. Один пикап телепортирует игрока на другой пикап, также и наоборот. Виртуальный мир и интерьеры также синхронизированы.


SyncPickup(syncid, withid)
Синхронизирует два пикапа
syncid - первый пикап
withid - второй пикап
Возвращает: всегда 1


Пример синхронизации:


new tcd = PickupCreate("", 19197, 23, 2507.3115, -2125.3401, 11.0047, 0);
PickupSetAntiFlood(tcd, 3);
new tsd = PickupCreate("", 19197, 23, 2507.3115, -2130.3401, 11.0047, 0);
PickupSetAntiFlood(tsd, 3);
SyncPickup(tcd, tsd);


Внимание! По умолчанию, для того, чтобы игрок не катался по пикапам, анти флуд у синхронизированных пикапов стоит 3 секунды, поэтому устанавливать антифлуд в этом случае не обязательно.



OnPlayerUseSyncPickup(playerid, pickupid, syncpickupid)
Вызывается, когда игрок телепортируется по синхронизированному пикапу.
playerid - id игрока
pickupid - id пикапа
syncpickupid - id пикапа, к которому игрок телепортировался


Пикап на клавишу
Пикап будет срабатывать только при нажатии на клавишу, которую можно поменять.



PickupSetOnKey(id)
Пикап будет срабатывать только при нажатой клавише
id - пикап
Возвращает: всегда 1


По умолчанию клавиша - левый альт, ее можно поменять вставив перед #include:


#define MAS_PCK_KEY 1024 // вместо 1024 код вашей клавиши


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


static const _mas_KEY_PRESS_TEXT[] = "{ADFF2F}Нажмите левый альт";



PickupSetOnPickup(id)
Противоположен прошлой функции, пикап будет срабатывать как обычно
id - пикап
Возвращает: 0, если не был найден, в остальных случаях 1




Текущая версия: 0.7 (Финальный релиз)
- Добавлены функции DeletePickup, PickupSetOnPickup, PickupSetTag
- Исправлены баги, а также небольшая оптимизация
- Добавлена совместимость с foreach, если он подключен, то будет дополнительная оптимизация.
- Отредактирована совместимость с YSF, теперь если он подключен, то будет дополнительная оптимизация.
- Изменен стандартный размер динамической зоны для срабатывания пикапа, теперь он меньше и работает лучше.



Прошлая версия: 0.6
- Добавлены функции SetPickupModel, SetPickupType, SetPickupVirtualWorld и SetPickupInterior
- Добавлена возможность сделать пикап работающим только по нажатию клавиши через функцию PickupSetOnKey
- Добавлена возможность полной настройки данных:
Можно задефайнить MAS_PCK_TEXT_KEY до подключения инклуда, это заменит текст-подсказку возле пикапа, работающем только по клавише.
Аналогично с PICKUP_SYNC_STANDART_ANTIFLOOD. Задефайнив новое значение, можно изменить стандартный антифлуд у синхронизированных пикапов (он добавляется к тому, что указан в PickupSetAntiFlood)




Скачать последнюю версию (https://github.com/MassonNN/mas_pickups/releases/download/0.7/mas_pickups.inc)
GitHub (https://github.com/MassonNN/mas_pickups)


Автор: Masson
Публикация в иных источниках без согласия автора запрещена.

tnc
03.06.2020, 20:48
1) Некоторые функции объявлены без ключевого слова stock, если я не буду вызывать (например: SetPickupModel), то компилятор сообщит, что я не использовал функцию
2) MAX_PICKUPS - довольно часто встречаемое название. Советую добавить префикс (например: MASPKP_)
3) Какой смысл от continue?

for(new i; i < MAX_PICKUPS; i++) {
if(IsPlayerInDynamicArea(playerid, getPickup[i][pickArea])) {
PickupEmitate(playerid, i);
} else continue;
}

4) getPickup - как-то неоч?

P.S: это быстрым взглядом, то что увидел.
P.S.S: есть tdw_pickup (https://github.com/tdworg/samp-include-pickup/blob/master/tdw_pickup.inc). Почему не устроил?

MassonNN
03.06.2020, 21:45
1) Некоторые функции объявлены без ключевого слова stock, если я не буду вызывать (например: SetPickupModel), то компилятор сообщит, что я не использовал функцию
2) MAX_PICKUPS - довольно часто встречаемое название. Советую добавить префикс (например: MASPKP_)
3) Какой смысл от continue?

for(new i; i < MAX_PICKUPS; i++) {
if(IsPlayerInDynamicArea(playerid, getPickup[i][pickArea])) {
PickupEmitate(playerid, i);
} else continue;
}

4) getPickup - как-то неоч?

P.S: это быстрым взглядом, то что увидел.
P.S.S: есть tdw_pickup (https://github.com/tdworg/samp-include-pickup/blob/master/tdw_pickup.inc). Почему не устроил?
1). никогда не встречался с такими варнингами, если честно, проверить это не могу в данный момент, если это вызывает проблемы на обычном компиляторе, то могу исправить, у меня все ок

2). Я использую именно MAX_PICKUP, так как это встроенная в самп константа, соответственно, чтобы не создавать отдельный идентификатор и в будущем заморачиваться с этим, я оставил как есть и использую системные id.

3). ну смысла, наверное, никакого, просто привычка.

4). могу поменять, но если честно какая разница, типа может быть использован?

по поводу tdw, не видел вообще такой библиотеки ранее, но пробежавшись по коду могу сказать, что, наверное, моя библиотека предназначена более для практического использования (те же синхронизированные пикапы, антифлуд и т.д.), остальной функционал в целом одинаковый. И да, сейчас обнаружил, что библиотека старая и в ней нет поддержки динамических пикапов

MassonNN
05.06.2020, 09:27
Текущая версия: 0.7 (Финальный релиз)
- Добавлены функции DeletePickup, PickupSetOnPickup, PickupSetTag
- Исправлены баги, а также небольшая оптимизация
- Добавлена совместимость с foreach, если он подключен, то будет дополнительная оптимизация.
- Отредактирована совместимость с YSF, теперь если он подключен, то будет дополнительная оптимизация.
- Изменен стандартный размер динамической зоны для срабатывания пикапа, теперь он меньше и работает лучше.

Основная разработка окончена, буду работать только над оптимизацией, фиксами и т.д.

tnc
05.06.2020, 15:56
Посмотрел ещё раз код.

1) Для "L.ALT" есть константа: KEY_WALK

#if !defined MAS_PCK_KEY
#define MAS_PCK_KEY 1024 // L.ALT
#endif


2) Точно тут не должно быть так?


// Optionall
#if !defined _mas_KEY_PRESS_TEXT
static const _mas_KEY_PRESS_TEXT[] = !"{ADFF2F}Press alt";
#endif


3)

if(strlen(pick_Function) > MAX_PICK_FUNC_NAME) return 1;
if(strlen(pick_Function))


?

new len = strlen(pick_Function);


Участок кода (https://github.com/MassonNN/mas_pickups/blob/master/mas_pickups.inc#L133-L180)

4) Почему тут отрицание перед "членом" перечисления?


if(getPickup[id][!pickModel]) return 0;


5) Параметры лучше пропускать через именованные параметр (https://github.com/MassonNN/mas_pickups/blob/master/mas_pickups.inc#L366-L375)ы (через .)

6) Параметры у функции, лучше всего указывать через const (которые дальше не должны изменятся во время работы функции)

7) Зачем ты делаешь дополнительные блоки кода (условия), когда можно без них (https://github.com/MassonNN/mas_pickups/blob/master/mas_pickups.inc#L559)?

Что мешает сделать так:


IsPickupCreated(id) {
if (getPickup[id][pickClass] > 0) {
return 1;
}
return 0;
}


if (newkeys == MAS_PCK_KEY && IsPlayerInAnyDynamicArea(playerid)) {
for (new i = 0; i < MAX_PICKUPS; i++) {
if (IsPlayerInDynamicArea(playerid, getPickup[i][pickArea])) {
PickupEmitate(playerid, i);
}
}
}

Или так:

if (newkeys == MAS_PCK_KEY && IsPlayerInAnyDynamicArea(playerid)) {
for (new i = 0; i < MAX_PICKUPS; i++) {
if (IsPlayerInDynamicArea(playerid, getPickup[i][pickArea]) == INVALID_STREAMER_ID) {
continue;
}
PickupEmitate(playerid, i);
}
}

MassonNN
05.06.2020, 19:19
Посмотрел ещё раз код.

1) Для "L.ALT" есть константа: KEY_WALK

#if !defined MAS_PCK_KEY
#define MAS_PCK_KEY 1024 // L.ALT
#endif


2) Точно тут не должно быть так?


// Optionall
#if !defined _mas_KEY_PRESS_TEXT
static const _mas_KEY_PRESS_TEXT[] = !"{ADFF2F}Press alt";
#endif


3)

if(strlen(pick_Function) > MAX_PICK_FUNC_NAME) return 1;
if(strlen(pick_Function))


?

new len = strlen(pick_Function);


Участок кода (https://github.com/MassonNN/mas_pickups/blob/master/mas_pickups.inc#L133-L180)

4) Почему тут отрицание перед "членом" перечисления?


if(getPickup[id][!pickModel]) return 0;


5) Параметры лучше пропускать через именованные параметр (https://github.com/MassonNN/mas_pickups/blob/master/mas_pickups.inc#L366-L375)ы (через .)

6) Параметры у функции, лучше всего указывать через const (которые дальше не должны изменятся во время работы функции)

7) Зачем ты делаешь дополнительные блоки кода (условия), когда можно без них (https://github.com/MassonNN/mas_pickups/blob/master/mas_pickups.inc#L559)?

Что мешает сделать так:


IsPickupCreated(id) {
if (getPickup[id][pickClass] > 0) {
return 1;
}
return 0;
}


if (newkeys == MAS_PCK_KEY && IsPlayerInAnyDynamicArea(playerid)) {
for (new i = 0; i < MAX_PICKUPS; i++) {
if (IsPlayerInDynamicArea(playerid, getPickup[i][pickArea])) {
PickupEmitate(playerid, i);
}
}
}

Или так:

if (newkeys == MAS_PCK_KEY && IsPlayerInAnyDynamicArea(playerid)) {
for (new i = 0; i < MAX_PICKUPS; i++) {
if (IsPlayerInDynamicArea(playerid, getPickup[i][pickArea]) == INVALID_STREAMER_ID) {
continue;
}
PickupEmitate(playerid, i);
}
}


1 - не вижу разницы особо
2 - исправим
3 - исправим
4 - потому что значение в нем принимается противоположным
5 - чем? Если только тем, что просто можно переставить, то для меня удобнее так, как уже привык
6 - таких параметров почти нет, если говорить о строках, для целочисленных разницы вроде нет
7 - уже отвечал на этот вопрос, просто привычка, в некоторых языках условные конструкции надёжнее

tnc
06.06.2020, 01:40
1 - не вижу разницы особо
представим, что Kalcor в следующих версиях сменить значение, то вам придется паттчить инклуд, а если будет константа, то ничего не нужно будет менять.


4 - потому что значение в нем принимается противоположным

Эмм?


5 - чем? Если только тем, что просто можно переставить, то для меня удобнее так, как уже привык

Так видно, какие параметры пропущены (потому что они именованные)


6 - таких параметров почти нет, если говорить о строках, для целочисленных разницы вроде нет

Есть SyncPickup, например и подобные вспомогательные функции
7 - уже отвечал на этот вопрос, просто привычка, в некоторых языках условные конструкции надёжнее[/QUOTE]

WTF? В каких таких языках? Это просто не нужно. Усложняешь код

MassonNN
06.06.2020, 14:45
представим, что Kalcor в следующих версиях сменить значение, то вам придется паттчить инклуд, а если будет константа, то ничего не нужно будет менять.

Эмм?

Так видно, какие параметры пропущены (потому что они именованные)

Есть SyncPickup, например и подобные вспомогательные функции
7 - уже отвечал на этот вопрос, просто привычка, в некоторых языках условные конструкции надёжнее

WTF? В каких таких языках? Это просто не нужно. Усложняешь код[/QUOTE]

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

SyncPickup не принимает строковых параметров, а про целочисленные я уже сказал, разницы не особо вижу


Инструкции, входящие в программу, могут исполняться как последовательно, одна за другой, так и одновременно; как однократно, так и многократно; последовательность исполнения инструкций может совпадать с последовательностью их расположения в записи программы или не совпадать, а также зависеть как от текущего состояния вычислителя, исполняющего программу, так и от внешних событий, образовывая, таким образом, разнообразные порядки выполнения инструкций. (https://ru-wikipedia-org.turbopages.org/s/ru.wikipedia.org/wiki/%D0%9F%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D0%BA_%D0%B2%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F?lite=1)

tnc
06.06.2020, 14:59
WTF? В каких таких языках? Это просто не нужно. Усложняешь код

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

SyncPickup не принимает строковых параметров, а про целочисленные я уже сказал, разницы не особо вижу


Инструкции, входящие в программу, могут исполняться как последовательно, одна за другой, так и одновременно; как однократно, так и многократно; последовательность исполнения инструкций может совпадать с последовательностью их расположения в записи программы или не совпадать, а также зависеть как от текущего состояния вычислителя, исполняющего программу, так и от внешних событий, образовывая, таким образом, разнообразные порядки выполнения инструкций. (https://ru-wikipedia-org.turbopages.org/s/ru.wikipedia.org/wiki/%D0%9F%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D0%BA_%D0%B2%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F?lite=1)

Зачем ты делаешь дополнительное условие? Ты можешь объяснить это? Если и так цикл пойдет дальше и не зайдет в блок кода под if'ом, но ты все равно делаешь continue / return. На счет Калкора: это частный случай, лучше всегда использовать константы.

Мне интересно: ты и в переменных, где хранится ник используешь 24 + 1, вместо MAX_PLAYER_NAME + 1?

P.S: Я не вижу смысла продолжать дальше доказывать, если ты все равно не примешь информацию.

Nexius_Tailer
06.06.2020, 15:48
Инструкции, входящие в программу, могут исполняться как последовательно, одна за другой, так и одновременно; как однократно, так и многократно; последовательность исполнения инструкций может совпадать с последовательностью их расположения в записи программы или не совпадать, а также зависеть как от текущего состояния вычислителя, исполняющего программу, так и от внешних событий, образовывая, таким образом, разнообразные порядки выполнения инструкций. (https://ru-wikipedia-org.turbopages.org/s/ru.wikipedia.org/wiki/%D0%9F%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D0%BA_%D0%B2%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F?lite=1)
Если тут ты пытался сослаться на многопоточность (под фразой "инструкции могут исполняться одновременно"), то эта история вообще не про самп

MassonNN
06.06.2020, 16:55
Зачем ты делаешь дополнительное условие? Ты можешь объяснить это? Если и так цикл пойдет дальше и не зайдет в блок кода под if'ом, но ты все равно делаешь continue / return. На счет Калкора: это частный случай, лучше всегда использовать константы.

Мне интересно: ты и в переменных, где хранится ник используешь 24 + 1, вместо MAX_PLAYER_NAME + 1?

P.S: Я не вижу смысла продолжать дальше доказывать, если ты все равно не примешь информацию.

Ещё один и надеюсь последний раз, "зачем ты делаешь дополнительное условие?" - я ответил ссылкой на сообщение про другие языки, которые ты у меня спросил, с самого начала сказал: имею привычку, не более. Коду от этого не горячо не холодно, можно конечно устроить проверку скорости, но даже если будет разница, то она крайне незначительна.

По поводу констант: эта константа в общем то настраиваемая и, я понимаю там MAX_PLAYERS, которое постоянно меняется или MAX_PLAYER_NAME, их изменения я понимаю, они разные и зависят от версии сервера, нужно учитывать. Но константа клавиши? Серьезно? Она все версии была одинаковая. Более того, если вдруг калкор действительно изменит этот макрос, то впринципе мне и менять ничего не надо, скрипт подразумевает самостоятельную настройку этой клавиши по удобству.

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


Если тут ты пытался сослаться на многопоточность (под фразой "инструкции могут исполняться одновременно"), то эта история вообще не про самп

Я и не про Pawn говорил. Ко мне претензия по поводу употребления дополнительных условных конструкций, я сказал в самом первом посте, что это просто привычка, которая досталась из Java, ведь там условные конструкции надежнее чистого кода из-за непоследовательного выполнения

Nexius_Tailer
07.06.2020, 15:02
Я и не про Pawn говорил. Ко мне претензия по поводу употребления дополнительных условных конструкций, я сказал в самом первом посте, что это просто привычка, которая досталась из Java, ведь там условные конструкции надежнее чистого кода из-за непоследовательного выполнения
С такими привычками можно и переменные при инициализации начать обнулять, и в принципе без табуляции кодить (ведь есть же примеры таких яп). Привычка привычкой, но это павн, а не java или любой другой язык, и гораздо эффективнее и правильнее придерживаться логики того языка, на котором пишешь. Просто хотя бы потому, что если ты, например, и в Java переносил бы привычки с pawn'а, то там это скорее всего уже к чему-то более серьёзному привело.

Daniel_Cortez
07.06.2020, 16:13
имею привычку, не более
Вариант того, что привычки могут быть вредными, конечно же, не рассматривается... Ясно =)

Изначально зашёл в эту тему, чтобы поздравить с первым релизом на форуме, но такая реакция на советы и объективную критику отбивает всякое желание.

P.S.: Но за пример ошибки с отрицанием элемента перечисления (getPickup[id][!pickModel]) всё же спасибо. Пару месяцев назад хотел сделать для компилятора варнинг, который мог бы такое отлавливать, но забросил идею, придя к выводу, что такого рода ляп нельзя допустить случайно. Похоже, я ошибался.

MassonNN
07.06.2020, 18:37
Вариант того, что привычки могут быть вредными, конечно же, не рассматривается... Ясно =)

Изначально зашёл в эту тему, чтобы поздравить с первым релизом на форуме, но такая реакция на советы и объективную критику отбивает всякое желание.

P.S.: Но за пример ошибки с отрицанием элемента перечисления (getPickup[id][!pickModel]) всё же спасибо. Пару месяцев назад хотел сделать для компилятора варнинг, который мог бы такое отлавливать, но забросил идею, придя к выводу, что такого рода ляп нельзя допустить случайно. Похоже, я ошибался.

Я и не говорил, что привычка хорошая. Остальные замечания, которые действительно могли сказаться на работе кода я уже исправил и они ждут будущего релиза. Отрицание элемента перечисления всегда работало, поэтому и не трогал, в любом случае уже тоже исправил. А по поводу критики: я принял всю критику, даже с константой, хотя считаю это не сильно нужным.