FnGetExternalForm
Revision as of 06:20, 5 April 2015 by imported>Odessa (Created page. Source me ;).)
Sometimes one may wish to reference a form from an external mod without making it a master. This can be achieved using BuildRef, but there are number of potential pitfalls detailed in it's article that must be avoided. The following UDF allows for safe and convenient BuildRefs:
< [[::Category:Functions|Category:Functions]]
An example UDF script.
Description
Returns a valid form of the type specified from an external mod, if one exists. Returns 0 if the mod is not loaded, the form doesn't exist, or the form is of an unexpected type.
Syntax
(ValidForm-or-0) call fnGetExternalForm ModName:string Hex-FormID:string TypeCode:int
Example
ref rCompanion let rCompanion := call fnGetExternalForm "SomeCompanionMod.esp", "000ADF", 200 if rCompanion ; rCompanion is a valid actor from the external mod. Safe to continue else ; Got 0, the mod is either not loaded or a different version to expected. endif
Script
To use this function, copy the following code into a new object script:
scn fnGetExternalForm ; # Safe BuildRef, passed a mod_name and form_id strings, and int type code. ; # Returns the target form if the mod is loaded, and the form is valid and ; # of the type expected ; # args string_var mod_name ; # eg: "FalloutNV.esm" string_var form_id ; # eg: "000ADD" - hex string without mod index int iTypeCode ; # eg: 200 for actor refs, 42 for NPC, see: http://geck.bethsoft.com/index.php?title=Form_Type_IDs ; # local int iModIndex ref BuiltRef int iFormID int iBuiltType Begin Function { mod_name, form_id, iTypeCode } PrintD "MyMod: call fnGetExternalForm "+mod_name+", "+form_id+", "+$iTypeCode if eval !(IsModLoaded $mod_name) PrintD " ...Mod not loaded" return endif let iModIndex := GetModIndex $mod_name let iFormID := ToNumber form_id, 1 ; # Convert hex string to int let BuiltRef := BuildRef iModIndex, iFormID if eval !(IsFormValid BuiltRef) PrintD " ...Aborting. Target form does not exist in mod!" return endif if iTypeCode == 200 ; # Actor is special case, GetType wont work. if eval !(IsReference BuiltRef) PrintD " ...Aborting. Not a reference!" return elseif eval !(BuiltRef.IsActor) PrintD " ...Aborting. Not an Actor!" return endif else let iBuiltType := GetType BuiltRef if iBuiltType != iTypeCode PrintD " ...Aborting. Got wrong type: "+$iBuiltType+" instead of: "+$iTypeCode+"!" return endif endif PrintD " ...Success, got: "+$BuiltRef SetFunctionValue BuiltRef ; # You don't need to sv_destruct UDF _arguments_ End