Function Reference: Difference between revisions
Jump to navigation
Jump to search
Accessing Functions From Other Scripts
imported>JLundin (→Calling Functions: Removing confusing and erroneous information about properties) |
imported>Egocarib (Accessing Functions From Other Scripts) |
||
| Line 139: | Line 139: | ||
</source> | </source> | ||
=== Notes | <br> | ||
== Accessing Functions From Other Scripts == | |||
There are several methods for accessing one script's functions (or properties, states, etc...) from another script. For the sake of the following examples, let us assume we are working on ScriptA, but we need to access a function that is in ScriptB. | |||
=== Method One: Setting up the Target Script as a Filled Property === | |||
Declare the script that you want to access (ScriptB) ''as a property within'' the script you are trying to access it from (ScriptA). | |||
*This method is best when you only need access to a script that has a single instance (like a script attached to a specific Quest or ReferenceAlias). This is because you will have to choose the ''specific instance'' of the script you want to access when you fill the property in the CK. | |||
<br>'''Example:''' | |||
<source lang="papyrus"> | |||
myRefAliasScript property refScript auto ;fill this property with your quest in the CK editor | |||
;... | |||
refScript.myRefAliasScriptFunction01() | |||
refScript.myRefAliasScriptFunction02() ;access two functions that are in the reference alias script | |||
</source> | |||
=== Method Two: Access the Target Script by Creating a Variable On-the-fly === | |||
Declare a variable that has the type of the target script (ScriptB) that you want to access. Then set that variable to equal the instance of ScriptB that needs to be accessed. This method is best for times when: | |||
*(1) There are more than one instances of ScriptB that need to be differentiated (ScriptB is attached to several different Actors, for example) | |||
*(2) ScriptB does not exist before run-time, so a property cannot be filled with it (ScriptB is attached to an ObjectReference that doesn't exist until ScriptA PlaceAtMe()'s it into existence, for example) | |||
<br>'''Example One:'''<br> | |||
''Access the script functions on a created ObjectReference:'' | |||
<source lang="papyrus"> | |||
ObjectReference Pony1 = PlayerRef.PlaceAtMe(myCustomPony) ;create two ponies. Let us assume that myCustomPony is a base Actor that has 'PonyScript.psc' attached to it. | |||
ObjectReference Pony2 = PlayerRef.PlaceAtMe(myCustomPony) | |||
PonyScript Pony1Script = Pony1 as PonyScript ;declare two variables, each pointing to the INSTANCE of PonyScript attached to one particular pony | |||
PonyScript Pony2Script = Pony2 as PonyScript | |||
Pony1Script.groomPony() ;groom pony one, using the groomPony() function in (its instance of) PonyScript | |||
Pony2Script.killPony() ;kill pony two, using the killPony() function in (its instance of) PonyScript | |||
</source> | |||
<br>Note: sometimes you will have to cast the object with ScriptB attached to it before declaring the variable will work. Let us say that Pony1 was an Actor instead of an ObjectReference, for instance. Since PonyScript extends ObjectReference, we first need to cast Pony1 ''as an ObjectReference'' before we can cast it ''as a PonyScript'', otherwise the compiler will throw out errors: | |||
<source lang="papyrus"> | |||
Actor Pony1 = somePony | |||
PonyScript Pony1Script = (Pony1 as ObjectReference) as PonyScript | |||
</source><br><br> | |||
'''Example Two:'''<br> | |||
''Find an Actor's linked reference, and conditionally access the script functions on that reference:'' | |||
<source lang="papyrus"> | |||
ObjectReference possibleTable1 = Actor1.GetLinkedRef() | |||
if (possibleTable1 as Furniture) == magicTable ;is the actor linked to a magicTable? | |||
magicTableScript TableScript1 = possibleTable1 as magicTableScript | |||
TableScript1.explode() ;if so, use the magicTable's script function to make the magicTable explode! | |||
endif | |||
</source> | |||
<br><br> | |||
== Notes == | |||
* The nomenclature of Bethesda's functions' arguments is consistent, prefixing argument names such that their nature is easily determined. The naming convention is as follows, each prefix denoting the corresponding qualities: | * The nomenclature of Bethesda's functions' arguments is consistent, prefixing argument names such that their nature is easily determined. The naming convention is as follows, each prefix denoting the corresponding qualities: | ||
| Line 146: | Line 200: | ||
: auiCount, for instance, is an unsigned integer argument while asFileName is a string argument. Note that 'p' and 'k', for Papyrus' purposes, are interchangeable and that Papyrus does not actually have pointers. | : auiCount, for instance, is an unsigned integer argument while asFileName is a string argument. Note that 'p' and 'k', for Papyrus' purposes, are interchangeable and that Papyrus does not actually have pointers. | ||
== Bugs == | |||
* In typed functions, the compiler does not properly check all code paths for returns with values. If the function exits without providing a return value, the result is indeterminate and causes unexplained failures throughout related scripts (possibly due to stack corruption). | * In typed functions, the compiler does not properly check all code paths for returns with values. If the function exits without providing a return value, the result is indeterminate and causes unexplained failures throughout related scripts (possibly due to stack corruption). | ||