- 7
- 63
E_STREAMER_CUSTUM раскрываем потанцевал!
На примере возьмём систему домов.
Система домов записана в ассоциативный массив
Коментарий Nexius
"в случае с хранением каких-то данных, привязанным к элементам, у которых глобально лимитов нет, хорошо было бы и на них каких-то фиксированных лимитов не иметь - такую возможность и даёт этот функционал. Да, тс открыл Америку, потому что тот же базовый EXTRA_ID был годами и до этого, и да, скорость обращения и записи не сравнится с тем вариантом, где мы бы хранили инфу в переменных, но этот функционал вполне полезен для своих нужд, где гибкость системы стояла бы превыше скорости её выполнения для человека, который намеревается это заюзать. Ну, например, если у него есть какие-то данные, которые не так часто нужно узнавать и перезаписывать, при этом они должны быть прикручены к стримерскому элементу и без свистоплясок автоматически удаляться вместе с удалением элемента, а количество этих элементов исчисляется несколькими тысячами (т.е. много) и постоянно меняется, возможно значительно"
Возьмём штатную ситуацию: игрок подбирает пикап дома и мы как скриптеры начинаем проверять пикап вот таким способом
Если закинуть на тест вот такой код станет ясно, немного медленно...
код выполнится 10.000 раз за 874 мл.сек - почти секунда!
И теперь перейдём к самой функции из за которой и затеялся данный карнавал!
Но мы будем использовать E_STREAMER_CUSTOM.
value - данные.
Так же можно использовать:
Данные функции предназначены для изменения и получения данных будь это позиция,тип,текстура, какого либо стрим объекта (объект,пикап,актёр..) но с версией 2.9.5 появилась функция E_STREAMER_CUSTOM ранее была E_STREAMER_EXTRA_ID, которая даёт возможность нам "как бы прикрепить переменную к объекту" зная id объекта мы сможем получить как из моего примера id дома, появляется повод отказаться от циклов.
E_STREAMER_CUSTOM(0xFF) 0xFF - это наша как бы адрес переменной для объекта она должна быть уникальна.
Модернизируем наш код...
Стример будет выбрасывать вот такое предупреждение
Это будет означать, что переменная не существует.
Перед использованием E_STREAMER_CUSTOM рекомендуют проверять существует ли вообще такой адрес Streamer_HasIntData.
Я просто отключу данное сообщение с помощью функции Streamer_ToggleErrorCallback(true); в GameModeInit или OnFilterScriptInit().
При тестировании сразу поймём, почему стоит использовать E_STREAMER_CUSTOM
Результат
Самому не верится, что в 400 раз быстрее делаем выводы.
Если посмотреть мои работы, они очень сырые и возможно данная статья сырая, так как полного знания терминов адрес это или переменная, как назвать правильно - не знаю. Я с удовольствием прочитаю отзыв каждого из вас, внесу правки. Возможно данный способ уже все используют. Не общаюсь с про скриптерами, но пока примеров с данным функционалом не встречал.
Какой я вижу потанцевал в этом?
Потенциал огромен. По сути мы можем использовать динамическую память стримера которую предоставил Y_Lees очень легко и просто.
Мы можем дать возможность игрокам выбрасывать предметы создавать их как объект и эти объекты не придётся заносить в массив. А потом бегать по массиву и искать является ли он предметом или нет, что это за объект. В этот момент чувствую себя неандертальцем с палкой в руке. Объект - есть переменная.
Так же мы можем привязывать группу объектов к объекту (под объектом имею введу любой элемент стримера) и удалять их синхронно. Создавать пикапы из нескольких объектов(элементов) вносить правки и другое как сказал без массивов и циклов.
Автор я: vawylon
На примере возьмём систему домов.
Система домов записана в ассоциативный массив
Коментарий Nexius
"в случае с хранением каких-то данных, привязанным к элементам, у которых глобально лимитов нет, хорошо было бы и на них каких-то фиксированных лимитов не иметь - такую возможность и даёт этот функционал. Да, тс открыл Америку, потому что тот же базовый EXTRA_ID был годами и до этого, и да, скорость обращения и записи не сравнится с тем вариантом, где мы бы хранили инфу в переменных, но этот функционал вполне полезен для своих нужд, где гибкость системы стояла бы превыше скорости её выполнения для человека, который намеревается это заюзать. Ну, например, если у него есть какие-то данные, которые не так часто нужно узнавать и перезаписывать, при этом они должны быть прикручены к стримерскому элементу и без свистоплясок автоматически удаляться вместе с удалением элемента, а количество этих элементов исчисляется несколькими тысячами (т.е. много) и постоянно меняется, возможно значительно"
C:
#define MAX_HOUSES 1000
enum h_data{
h_handle, // id дома
h_pickup_enter, // пикап вход в дом
h_pickup_exit, // пикап выход из дома
h_x,// позиция пикапа
h_y,// позиция пикапа
h_z// позиция пикапа
};
new house_data[MAX_HOUSE][h_data];
Возьмём штатную ситуацию: игрок подбирает пикап дома и мы как скриптеры начинаем проверять пикап вот таким способом
C:
public OnPlayerPickUpDynamicPickup(playerid, pickupid)
{
for(new i; i<MAX_HOUSE; i++)
{
if(pickupid == house[i][h_pickup_enter])
{
printf("Номер дома: %d", house_data[i][h_handle]);
break;
}
}
}
код выполнится 10.000 раз за 874 мл.сек - почти секунда!
C:
IsFind: 1
Tick count standart: 874
И теперь перейдём к самой функции из за которой и затеялся данный карнавал!
C:
Streamer_SetIntData(type, STREAMER_ALL_TAGS:id, data, value)
//type - тип объекта (объект,пикап,актёр...)
/*
STREAMER_TYPE_OBJECT (0)
STREAMER_TYPE_PICKUP (1)
STREAMER_TYPE_CP (2)
STREAMER_TYPE_RACE_CP (3)
STREAMER_TYPE_MAP_ICON (4)
STREAMER_TYPE_3D_TEXT_LABEL (5)
STREAMER_TYPE_AREA (6)
STREAMER_TYPE_ACTOR (7)
STREAMER_ALL_TAGS:id - id стримерского элемента.
data - "переменная" список стандартных:
*/
enum
{
E_STREAMER_AREA_ID,
E_STREAMER_ATTACHED_OBJECT,
E_STREAMER_ATTACHED_PLAYER,
E_STREAMER_ATTACHED_VEHICLE,
E_STREAMER_ATTACH_OFFSET_X,
E_STREAMER_ATTACH_OFFSET_Y,
E_STREAMER_ATTACH_OFFSET_Z,
E_STREAMER_ATTACH_R_X,
E_STREAMER_ATTACH_R_Y,
E_STREAMER_ATTACH_R_Z,
E_STREAMER_ATTACH_X,
E_STREAMER_ATTACH_Y,
E_STREAMER_ATTACH_Z,
E_STREAMER_COLOR,
E_STREAMER_DRAW_DISTANCE,
E_STREAMER_EXTRA_ID,
E_STREAMER_HEALTH,
E_STREAMER_INTERIOR_ID,
E_STREAMER_INVULNERABLE,
E_STREAMER_MAX_X,
E_STREAMER_MAX_Y,
E_STREAMER_MAX_Z,
E_STREAMER_MIN_X,
E_STREAMER_MIN_Y,
E_STREAMER_MIN_Z,
E_STREAMER_MODEL_ID,
E_STREAMER_MOVE_R_X,
E_STREAMER_MOVE_R_Y,
E_STREAMER_MOVE_R_Z,
E_STREAMER_MOVE_SPEED,
E_STREAMER_MOVE_X,
E_STREAMER_MOVE_Y,
E_STREAMER_MOVE_Z,
E_STREAMER_NEXT_X,
E_STREAMER_NEXT_Y,
E_STREAMER_NEXT_Z,
E_STREAMER_PLAYER_ID,
E_STREAMER_PRIORITY,
E_STREAMER_ROTATION,
E_STREAMER_R_X,
E_STREAMER_R_Y,
E_STREAMER_R_Z,
E_STREAMER_SIZE,
E_STREAMER_STREAM_DISTANCE,
E_STREAMER_STYLE,
E_STREAMER_SYNC_ROTATION,
E_STREAMER_TEST_LOS,
E_STREAMER_TYPE,
E_STREAMER_WORLD_ID,
E_STREAMER_X,
E_STREAMER_Y,
E_STREAMER_Z
}
Но мы будем использовать E_STREAMER_CUSTOM.
value - данные.
Так же можно использовать:
C:
native Streamer_GetFloatData(type, STREAMER_ALL_TAGS:id, data, &Float:result); // получить число с плавоющей точкой, Float тип
native Streamer_SetFloatData(type, STREAMER_ALL_TAGS:id, data, Float:value); // установить число с плавоющей точкой, Float тип
native Streamer_GetIntData(type, STREAMER_ALL_TAGS:id, data); // получить целое число
native Streamer_SetIntData(type, STREAMER_ALL_TAGS:id, data, value); // установить целое число
native Streamer_RemoveIntData(type, STREAMER_ALL_TAGS:id, data); // удалить "переменную"
native Streamer_HasIntData(type, STREAMER_ALL_TAGS:id, data); // существует ли что то в "переменной"
native Streamer_GetArrayData(type, STREAMER_ALL_TAGS:id, data, dest[], maxdest = sizeof dest); // получить массив
native Streamer_SetArrayData(type, STREAMER_ALL_TAGS:id, data, const src[], maxsrc = sizeof src); // записать массив
native Streamer_IsInArrayData(type, STREAMER_ALL_TAGS:id, data, value); // есть ли число в массиве
native Streamer_AppendArrayData(type, STREAMER_ALL_TAGS:id, data, value); //добавить данные в массив
native Streamer_RemoveArrayData(type, STREAMER_ALL_TAGS:id, data, value); // удалить значение value из массив
native Streamer_HasArrayData(type, STREAMER_ALL_TAGS:id, data); //существует ли массив
native Streamer_GetArrayDataLength(type, STREAMER_ALL_TAGS:id, data); //получить колличество элементов в массиве
Данные функции предназначены для изменения и получения данных будь это позиция,тип,текстура, какого либо стрим объекта (объект,пикап,актёр..) но с версией 2.9.5 появилась функция E_STREAMER_CUSTOM ранее была E_STREAMER_EXTRA_ID, которая даёт возможность нам "как бы прикрепить переменную к объекту" зная id объекта мы сможем получить как из моего примера id дома, появляется повод отказаться от циклов.
E_STREAMER_CUSTOM(0xFF) 0xFF - это наша как бы адрес переменной для объекта она должна быть уникальна.
C:
#define CUSTUM_HOUSEID 0xFF
#define E_STREAMER_HOUSE_PICKUP_ENTER E_STREAMER_CUSTOM(CUSTUM_HOUSEID)
Модернизируем наш код...
C:
#define CUSTUM_HOUSEID 0xFF
#define E_STREAMER_HOUSE_PICKUP_ENTER E_STREAMER_CUSTOM(CUSTUM_HOUSEID)
#define SetPickUpHouseHandle(%0,%1) Streamer_SetIntData(STREAMER_TYPE_PICKUP, %0, E_STREAMER_HOUSE_PICKUP_ENTER, %1)
#define GetPickUpHouseHandle(%0) Streamer_GetIntData(STREAMER_TYPE_PICKUP, %0, E_STREAMER_HOUSE_PICKUP_ENTER)
// STREAMER_TYPE_PICKUP - потому что мы работаем с пикапом;
/// SetPickUpHouseHandle(pickupid,value)
//.......
house[i][h_pickup_enter] = CreateDynamicPickup(1273, 2, house[i][h_x],house[i][h_y], house[i][h_z]);
SetPickUpHouseHandle(house[i][h_pickup_enter],i);
//.......
public OnPlayerPickUpDynamicPickup(playerid, pickupid)
{
if(GetPickUpHouseHandle(pickupid) != 0) // примечание дома должны начинаться с 1, а не 0. 0 - не валидный дом!
{
printf("Номер дома: %d", GetPickUpHouseHandle(pickupid));
return 1;
}
}
C:
*** Streamer Plugin: Streamer_GetIntData: Invalid data specified.
Это будет означать, что переменная не существует.
Перед использованием E_STREAMER_CUSTOM рекомендуют проверять существует ли вообще такой адрес Streamer_HasIntData.
Я просто отключу данное сообщение с помощью функции Streamer_ToggleErrorCallback(true); в GameModeInit или OnFilterScriptInit().
При тестировании сразу поймём, почему стоит использовать E_STREAMER_CUSTOM
C:
new pickupid = house[998][h_pickup_enter];
new = tick = GetTickCount();
new bool:isfind;
for(new loop; loop<10000; loop++)
{
if(GetPickUpHouseHandle(pickupid) == 998)
{
isfind = true;
}
}
printf("IsFind: %d", isfind);
printf("Tick count standart: %d", GetTickCount()-tick);
C:
IsFind: 1
Tick count custom: 2
Самому не верится, что в 400 раз быстрее делаем выводы.
Если посмотреть мои работы, они очень сырые и возможно данная статья сырая, так как полного знания терминов адрес это или переменная, как назвать правильно - не знаю. Я с удовольствием прочитаю отзыв каждого из вас, внесу правки. Возможно данный способ уже все используют. Не общаюсь с про скриптерами, но пока примеров с данным функционалом не встречал.
Какой я вижу потанцевал в этом?
Потенциал огромен. По сути мы можем использовать динамическую память стримера которую предоставил Y_Lees очень легко и просто.
Мы можем дать возможность игрокам выбрасывать предметы создавать их как объект и эти объекты не придётся заносить в массив. А потом бегать по массиву и искать является ли он предметом или нет, что это за объект. В этот момент чувствую себя неандертальцем с палкой в руке. Объект - есть переменная.
Так же мы можем привязывать группу объектов к объекту (под объектом имею введу любой элемент стримера) и удалять их синхронно. Создавать пикапы из нескольких объектов(элементов) вносить правки и другое как сказал без массивов и циклов.
C:
.....
new Float:x, Float:y, Float:z, Float:distance;
GetPlayerPos(playerid, x, y, z);
new pickups[1];
Streamer_GetAllVisibleItems(playerid, STREAMER_TYPE_PICKUP, pickups); // получаем список видимых пикапов сортируются по дистанции 0-самый ближайший. будем использовать самый ближайший хватит единичного размера
if(GetPickUpHouseHandle(pickups[0]) != 0)
{
Streamer_GetDistanceToItem(x,y,z, STREAMER_TYPE_PICKUP, pickups[0], distance, 3); // dimensions = 3 используем дистанцию по трём осям. можно убрать. стандарт - 3.
if(distance < 3.0)
{
printf("Рядом дом: %d", GetPickUpHouseHandle(pickups[0]));
}
}
}
.....
Автор я: vawylon
Последнее редактирование: