TESAll.Ru

  

OBSE В МАССЫ

YourBunnyWrote

 

2011


ЧАСТЬ 2

СОДЕРЖАНИЕ


4.    Глава 4. ПОЛЬЗОВАТЕЛЬСКИЕ ФУНКЦИИ
    4.1.    Что такое функция?
    4.2.    Пользовательские функции
    4.3.    Обработчики событий
5.    Глава 5. СПЕЦИАЛЬНЫЕ ФУНКЦИИ OBSE
    5.1.    Функции для работы с массивами


Глава 4. ПОЛЬЗОВАТЕЛЬСКИЕ ФУНКЦИИ

Принципиально новое понятие в рамках скриптового языка Oblivion-а.


Что такое функция?

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

Функция, которая не предусматривает возвращение результатов (не имеет значения), называется процедурой.

Вызов функцией самой себя называется рекурсией.

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

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


Пользовательские функции

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

Аргументы функции перечисляются в системных скобках, за ключевым словом Function, через запятую. Функция в OBSE может иметь до десяти аргументов, или не иметь их вовсе. Все аргументы функции – переменные, объявляются как в обычном скрипте.

Значение функции определяется ключевым словом SetFunctionValue. Значением функции может служить как константа, так и переменная. Возврат из функции, имеющей или не имеющей значения, выполняется ключевым словом Return. Возврат из функции означает прекращение её выполнения. Помните, нельзя использовать Return в циклах!

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 ScriptName FunctionName ; Имя функции
 
 type arg1    ; Первый аргумент функции
 type arg2    ; Второй аргумент функции
 …
 type arg10   ; Десятый аргумент функции
 type RetVal  ; Значение функции
 
 Begin Function {arg1arg2, …, arg10}
       ; …
       SetFunctionValue RetVal ; Определение значения функции
       Return                  ; Возврат из функции
 End


Для примера составим функцию, суммирующую два числа.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 ScriptName Sum
 
 float Num1 ; Первое число
 float Num2 ; Второе число
 
 Begin Function {Num1, Num2}
       Let Num1 += Num2       ; Находим сумму чисел
       SetFunctionValue Num1  ; Задаём возвращаемое значение
       Return                 ; Возвращаем результат
 End


Для вызова пользовательской функции нужно использовать ключевое слово Call.

1.
2.
3.
4.
5.
6.
7.
8.
 ScriptName SomeScript
 
 float Var
 
 Begin GameMode
       Let Var := Call Sum 10 20
       ; Var == 30
 End

 

Как я уже говорил ранее, не все функции обязательно должны иметь аргументы и/или возвращать значение. Давайте составим пример такой функции, она будет просто добавлять сто Септимов в карман игрока.

1.
2.
3.
4.
5.
 ScriptName ProcedureExample
 
 Begin Function {}
       Player.AddItem Gold001 100
 End


В OBSE существует функция, которая позволяет определить скрипт (функция возвращает ссылку на него), из которого произошёл вызов функции, она называется  GetCallingScript.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 ScriptName GetCallingScriptExample
 
 Begin Function {}
       If GetCallingScript == MyQuestScript
             SetFunctionValue 1
       Else
             SetFunctionValue 0
       EndIf
       Return
 End

 

Функция GetCallingScript ничего не возвращает, если вызов функции произошёл без помощи оператора Call или функция была использована как обработчик события.


Обработчики событий

Понятие заимствованное из .NET языков программирования. Обработчики событий являются функциями, которые автоматически вызываются программой, если происходит определённое событие. Все события в OBSE предопределены, с большинством из них вы должны быть уже знакомы, если ранее вам уже приходилось писать скрипты на родном скриптовом языке Oblivion-а:

Имя события

Аргумент события : Тип

Описание

Первый аргумент

Второй аргумент

OnHit

Цель:ref

Атакующий:ref

Происходит при нанесении атакующим урона цели

OnHitWith

Цель:ref

Оружие:ref

Происходит при нанесении оружием урона цели

OnMagicEffectHit

Цель:ref

Магический_эффект:string (четырёхсимвольный код)

Происходит при наложении магического эффекта на цель

OnActorEquip

Цель:ref

Предмет:form

Происходит при надевании предмета целью

OnDeath

Цель:ref

Убийца:form

Происходит при смерти цели

OnMurder

Цель:ref

Убийца:form

Происходит при убийстве цели убийцей

OnKnockout

Цель:ref

 

Происходит при нокаутировании цели

OnActorUnequip

Цель:ref

Предмет:form

Происходит при снятии предмета целью

OnAlarm Trespass

Заметивший:ref

Нарушитель:ref

Происходит, когда заметивший актёр поднимает тревогу, если нарушитель совершил взлом.

OnAlarm Steal

Заметивший:ref

Нарушитель:ref

Происходит, когда заметивший актёр поднимает тревогу, если нарушитель совершил кражу.

OnAlarm Attack

Заметивший:ref

Нарушитель:ref

Происходит, когда заметивший актёр поднимает тревогу, если нарушитель совершил нападение.

OnAlarm Pickpocket

Заметивший:ref

Нарушитель:ref

Происходит, когда заметивший актёр поднимает тревогу, если нарушитель совершил карманную кражу.

OnAlarm Murder

Заметивший:ref

Нарушитель:ref

Происходит, когда заметивший актёр поднимает тревогу, если нарушитель совершил убийство.

OnPackageChange

Цель:ref

Пакет:form

Происходит при смене целью AI пакета

OnPackageStart

Цель:ref

Пакет:form

Происходит при старте целью AI пакета

OnPackageDone

Цель:ref

Пакет:form

Происходит при завершении целью AI пакета

OnStartCombat

Цель:ref

Опонент:ref

Происходит, когда цель нападает на оппонента

OnActivate

Активатор:ref

Цель:ref

Происходит, когда цель активирует активатор

OnVampireFeed

NONE

 

Происходит, когда вампир перестаёт питаться

OnSkillUp

Код_навыка:int

 

Происходит при повышении навыка игрока

OnScriptedSkillUp

skillActorValueCode:int amount:int

 

Происходит перед изменением навыка игрока скриптовой командой

OnDrinkPotion

Цель:ref

Зелье:form

Происходит, когда цель принимает зелье

OnEatIngredient

Цель:ref

Ингридиент:form

Происходит, когда цель съедает ингредиент

OnActorDrop

Цель:ref

Предмет:ref

Происходит, когда цель выбрасывает/роняет предмет

OnSpellCast

Цель:ref

Заклинание:form

Происходит, когда цель произносит заклинание

OnScrollCast

Цель:ref

свиток:form

Происходит, когда цель читает заклинание со свитка

OnFallImpact

Цель:ref

 

Происходит, когда цель упадёт с опасной высоты, перед тем, как получить повреждение

OnMapMarkerAdd

Маркер:ref

 

Происходит при добавлении маркера на карту игрока

OnHealthDamage

Величина_повреждения:float

Атакующий:ref

Происходит перед тем, как актёр получит повреждение. Если актёр свалится с высоты, то аргумент «Атакующий» будет иметь нулевое значение. Для определения актёра получившего повреждение стоит использовать функцию GetSelf.

OnCreateSpell

Заклинание:ref

 

Происходит, когда игрок создаёт новое заклинание

OnCreatePotion

Зелье:ref

Уникальное_ли:int

Происходит, когда игрок приготовит новое зелье. Второй аргумент будет равен 1, если игрок впервые приготовил такое зелье, иначе он будет равен 0.

OnEnchant

Предмет:ref

 

Происходит, когда игрок зачаровывает предмет.

OnAttack

Цель:ref

 

Происходит, когда цель начинает проигрывать анимацию атаки или наложения заклинания.

OnBowAttack

Цель:ref

 

Происходит, когда цель начинает проигрывать анимацию стрельбы из лука.

OnRelease

Цель:ref

 

Происходит, когда цель заканчивает проигрывать анимацию атаки, стрельбы или наложения заклятья.

OnBlock

Цель:ref

 

Происходит, когда цель начинает проигрывать анимацию блокирования ударов.

OnRecoil

Цель:ref

 

Происходит, когда цель начинает проигрывать анимацию получения отдачи.

OnStagger

Цель:ref

 

Происходит, когда цель начинает проигрывать анимацию получения урона.

OnDodge

Цель:ref

 

Происходит, когда цель начинает проигрывать анимацию уклонения от атаки.

LoadGame

Имя_файла:string

 

Происходит при загрузке игры

SaveGame

Имя_файла:string

 

Происходит при сохранении игры

PostLoadGame

Игра_загружена_удачно:bool

 

Происходит после загрузки игры. Передаёт функции-обработчику события 1, если игра была загружена удачно, 0 - если нет

ExitGame

NONE

 

Происходит при выходе из игры

ExitToMainMenu

NONE

 

Происходит при выходе в главное меню

QQQ

NONE

 

Происходит при выходе из игры посредствам вызова консольной команды QQQ

OnNewGame

NONE

 

Происходит при старте новой игры


Для того, чтобы задать обработчик события, существует функция SetEventHandler, её синтаксис таков:

1.
 (success:bool) SetEventHandler eventID:string functionScript:ref filter1:pair filter2:pair

 

Где, eventID – имя события, одно из тех, которые наведены в таблице; functionScript – имя функция, которая будет использована для обработки события;

filter1 – фильтр первого аргумента функции-обработчика;

filter2 – фильтр второго аргумента функции-обработчика.


Функция SetEventHandler возвращает единицу, если удалось назначить указанную функцию обработчиком события, или 0 – если нет.

Аргументы filter1 и filter2 применяются для фильтрации аргументов, передаваемых функции-обработчику события. Если их не задавать, то обработчику события будут передаваться все аргументы, инициируемые определённым событием.

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

1.
2.
3.
4.
5.
6.
7.
8.
 ScriptName OnHitHandlerExample
 
 ref Target
 ref Attacker
 
 Begin Function {Target, Attacker}
       Print Attacker.GetName + " attacked " + Target.GetName
 End


И инициализируем её как обработчик события:

1.
2.
3.
4.
5.
 ScriptName OnHitHandlerQuestScript
 
 Begin GameMode
       SetEventHandler "OnHit" OnHitHandlerExample
 End

 

В таком случае, в ячейке, где разворачиваются игровые действия, на данный момент, любое событие OnHit инициализирует выполнение функции OnHitHandlerExample. Т.е. если любой NPC или Creature нанесёт урон любому другому NPC или Creature  в ячейке, в которой находится игрок, будет вызвана функция OnHitHandlerExample, которой будут переданы ссылки атакуемого и атакующего.

Если мы хотим, допустим, чтобы это событие выполнялось только когда атакуют игрока, следует установить фильтр первому аргументу, согласно описанию события OnHit.

1.
2.
3.
4.
5.
 ScriptName OnHitHandlerQuestScript
 
 Begin GameMode
       SetEventHandler "OnHit" OnHitHandlerExample "ref"::Player.GetSelf
 End

 

Оператор :: создаёт пару “Ключ”::”Значение”. Ключ должен иметь значение типа соответствующего аргумента, согласно перечню событий.

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

Если мы хотим избавиться от обработчика события, следует использовать функцию RemoveEventHandler. Её синтаксис аналогичен функции SetEventHandler.

1.
2.
3.
4.
5.
 ScriptName OnHitHandlerQuestScript
 
 Begin GameMode
       RemoveEventHandler "OnHit" OnHitHandlerExample
 End

 

Если у нас есть несколько обработчиков события OnHit, то вызов функции RemoveEventHandler без фильтров приведёт к удалению их всех.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
 ScriptName OnHitHandlerQuestScript
 
 Begin GameMode
       SetEventHandler "OnHit" OnHitHandlerExample
       SetEventHandler "OnHit" OnHitHandlerExample "ref"::Player.GetSelf
 ; ----------------------------------------------------------------------
       RemoveEventHandler "OnHit" OnHitHandlerExample
       ; Удалит все события OnHit
 ; ----------------------------------------------------------------------
       RemoveEventHandler "OnHit" OnHitHandlerExample "ref"::Player.GetSelf
       ; Удалит события только с соответствующим фильтром
 End


С помощью функции GetCurrentEventName, вызванной из функции-обработчика события, можно узнать имя текущего события. Это полезно, если одна функция используется как обработчик нескольких событий.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
 ScriptName MultiEventHandlerFunction
 
 ref Arg1
 ref Arg2
 
 Begin Function {Arg1, Arg2}
       If Eval (GetCurrentEventName == "OnHit")
             Print Arg2.GetName + " атаковал " + Arg1.GetName
       ElseIf Eval (GetCurrentEventName == "OnActorEquip")
             Print "Игрок " + Arg1.GetName + " одел " + Arg2.GetName
       EndIf
 End




Глава 5. СПЕЦИАЛЬНЫЕ ФУНКЦИИ OBSE

Функции для работы с массивами

ar_Construct – создаёт массив. Синтаксис:

(array_var) ar_Construct arrayType:string

Где,    arrayType – тип массива:

Array – индексный массив

Map – вещественный массив

StringMap – ассоциативный массив


ar_Size – возвращает количество элементов массива. Синтаксис:

(size:int) ar_Size array:array_var

Где,    array – массив, размер которого стоит определить.


ar_Dump – отладочная функция. Выводит в консоль все пары “Ключ”:”Значение” для выбранного массива. Синтаксис:

(nothing) ar_Dump array:array_var

Где,    arrayмассив.

 

ar_DumpID – отладочная функция. Делает то же самое, что и ar_Dump, за исключением того, что принимает ID массива вместо array_var .

(nothing) ar_Dump array:array_var

Где,    array – массив.

 

ar_Erase – удаляет элемент массива, диапазон элементов или все элементы массива. Возвращает количество удалённых элементов.

(numRemoved:int) ar_Erase target:array index:arrayIndex

(numRemoved:int) ar_Erase target:array range:slice

Где,    target – массив.

index – индекс элемента массива, который стоит удалить. Если этот аргумент пропущен, то будут удалены все элементы массива. Индекс следующих за удалённым элементов будет смещён на единицу.

range – стартовый индекс диапазона элементов, которые нужно удалить.

slice конечный индекс диапазона элементов, которые нужно удалить.


1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 Let Arr := ar_Construct Array
 Let StrMp := ar_Construct StringMap
 Let Mp := ar_Construct Map
 While Tmp < 10
       Let Arr[Tmp] := StrMp["Elem" + $Tmp] := Mp[Tmp / 10] := Tmp
 Loop
 ; ar_Size Arr == ar_Size StrMp == ar_Size Mp == 10
 ar_Erase Arr 5                 ; ar_Size Arr == 9
 ar_Erase StrMp "Elem3":"Elem6" ; ar_Size StrMp == 6
 ar_Erase Mp                    ; ar_Size Mp == 0

 

 

ar_Find – ищет значение в массиве. Возвращает ключ первого попавшегося элемента массива, значение которого соответствует искомому. Если искомому значению не соответствует ни один элемент массива, то возвращает пустую строку, если поиск происходил в ассоциативном массиве, или число -99999.0 – если в индексном или вещественном.

(key:stringOrNumber) ar_Find value:stringOrNumberOrForm arrayToSearch:array inRange:range

Где,    value – искомое значение. Может быть строкой, числом или формой.

arrayToSearch – массив, в котором будет происходить поиск.

inRangeдиапазон элементов массива, среди которых будет происходить поиск. Если не указан, то поиск будет происходить среди всех элементов массива.

 

ar_Sort – сортирует значения элементов массивов по возрастанию или по убыванию. Возвращает новый, отсортированный массив, связь «Ключ»::»Значение» не сохраняется. Внимание, тип элементов массива, который сортируется, должен быть одинаковым (строка, число, или объект), в противном случае функция возвращает пустой массив. Строки сортируются по алфавиту и без учёта регистра, номера - в номерном порядке, объекты - по ID.

(sortedArray:Array) ar_Sort toSort:array sortDescending:bool

Где,    toSort – массив, который будет отсортирован.

sortDescendingсортировать в обратном порядке. 1 – ДА, 0 – НЕТ. Указывать этот параметр не обязательно, по умолчанию сортировка происходит в прямом порядке.

 

ar_SortAlpha – сортирует значения элементов массивов по алфавиту, по возрастанию или по убыванию. Возвращает новый, отсортированный массив, связь «Ключ»::»Значение» не сохраняется. В отличие от функции ar_Sort, не требует, чтобы значения элементов массива имели один тип. Если в массиве содержатся и численные и строковые значения, то численные значения преобразуются в строки, формы сортируются по имени, если такое имеется, иначе - по ID.

(sortedArray:Array) ar_SortAlpha toSort:array sortDescending:bool

Где,    toSort – массив, который будет отсортирован.

sortDescendingсортировать в обратном порядке. 1 – ДА, 0 – НЕТ. Указывать этот параметр не обязательно, по умолчанию сортировка происходит в прямом порядке.

 

ar_Copy – создаёт точную копию массива. Если копируемый массив содержит другие массивы, то копия будет содержать указатели на те самые массивы.

(copy:array) ar_Copy src:array

Где,    src – массив, который будет скопирован.


ar_DeepCopy – то же самое, что и ar_Copy, за исключением того, что делает копии всех вложенных массивов.

(copy:array) ar_DeepCopy src:array

Где,    src – массив, который будет скопирован.

 

ar_First – возвращает ключ первого элемента массива.

(key:arrayKey) ar_First src:array

Где,    src – массив.

 

ar_Last – возвращает ключ последнего элемента массива.

(key:arrayKey) ar_Last src:array

Где,    src – массив.

 

ar_Next – возвращает ключ следующего элемента массива.

(key:arrayKey) ar_Next src:array precedingKey:arrayKey

Где,    src – массив.

precedingKey ключ текущего элемента массива.

 

ar_Prev – возвращает ключ предыдущего элемента массива.

(key:arrayKey) ar_Prev src:array prevKey:arrayKey

Где,    src – массив.

precedingKey ключ текущего элемента массива.

 

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

(badKey:int) ar_BadNumericIndex

 

ar_BadStringIndex – то же самое, что и ar_BadNumericIndex для ассоциативных массивов.

(badKey:string) ar_BadStringIndex

 

ar_Keys – возвращает индексный массив, содержащий ключи элементов заданного массва.

(keys:Array) ar_Keys src:array

Где,    src – массив.

 

ar_HasKey – возвращает 1, если заданный массив имеет элемент с заданным ключом, иначе возвращает 0.

(hasKey:bool) ar_HasKey src:array key:arrayKey

Где,    src – массив.

key – ключ.

 

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

(badKey:int) ar_BadNumericIndex

 

ar_List – возвращает индексный массив из последовательности аргументов. Может принимать до двадцати аргументов произвольного типа. Рекомендуется разделять аргументы через запятые.

(list:Array) ar_List element0:multi element1:multi ... element19:multi

 

ar_Resize – изменяет размер указанного индексного массива. Если новый размер меньше текущего размера массива, то элементы с превышающими его индексами будут отброшены. Если новый размер, наоборот - больше, то новые элементы будут добавлены в конец массива. По умолчанию они имеют значение 0, но могут принимать и любое другое значение, определяемое необязательным параметром функции paddingValue. Возвращает единицу, если удалось изменить размер массива, ноль – если нет.

(bResized:bool) ar_Resize array:Array newSize:int paddingValue:multi

Где,    array – массив.

newSize – новый размер массива.

paddingValue – значение, которое будет использовано для новых элементов массива.

 

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

(bInserted:bool) ar_Insert array:Array index:int valueToInsert:multi

Где,    array – массив.

index – индекс нового элемента.

valueToInsert – значение нового элемента.


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

(bInserted:bool) ar_Insert target:Array index:int rangeToInsert:Array

Где,    target – массив.

index – индекс первого элемента диапазона в целевом массиве.

rangeToInsert – индексный массив элементов, которые будут добавлены в целевой массив.


ar_Range – возвращает индексный массив, состоящий из последовательности целых чисел, от начального до конечного числа, с заданным шагом.

(range:Array) ar_Range start:int end:int step:int

Где,    start – стартовое число.

end – конечное число.

step – величина шага.


1.
2.
3.
4.
 Let Arr := ar_Range 5 10 2
 ; Arr[0] == 5
 ; Arr[1] == 7
 ; Arr[2] == 9

 

 

ar_Map – возвращает вещественный или ассоциативный массив, состоящий из аргументов функции. Аргументы «Ключ»::»Значение», которых может быть до двадцати.

(Map/StringMap) ar_Map key-value pair: key-value pair: key-value pair: entry_1:pair


1.
2.
3.
 Let Arr := ar_Map "Name"::"Alex" "Age"::20
 ; Arr["Name"] == "Alex"
 ; Arr["Age"] == 20

 

 

ar_Append – добавляет новый элемент в конец массива.

(nothing) ar_Append array: toInsert:

Где,    array – массив.

toInsert – значение.



Вернутся к части 1.

Войдите или зарегистрируйтесь, чтобы оставлять комментарии.