Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 2 1 2 ПоследняяПоследняя
Показано с 1 по 10 из 20
  1. #1
    Аватар для Nexius_Tailer
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±

    Дополнительные функции стримера / Функции манипуляции данными [Часть 1]

    Вторая часть: перейти.
    Третья часть: перейти.


    Дисклеймер

    Эта статья исключительно для тех, кто заинтересован в более глубоком изучении дополнительного функционала стримера, и не рекомендуется к прочтению, если вы используете его только для того, чтобы ставить через него свой маппинг на сервер и дальше этого он вам не нужен. Актуально для последних версий стримера (2.8.2 - 2.9.4).

    Предисловие

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

    Кстати, если вы здесь именно поэтому, то есть нуждаетесь в каком-либо функционале, коего вы не можете найти в стримере в качестве отдельных выделенных функций, то могу порекомендовать очень полезный include Streamer Functions (кликабельно), в котором есть абсолютно всё что вам нужно, и который, собственно, стал поводом для написания данной статьи.

    Далее речь пойдёт о самых, по моему мнению, важных второстепенных функциях стримера, а также подробное описание, как ими пользоваться (чтобы далее вы сами могли использовать их абсолютно где хотите, понимая то, где их использование будет действительно выгодным и нужным). В первой части, в особенности, будет знакомство с функциями манипуляции данными.

    Также это будет полезно для вас, если вы пишете какой-либо серверный модуль (include, fs), где вам нужно реализовать некую совместимость или более тесное взаимодействие со стримером. Ну или же если вы просто хотите узнать, например, как настроить лимиты для стримерских зон (которых по умолчанию нет), как поменять модель уже созданного актёра без его пересоздания (и соответственно возможного смещения его ида), или как узнать иды ближайших к игроку объектов без единого цикла с вашей стороны.

    Определения (макросы)
    для стримерских элементов


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

    Список чего-либо виден ниже:
    PHP код:
    #define STREAMER_TYPE_OBJECT (0)        //Этот макрос мы будем писать, когда нужно будет изменить какие-то данные для объекта
    #define STREAMER_TYPE_PICKUP (1)        //Этот для пикапов
    #define STREAMER_TYPE_CP (2)            //Для чекпоинтов
    #define STREAMER_TYPE_RACE_CP (3)        //Для гоночных чекпоинтов
    #define STREAMER_TYPE_MAP_ICON (4)        //Для мап-иконок (иконок на карте)
    #define STREAMER_TYPE_3D_TEXT_LABEL (5)    //Для 3D-текстов
    #define STREAMER_TYPE_AREA (6)            //Для стримерских зон
    #define STREAMER_TYPE_ACTOR (7)            //Для актёров 
    Почему выше в комментариях не написано, что типы именно для стримерских объектов, именно стримерских актёров или именно стримерских чекпоинтов? Потому что в некоторых функциях стример может работать также и с идами обычных объектов/актёров/чего-то ещё, если вдруг это понадобится, но об этом позже. В общем эти типы дают понять стримеру то, что ваш переданный ему далее ID 5 это именно ид (стримерского) пикапа, а не (стримерского) объекта или (стримерского) 3D-текста, если, к примеру, как тип вы передали именно "STREAMER_TYPE_PICKUP".

    Перечисление
    того, что можно установить стримерским элементам


    Уже знаем, что первым аргументом в большинстве функций будет конкретный тип элемента. Вторым аргументом, логично предположить, будет сам ид элемента. Хорошо, но как нам понять, какие именно данные этому иду можно будет установить или их узнать?

    Ниже показан enum, перечисляющий все данные, которые могут быть установлены большинством второстепенных функций стримера:
    PHP код:
    enum
    {
        
    E_STREAMER_AREA_ID,    //(Int) (Array) Тип данных для установки/узнавания, при котором выбранный элемент будет отображаться только в данной(ых) стримерской(их) зоне(ах) либо будет узнано, внутри какой(их) стримерской(их) зоны(ах) отображается элемент
        
    E_STREAMER_ATTACHED_OBJECT,    //(Int) Тип, при котором выбранный элемент будет прикреплён (приаттачен) к объекту либо будет узнан ID объекта, к которому он приаттачен
        
    E_STREAMER_ATTACHED_PLAYER,    //(Int) Выбранный элемент будет прикреплён (приаттачен) к игроку либо будет узнан ID игрока, к которому он приаттачен
        
    E_STREAMER_ATTACHED_VEHICLE,    //(Int) Выбранный элемент будет прикреплён (приаттачен) к машине либо будет узнан ID машины, к которой он приаттачен
        
    E_STREAMER_ATTACH_OFFSET_X,    //(Float) Тип данных, при котором производится редактирование/узнавание смещений аттача по координате X
        
    E_STREAMER_ATTACH_OFFSET_Y,    //(Float) Редактирование/узнавание смещений аттача по координате Y
        
    E_STREAMER_ATTACH_OFFSET_Z,    //(Float) Редактирование/узнавание смещений аттача по координате Z
        
    E_STREAMER_ATTACH_R_X,    //(Float) Редактирование/узнавание координат аттача по вращению X
        
    E_STREAMER_ATTACH_R_Y,    //(Float) Редактирование/узнавание координат аттача по вращению Y
        
    E_STREAMER_ATTACH_R_Z,    //(Float) Редактирование/узнавание координат аттача по вращению Z
        
    E_STREAMER_ATTACH_X,    //(Float) Узнавание координат аттача по X
        
    E_STREAMER_ATTACH_Y,    //(Float) Узнавание координат аттача по Y
        
    E_STREAMER_ATTACH_Z,    //(Float) Узнавание координат аттача по Z
        
    E_STREAMER_COLOR,    //(Int) Редактирование/узнавание цвета элемента (map-иконки, 3D-текста)
        
    E_STREAMER_DRAW_DISTANCE,    //(Float) Редактирование/узнавание дистанции прорисовки элемента
        
    E_STREAMER_EXTRA_ID,     //(Int) (Array) Редактирование/узнавание своей собственной информации, которая будет закреплена за элементом
        
    E_STREAMER_HEALTH,    //(Float) Редактирование/узнавание кол-ва здоровья (актёра)
        
    E_STREAMER_INTERIOR_ID,    //(Int) (Array) Редактирование/узнавание интерьера(ов)
        
    E_STREAMER_INVULNERABLE,    //(Int) Редактирование/узнавание неуязвимости (актёра)
        
    E_STREAMER_MAX_X,    //(Float) Редактирование/узнавание максимальной координаты X (гангзоны, стримерской зоны)
        
    E_STREAMER_MAX_Y,    //(Float) Редактирование/узнавание максимальной координаты Y (гангзоны, стримерской зоны)
        
    E_STREAMER_MAX_Z,    //(Float) Редактирование/узнавание максимальной координаты Z (стримерской зоны)
        
    E_STREAMER_MIN_X,    //(Float) Редактирование/узнавание минимальной координаты X (гангзоны, стримерской зоны)
        
    E_STREAMER_MIN_Y,    //(Float) Редактирование/узнавание минимальной координаты Y (гангзоны, стримерской зоны)
        
    E_STREAMER_MIN_Z,    //(Float) Редактирование/узнавание минимальной координаты Z (стримерской зоны)
        
    E_STREAMER_MODEL_ID,    //(Int) Редактирование/узнавание ID'а модели элемента
        
    E_STREAMER_MOVE_R_X,    //(Float) Редактирование/узнавание финишной координаты движения вращения X (объекта)
        
    E_STREAMER_MOVE_R_Y,    //(Float) Редактирование/узнавание финишной координаты движения вращения Y (объекта)
        
    E_STREAMER_MOVE_R_Z,    //(Float) Редактирование/узнавание финишной координаты движения вращения Z (объекта)
        
    E_STREAMER_MOVE_SPEED,    //(Float) Редактирование/узнавание скорости движения (объекта)
        
    E_STREAMER_MOVE_X,    //(Float) Редактирование/узнавание финишной координаты движения X (объекта)
        
    E_STREAMER_MOVE_Y,    //(Float) Редактирование/узнавание финишной координаты движения Y (объекта)
        
    E_STREAMER_MOVE_Z,    //(Float) Редактирование/узнавание финишной координаты движения Z (объекта)
        
    E_STREAMER_NEXT_X,    //(Float) Редактирование/узнавание следующей координаты X (гоночного чекпоинта)
        
    E_STREAMER_NEXT_Y,    //(Float) Редактирование/узнавание следующей координаты Y (гоночного чекпоинта)
        
    E_STREAMER_NEXT_Z,    //(Float) Редактирование/узнавание следующей координаты Z (гоночного чекпоинта)
        
    E_STREAMER_PLAYER_ID,    //(Int) (Array) Редактирование/узнавание игрока(ов), которому(ым) будет виден элемент
        
    E_STREAMER_PRIORITY,    //(Int) Редактирование/узнавание приоритета элемента
        
    E_STREAMER_ROTATION,    //(Float) Редактирование/узнавание координаты вращения Z (угла поворота актёра)
        
    E_STREAMER_R_X,    //(Float) Редактирование/узнавание координаты вращения X
        
    E_STREAMER_R_Y,    //(Float) Редактирование/узнавание координаты вращения Y
        
    E_STREAMER_R_Z,    //(Float) Редактирование/узнавание координаты вращения Z
        
    E_STREAMER_SIZE,    //(Float) Редактирование/узнавание размера элемента (чекпоинта, гоночного чекпоинта, стримерской зоны)
        
    E_STREAMER_STREAM_DISTANCE,    //(Float) Редактирование/узнавание дистанции появления элемента
        
    E_STREAMER_STYLE,    //(Int) Редактирование/узнавание стиля (map-иконки)
        
    E_STREAMER_SYNC_ROTATION,    //(Int) Редактирование/узнавание синхронизации вращения (это параметр SyncRotation в функции AttachObjectToObject)
        
    E_STREAMER_TEST_LOS,    //(Int) Редактирование/узнавание видимости сквозь объекты (3D-текстов)
        
    E_STREAMER_TYPE,    //(Int) Редактирование/узнавание типа (map-иконки, пикапа, гоночного чекпоинта)
        
    E_STREAMER_WORLD_ID,    //(Int) (Array) Редактирование/узнавание виртуального(ых) мира(ов)
        
    E_STREAMER_X,    //(Float) Редактирование/узнавание координаты X
        
    E_STREAMER_Y,    //(Float) Редактирование/узнавание координаты Y
        
    E_STREAMER_Z    //(Float) Редактирование/узнавание координаты Z

    Имейте в виду: Некоторые типы того, что можно изменить у элемента применимы только для определённых типов элементов, а не для всех! К примеру "E_STREAMER_INVULNERABLE" явно намекает на редактирование неуязвимости для актёра, и вряд ли возымеет эффект, если вы попытаетесь применить её для объекта или мап-иконки.

    Функции манипуляции данными
    Streamer_(Get/Set)(Int/Float)Data и другие


    Собственно, начнём с простого примера. Как было сказано в начале, мы имеем немалое количество функций, которые позволяют производить различные действия над объектами, актёрами, 3D-текстами и прочим, но для которых нет явных стримерских аналогов. Это такие функции, как: GetDynamicObjectModel, AttachDynamic3DTextLabelToPlayer, AttachDynamic3DTextLabelToVehicle и т.д. Что же делать, спросите вы наконец? Как их добавить или хотя-бы сделать то, что они делают, как-то самому, "вручную".

    Для этого нам на помощь приходят функции Streamer_GetIntData и Streamer_SetIntData (именно на их примере я и начну рассказ о функциях манипуляции данными).

    • Streamer_GetIntData
      Как написано в вики, эта функция узнаёт (получает) целочисленные данные стримерского элемента.

      PHP код:
      Streamer_GetIntData(typeiddata
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете узнать у элемента (из enum'а).

      Возвращает:
      Целочисленное значение данных.

      Использование (на примере реализации функции GetDynamicObjectModel):
      PHP код:
      stock GetDynamicObjectModel(objectid)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим узнать - E_STREAMER_MODEL_ID
          //По итогу: узнаём и возвращаем модель динамического объекта
          
      return Streamer_GetIntData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_MODEL_ID);

    • Streamer_SetIntData
      По информации с той же вики, эта функция устанавливает целочисленные данные для стримерского элемента.

      PHP код:
      Streamer_SetIntData(typeiddatavalue
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете установить элементу (из enum'а).
      value: Устанавливаемое целое значение.

      Возвращает:
      0 при неудаче, 1 при успешном выполнении.

      Использование (на примере реализации функции SetDynamicObjectModel):
      PHP код:
      stock SetDynamicObjectModel(objectidmodelid)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим установить - E_STREAMER_MODEL_ID
          //В четвёртый аргумент сам ID желаемой модели - modelid
          //По итогу: задаём модель динамического объекта и возвращаем результат выполнения функции
          
      return Streamer_SetIntData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_MODEL_IDmodelid);



    Как вы могли заметить, выше в enum'е со всеми перечислениями под комментариями в начале стоят "Int" или "Float" для каждого типа. Так я пометил, что нужно вызывать через Streamer_(Get/Set)IntData, а что через Streamer_(Get/Set)FloatData, чтобы у вас вдруг не возникло путаницы. Далее мы как раз рассмотрим функции Streamer_GetFloatData и Streamer_SetFloatData, которые, по сути, абсолютно аналогичны двум предыдущим, только уже работают с вещественным типом данных (Float).

    • Streamer_GetFloatData
      Эта функция узнаёт (получает) из стримерского элемента значение типа Float.

      PHP код:
      Streamer_GetFloatData(typeiddata, &Float:result
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете узнать у элемента (из enum'а).
      result: Переменная, куда запишется результат.

      Возвращает:
      0 при неудаче, 1 при успешном выполнении (узнаваемое значение тут уже передаётся в result).

      Использование (на примере реализации функции GetDynamicPickupPos):
      PHP код:
      stock GetDynamicPickupPos(pickupid, &Float:x, &Float:y, &Float:z)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_PICKUP
          //Во второй аргумент передали сам ID элемента - pickupid
          //В третий аргумент тип данных, который хотим узнать - E_STREAMER_X
          //В четвёртый аргумент саму координату x - x
          
      Streamer_GetFloatData(STREAMER_TYPE_PICKUPpickupidE_STREAMER_Xx);
          
      //В третий аргумент тип данных, который хотим узнать - E_STREAMER_Y
          //В четвёртый аргумент саму координату y - y
          
      Streamer_GetFloatData(STREAMER_TYPE_PICKUPpickupidE_STREAMER_Yy);
          
      //В третий аргумент тип данных, который хотим узнать - E_STREAMER_Z
          //В четвёртый аргумент саму координату z - z
          //По итогу: узнаём позицию динамического пикапа и возвращаем результат выполнения функции
          
      return Streamer_GetFloatData(STREAMER_TYPE_PICKUPpickupidE_STREAMER_Zz);

    • Streamer_SetFloatData
      Эта функция устанавливает для стримерского элемента значение типа Float.

      PHP код:
      Streamer_SetFloatData(typeiddataFloat:value
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете установить для элемента (из enum'а).
      value: Устанавливаемое значение.

      Возвращает:
      0 при неудаче, 1 при успешном выполнении.

      Использование (на примере реализации функции AttachDynamic3DTextLabelToPlayer и AttachDynamic3DTextLabelToVehicle):
      PHP код:
      stock AttachDynamic3DTextLabelToPlayer(Text3D:labelidplayeridFloat:offsetxFloat:offsetyFloat:offsetz)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_3D_TEXT_LABEL
          //Во второй аргумент передали сам ID элемента - labelid
          //В третий аргумент тип данных, который хотим установить - E_STREAMER_ATTACHED_PLAYER
          //В четвёртый аргумент сам ID игрока - playerid
          
      Streamer_SetIntData(STREAMER_TYPE_3D_TEXT_LABELlabelidE_STREAMER_ATTACHED_PLAYERplayerid);
          
      //В третий аргумент тип данных, который хотим установить - E_STREAMER_ATTACH_OFFSET_X
          //В четвёртый аргумент саму координату смещения аттача по x - offsetx
          
      Streamer_SetFloatData(STREAMER_TYPE_3D_TEXT_LABELlabelidE_STREAMER_ATTACH_OFFSET_Xoffsetx);
          
      //В третий аргумент тип данных, который хотим установить - E_STREAMER_ATTACH_OFFSET_Y
          //В четвёртый аргумент саму координату смещения аттача по y - offsety
          
      Streamer_SetFloatData(STREAMER_TYPE_3D_TEXT_LABELlabelidE_STREAMER_ATTACH_OFFSET_Yoffsety);
          
      //В третий аргумент тип данных, который хотим установить - E_STREAMER_ATTACH_OFFSET_Z
          //В четвёртый аргумент саму координату смещения аттача по z - offsetz
          //По итогу: аттачим динамический 3D-текст к игроку на заданные координаты и возвращаем результат выполнения функции
          
      return Streamer_SetFloatData(STREAMER_TYPE_3D_TEXT_LABELlabelidE_STREAMER_ATTACH_OFFSET_Zoffsetz);
      }

      stock AttachDynamic3DTextLabelToVehicle(Text3D:labelidvehicleidFloat:offsetxFloat:offsetyFloat:offsetz)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_3D_TEXT_LABEL
          //Во второй аргумент передали сам ID элемента - labelid
          //В третий аргумент тип данных, который хотим установить - E_STREAMER_ATTACHED_VEHICLE
          //В четвёртый аргумент сам ID машины - vehicleid
          
      Streamer_SetIntData(STREAMER_TYPE_3D_TEXT_LABELlabelidE_STREAMER_ATTACHED_VEHICLEvehicleid);
          
      //В третий аргумент тип данных, который хотим установить - E_STREAMER_ATTACH_OFFSET_X
          //В четвёртый аргумент саму координату смещения аттача по x - offsetx
          
      Streamer_SetFloatData(STREAMER_TYPE_3D_TEXT_LABELlabelidE_STREAMER_ATTACH_OFFSET_Xoffsetx);
          
      //В третий аргумент тип данных, который хотим установить - E_STREAMER_ATTACH_OFFSET_Y
          //В четвёртый аргумент саму координату смещения аттача по y - offsety
          
      Streamer_SetFloatData(STREAMER_TYPE_3D_TEXT_LABELlabelidE_STREAMER_ATTACH_OFFSET_Yoffsety);
          
      //В третий аргумент тип данных, который хотим установить - E_STREAMER_ATTACH_OFFSET_Z
          //В четвёртый аргумент саму координату смещения аттача по z - offsetz
          //По итогу: аттачим динамический 3D-текст к машине на заданные координаты и возвращаем результат выполнения функции
          
      return Streamer_SetFloatData(STREAMER_TYPE_3D_TEXT_LABELlabelidE_STREAMER_ATTACH_OFFSET_Zoffsetz);



    Хорошо, с этим разобрались. И как вы, наверное, снова могли заметить, в enum'е некоторые типы данных под комментариями также имеют пометку в скобках "Array", что означает, что в эти типы могут записывать/узнавать данные в качестве массива, а не отдельной единичной переменной. Рассмотрим простой практический пример: на этот раз нам нужно установить для объекта три интерьера (а именно 2, 3 и 5), в которых он будет виден игрокам. Напомню, что такое возможно сделать, к примеру, при его создании через CreateDynamicObjectEx, но нам нужно проделать это с уже созданным объектом. И о какая удача, что тип данных для установки "E_STREAMER_INTERIOR_ID" как раз имеет пометку Array! (на самом деле это просто я заранее выбрал подходящий для примера тип, не обольщайтесь).

    Ок, как же нам сделать это через массив (а любые данные вроде нескольких интерьеров или чего-либо ещё придётся всегда передавать именно через него), если функции выше работают только с одиночными переменными? Для этого нам понадобятся функции Streamer_GetArrayData и Streamer_SetArrayData, встречайте.

    • Streamer_GetArrayData
      Эта функция узнаёт (получает) данные в качестве массива у стримерского элемента.

      PHP код:
      Streamer_GetArrayData(typeiddatadest[], maxdest sizeof dest
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете узнать у элемента (из enum'а).
      dest: Массив, в который запишется результат.
      maxdest: Размер массива с данными (по умолчанию размер dest).

      Возвращает:
      0 при неудаче, 1 при успешном выполнении (узнаваемый массив значений передаётся в dest).

      Использование (на примере реализации функции GetDynamicObjectInteriors):
      PHP код:
      stock GetDynamicObjectInteriors(objectidinteriors[], maxinteriors sizeof interiors)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим узнать - E_STREAMER_INTERIOR_ID
          //В четвёртый аргумент сам массив interiors - interiors
          //В пятый аргумент размер массива interiors - maxinteriors
          //По итогу: узнаём все интерьеры (если он не 1), в которых отображается динамический объект и возвращаем результат выполнения функции
          
      return Streamer_GetArrayData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_IDinteriorsmaxinteriors);
      }

      //Использование получившейся функции в коде
      new interiors[5]; //Таким образом в этот массив сможет записаться максимум 5 первых интерьеров, если вдруг объект имеет больше
      GetDynamicObjectInteriors(objectidinteriorssizeof interiors); //Если объект отображается во 2, 3 и 5 интерьерах, то interiors = {2, 3, 5} 
    • Streamer_SetArrayData
      Эта функция устанавливает данные в качестве массива для стримерского элемента.

      PHP код:
      Streamer_SetArrayData(typeiddatadest[], maxdest sizeof dest
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете установить элементу (из enum'а).
      dest: Массив с данными для установки.
      maxdest: Размер массива с данными (по умолчанию размер dest).

      Возвращает:
      0 при неудаче, 1 при успешном выполнении.

      Использование (на примере реализации функции SetDynamicObjectInteriors):
      PHP код:
      stock SetDynamicObjectInteriors(objectidinteriors[], maxinteriors sizeof interiors)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим установить - E_STREAMER_INTERIOR_ID
          //В четвёртый аргумент сам массив interiors - interiors
          //В пятый аргумент размер массива interiors - maxinteriors
          //По итогу: устанавливаем несколько интерьеров, в которых будет отображаться динамический объект и возвращаем результат выполнения функции
          
      return Streamer_SetArrayData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_IDinteriorsmaxinteriors);
      }

      //Использование получившейся функции в коде
      new interiors[] = {235}; //Таким образом в этом массиве записаны 3 интерьера: интерьер 2, 3 и 5
      SetDynamicObjectInteriors(objectidinteriorssizeof interiors); //Теперь объект будет отображаться только в интерьерах 2, 3 и 5 


    Ура! Уже более-менее умеем узнавать и изменять данные у стримерских элементов, но для работы с массивами есть ещё пара функций... Зачем здесь что-то ещё, спросите вы? Но вы ведь заметили, что в примере выше, устанавливая несколько интерьеров нашему объекту, мы абсолютно не учитываем, в каких интерьерах он отображался до нашего вмешательства и тупо перезаписываем всё на наши значения. Согласитесь, что было бы удобно как-то добавлять в этот массив данные, не вызывая сначала их узнавание, записывание в буферный массив, объединение с новыми данными, и уже только потом их установка этому элементу. А ещё представьте обратную ситуацию: объект уже отображается во множестве интерьеров, но нам нужно один или два интерьера из этого списка удалить. Схема ваших действий, если бы вы жили в параллельной реальности, где других функций больше бы не было, была бы примерно такой же, как и в предыдущем варианте. Но, к счастью, мы живём именно в той, где Incognito добавил для таких случаев функции Streamer_AppendArrayData и Streamer_RemoveArrayData.

    • Streamer_AppendArrayData
      Эта функция добавляет данные (одно значение) в массив для стримерского элемента.

      PHP код:
      Streamer_AppendArrayData(typeiddatavalue
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете установить элементу (из enum'а).
      value: Значение для добавления в массив.

      Возвращает:
      0 при неудаче, 1 при успешном выполнении.

      Использование (на примере реализации функции AddDynamicObjectInterior):
      PHP код:
      stock AddDynamicObjectInterior(objectidinteriorid)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим установить - E_STREAMER_INTERIOR_ID
          //В четвёртый аргумент сам интерьер - interiorid
          //По итогу: добавляем интерьер к уже имеющимся, в которых будет отображаться динамический объект и возвращаем результат выполнения функции
          
      return Streamer_AppendArrayData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_IDinteriorid);

    • Streamer_RemoveArrayData
      Эта функция удаляет данные (одно значение) из массива для стримерского элемента.

      PHP код:
      Streamer_RemoveArrayData(typeiddatavalue
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете установить элементу (из enum'а).
      value: Значение для удаления из массива.

      Возвращает:
      0 при неудаче, 1 при успешном выполнении.

      Использование (на примере реализации функции RemoveDynamicObjectInterior):
      PHP код:
      stock RemoveDynamicObjectInterior(objectidinteriorid)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим установить - E_STREAMER_INTERIOR_ID
          //В четвёртый аргумент сам интерьер - interiorid
          //По итогу: удаляем интерьер из списка уже имеющихся, в которых будет отображаться динамический объект и возвращаем результат выполнения функции
          
      return Streamer_RemoveArrayData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_IDinteriorid);



    Также мы можем в любой момент проверить, есть ли конкретное значение в этом массиве данных или нет. За примером "для чего это", опять же, далеко ходить не надо: предположим, нам нужно узнать, отображается ли объект в конкретном интерьере, но при этом мы знаем, что он отображается в нескольких и мы не хотим получать для этого весь их список и уже поочерёдно сверять циклом все его значения с тем интерьером, который мы захотели проверить. Мы просто хотим сделать это одной функцией, и такая функция тоже есть - Streamer_IsInArrayData.

    • Streamer_IsInArrayData
      Эта функция узнаёт: есть ли указанное значение в массиве у стримерского элемента.

      PHP код:
      Streamer_IsInArrayData(typeiddatavalue
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, в массиве которого будет идти поиск (тип из enum'а).
      value: Значение для поиска в массиве.

      Возвращает:
      0, если значение в массиве не найдено и 1, если найдено.

      Использование (на примере реализации функции IsDynamicObjectInInterior):
      PHP код:
      stock IsDynamicObjectInInterior(objectidinteriorid)
      {
          if(
      interiorid == -1) return 1//Если пользователь указал аргумент "interiorid" как -1, возвращаем 1 (-1 обозначается стримером как все интерьеры, соответственно будем считать это правдой, потому как объект очевидно в каком-то из всех интерьеров)

          //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT 
          //Во второй аргумент передали сам ID элемента - objectid 
          //В третий аргумент тип данных, который хотим узнать - E_STREAMER_INTERIOR_ID
          
      if(Streamer_GetIntData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_ID) == -1) return 1//Если объекту задан -1 интерьер, возвращаем 1 по той же причине

          //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим узнать - E_STREAMER_INTERIOR_ID
          //В четвёртый аргумент сам интерьер - interiorid
          //По итогу: узнаём, отображается ли динамический объект в указанном интерьере и возвращаем результат выполнения функции
          
      return Streamer_IsInArrayData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_IDinteriorid);
      }

      //Использование получившейся функции (в связке с уже добавленной SetDynamicObjectInteriors) в коде
      new interiors[] = {235}; //Таким образом в этом массиве записаны 3 интерьера: интерьер 2, 3 и 5
      SetDynamicObjectInteriors(objectidinteriorssizeof interiors); //Теперь объект будет отображаться только в интерьерах 2, 3 и 5
      IsDynamicObjectInInterior(objectid2); //Результат - 1 (объект находится в интерьере 2)
      IsDynamicObjectInInterior(objectid3); //Результат - 1 (объект находится в интерьере 3)
      IsDynamicObjectInInterior(objectid6); //Результат - 0 (объект не находится в интерьере 6) 


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

    • Streamer_GetArrayDataLength
      Эта функция узнаёт длину массива данных для указанного стримерского элемента.

      PHP код:
      Streamer_GetArrayDataLength(typeiddata
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, длина массива которого будет узнана (тип из enum'а).

      Возвращает:
      Длину массива данных.

      Примечание:
      Эта функция появилась лишь совсем недавно в версии 2.9.3, для её использования вам следует обновить стример (кликабельно).

      Использование (на примере реализации функции GetDynamicObjectInteriorsCount):
      PHP код:
      stock GetDynamicObjectInteriorsCount(objectid)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим узнать - E_STREAMER_INTERIOR_ID
          //По итогу: узнаём и возвращаем количество интерьеров, в которых отображается динамический объект
          
      return Streamer_GetArrayDataLength(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_ID);



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

    Ну и наконец, добивая этот раздел (и первую часть этого урока), остаётся представить ещё одну функцию, которая является аналогом функциям GetPlayerPoolSize/GetVehiclePoolSize, то есть по сути она узнаёт и возвращает наивысший занятый ид любого элемента, созданного стримером. Это функция Streamer_GetUpperBound. Может быть полезна в циклах в качестве использования как наивысшее значение, до которого он будет выполняться. Важным моментом является то, что наивысший ID созданного элемента не всегда отражает реальное количество всех созданных элементов вообще (для этого есть другая функция, о которой будет рассказано чуть позже), потому что если мы, к примеру, по порядку создадим стримерские объекты с идами 1, 2, 3, 4, 5, а потом удалим 3 и 4, то функция Streamer_GetUpperBound будет возвращать 5 как наивысший занятый ид для стримерских объектов, хотя всех созданных объектов уже будет 3 (с идами 1, 2, 5).

    • Streamer_GetUpperBound
      Эта функция узнаёт наивысший занятый ID для указанного типа стримерских элементов.

      PHP код:
      Streamer_GetUpperBound(type
      Параметры:
      type: Тип элемента.

      Возвращает:
      Наивысший занятый ID.

      Использование (на примере реализации функции StopAllDynamicObjects):
      PHP код:
      stock StopAllDynamicObjects()
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //По итогу: узнаём наивысший занятый ID динамического объекта
          
      for(new 1Streamer_GetUpperBound(STREAMER_TYPE_OBJECT); <= ji++) //Объекты стартуют с ида 1 (отсюда i = 1)
          
      {
              
      StopDynamicObject(i); //Останавливаем (возможно) движущийся динамический объект
          
      }
          return 
      1;



    Заключение

    Думаю, уже по ознакомлению с первой частью вам стало видно, что стример обладает поистине богатым функционалом, с помощью которого можно делать абсолютно любые вещи над стримерскими элементами, в числе которых и те, что для обычных объектов/актёров/пикапов/map-иконок или 3D-текстов просто недоступны в сампе нативно. Это даёт большое преимущество в использовании стримера не только тогда, когда нужно просто расширить лимиты, но и эффективно управлять всем через него созданным, что теперь, я надеюсь, вы и умеете делать. Однако есть ещё как минимум два раздела, которые мы не рассмотрели и обязательно сделаем это в следующих частях: на очереди у нас функции настройки элементов стримера (Streamer_SetMaxItems, Streamer_SetVisibleItems, Streamer_GetTypePriority и т.д.) и раздел "Разное" (Streamer_GetDistanceToItem, Streamer_GetItemStreamerID, Streamer_CountItems и т.д.).

    Домашнее задание

    Ну а пока готовится вторая часть, предлагаю вам сделать некоторые задания, которые помогут вам убедиться, что вы точно теперь понимаете, как с этим работать. Первые посты с правильной реализацией каждого задания (не противоречащей любому из условий) пролайкаю

    1. Написать функцию, которая будет возвращать ID модели динамического пикапа.
      Примерный шаблон функции: GetDynPickupModel(pickupid);
      Должна возвращать: модель стримерского пикапа.
    2. Написать функцию, которая будет устанавливать дальность прорисовки (DrawDistance) для динамического объекта без его пересоздания.
      Примерный шаблон функции: SetDynObjectDrawDistance(objectid, Float:drawdist);
      Должна возвращать: 1 в случае успешного выполнения и 0 в случае неудачи.
    3. Написать функцию, которая будет вычислять: создан ли стримером 3D-текст для конкретного указанного игрока. Заметьте, что узнать нужно именно факт существования динамического 3D-текста для игрока (а не его видимость в данный момент или что-то ещё).
      Примерный шаблон функции: IsDyn3DTextLabelExistForPlayer(labelid, playerid);
      Должна возвращать: 1, если стримерский 3D-текст создан для этого игрока и 0, если не создан.


    Ссылки по теме

    Streamer Plugin
    Streamer Functions include
    Streamer Plugin Wiki
    Последний раз редактировалось Nexius_Tailer; 08.10.2021 в 20:03.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

  2. #2
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    С оформлением бы поработать. А именно как-то выделить имена функций, к которым в последующем идёт описание. Сейчас они и по размеру текста, и по цвету совпадают с пунктами описания, что выглядит не очень (особенно когда нужно будет найти тот или иной пункт через некоторое время после прочтения статьи, дабы освежить память).

    Можно хотя бы с отступами поиграться как-нибудь так:


      Открыть/закрыть

    • Streamer_GetArrayData
      Эта функция узнаёт (получает) данные в качестве массива у стримерского элемента:

      PHP код:
      Streamer_GetArrayData(typeiddatadest[], maxdest sizeof dest
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете узнать у элемента (из enum'а).
      dest: Массив, в который запишется результат.
      maxdest: Размер массива с данными (по умолчанию размер dest).

      Возвращает:
      0 при неудаче, 1 при успешном выполнении (узнаваемый массив значений передаётся в dest).

      Использование (на примере реализации функции GetDynamicObjectInteriors):
      PHP код:
      stock GetDynamicObjectInteriors(objectidinteriors[], maxinteriors sizeof interiors)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим узнать - E_STREAMER_INTERIOR_ID
          //В четвёртый аргумент сам массив interiors - interiors
          //В пятый аргумент размер массива interiors - maxinteriors
          //По итогу: узнаём все интерьеры (если он не 1), в которых отображается динамический объект и возвращаем результат выполнения функции
          
      return Streamer_GetArrayData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_IDinteriorsmaxinteriors);
      }

      //Использование получившейся функции в коде
      new interiors[5]; //Таким образом в этот массив сможет записаться максимум 5 первых интерьеров, если вдруг объект имеет больше
      GetDynamicObjectInteriors(objectidinteriorssizeof interiors); //Если объект отображается во 2, 3 и 5 интерьерах, то interiors = {2, 3, 5} 
    • Streamer_SetArrayData
      Эта функция устанавливает данные в качестве массива для стримерского элемента:

      PHP код:
      Streamer_SetArrayData(typeiddatadest[], maxdest sizeof dest
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете установить элементу (из enum'а).
      dest: Массив с данными для установки.
      maxdest: Размер массива с данными (по умолчанию размер dest).

      Возвращает:
      0 при неудаче, 1 при успешном выполнении.

      Использование (на примере реализации функции SetDynamicObjectInteriors):
      PHP код:
      stock SetDynamicObjectInteriors(objectidinteriors[], maxinteriors sizeof interiors)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим установить - E_STREAMER_INTERIOR_ID
          //В четвёртый аргумент сам массив interiors - interiors
          //В пятый аргумент размер массива interiors - maxinteriors
          //По итогу: устанавливаем несколько интерьеров, в которых будет отображаться динамический объект и возвращаем результат выполнения функции
          
      return Streamer_SetArrayData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_IDinteriorsmaxinteriors);
      }

      //Использование получившейся функции в коде
      new interiors[] = {235}; //Таким образом в этом массиве записаны 3 интерьера: интерьер 2, 3 и 5
      SetDynamicObjectInteriors(objectidinteriorssizeof interiors); //Теперь объект будет отображаться только в интерьерах 2, 3 и 5 



      Ура! Уже более-менее умеем узнавать и изменять данные у стримерских элементов, но для работы с массивами есть ещё пара функций...
      Зачем здесь что-то ещё, спросите вы?
      Но вы ведь заметили, что в примере выше, устанавливая несколько интерьеров нашему объекту мы абсолютно не учитываем, в каких интерьерах он отображался до нашего вмешательства и тупо перезаписываем всё на наши значения. Согласитесь, что было бы удобно как-то добавлять в этот массив данные, не вызывая сначала их узнавание, записывание в буферный массив, объединение с новыми данными, и уже только потом их установка этому элементу. А ещё представьте обратную ситуацию: объект уже отображается во множестве интерьеров, но нам нужно один или два интерьера из этого списка удалить. Схема ваших действий, если бы вы жили в параллельной реальности, где других функций больше бы не было, была бы примерно такой же, как и в предыдущем варианте. Но, к счастью, мы живём именно в той, где Incognito добавил для таких случаев функции Streamer_AppendArrayData и Streamer_RemoveArrayData.


    • Streamer_AppendArrayData
      Эта функция добавляет данные (одно значение) в массив для стримерского элемента:

      PHP код:
      Streamer_AppendArrayData(typeiddatavalue
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете установить элементу (из enum'а).
      value: Значение для добавления в массив.

      Возвращает:
      0 при неудаче, 1 при успешном выполнении.

      Использование (на примере реализации функции AddDynamicObjectInterior):
      PHP код:
      stock AddDynamicObjectInterior(objectidinteriorid)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим установить - E_STREAMER_INTERIOR_ID
          //В четвёртый аргумент сам интерьер - interiorid
          //По итогу: добавляем интерьер к уже имеющимся, в которых будет отображаться динамический объект и возвращаем результат выполнения функции
          
      return Streamer_AppendArrayData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_IDinteriorid);






    Хотя в идеале ещё играться с цветом/размером букв, ибо в таких объёмных статьях трудно воспринимать информацию, когда она чуть ли не сплошным текстом написана
    Последний раз редактировалось DeimoS; 08.02.2018 в 07:08.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  3. #3
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Тёмно-красный цвет плохо смотрится на тёмном фоне, приходится напрягать глаза, чтобы хоть что-то прочесть. Лично я использую для подзаголовков оранжевый цвет, но в принципе может подойти любой, главное чтобы он смотрелся примерно одинаково и на светлом, и на тёмном фоне.

    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    могу порекомендовать очень полезный include Streamer Functions
    Вот здесь не помешало бы указать ссылку.

    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    Эта функция узнаёт (получает) Float данные стримерского элемента
    Что за странная мода в словосочетаниях ставить зависимые слова из англ. языка перед главными? Серьёзно, никогда не понимал этого.
    Проверяется очень просто: как правильно, "экземпляр объекта" или "объекта экземпляр"? Здесь то же самое, для слов из инглиша исключений нет.


    Думаю, эти несколько изменений, и можно смело перемещать статью в проверенные.

    P.S.: Также в тексте было несколько других незначительных пунктуационных и грамматических ошибок - все их перечислять нет смысла, я исправил их сам (надеюсь, не против?)
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  4. #4
    Аватар для Nexius_Tailer
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
      Открыть/закрыть
    С оформлением бы поработать. А именно как-то выделить имена функций, к которым в последующем идёт описание. Сейчас они и по размеру текста, и по цвету совпадают с пунктами описания, что выглядит не очень (особенно когда нужно будет найти тот или иной пункт через некоторое время после прочтения статьи, дабы освежить память).

    Можно хотя бы с отступами поиграться как-нибудь так:



    • Streamer_GetArrayData
      Эта функция узнаёт (получает) данные в качестве массива у стримерского элемента:

      PHP код:
      Streamer_GetArrayData(typeiddatadest[], maxdest sizeof dest
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете узнать у элемента (из enum'а).
      dest: Массив, в который запишется результат.
      maxdest: Размер массива с данными (по умолчанию размер dest).

      Возвращает:
      0 при неудаче, 1 при успешном выполнении (узнаваемый массив значений передаётся в dest).

      Использование (на примере реализации функции GetDynamicObjectInteriors):
      PHP код:
      stock GetDynamicObjectInteriors(objectidinteriors[], maxinteriors sizeof interiors)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим узнать - E_STREAMER_INTERIOR_ID
          //В четвёртый аргумент сам массив interiors - interiors
          //В пятый аргумент размер массива interiors - maxinteriors
          //По итогу: узнаём все интерьеры (если он не 1), в которых отображается динамический объект и возвращаем результат выполнения функции
          
      return Streamer_GetArrayData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_IDinteriorsmaxinteriors);
      }

      //Использование получившейся функции в коде
      new interiors[5]; //Таким образом в этот массив сможет записаться максимум 5 первых интерьеров, если вдруг объект имеет больше
      GetDynamicObjectInteriors(objectidinteriorssizeof interiors); //Если объект отображается во 2, 3 и 5 интерьерах, то interiors = {2, 3, 5} 
    • Streamer_SetArrayData
      Эта функция устанавливает данные в качестве массива для стримерского элемента:

      PHP код:
      Streamer_SetArrayData(typeiddatadest[], maxdest sizeof dest
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете установить элементу (из enum'а).
      dest: Массив с данными для установки.
      maxdest: Размер массива с данными (по умолчанию размер dest).

      Возвращает:
      0 при неудаче, 1 при успешном выполнении.

      Использование (на примере реализации функции SetDynamicObjectInteriors):
      PHP код:
      stock SetDynamicObjectInteriors(objectidinteriors[], maxinteriors sizeof interiors)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим установить - E_STREAMER_INTERIOR_ID
          //В четвёртый аргумент сам массив interiors - interiors
          //В пятый аргумент размер массива interiors - maxinteriors
          //По итогу: устанавливаем несколько интерьеров, в которых будет отображаться динамический объект и возвращаем результат выполнения функции
          
      return Streamer_SetArrayData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_IDinteriorsmaxinteriors);
      }

      //Использование получившейся функции в коде
      new interiors[] = {235}; //Таким образом в этом массиве записаны 3 интерьера: интерьер 2, 3 и 5
      SetDynamicObjectInteriors(objectidinteriorssizeof interiors); //Теперь объект будет отображаться только в интерьерах 2, 3 и 5 



      Ура! Уже более-менее умеем узнавать и изменять данные у стримерских элементов, но для работы с массивами есть ещё пара функций...
      Зачем здесь что-то ещё, спросите вы?
      Но вы ведь заметили, что в примере выше, устанавливая несколько интерьеров нашему объекту мы абсолютно не учитываем, в каких интерьерах он отображался до нашего вмешательства и тупо перезаписываем всё на наши значения. Согласитесь, что было бы удобно как-то добавлять в этот массив данные, не вызывая сначала их узнавание, записывание в буферный массив, объединение с новыми данными, и уже только потом их установка этому элементу. А ещё представьте обратную ситуацию: объект уже отображается во множестве интерьеров, но нам нужно один или два интерьера из этого списка удалить. Схема ваших действий, если бы вы жили в параллельной реальности, где других функций больше бы не было, была бы примерно такой же, как и в предыдущем варианте. Но, к счастью, мы живём именно в той, где Incognito добавил для таких случаев функции Streamer_AppendArrayData и Streamer_RemoveArrayData.


    • Streamer_AppendArrayData
      Эта функция добавляет данные (одно значение) в массив для стримерского элемента:

      PHP код:
      Streamer_AppendArrayData(typeiddatavalue
      Параметры:
      type: Тип элемента.
      id: ID элемента.
      data: Тип данных, кои желаете установить элементу (из enum'а).
      value: Значение для добавления в массив.

      Возвращает:
      0 при неудаче, 1 при успешном выполнении.

      Использование (на примере реализации функции AddDynamicObjectInterior):
      PHP код:
      stock AddDynamicObjectInterior(objectidinteriorid)
      {
          
      //В первый аргумент передали тип элемента - STREAMER_TYPE_OBJECT
          //Во второй аргумент передали сам ID элемента - objectid
          //В третий аргумент тип данных, который хотим установить - E_STREAMER_INTERIOR_ID
          //В четвёртый аргумент сам интерьер - interiorid
          //По итогу: добавляем интерьер к уже имеющимся, в которых будет отображаться динамический объект и возвращаем результат выполнения функции
          
      return Streamer_AppendArrayData(STREAMER_TYPE_OBJECTobjectidE_STREAMER_INTERIOR_IDinteriorid);






    Хотя в идеале ещё играться с цветом/размером букв, ибо в таких объёмных статьях трудно воспринимать информацию, когда она чуть ли не сплошным текстом написана
    Про отступ и размер текста возьму на заметку, но вот выравнивание сплошного текста по центру как по мне выглядит не всегда в тему и читается не очень.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Тёмно-красный цвет плохо смотрится на тёмном фоне, приходится напрягать глаза, чтобы хоть что-то прочесть. Лично я использую для подзаголовков оранжевый цвет, но в принципе может подойти любой, главное чтобы он смотрелся примерно одинаково и на светлом, и на тёмном фоне.
    На тёмном фоне и код в php смотрится не очень, но всех вроде устраивает)
    Раньше экспериментировал с разными более яркими цветами, на белом фоне тоже не всегда всё хорошо среди них воспринималось. В этот раз не особо заморачивался, но думаю на белой теме вполне нормальный вариант.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Вот здесь не помешало бы указать ссылку.
    Изначально указывал, но потом вспомнил, что совсем недавно его автора забанили на офе и большинство работ он, к сожалению, удалил (включая эту) и в конечном итоге её убрал, чтобы было меньше вопросов. В конце оставил на неё ссылку лишь для ознакомления, возможно когда-нибудь кто-нибудь перезальёт.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Что за странная мода в словосочетаниях ставить зависимые слова из англ. языка перед главными? Серьёзно, никогда не понимал этого.
    Проверяется очень просто: как правильно, "экземпляр объекта" или "объекта экземпляр"? Здесь то же самое, для слов из инглиша исключений нет.
    Мне так больше нравится и смотрится, как мне кажется, это понятнее. "Данные Float стримерского объекта" сложнее воспринять, т.к. в таком случае это больше походит на набор слов, нежели на какое-то предложение, имеющее смысл, приходится перечитывать. Нет никакой нужды в этом случае что-то соблюдать (если и есть в этом нормы), когда в конечном итоге это только всё усложнит для конечного пользователя, которому, уверен, это также малоинтересно.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    P.S.: Также в тексте было несколько других незначительных пунктуационных и грамматических ошибок - все их перечислять нет смысла, я исправил их сам (надеюсь, не против?)
    Только за. Перед публикацией пробежался быстро в их поиске, что-то возможно упустил из виду.
    Последний раз редактировалось Nexius_Tailer; 07.02.2018 в 22:01.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

  5. #5
    Аватар для VVWVV
    ?

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    731
    Репутация:
    353 ±
    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    Изначально указывал, но потом вспомнил, что совсем недавно его автора забанили на офе и большинство работ он, к сожалению, удалил (включая эту) и в конечном итоге её убрал, чтобы было меньше вопросов. В конце оставил на неё ссылку лишь для ознакомления, возможно когда-нибудь кто-нибудь перезальёт.
    У него же другой аккаунт есть. вот

  6. #6
    Аватар для Nexius_Tailer
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    Цитата Сообщение от VVWVV Посмотреть сообщение
    У него же другой аккаунт есть. вот
    О, спасибо. Теперь можно и добавить)

    Upd:
    Немного обновил тему: добавлена ссылка на сам исходный код инклуда Streamer Functions, а также теперь немного лучше выделены заголовки функций для их более удобного поиска в сообщении.
    Последний раз редактировалось DeimoS; 08.02.2018 в 12:40.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

  7. #7
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    но вот выравнивание сплошного текста по центру как по мне выглядит не всегда в тему и читается не очень.
    Ну это просто была попытка как-то большой однородный кусок текста выделить, отделив от описания функций. Это можно и чуть изменённым шрифтом сделать, найдя похожий на основной шрифт. Или чертами сверху и снизу через BB код [HR ][ /HR]
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  8. #8
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    На тёмном фоне и код в php смотрится не очень, но всех вроде устраивает)
    Вот только не надо переводить стрелки на форум. Подсветка PHP-кода, в том числе и цвет фона, захардкожена в коде форумного движка и никак не настраивается. Если же менять цвета в коде, они сменятся и на светлой форумной теме, и на тёмной.

    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    В этот раз не особо заморачивался, но думаю на белой теме вполне нормальный вариант.
    Это не устраняет проблему с тёмным фоном. В общем, звучит, как очередное

    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    "Данные Float стримерского объекта" сложнее воспринять
    Ну так это ж далеко не единственный вариант. Если подумать, можно получить что-то вроде:
    Эта функция узнаёт (получает) из стримерского элемента значение типа Float:
    Собственно, так я и сделал ещё вчера, когда правил пунктуацию и грамматику. Хотя пока что складывается ощущение, что не стоило даже и пытаться.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  9. #9
    Аватар для Nexius_Tailer
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Ну это просто была попытка как-то большой однородный кусок текста выделить, отделив от описания функций. Это можно и чуть изменённым шрифтом сделать, найдя похожий на основной шрифт. Или чертами сверху и снизу через BB код [HR ][ /HR]
    В целом с добавлением пунктов для функций ситуация уже вроде лучше, сейчас можно легко сориентироваться по точкам перед ними (за что, кстати, спасибо, довольно интересная идея для оформления как оказывается). Шрифт и всё остальное, я думаю, лучше оставить для единого стиля.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Вот только не надо переводить стрелки на форум. Подсветка PHP-кода, в том числе и цвет фона, захардкожена в коде форумного движка и никак не настраивается. Если же менять цвета в коде, они сменятся и на светлой форумной теме, и на тёмной.
    Тут имелось в виду, что пока существуют и более серьёзные неудобства на тёмной теме (неважно чем вызванные, сам факт они есть), напряжение глаз на темноватый цвет это, наверное, самое меньшее из того, что чувствуют его пользователи.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Это не устраняет проблему с тёмным фоном. В общем, звучит, как очередное
    Это выглядит как очередное удобство для большинства, кто сидит но белой теме, ибо те, кто ставит себе что-то более экзотическое, должны понимать, что это также для них может нести.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Ну так это ж далеко не единственный вариант. Если подумать, можно получить что-то вроде:
    Да, я потом уже это заметил, просто в контексте моей изначальной формулировки то был самый понятный вариант.

    Цитата Сообщение от DeimoS Посмотреть сообщение
    Хотя пока что складывается ощущение, что не стоило даже и пытаться.
    Не знаю почему складывается, но раз не стоило, нужно было было думать об этом тогда.
    Последний раз редактировалось Nexius_Tailer; 08.02.2018 в 13:36.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

  10. #10
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    Тут имелось в виду, что пока существуют и более серьёзные неудобства на тёмной теме (неважно чем вызванные, сам факт они есть), напряжение глаз на темноватый цвет это, наверное, самое меньшее из того, что чувствуют его пользователи.
    Существуют, только это не повод наплевательски относиться к своему оформлению. Особенно, когда исправить проблему не так уж и сложно.


    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    Это выглядит как очередное удобство для большинства, кто сидит но белой теме, ибо те, кто ставит себе что-то более экзотическое, должны понимать, что это также для них может нести.
    "Экзотическое"? Это всегда была обычная форумная тема, наравне со светлой.
    Ок, уже понятно, что этот разговор абсолютно ни к каким изменениям не приведёт, но я просто очень хочу знать, разве я прошу что-то сложное?
    Работы буквально на пару минут: подобрать цвет чуть посветлее (чтобы смотрелся одинаково удобно и на светлом, и на тёмном фоне) и пройтись по тексту автозаменой. Но нет, нужно упереться и оправдываться в стиле "пользователи сами виноваты". Странная логика. Многое говорит об отношении и к своему контенту, и к читателям.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

 

 
Страница 1 из 2 1 2 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •