FnGetExternalForm

From the Fallout3 GECK Wiki
Revision as of 06:20, 5 April 2015 by imported>Odessa (Created page. Source me ;).)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

[help]
(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

See Also