FnGetExternalForm

From GECK
Jump to: navigation, search
This article is incomplete. You can help by filling in any blank descriptions.
Further information might be found in a section of the discussion page. Please remove this message when no longer necessary.



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.

This UDF avoids the potential pitfalls of using BuildRef, detailed in it's article.

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