Difference between revisions of "User Defined Function"
imported>Odessa m |
imported>Pintocat |
||
(4 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{Template:Community_Wiki}} | |||
==Overview== | ==Overview== | ||
User defined functions (UDF) are added by NVSE V4. They must be saved as 'object' type scripts that must use the "Function" block type only. Although 'object' type, they must not be attached to any object and are instead called directly by script name from within other scripts, using the [[Call]] command. | User defined functions (UDF) are added by NVSE V4. They must be saved as 'object' type scripts that must use the "Function" block type only. Although 'object' type, they must not be attached to any object and are instead called directly by script name from within other scripts, using the [[Call]] command. | ||
UDFs may optionally return a single value of any type, using the [[SetFunctionValue]] command within them. They may optionally accept | UDFs may optionally return a single value of any type, using the [[SetFunctionValue]] command within them. They may optionally accept up to 15 arguments of any type, which are defined within curly braces: | ||
<pre> | <pre> | ||
scn SomeUDF | |||
int arg1 ; * args are optional | int arg1 ; * args are optional | ||
ref arg2 | ref arg2 | ||
Line 9: | Line 14: | ||
Begin Function { arg1, arg2, arg3... } | Begin Function { arg1, arg2, arg3... } | ||
; * | ; * do whatever like any other script | ||
End | End | ||
</pre> | </pre> | ||
and called in a similar way to regular functions: | and called in a similar way to regular functions: | ||
<pre> | <pre> | ||
scn SomeOtherScript | |||
... | |||
call SomeUDF arg1, arg2, arg3... | |||
</pre> | |||
let SomeVariable := | However, to assign the return to a variable, [[Let]] must be used rather than <b>set .. to ..</b>, and to use in a conditional, [[Eval|if eval]] rather than simply <b>if</b>: | ||
<pre> | |||
let SomeVariable := call SomeOtherUDF arg1 | |||
if eval (call SomeSuitableUDF) | if eval (call SomeSuitableUDF) | ||
Line 23: | Line 33: | ||
</pre> | </pre> | ||
== | ==Examples== | ||
<pre> | |||
scn GetRandomForm | |||
; *** This script accepts a form list and returns one random form from it | |||
; local variables | |||
int iCount | |||
int iChoice | |||
ref RandomForm | |||
; arguments | |||
ref rFormList | |||
Begin Function { rFormList } | |||
let iCount := ListGetCount rFormList | |||
let iChoice := Rand 0, iCount | |||
let RandomForm := ListGetNthForm rFormList, iChoice | |||
SetFunctionValue RandomForm | |||
End | |||
</pre> | |||
<pre> | <pre> | ||
scn fnShuffle | scn fnShuffle | ||
Line 70: | Line 104: | ||
End | End | ||
</pre> | </pre> | ||
==Accepting any type arguments (advanced)== | |||
In some contexts, it is useful to allow arguments of any type for a UDF. Since [[Array Variable|array]] elements can be any type, this can be conveniently achieved using the [[NVSE Expressions]], <b>*</b> ('box') and <b>&</b> ('unbox'), and the [[TypeOf]] / [[GetType]] functions. | |||
<pre> | |||
scn MyUDF | |||
array_var AnyTypeArgument | |||
Begin Function { AnyTypeArgument } | |||
if eval (TypeOf *AnyTypeArgument) == "form" | |||
... | |||
End | |||
</pre> | |||
<pre> | |||
ref MyRef | |||
int MyInt | |||
call MyUDF &MyRef | |||
call MyUDF &MyInt | |||
</pre> | |||
==Notes== | ==Notes== | ||
*UDFs may be used recursively by saving the script once first without the sub call. | *UDFs may be used recursively by saving the script once first without the sub call. | ||
==See Also== | ==See Also== | ||
Line 79: | Line 133: | ||
*[[Eval]] | *[[Eval]] | ||
*[[Let]] | *[[Let]] | ||
*[[Script Compiler Override]] | |||
==External Links== | ==External Links== | ||
*[ | *[http://www.loverslab.com/topic/26802-tutorial-nvse4-part-2-user-defined-functions-udfs/ Tutorial on User Defined Functions in NVSE 4] | ||
[[Category:NVSE]] | [[Category:NVSE]] | ||
[[Category:User Defined Functions]] |
Latest revision as of 12:31, 7 May 2017
Please Note: The official wiki is no longer being maintained by the community[edit source]
The modding community for Fallout 3 and Fallout New Vegas has created its own wiki due to onerous and painful captcha requirements for every edit.
The active wiki contributors have moved to the new wiki -- for the most current information, visit:
http://geckwiki.com[edit source]
Overview[edit | edit source]
User defined functions (UDF) are added by NVSE V4. They must be saved as 'object' type scripts that must use the "Function" block type only. Although 'object' type, they must not be attached to any object and are instead called directly by script name from within other scripts, using the Call command.
UDFs may optionally return a single value of any type, using the SetFunctionValue command within them. They may optionally accept up to 15 arguments of any type, which are defined within curly braces:
scn SomeUDF int arg1 ; * args are optional ref arg2 float arg3 .... Begin Function { arg1, arg2, arg3... } ; * do whatever like any other script End
and called in a similar way to regular functions:
scn SomeOtherScript ... call SomeUDF arg1, arg2, arg3...
However, to assign the return to a variable, Let must be used rather than set .. to .., and to use in a conditional, if eval rather than simply if:
let SomeVariable := call SomeOtherUDF arg1 if eval (call SomeSuitableUDF) ; the UDF return evaluates to true endif
Examples[edit | edit source]
scn GetRandomForm ; *** This script accepts a form list and returns one random form from it ; local variables int iCount int iChoice ref RandomForm ; arguments ref rFormList Begin Function { rFormList } let iCount := ListGetCount rFormList let iChoice := Rand 0, iCount let RandomForm := ListGetNthForm rFormList, iChoice SetFunctionValue RandomForm End
scn fnShuffle ; *** This script accepts a list array and returns it in a shuffled order ; *** ; * local vars array_var aNew int iKey int iLast ; * args array_var aList Begin Function { aList } let aNew := Ar_Construct "array" ; * get a new empty list array while (Ar_Size aList) > 0 ; * while input array contains an element let iLast := Ar_Size aList ; * get size of input array let iKey := Rand 0, iLast ; * get random valid key for input array Ar_Append aNew, aList[iKey] ; * append the random choice element to output array Ar_Erase aList, iKey ; * erase that element from input array loop SetFunctionValue aNew ; * return the shuffled array return End
The above example shows a user defined function that accepts a list array and returns it in a shuffled order. This might be called in another script, like:
scn SomeOtherScript array_var aBeatles Begin GameMode ; * or some other block type let aBeatles := Ar_List JohnREF, PaulREF, GeorgeREF, RingoREF let aBeatles := Call fnShuffle aBeatles ; * The Beatles array is now in a shuffled order End
Accepting any type arguments (advanced)[edit | edit source]
In some contexts, it is useful to allow arguments of any type for a UDF. Since array elements can be any type, this can be conveniently achieved using the NVSE Expressions, * ('box') and & ('unbox'), and the TypeOf / GetType functions.
scn MyUDF array_var AnyTypeArgument Begin Function { AnyTypeArgument } if eval (TypeOf *AnyTypeArgument) == "form" ... End
ref MyRef int MyInt call MyUDF &MyRef call MyUDF &MyInt
Notes[edit | edit source]
- UDFs may be used recursively by saving the script once first without the sub call.