Difference between revisions of "Associating data with a reference"

expanded with dictionaries
imported>Odessa
(created article)
 
imported>Odessa
(expanded with dictionaries)
Line 2: Line 2:


==Object Scripts==
==Object Scripts==
The approach used in the vanilla game is to attach on object script to a reference, with variables included in. This technique works well for one's mod added NPCS, but is a poor choice for vanilla ones.
The approach used in the vanilla game is to attach on object script to a reference, with variables included in it. This technique works well for new NPCS added by one's mod, but is a poor choice for modifying vanilla NPCs.
*All variables must be predefined, although if one of them is an array it is easy to add arbitrary data.
*All variables must be predefined, although if one of them is an array it is easy to add arbitrary data.
*The script can be attached in the GECK, or using [[SetScript]] to add or change the existing script. However, using this approach to modify vanilla references it is risky for compatibility with other mods and the vanilla game.
*The script can be attached in the GECK, or using [[SetScript]] to add or change the existing script. However, using this approach to modify vanilla references it is risky for compatibility with other mods and the vanilla game.
Line 13: Line 13:
==Actor Values==
==Actor Values==
There are many [[Actor Value Codes|actor values]], including the unused <b>Variable01-Variable10</b>, which can be modified using for example, [[ForceActorValue]]
There are many [[Actor Value Codes|actor values]], including the unused <b>Variable01-Variable10</b>, which can be modified using for example, [[ForceActorValue]]
*These can only store numbers, although a single number could be used as the key to [[Array Variables|map array]] attached to a quest script, to facilitate storing any arbitrary data. By using [[BuildRef]] or perhaps referencing array IDs it is possible for two mods to share this data without one being an official master to the other.
*These can only store numbers, although a single number could be used as the key to [[Array Variables|map array]] attached to a quest script, to facilitate storing any arbitrary data. By using [[BuildRef]] or perhaps referencing array IDs it is possible for two mods to share this data without one being a master to the other.
*Since actor values exist in the vanilla game are are accessible to all modders, but there is no guarantee another mod will not overwrite your data with something irrelevant.
*Since actor values exist in the vanilla game they are accessible to all modders, but there is no guarantee another mod will not overwrite your data with something irrelevant.
<pre>
<pre>
let MyData := MyArray[(SomeActor.GetAV Variable01)]
let MyData := MyArray[(SomeActor.GetAV Variable01)]
Line 21: Line 21:
==Using the reference as an array key==
==Using the reference as an array key==
Map and string map arrays allow either numeric or string keys to retrieve arbitrary data, but it is not possible to directly use a reference as a key. A number of workarounds exist however.
Map and string map arrays allow either numeric or string keys to retrieve arbitrary data, but it is not possible to directly use a reference as a key. A number of workarounds exist however.
*You can use [[ToString|ToString($)]] to obtain the name of a reference as a string. However, all references with identical names will share the same data.
*You can use [[ToString|ToString($)]] to obtain the name of a reference as a string. However, all references with identical names will share the same key.
*You can use [[GetFormIDString]] to return the unique form id as a string for any reference. However, form ids may change on game load with load order. Hence, if the data must be persistent some additional scripting is required.
*You can use [[GetFormIDString]] to return the unique form id as a string for any reference. However, form ids may change on game load with load order. Hence, if the data must be persistent some additional complex scripting is required.
*You can also store the reference as an entry rather than key in an array, and use some search technique to find it. Beware that references are removed if their parent mod is unloaded, so no static order to array data can be assumed.
 
<pre>
<pre>
let MyKey := $SomeActor ; or:
let MyKey := $SomeActor ; or:
Line 30: Line 28:


let MyData := MyArray[MyKey]
let MyData := MyArray[MyKey]
</pre>
*You can also store the reference as an entry rather than a key in a map, and use this as a kind of 'dictionary' of keys for a second map. Beware that references are removed if their parent mod is unloaded, so a regular array (list) is unsuitable, since the order may change. You can use [[Ar_Find]] on the dictionary to return a key, then use that key on a second array to return any data. Creating a [[User Defined Function|UDF]] can make this approach very convenient.
<pre>
array_var Dictionary ; Map
array_var MyData ; Map
...
let Dictionary[X] := SomeActor
let MyData[X] := SomeData
...
let DataKey := Ar_Find SomeActor, Dictionary
let ActorData := MyData[DataKey]
</pre>
</pre>
==Using Tokens==
==Using Tokens==
Line 45: Line 55:
Added by the [[NX]] plugin for NVSE, and are probably the most powerful way to associate data with a reference. Of course, the plugin is then required by all users.
Added by the [[NX]] plugin for NVSE, and are probably the most powerful way to associate data with a reference. Of course, the plugin is then required by all users.
*Any number of persistent variables of either numeric, form or string may be stored on any reference.
*Any number of persistent variables of either numeric, form or string may be stored on any reference.
*NX variables are fully accessible to all mods without needing masters. If a variable does not exist, the value 0 is simply returned.  
*NX variables are fully accessible to all mods without needing masters. If attempting to retrieve a variable that does not exist, the value 0 is simply returned.  
*Many functions exist to easily manipulate the variables.
*Many functions exist to easily manipulate the variables.
<pre>
<pre>
Anonymous user