integer
llWhisper
llSay
llDialog
llOwnerSay
llInstantMessage
llShout
llRegionSay
llSetText
float
string
llGetSubstring
llSrtingLength
vector и rotation
list
llList2CSV
llList2String
llList2Float
llList2Integer
llList2Key
llList2Rot
llList2Vector
llList2List
llList2ListStrided
llGetListEntryType
llGetListLength
llListFindList
llDeleteSubList
llListInsertList
llListRandomize
llListReplaceList
llListSort
llListStatistics
llCSV2List
llParseString2List
llParseStringKeepNulls
llDumpList2String
инвентарные функтцыи
llAllowInventoryDrop
llGetInventoryKey
llGetInventoryName
llGetInventoryNumber
llGetInventoryCreator
llGetInventoryPermMask
llGetInventoryType
llGetScriptName
llGetScriptState
llSetScriptState
llResetOtherScript
llGiveInventory
llGiveInventoryList
llRemoveInventory
llParticleSystem
llSetPrimitiveParams
llSetTextureAnim
Во втором уроке, мы рассмотрим преобразования переменных и познакомимсця с частицами
и параметрами примитивов.
Некоторые типы переменных представленные в предыдущем уроке иногда приходится конвертировать
в другие типы. Давайте рассмотрим, как это делается.
integer - переменные данного типа можно преобразовать только в переменные типа list, string и key.
Делается преобразование следующим образом:
integer num=1;
default
{
State_entry()
{
llSay(0,(string)num);
}
}
Что сопсна сие означает: перед начальным событием объявляется переменная num,
затем в самом начальном событии вызывается функция llSay, которая на нулевом (общем) канале
говорит в чат значение нашей переменной, а поскольку прараметр, который выводит в чат значение
является string-ом, то для избежания синтакс эррора наш integer необходимо перевести в string.
Делается это, путём указания в круглых скобках нового типа нашей переменной (это num которая).
В данном случае новый тип – это (string).
Интегеры можно увеличивать или уменьшать следующими способами:
num++;
или ++num;
или num=num+1;
или num+=1;
Вышеперечисленные выражения увеличивают переменную num на 1 (точно так же можно увеличивать дроби, если плюсы в этих
выражениях заменить на минусы, то выражение будит, соответственно уменьшаться).
А заодно, чтобы потом нигде не искать, рассмотрим функции, которые тем или иным образом отвечают
за вывод текстовой информации:
llWhisper(integer chanel, string msg); - Эта функция говорит в чат текст, который слышен в радиусе 10 метров.
integer chanel – номер канала.
string msg – сообщение.
llSay(integer chanel, string msg); - Эта функция говорит в чат текст, который слышен в радиусе 20 метров.
integer chanel – номер канала.
string msg – сообщение.
llDialog(key avatar, string msg, list buttons, integer chanel) – ента функтцыя выводит окошко с текстом и кнопками,
а после нажатия одной из кнопок говорит её имя в чат, так же, как и llSay.
key avatar – тут указываетсця ключ аватара, которому надо показать окошко.
string msg – тут пишетсо текст сообшчения, которое должно содержать окошко (не более 512 символов).
list buttons – тута, пишетсця лист с именами кнопок, которые должны быть в окошке (не более 12 шт.)
Алсо: в листе кнопок должны содержатьсця ТОКА ДАННЫЕ ТИПА STRING (“это в кавычках которые”).
Если лист для кнопок будит пустым – [], то в выползшем окошке будит фсево одна кнопка ”ОК”.
Если в имени кнопки начепятан тока один пробел и ничего больше, то кнопка будит пустой.
integer chanel – канал, на котором после нажатия кнопки будит сказано имя этой кнопки.
Пыремер использования:
default
{
state_entry()
{
llSay(0,a);
llDialog(llGetOwner(),a,[“для удобства”,”шобы не делать HUD”,”за печкой”],0);
}
}
llOwnerSay(string msg); - Эта функция говорит текст, который слышен только обладателю вещи с данным скриптом
и никому другому.
string msg – сообщение.
llInstantMessage(key user, string msg); - Эта функция говорит текст, который слышен только одному конкретному аватару.
key user – ключ того, кому посылается сообщение.
string msg – сообщение.
Примечание: Посылать сообщения примам спомощью этой функции – нельзя.
llShout(integer chanel, string msg); - Эта функция говорит в чат текст, который слышен в радиусе 100 метров.
integer chanel – номер канала.
string msg – сообщение.
llRegionSay(integer chanel, string msg); - Эта функция говорит в чат текст, который слышен на всём симе
(флудеры могут достать губозакатывательную машинку, поскольку на нулевом канале данная функция ничего говорить не может).
integer chanel – номер канала.
string msg – сообщение.
llSetText(string msg, vector color, float alpha); - Эта функция устанавливает текст над объектом.
string msg - сообщение.
vector color – цвет текста вида <R,G,B>, значения цвета представляются в диапазоне от 0.000000 до 1.000000
float alpha – Прозрачность текста.
Примечание: если поставить \n между словами в ллСетТекст, то та часть, которая находится после этой конструкции
перенесётся на следующую строчку.
Алсо: Если вы удалите скрипт из прима текст над ним останется. Для удаления текста, надо обнулить его - llSetText("",<0,0,0>,0);
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
float - переменные этого типа можно преобразовать в переменные типов string, integer, list.
Правда в целое число дробь преобразуется, только после округления.
Преобразования делаются следующими путями:
float num=1.0001;
string str=(string)num;
integer int=(integer)llRound(num);
list l=[num];
default
{
State_entry()
{
llSay(0,”Стринг ”+(string)str);
llSay(0,”Интегер ”+(string)int);
llSay(0,”Лист ”+(string)l);
}
}
Шо мы тута сопсна видим?
А видим мы следующее,- перед стейт_интри объявляются четыре глобальных переменных, в три из них путём преобразования
запихиваетсця наша дробь. В самом стейт_интри функтцыя llSay говорит значения и тип каждой преобразованной переменной, но,
как мы можем заметить перед самим значением стоят кавычки и плюстц, как мы так же замечаем,
после слова в кавычках стоит пробел.
Ща объясню, зачем енто нада:
Слова в кавычках, после или перед которыми находится знак + добавляются к конечному результату,
причём при выводе в чат значения таким вот образом оба значения никак друг от друга не отделяются,
вот сопсна поэтому после слова в кавычках стоит пробел.
Примечание: Обратите вминание на порядок следования переменных – ЭТО ОЧЕНЬ ВАЖНО!!! СПЕРВА объявляетсця сама дробь,
ПОТОМ тока фсё остальное, ПОСКОЛЬКУ во всех переменных идущих после нашей дроби поставлены ССЫЛКИ на неё,
если эту переменную объявить после остальных, то скрипт вылетит с ошибкой,
поскольку преобразованные переменные при запуске появляются именно в той последовательности, в которой вы их написали,
а если дробь будит объявлена последней, то остальные переменные, в которых лежит ссылка на дробь,
на момент их запуска будут ссылаться на пустое место.
Тобиш ситуация будит равносильна тому, как если бы вас попросили пересказать текст, которого вы ещё не читали.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
string - переменные этого типа можно преобразовать в переменные типов integer, list, key.
Правда при условии, что знаки, содержащиеся в переменной возможно перевести в другой тип.
Тоесть – если в переменной содержатся только цифры, то её можно перевести в integer или list.
Перевод в integer:
string a=”12345”;
Integer b=(integer)a;
Перевод в list:
string a=”многабукав”;
list b=[a];
Примечание: Переменную типа string содержащую в себе буквы, иногда таки можна перевести в интегер,
делаетсця это вот так вота:
string a=”48a5e”;
integer b=("0x"+a);
default
{
state_entry()
{
llSay(b,”Тест”);
}
}
Э… и как понимать сию конструктцыю?
Понимаетсця это следующим образом:
Сперва объявляется текстовая переменная, которая содержит в себе шестнадцатиричное значение,
затем в следующей переменной string конвертируется в шестнадцатиричный интегер путём добавления "0x".
Ну и затем получившееся число вставляется в llSay как номер канала и на этом канале говорится слово ”Тест”.
Если перевести 48a5e в десятичную систему счисления, то получится 297566,
десятичные числа можно перевести обратно в шестнадцатиричные при помощи виндовского инженерного калькулятора,
введя число и выбрав нужную систему счисления (это там, где Hex – 16ричная, Dec - 10ичная, Oct - 8ричная, Bin - 2ичная).
Перед конвертацией, убедитесь, что получившееся в итоге число не превышает максимальный предел для интегера,
иначе ваше число автоматически станет равным -1.
Также можно взять определённый кусок стринговой переменной, делаетсця это при помощи следующей функтцыи:
string llGetSubstring(string source, integer start, integer end);
string source – тут должно быть имя переменной, из которой надо выдрать кусок
(также тут можно просто начепятать нужный, текст поместив его в кавычки).
integer start – тута ставится цыфера обозначающая с какого по счёту знака начанать извлечение данных
нумерация начанаетсця с нуля).
integer end – а тута ставится цифра, указывающая на каком знаке извлечение закончить.
Шобы понятней было, как эта функция работает на практике, приведу пример её использования.
string a=”**МНОГАБУКАВ**”;
string b;
default
{
state_entry()
{
b=llGetSubString(a,2,11);
llSay(0,b);
}
}
Что тут происходит – объявляются две переменных, одна с нужной нам командой, другая пустая.
Патом пустой переменной присваиваются знаки первой переменной со второго по 11
(до и после как можем заметить, у нас стоят звёздочки).
В результате получаем ответ – ”МНОГАБУКАВ”.
integer llStringLength(string src) – эта функтцыя возвращает количество знаков в переманной указанной в string src.
Обращаю вминание особо рассеянных, шо работает ента функтцыя тока с переменными типа string!!!
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
vector и rotation – эти типы переменных можно преобразовывать в переменные типов string и float
(в float можно преобразовать только одну из частей переменной).
Преобразовать какую-либо часть вектора или кватерниона можно следующим образом:
rotation a=<1.01,2.02,3.03,4.04>;
float b=a.x;
float c=a.y;
float d=a.z;
float e=a.s;
default
{
state_entry()
{
llSay(0,(string)b);
llSay(0,(string)c);
llSay(0,(string)d);
llSay(0,(string)e);
}
}
Так, сопсна, шо мы тута имеем? А имеем мы скрипт, который проговаривает все части кватерниона по отдельности.
Причём проговаривает он не сами части, а дроби, в которые мы преобразовали части кватерниона.
Ну, а преобразовали мы их способом, который я вскользць описывал в предыдущем уроке – я поставил специальный индекс
для каждой части кватерниона.
Вектора преобразуются в дроби точно таким же способом, с той лишь разницей, что в них нет четвёртой координаты, и соответственно индекса .s тоже нема.
Преобразование в string осуществляется объявлением нового типа перед именем переменной, тоесть вот так вота:
vector a=<1.1,2.2,3.3>;
default
{
state_entry()
{
llSay(0,(string)a);
}
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
list – О! А вот это самый интерестцный в плане преобразований тип переменных,
в нево можна упихать любую другую переменную, равно как и блоки листа можно конвертить почти в любые типы переменных.
Почему ”почти”? А, ну… не все же переменные совместимы-то, буквы в цифры, ведь не переконвертируешь
(во всяком случае не все и не всегда).
Для того, чтобы добавить к листу какую-нибудь переменную, используется следующая конструкция:
list a=a+b;
а можно такую:
list a+=b;
или вот такую:
list a+=”многабукав”;
Листы можно переконвертировать в другие типы переменных (а заодно и другие переменные запихивать в лист)
спомощью некольких функтцый:
string llList2CSV(list source); - Эта функция сохраняет всё содержимое листа как одну переменную типа string.
Блоки листа разделены запятыми.
string llList2String(list source, integer index); - Эта функция вытаскивает данные в переменную типа string из листа
по указанному номеру блока данных.
list source – тут пишется имя листа из которого нужно утянуть данные.
integer index – а тут ставится порядковый номер блока данных (нумерация идёт с нуля).
Пример использования:
list a=[”0”,”многабукав”,”2”];
string b;
default
{
state_entry()
{
b=llList2String(a,1);
llSay(0,b);
}
}
Можно также записать и вот так вота:
default
{
state_entry()
{
list a=[”0”,”многабукав”,”2”];
string b=llList2String(a,1);
llSay(0,b);
}
}
Помнится, я уже в первом уроке упоминал хде-та о глобальных и локальных переменных, дык вота – разница между первым
и вторым примером в том, что в прервом примере объявлены глобальные переменные,
которые можно использовать в любом событии, а во втором объявлены локальные переменные,
которые существует ТОЛЬКО в этом событии
(вернее не ”существуют”, а объявляется каждый раз, как только событие срабатывает).
Порядок написания переменных внутри какого-то события тот же самый, что и при объявлении глобальных переменных,
тоесть если сперва написать ссылки на какую-то переменную, потом её объявить, то скрипт съERRORится на месте.
float llList2Float(list source, integer index); - то же что и llList2String,
тока конвертирует указанный блок листа в дробь.
integer llList2Integer(list source, integer index); - то же что и llList2String,
тока конвертирует указанный блок листа в целое число.
key llList2Key(list source, integer index); - то же что и llList2String,
тока конвертирует указанный блок листа в ключ.
rotation llList2Rot(list source, integer index); - то же что и llList2String,
тока конвертирует указанный блок листа в кватернион.
vector llList2Vector(list source, integer index); - то же что и llList2String,
тока конвертирует указанный блок листа в вектор.
Дальше идут функции, с помощью которых можно производить над листами определённые операции:
list llList2List(list source, integer start, integer end); - вытаскивает из листа в новый лист сразу несколько блоков.
list source – сопсна имя листа ИЗ которого надо вытянуть данные.
integer start – порядковый номер блока в листе С КОТОРОГО начипается извлечение.
integer end – обозначает сколько взять знаков ОТ НАЧАЛЬНОЙ точки (integer start).
Попрошу не путать понятие ”количество блоков от начала” и ”количество блоков от начального параметра”
(тоесть то, что этот параметр и означает), поскольку такой метод отсчёта используется ещё в нескольких функциях.
Шобы понять, как работают эти точки извлечения с нестандартными атрибутами, приведу несколько интерестцных примеров:
list a=[”0”,”1”,”2”,”3”,”4”,”5”];
list b;
list c;
list d;
list e;
default
{
state_entry()
{
b=llList2List(a,0,0); //На выходе у нас получится – ”0”
c=llList2List(a,1,0); //На выходе у нас получится – ”0”,”1”,”2”,”3”,”4”,”5”
d=llList2List(a,2,-1); //На выходе у нас получится - ”2”,”3”,”4”,”5”
e=llList2List(a,1,-2); //На выходе у нас получится - ”1”,”2”,”3”,”4”
}
}
Тоесть, как можно заметить, при указании в integer end меньщего значения, чем в integer start в конечный результат
не попадают значения, которые лежат в диапазоне от integer end до integer start, причём,
если начальный параметр равен нулю или если при вычитании конечного параметра из начального
получается отрицательный результат, то отсчёт невходящих в лист ”отрицательных” блоков будит производиться С КОНЦА ЛИСТА!
list llList2ListStrided(list source, integer start, integer end, integer stride); - эта функция вытаскивает в новый лист
несколько однотипных переменных лежащих в определённом диапазоне блоков.
list source – тут пишется лист из которого блоки надо вытянуть.
integer start – цифра, обозначающая начало диапазона блоков.
integer end – цифра, обозначающая конец диапазона блоков.
integer stride – Шаг, тоесть если у нас допустим тут стоит 2, в листе 20 элементов, start=0 end=10, то вернётся каждое
второе число в диапазоне от 0 до 10.
integer llGetListEntryType(list source, integer index); - с помощью этой функции можно узнать,
какому типу соответствует конкретный блок листа.
list source – сюды надо вписать сам лист, сведения о блоке которого необходимо получить.
integer index – ну а тута указывается номер нужного блока.
Данная функция при её использовании возвращает цифру, которая обозначает определённый тип переменной.
Шобы было понятно, какая цифра какому типу соответствует, пывэду их значения:
0 он же TYPE_INVALID – показывает, что переменная не принадлежит ни к одному из существующих типов
Как правило выдаётся, если integer index больше положительной или отрицательной длинны листа.
Тоесть – если в листе у нас, допустим, 5 блоков, а integer index равен 7 или -7, то функция вернёт ”типичного_инвалида”.
1 он же TYPE_INTEGER – означает, что указанный блок содержит в себе целое число.
2 он же TYPE_FLOAT - означает, что указанный блок содержит в себе дробь.
3 он же TYPE_STRING - означает, что указанный блок содержит в себе текст.
4 он же TYPE_KEY - означает, что указанный блок содержит в себе ключ.
5 он же TYPE_VECTOR - означает, что указанный блок содержит в себе вектор.
6 он же TYPE_ROTATION - означает, что указанный блок содержит в себе кватернион.
Как правильно использовать эту функтцыю:
integer a;
list b=[0xA5D3,42451,1.500000,”Многабукав”,”f73e94ac-1bfd-43e2-ff0a-efc7fee1029e”, <1.000000,2.000000,3.000000>,
<1.000000,2.000000,3.000000,4.000000>];
default
{
state_entry()
{
a=llGetListEntryType(b,0);
llSay(0,(string)a+” <- тип | значение -> ”+llList2String(b,0));
llSetText(”0=хрен знает шо \n 1=integer \n 2=float \n 3=string \n 4=key \n 5=vector \n 6=rotation”,<0,1,0>,1);
}
}
Как мы можем заметить ответ от функции llGetListEntryType присвоен переменной a, которая потом вставляется в llSay.
Оговорюсць, шо если блоки типов vector и rotation будут содержать в себе данные вида <1,2,3>, <1,2,3,4>,
вместо <1.000000,2.000000,3.000000>, <1.000000,2.000000,3.000000,4.000000>,
то функция выдаст значение TYPE_STRING вместо того, которое по идее должно быть.
Алсо: если число, содержащееся в листе было взято из переменной типа string,
то функция, почему-то возвращает опять же тип string вместо по факту имеющегося.
integer llGetListLength(list source); - Выдаёт общее количество блоков в указанном листе (ну или, если по русски,
то ”длину листа”).
integer llListFindList(list source, list test); - Эта функция выдаёт местоположение ПЕРВОГО блока данных того листа,
который используется как ЦЕЛЬ поиска в листе, который используется как МЕСТО поиска.
Тоесть если по русски, функция ищет в указанном в list source листе позицию первого (тот, шо за номером 0) блока данных
листа указанного в list test, если таковой имеется, то выдаёт его порядковый номер, если же ничего похожего нема,
то выдаёт -1.
list llDeleteSubList(list source, integer start, integer end); - Эта функция возвращает лист из которого удалены
определённые блоки.
list source – суды вставляетсця исходный лист.
integer start – тут указывается порядковый номер с которого надо начать удаление.
integer end – а тута номер блока, которым удаление закончить.
Сопсна, как этим пользоваться на практике:
list a=[0,1,2,3,4,5,6,7,8,9];
list b;
default
{
state_entry()
{
b=llDeleteSubList(a,2,5);
llOwnerSay((string)b);
}
}
list llListInsertList(list destination, list source, integer position); - эта функтцыя позволяет вставить все блоки
одного листа в определённую часть другого.
list destination – тут указывается лист, КОТОРЫЙ надо куда-то запихнуть.
list source – тут, лист, В КОТОРЫЙ запихивиаем.
integer position – ну а тут позиция блока листа, с которой начинаем вставлять другие блоки.
list llListRandomize(list source, integer stride); - перемешивает компоненты листа в случайном порядке.
list source – сопсна лист, каторый нада перемешать.
integer stride – число на основе которого, насколько я понял и идёт перемешивание.
list llListReplaceList(list destination, list source, integer start, integer end); - эта функция заменяет определённый
участок одного листа определённым участком другого.
list destination – лист В КОТОРОМ нада шо-то поменять.
list source – лист ИЗ КОТОРОГО берут данные для замены.
Примечание: если заменяютсця, ну допустим 4 блока, а в этом листе их меньше, или он пустой, то те блоки,
которые тута есть заменят данные лежащие в list destination, а те номера блоков, по которым в list source пусто,
а в заменяемом листе они присутствуют, будут удалены из листа.
integer start и integer end – это координаты начала и соответна конца замены.
list llListSort(list source, integer stride, integer ascending); - эта функция сортирует содержимое листа
указанного в list source (разбив его на куски, в каждом из которых содержится по столько блоков листа,
сколько написано в integer stride) по определённому алгоритму.
Сопстна, как работает этот алгоритм - предположим у нас есть следующий скрипт:
list a=["б",2,4.01,"а",<1.0,2.5,3.9>,1,"в",<2.5,4.9,1.9>,3,2.12,1.02];
list b; //Пустой (пока что) лист.
integer i; //Переменная счётчика.
default
{
state_entry()
{
b=llListSort(a,1,TRUE); //Выкладываем результат сортировка листа ”a” в лист ”b”.
for(i=0; i<llGetListLength(a); i++) //for – это некий аналог таймера, тока счёт он ведёт не
//”от начала и до пока не остановят”, как таймер, а ”От сих и до сих!”
//Сопсна, то, шо в скобках, после for написано дословно переводится вот так вота:
//до тех пор, пока (переменная i равна нулю, а так же i меньше суммарного количества блоков в листе,
//увеличивать i на 1, а затем, после каждого увеличения выполнять нижеследующий блок кода)
{
llSay(0,llList2String(b,i)); //а в ”нижеследующем блоке кода” написано отдельной строкой
//проговорить каждый блок отсортированного листа.
}
}
}
Если поставить integer stride равным 1, то лист отсортируется следующим образом:
”в”,1,<2.5, 4.9, 1.9>,1.02, 2.12, 2, 3, ”б”, <1.0, 2.5, 3.9>, ”а”, 4.01
Тоезь, шо мы тута, собсна магём заметить?
А заметить мы можем, например, то, что буквы отсортировались по убыванию – было ”б,а,в”, стало ”в,б,а”.
Алсо, мы заметили, шо между буковами осталисць числа…
Алсо, мы заметили, шо если выкинуть все вектора, то числа идут по возрастанию.
Алсо, до нас наконец-то доехало, почему вектора стояли между обычными числами:
Все числа вектора <2.5, 4.9, 1.9> больше единицы, поэтому вектор стоит апосля неё.
Но при этом он меньше вектора <1.0, 2.5, 3.9> (красный атрибут этого вектора не учитываем,
поскольку он равен единице, а такое число в листе уже писутствует), последний атрибут которого в свою очередь больше,
чем все остальные числа, кроме числа 4.01, поэтому вектора и стояли ”не там, где надо”.
Тоесть, данная функтцыя сортирует текст по алфавитному убыванию (от Я, до А, или от Z, до A),
а числа по возрастанию, причём, если попадается вектор, то в случае обнаружения в нём числа,
которое больше предыдущих блоков, но меньше следующих, то весць вектор пихается между этими блоками.
Так, теперь смотрим, шо получитсця, если в параметр integer stride поставить значение 2:
Тока, сперва поменяйте всё содержимое листа ”a” на [3,"a",1,"c",2,"b"].
А получится следующее:
1,"c", - Первая группа.
2,"b", - Вторая группа.
3,"a". - Третья группа.
Как я уже сказал выше, перед непосредственно самой сортировкой лист разбивается на группы,
каждая из которых содержит указанное число блоков, которые идут ПОДРЯД ДРУГ ЗА ДРУГОМ, ТАК КАК ОНИ СТОЯЛИ ИЗНАЧАЛЬНО,
а сортируются только первые элементы этих групп. Если группы блоков содержат много бессвязных блоков,
то сортировка производиться не будит, тоесть шо изначально в листе лежало, то и выдастьсця.
float llListStatistics(integer operations, list input); - эта функция выдаёт ”статистику” листа.
integer operations – тип операции, которую функции надо применить.
Сопсна возможные типы:
0 он же LIST_STAT_RANGE – эта константа заставляет функцию возвращать… э… какой-то range (диапазон или предел)
1 он же LIST_STAT_MIN – заставляет функцию возвращать самое маленькое число, которое есть в листе.
2 он же LIST_STAT_MAX - заставляет функцию возвращать самое большое число, которое есть в листе.
3 он же LIST_STAT_MEAN - эта константа заставляет функцию возвращать… какой-то mean
(даже как правильно это перевести нипонял).
4 он же LIST_STAT_MEDIAN - эта константа заставляет функцию возвращать… какой-то median.
5 он же LIST_STAT_STD_DEV - эта константа заставляет функцию возвращать… какие-то standard deviation
(стандартные отклонения).
6 он же LIST_STAT_SUM - заставляет функцию возвращать сумму всех целых и дробных чисел находящихсця в листе.
7 он же LIST_STAT_SUM_SQUARES - заставляет функцию возвращать сумму квадратов всех целых и дробных чисел
находящихсця в листе.
8 он же LIST_STAT_NUM_COUNT - заставляет функцию возвращать общее количество всех чисел в листе
(вектора и кватернионы не учитываютсця!).
9 он же LIST_STAT_GEOMETRIC_MEAN - эта константа заставляет функцию возвращать… какой-то geometric mean.
list input – сюда вписывается лист, о котором, сопсна и надо статистику собрать.
Замечу, шо данная функтцыя работает только с числами. Стринги, ключи, вектора и кватернионы
(если таковые в листе присутсцтвуют) ею не учитываютсця.
list llCSV2List(string source); - Эта функция являетсця обратной llList2CSV, она создаёт лист из стринга,
в котором записаны значения разделённые запятой.
list llParseString2List(string source, list separators, list spasers); - О! А вот эта НАИПОЛЭЗНЕЙШАЯ функтцыя разбивает
переменную типа string на несколько частей, тока в отличии от предыдущей имеет куда более гибкие параметры настройки.
string source – тут пишется переменная, которую сопсна и надо разобрать
(обратите вминание переменная должна быть стрингом, или же, если надо разложить,
ну допустим ключ, то его надо преобразовать в string вот таким вота способом (string)peremennaya).
list separators – тут надо либо поставить переменную типа list, в которой хранятся разделители, либо напечатать их самому,
вот так вот: [”-”,”,”]. Знаки, которые тут обозначены воспринимаются функцией, как разделители между которыми заключены
блоки. Сами разделители в лист при этом не попадут.
list spacers – а это почти то же, шо и предыдущее, тока знаки начепятанные тут попадут в лист.
list llParseStringKeepNulls(string source, list separators, list spasers); - эта функция почти то же самое, шо и предыдущая,
тока при её использовании разделители будут не пропускаться, а сохраняться в виде пустого блока (это ”” который).
string source – стринг, который необходимо разделить.
list separators – разделитель заменяемый пустым блоком.
list spacers – сохраняемый разделитель.
string llDumpList2String(list source, string separators); - ну и наконетц эта функция является обратной двум предыдущим.
Она запихивает все блоки листа (который надо вписать в list source) в один стринг разделяя их знаком указанным
в string separators (попрошу обратить внимание на то, шо разделитель является переменной типа STRING, а не листом!)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Угу… значит с пребобразованиями ознакомилистць вроде… тагда переползаем к инвентарным функтцыям:
Инвентарные функции нужны, как явствует из их названия для изменения или перемещения объектов внутри инвентаря объекта.
llAllowInventoryDrop(integer add) – Если параметру integer add поставить значение TRUE,
то ЛЮБОЙ аватар сможет положить что-либо в инвентарь прима содержащего данный скрипт (это очень удобно, если вы хотите,
ну… например поставить у себя на земле смотрелку текстур, которая сразу же натягивает на себя положенную в неё текстуру).
key llGetInventoryKey(string name) – Эта функция выдаёт ключ объекта имя которого указано в string name, правда,
сесна при условии, шо в инвентаре шо-та вообще лежит…
string llGetInventoryName(integer type, integer num) – О, а с помощью вот этой функтции можна узнать имя объекта,
если известен его тип (указываетсця в integer type) и порядковый номер (указывается саатветсна в integer num).
Типы:
-1 он же INVENTORY_ALL – Любой тип.
0 он же INVENTORY_ANIMATION – только анимации.
1 он же INVENTORY_BODYPART – только шейпы и скины тушек.
3 он же INVENTORY_CLOTHING – только одежда.
5 он же INVENTORY_GESTURE – только гэстуры.
6 он же INVENTORY_LANDMARK – только лэндмарки.
7 он же INVENTORY_NOTECARD – только ноуткарты.
10 он же INVENTORY_OBJECT – только примовые объекты.
13 он же INVENTORY_SCRIPT – только скрипты.
20 он же INVENTORY_SOUND – только звуки.
21 он же INVENTORY_TEXTURE – только текстуры.
integer llGetInventoryNumber(integer type) – эта функцыя сообшчает скока всего объектов определённого типа иметсця в
инвентаре. Типы объектов приведены чуть выше.
key llGetInventoryCreator(string item) – эта функтция выдаёт ключ создателя объекта, который лежит в инвентаре прима.
integer llGetInventoryPermMask(string item, integer mask) – эта функция возвращает число, по которому можно узнать,
какие права есть у вещи, лежащей в инвентаре прима.
в string item вбивается имя объекта,
а в integer mask так называемую маску.
Маски:
MASK_BASE – заставляет функтцыю вернуть базовые права установленные непосредсна создателем объекта.
MASK_EVERYONE - заставляет функтцыю вернуть права, которые даны любому аватару (можно или нельзя копирвать,
перемещать объект)
MASK_GROUP - заставляет функтцыю вернуть права, которые имеют аватары принадлежащие к определённой группе
(галку Share with group в Edit-меню вспоминаем).
MASK_NEXT - заставляет функтцыю вернуть права, которые будут даны следующему обладателю объекта.
MASK_OWNER – заставляет функтцыю вернуть ваши права у данного объекта.
Возвращаемые значения:
2147483647, он же PERM_ALL – означает, шо фсе права доступны.
32768, он же PERM_COPY – означает, шо имеютсця права на копирование.
16384, он же PERM_MODIFY - означает, шо имеютсця права на мадификатцыю.
8192, он же PERM_TRANSFER - означает, шо имеютсця права на передачу объекта.
524288, он же PERM_MOVE - означает, шо объект могут двигать.
Так, теперь стоп! Насчёт возвращаемых значений – функция может вернуть не одно, а сразу несколько значений…
В ОДНОЙ ПЕРЕМЕННОЙ!!!
Э… в одном числе несколько значений сразу… эта КАК?! >О___о<
Щасц объясню, - если представить эти числа, в двоичной системе счисления, то мы получим следующие значеня:
2147483647 = 01111111 11111111 11111111 11111111 = PERM_ALL
524288 = 00000000 00001000 00000000 00000000 = PERM_MOVE
32768 = 00000000 00000000 10000000 00000000 = PERM_COPY
16384 = 00000000 00000000 01000000 00000000 = PERM_MODIFY
8192 = 00000000 00000000 00100000 00000000 = PERM_TRANSFER
Заметили?
Шо? Низаметили ешчо?! =Х.х= Ну вы, однако даёте товарисчи…
За исключением ПЕРМИШШН_АЛЛ остальные числа в двоичном представлении имеют всего одну единицу и ни одна из них не стоит
на том же месте, шо и в других константах.
Воо! Пральна, значит доходить фсё-таки начало, если, допустим нам возвращаются одновременно PERM_MOVE, PERM_COPY, PERM_MODIFY и PERM_TRANSFER,
то бинарка (binary - двоичный) будит выглядеть следующим образом:
00000000 00001000 11100000 00000000 – шо в десятиричной системе равно 581632,
шо в свою очередь является СУММОЙ всех четырёх значений – 524288 + 32768 + 16384 + 8192 = 581632.
=О_О= А… как их тогда распознавать из под скрипта-то?
Очень просто, для этого используется следующая конструкция:
If(llGetInventoryPermMask(”Object_name_here”, MASK_OWNER)==PERM_MOVE|PERM_COPY|PERM_MODIFY|PERM_TRANSFER)
{
//Выполнять какой-то код.
}
Вертикальная черта, это двоичный оператор сложения, но это мы разберём попозже, когда будим изучать логику,
а пока шо тока предостерегу от того, шобы вы не путали двоичный оператор | с ЛОГИЧЕСКИМ || это совершенно разные вещи,
первый используется при выполнении вычислений, а второй используется тока в условиях (это if которые) и означает ”ИЛИ”
(ну или ”OR”).
Алсо: попрошу заметить, шо в условии у нас стоит не один, а два знака равенства,
запомните равенство В УСЛОВИИ всегда двойное,
а в самом блоке с кодом (эт который в фигуристых скобках – {}) ВСЕГДА одинарное.
НЕ ПУТАТЬ! Х___________х
Примечание: Если вдруг вам приспичит перевести десятичное число в двоичное, юзаем этот вота скрипт:
// AND - & - оставляет только совпадающие единицы, тоесть 10101 & 10001 = 10001
//(единица в середине левого числа "ушла лесом")
// OR - | - заменяет единицами нули в конечном числе (совпадающие единицы не трогает), тоесть 1001 | 0110 = 1111
// NOT - ~ - побитно реверсирует число, тоесть ~1001 = 0110
// XOR - ^ - оставляет только те единицы, которые попарно не совпадают (остальное обнуляется), тоесть 11011 ^ 01010 = 10001
// Right Sift - >> - сдвигает все биты числа на указанное число вправо (биты вышедшие за границу числа теряются),
//тоесть 10101 >> 2 = 101
// Left Shift - << - тоже, что и предыдущем случае, тока сдвиг идёт влево
// Reminder - % - операция вычисления остатка от деления, тоесть 20 % 18 = 2, тоесть 20/18=1 целая и 2 в остатке,
//вот остаток и возвращается.
integer var=7; //Значение, которое надо перевести в бинарку.
string func_calc(integer input)
{
integer i=0; //Счётчик
integer meta=input; //Переменная, которой присваивается значение входного числа
integer reminder; //Э... ну, как явствует из названия, тута будит храниться остаток от деления.
list output=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; //Лист, включающий в себя 32 значения,
//в которые запишем ответ.
for(i=0; i<32; i++) //До тех пор, пока i меньше 32, увеличивать i на 1 попутно выполняя определённый код.
{
reminder=meta%2; //тута складируем остаток от каждого деления
meta=llFloor(meta/2); //а тута результат деления
output=llListReplaceList(output,[reminder],31-i,31-i); //Складируем ответ в лист
}
return (string)output; //Возвращаем ответ
}
default
{
state_entry()
{
llSay(0,func_calc(var)); //Говорим ответ.
}
}
integer llGetInventoryType(string name) – эта функтцыя возвращает тип объекта, имя которого указано в string name.
Возвращает те же типы, шо описаны в llGetInventoryName, тока к ним добавляется INVENTORY_NONE, каторый,
как и INVENTORY_ALL равен -1.
string llGetScriptName() – эта функция возвращает имя того скрипта, из которого она запрашивается.
integer llGetScriptState(string name) – с помощью этой функции можно запросить текущее состояние указанного в string name
скрипта. Если скрипт работает, то вернётся ТРУЪ (он же 1), а если нет, то FALSE (он же 0).
llSetScriptState(string name, integer off_on) – а с помощью этой функтцыи состояние выбранному скрипту можно поставить.
string name – имя скрипта, которому надо включить/выключить отрубильник.
integer off_on – сопсна сам отрубильник, если стоит 1 – скрипт включается, если 0, то наоборот выключается.
llResetOtherScript(string name) – с помощью этой функции можно перезапустить указанный в string name скрипт.
llGiveInventory(key to_who, string inventory) – эта функция выдаёт указанному в key to_who аватару указанный
в string inventory объект.
llGiveInventoryList(key to_who, string cathegory, list inventory) – а эта даёт указанному в key to_who аватару папку
(имя которой указывается в string cathegory) с несколькими объектами, имена которых прописаны в list inventory.
llRemoveInventory(string inventory) – эта функция удаляет из инвентаря прима указанный в string inventory объект.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Так, с преобразованиями и инвентарём пожалуй всё, теперь перейдём к кое-чему более полезному, а именно к партиклам.
Частицы используются во многих изделиях и зданиях для имитации блеска (кольца, серьги, и прочий ширпотреб),
дыма, искр, огня, снега, взрывов, цепей (уверен, почти все в SL видели ошейники, которые связанны цепью), травы,
фонтанов, испускания фсяких сердечек, смайликов, трассирующих следов от снарядов, лазеров,
лучей от прожекторов или фонарей (один из самых не эффективных, но зато самых эффектных способов применения частитц).
Частица представляет из себя плоскость, на которую натянута текстура, эта плоскость в большинстве случаев повёрнута
перпендикулярно камере (тобиш перпендикулярно экрану).
Частицы запускаются следующей функцией:
llParticleSystem(list rullz):
list rullz – тут, через запятую задаётся список параметров, которые влияют на поведение частиц.
Я их тут рассортировал как в LSL-wiki, шобы было понятно что зачем нужно и как всё это друг с другом вяжется.
Ну, а параметры следующие:
20 он же PSYS_SRC_TARGET_KEY – этот параметр заставляет лететь частицы до указанного объекта.
После этого параметра через запятую пишется переменная типа key с ключём ”полуучателя”.
12 он же PSYS_SRC_TEXTURE – этот параметр позволяет натянуть на партикл текстуру.
Примечание: слишком большие текстуры могут вызвать некислые тормоза
(особенно если параметр PSYS_SRC_BURST_RATE выставлен где-то так в 0.1) да и грузиться они будут довольно долго
(а пока текстуры грузятся из источника вместо частиц будут вылетать одноцветные прямоугольники, шо не езь ”красива”).
Максимальный размер текстуры для частиц не должен быть больше 128х128 пикселей… лучше, конечно, если и того меньше.
После этого параметра ставится имя текстуры лежащей в инвентаре прима или ключ текстуры лежащей в вашем инвентаре
(ну или переменная типа string в которой лежат эти имя или ключ).
2 он же PSYS_PART_START_ALPHA – этот параметр отвечает за то, насколько прозрачной будит частица на момент её появления.
Через запятую после этого параметра пишется дробь (ну или ставится переменная типа float), которая указывает,
насколько прозрачной должна быть частица (0.0 – полностью прозрачная, 1.0 полностью видимая).
4 он же PSYS_PART_END_ALPHA - этот параметр отвечает за то, насколько прозрачной будит частица на момент её исчезновения.
Через запятую после этого параметра пишется дробь, которая указывает, насколько прозрачной должна быть частица
(0.0 – полностью прозрачная, 1.0 полностью видимая).
1 он же PSYS_PART_START_COLOR – этот параметр отвечает за начальный цвет частицы.
Через запятую после этого параметра пишется (vector), а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа), который и устанавливает цвет частицы.
Сразу придупредю, шо цвет в LSL всегда указываетсця в радианах,
тоесть диапазон значений идёт не как в обычном RGB от 0 до 255, а от 0.0 до 1.0.
Значения выше 1.0 будут восприниматься игрой как 1.0.
Но… сесна те, хто работают в основном с графикой и RGB-значениями обалдеют каждый раз подсчитывать
радианное значение цветов, поэтому приведу несколько примеров цветов и скрипт для конвертации RGB в радианные значения:
<1.0,1.0,1.0> - Белый – RGB - <255,255,255>.
<0.0,0.0,0.0> - Чёрный – RGB - <0,0,0>.
<1.0,0.0,0.0> - Красный – RGB - <255,0,0>.
<1.0,1.0,0.0> - Оранжевый – RGB - <255,255,0>.
<0.5,1.0,0.0> - Жёлтый – RGB - <128,255,0>.
<0.0,1.0,0.0> - Зелёный – RGB - <0,255,0>.
<0.0,1.0,1.0> - Голубой – RGB - <0,255,255>.
<0.0,0.0,1.0> - Синий – RGB - <0,0,255>.
<1.0,0.0,1.0> - Фиолетовый – RGB - <255,0,255>.
<1.0,0.0,0.5> - Розовый – RGB - <255,0,128>.
И сопсна сам скрипт цветодекодер:
float RGB_TO_VECTOR=0.003921; //Это у нас будит аналог константы DEG_TO_RAD, тока переводить он будит
//в радианы не градусы, а цвета. Откуда я, сопсна взял это значение - цвета необходимо представить в
//диапазоне от 0 до 1, так? Во! Значит нам сперва надо узнать чему будит равен "одна двести пятьдесят пятая от ста"...
//Шо говорите?.. КАКИЕ НАФИХ 2.55 ?!! =О.О= Нам В РАДИАНЫ надо перевести, а НЕ ИЗ НИХ! =>_<=
//Тоезь, надо 100/255 (а не наоборот!), но тогда мы получим число, которое при умножении на него
//цвета будит давать результат, который в 100 раз больше нужного. Атседова выводим - (100/255)/100.
//И получаем - 0,003921568627450980392156862745098. Обрезаем дробь до 6 знаков после запятой и константа готова.
//Правда, в виду того, что во время вычислений значения округляются, итоговый результат
//будит чуууть-чуть меньше верного...
list parse;
vector col;
default
{
on_rez(integer x)
{
llResetScript(); //При каждом выкладывании перезапускать скрипт.
}
state_entry()
{
llListen(0,"",llGetOwner(),"");
llOwnerSay("Введите RGB-цвет. Пример: 128-64-255");
}
listen(integer chnl, string name, key id, string msg)
{
parse=llParseString2List(msg,["-"],[]); //Разбиваем команду из чата на 3 куска.
if(llGetListLength(parse)==3) //Если количество блоков в листе равно трём...
{
//Присваиваем значение переменной col
col=<0.01*(llRound((llList2Float(parse,0)*RGB_TO_VECTOR)*100)),
0.01*(llRound((llList2Float(parse,1)*RGB_TO_VECTOR)*100)),
0.01*(llRound((llList2Float(parse,2)*RGB_TO_VECTOR)*100))>;
//Сопсна, как понимать сию конструктцыю:
//Паскольку нам нужно более-менее понятное значение, то тут взятое из листа число, переведёное в радиан сперва
//умножается на 100, патом округляется до целого, затем делится обратно на 100... э... вернее умножается на 0.01
//это, для тех, кто забыл равносильные действия, просто при делении на 100 LSL по непонятной причине начанает
//плющщить, кароче... в итоге у нас вместо линнююююющей дроби получается она же но всего с двумя знаками после
//запятой, такую запись понимать гораздо легче, да и цветовая погрешность на глаз всёравно почти не различима.
//Хатя... если хотите, чтобы погрешность была минимальной, тогда сотрите исходную и раскомментируйте
//следуюшую строчку:
//col= < llList2Float(parse,0)*RGB_TO_VECTOR, llList2Float(parse,1)*RGB_TO_VECTOR, llList2Float(parse,2)*RGB_TO_VECTOR > ;
llOwnerSay((string)col); //Говорим результат овнеру.
parse=[]; //Очищаем лист.
}
else{} //Если количество блоков в листе не равно трём, ничего не делаем.
}
}
3 он же PSYS_PART_END_COLOR - этот параметр отвечает за конечный цвет частицы.
Через запятую после этого параметра пишется вектор (или вставляется переменная этого типа),
который и устанавливает цвет частицы. Работает только при активной маске INTERP_COLOR_MASK.
5 он же PSYS_PART_START_SCALE - этот параметр отвечает за начальный размер частицы.
Через запятую после этого параметра пишется vector, а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа), который и устанавливает размер частицы. Размер указывается в метрах,
максимально возможный размер – 4 м.
Примечание: значения вписываются тока в первые два значения, тоесть вот так - <2.5,.5,FALSE>
6 он же PSYS_PART_END_SCALE - этот параметр отвечает за конечный размер частицы.
Через запятую после этого параметра пишется float, а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа), который и устанавливает размер частицы. Размер указывается в метрах,
максимально возможный размер – 4 м.
Примечание: числа вписываются тока в первые два значения, тоесть вот так - <2.5,.5,FALSE>
7 он же PSYS_PART_MAX_AGE - этот параметр отвечает за время жизни частицы.
Через запятую после этого параметра пишется vector, а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа),который и устанавливает время жизни частицы. Время жизни задаётся в секундах,
максимально возможное значение, если мне ни с кем не изменяет память - 9 сек.
19 он же PSYS_SRC_MAX_AGE - этот параметр отвечает за время жизни источника частиц.
По русски говоря – сколько времени вы тут поставите, столько и будит работать функция.
Как только время истекает частицы перестают появляться и единственный способ их включить,
это вновь вызвать функцию llParticleSystem или перезапустить скрипт.
Через запятую после этого параметра пишется float, а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа), который и устанавливает время жизни источника.
8 он же PSYS_SRC_ACCEL – этот параметр отвечает за силу ускорения частиц.
А… сопсна… шо есть это ускорение? =О.о=
Ускорение представляет из себя примерно следующее – когда частица только появилась,
она движется довольно медленно, но по мере приближения к конечной точке начинает разгоняться.
Через запятую после этого параметра пишется float, а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа), который и устанавливает ускорение.
Примечание: если выставить отрицательное значение, то частицы будут не ускоряться, а наоборот
замедляться.
15 он же PSYS_SRC_BURST_PART_COUNT – этот параметр отвечает за то сколько частиц будит сгенерировано за раз.
Через запятую после этого параметра пишется integer, а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа), который и устанавливает количество генерируемых частиц.
13 он же PSYS_SRC_BURST_RATE – а этот параметр устанавливает эти самые ”разы”,
тоесть определяет раз в какой промежуток времени будит производиться генерация частиц.
Через запятую после этого параметра пишется float, а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа), который и устанавливает интервал между генерациями.
16 он же PSYS_SRC_BURST_RADIUS – этот параметр устанавливает радиус (в метрах), в котором возможна генерация частиц.
Если поставить 0, то генерация будит происходить из центральной точки прима.
Через запятую после этого параметра пишется float, а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа), который и устанавливает радиус.
17 он же PSYS_SRC_BURST_SPEED_MIN – этот параметр устанавливает минимальную скорость частицы.
Через запятую после этого параметра пишется float, а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа), который и устанавливает скорость.
18 он же PSYS_SRC_BURST_SPEED_MAX – а этот устанавливает максимальную скорость частицы.
Через запятую после этого параметра пишется float, а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа), который и устанавливает скорость.
22 он же PSYS_SRC_ANGLE_BEGIN – этот параметр устанавливает угол верхнего конуса в котором не производится генерация частиц.
Через запятую после этого параметра пишется float, а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа), который и устанавливает угол.
23 он же PSYS_SRC_ANGLE_END - этот параметр устанавливает угол нижнего конуса в котором не производится генерация частиц.
Через запятую после этого параметра пишется float, а затем вставляетсця значение соответствующего типа
(или вставляется переменная этого типа), который и устанавливает угол.
Если предсталять последние два параметра в виде картинки, то выглядеть это будит так вота:
21 он же PSYS_SRC_OMEGA – этот параметр указывает по какой оси и с какой скоростью будит вращаться источник частиц.
Через запятую после этого параметра пишется vector (или вставляется переменная этого типа),
который и устанавливает угол и скорость вращения.
9 он же PSYS_SRC_PATTERN – этот параметр задаёт шаблон генерации частиц.
Можно поставить только ОДИН из ниже перечисленных шаблонов:
1 он же PSYS_SRC_PATTERN_DROP – при этом шаблоне, частицы будут вести себя… ну… примерно, как капающая из крана вода.
2 он же PSYS_SRC_PATTERN_EXPLODE – при этом шаблоне частицы разлетаются во все стороны (самый часто используемый).
4 он же PSYS_SRC_PATTERN_ANGLE – при этом шаблоне частицы летят в одной плоскости в разные стороны.
8 он же PSYS_SRC_PATTERN_ANGLE_CONE – при этом шаблоне частицы генерируются только в определённом конусе.
16 он же PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY – а этот шаблон заставляет частицы генерироваться обратно предыдущему
шаблону, тоесть во все стороны, кроме заданного в PSYS_SRC_ANGLE_BEGIN и PSYS_SRC_ANGLE_END конусов.
Сесна, если шаблон не является PSYS_SRC_PATTERN_ANGLE, PSYS_SRC_PATTERN_ANGLE_CONE, или PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY,
то параметры PSYS_SRC_ANGLE_BEGIN и PSYS_SRC_ANGLE_END работать НЕ БУДУТ!
0 он же PSYS_PART_FLAGS – а после этого параметра ставятсця так называемые ”флаги” – они отвечают за некоторые визуальные
эффекты и за траектории полёта частиц. Ставятся нужные флаги через | если шо…
4 он же PSYS_PART_BOUNCE_MASK – если стоит этот флаг, то частицы долетевшие до нуля по локальной оси Z начанают
подскакивая разлетаться в стороны. Широко используетсця во всякого рода фонтанах.
256 он же PSYS_PART_EMISSIVE_MASK – этот флаг выставляет текстуре партикла полное самосвечение
(по типу галки Full Bright в етит-меню).
16 он же PSYS_PART_FOLLOW_SRC_MASK – при этом флаге все частицы перемещаются вместе с источником.
32 он же PSYS_PART_FOLLOW_VELOCITY_MASK – если поставлен этот флаг, то частицы генерируютсця,
тока если источник движется.
1 он же PSYS_PART_INTERP_COLOR_MASK – если есть этот флаг, то работают параметры PSYS_PART_START_COLOR и PSYS_PART_END_COLOR.
2 он же PSYS_PART_INTERP_SCALE_MASK – то же, шо и предыдущее, тока для параметров PSYS_PART_STSRT_SCALE и PSYS_PART_END_SCALE.
128 он же PSYS_PART_TARGET_LINEAR_MASK – если стоит этот флаг, то работает параметр PSYS_SRC_TARGET_KEY,
тоесть все частицы полетят только к указанному объекту.
64 он же PSYS_PART_TARGET_POS_MASK – этот флаг не может быть поставлен, если активен предыдущий,
поскольку если таргет_пос активен, то конечная цель движения всех частиц это центр источника частиц.
8 он же PSYS_PART_WIND_MASK – если активен этот флаг, то частицы при движении немного сносятся ветром.
Так, параметры мы рассмотрели, теперь чешим тыкаву и смотрим, как их использовать на практике:
default
{
state_entry()
{
llParticleSystem([
PSYS_SRC_TEXTURE, "UUID текстуры",
PSYS_PART_START_COLOR, <.3,.4,.5>,
PSYS_PART_END_COLOR, <.5,.6,.7>,
PSYS_PART_START_SCALE, <.1,.5, FALSE>,
PSYS_PART_END_SCALE, <.05,4.0, FALSE>,
PSYS_PART_START_ALPHA, (float).7,
PSYS_PART_END_ALPHA, (float).5,
PSYS_SRC_BURST_PART_COUNT, (integer)1,
PSYS_SRC_BURST_RATE, (float) 0.05,
PSYS_PART_MAX_AGE, (float)1.0,
PSYS_SRC_MAX_AGE,(float) 0.0,
//Паттерны:
PSYS_SRC_PATTERN, (integer)8,
//1, он же DROP
//2, он же EXPLODE
//4, он же ANGLE
//8, он же ANGLE_CONE
// Параметры, которые работают с любым паттерном, акромя DROP
PSYS_SRC_BURST_SPEED_MIN, (float)0.0,
PSYS_SRC_BURST_SPEED_MAX, (float)0.0,
PSYS_SRC_BURST_RADIUS, 5.0,
// Параметры, которые работают только при активных паттернах ANGLE & ANGLE_CONE)
PSYS_SRC_ANGLE_BEGIN, (float) .25*PI,
PSYS_SRC_ANGLE_END, (float)0.0*PI,
// PSYS_SRC_OMEGA, <0,0,0>,
PSYS_SRC_ACCEL, <0.0,0.0,-10.5>,
// PSYS_SRC_TARGET_KEY, "UUID целевого аватара или прима",
//Флаги
PSYS_PART_FLAGS, (integer)( 0
| PSYS_PART_INTERP_COLOR_MASK
| PSYS_PART_INTERP_SCALE_MASK
| PSYS_PART_EMISSIVE_MASK
| PSYS_PART_WIND_MASK
| PSYS_PART_BOUNCE_MASK
// | PSYS_PART_FOLLOW_VELOCITY_MASK
// | PSYS_PART_FOLLOW_SRC_MASK
// | PSYS_PART_TARGET_POS_MASK
// | PSYS_PART_TARGET_LINEAR_MASK
) ]);
}
}
Примечание: После удаления скрипта, частитцы как из прима летели, так лететь и продолжат.
Для того шобы накрыть их медным тазом, их надо обнулить - llParticleSystem([]);
Выше приведённые значения при изменении дают результаты от фонтанов частиц, до ”чёрной дыры”.
Халявные скрипты с партиклами для исследования и раздраконивания можно в большом количестве найти в Particle laboratory.















