Jump to content

[LE] Is the ordering of items in a FormList stable?


Haravikk

Recommended Posts

On the CreationKit.com wiki page for FormList.AddForm() there are conflicting notes about whether the ordering of items added to a form list is stable or not, i.e- if I iterate through the FormList, I should receive the items in the same order in which I added them (assuming the base list isn't changed).

 

Put another way; if I create a FormList in CK and add items A and B to it, then in game I run a script that adds items C, D and E, when I iterate over the list (Calling GetAt for indices 0 to 4) I expect to get the items back in the order A, B, C, D, E. If I remove item D, I expect to get A, B, C, E and so-on.

 

In my own testing this appears to be the case, but the conflicting notes on the CreationKit.com page has me concerned that this isn't behaviour that can be relied upon. I realise that the separate of base vs. added means there are some novel ordering issues (i.e- if I add an item in the CK, it seems to appear before all added forms, which is consistent with the theory that FormLists always iterate over base forms first), but assuming base and added forms are stored separate, they should have consistent ordering otherwise, right?

 

 

So anyway, does anybody know conclusively whether FormLists actually have stable ordering or not?

 

I'm hoping to avoid having to use too many arrays for things that lists should be suitable for, but the ordering is going to be very important for my script.

Link to comment
Share on other sites

You have already posted that on Skyrim wiki talk: https://www.creationkit.com/index.php?title=Talk:AddForm_-_FormList

Notes about formlists:

1) If you want to use an empty formlist within a papyrus script this one
has to be a property assigned with an already created formlist by Creation Kit.

2) FormLists cannot contain duplicate entries. That means by using AddForm() with a form
that is already in the list will not add a second copy to the list.

3) A created Ref like PlaceAtMe() does not become persistent by adding to a FormList.
If you try to retrieve such a reference from a FormList you will get almost a <None> result,
when this Ref is not loaded and not persistent.

4) fromlist order ( FiLe - First in Last entry )

"New forms added with papyrus scripts are appended to a block at the start of the list.
This is almost the same as adding them to the start of the list." (wiki)

 

Use next script to control: "How stable is the order in dual formlists?".

TestPlayerAliasScript

 

Scriptname TestPlayerAliasScript extends ReferenceAlias
{make a quest and add a PlayerAlias with this script}

    FormList PROPERTY myList    auto    ; create list and prefill with some entries different to script added forms
    FormList PROPERTY emptyList auto    ; create list, let it empty


; -- EVENTs --

EVENT OnInit()
    RegisterForSinlgeUpdateGameTime(0.0)
ENDEVENT

EVENT OnPlayerLoadGame()
ENDEVENT

EVENT OnUpdateGameTime()
    myF_Add(myList)
    myF_Add(emptyList)
    Debug.Trace(" =1= ==================== ")
    myF_Show(myList)
    myF_Show(emptyList)

    myList.RemoveAddedForm( Game.GetForm(0x0F) )
    emptyList.RemoveAddedForm( Game.GetForm(0x0F) )
    Debug.Trace(" =2= ==================== ")
    myF_Show(myList)
    myF_Show(emptyList)

    myList.Revert()
    emptyList.Revert()
    Debug.Trace(" =3= ==================== ")
    myF_Show(myList)
    myF_Show(emptyList)
ENDEVENT


; -- FUNCTIONs -- 2

;-----------------------------
FUNCTION myF_Add(FormList fml)
;-----------------------------
    fml.AddForm( Game.GetForm(0x07) )        ; the player as prisoner
    fml.AddForm( Game.GetForm(0x0A) )        ; lockpick
    fml.AddForm( Game.GetForm(0x0F) )        ; gold001
    fml.AddForm( Game.GetForm(0x14) )        ; the player
    fml.AddForm( Game.GetPlayer()   )    ; should not be added, player is already inside the formlist !!!
ENDFUNCTION


;--------------------------------------------------
FUNCTION myF_Show(FormList fml, Bool bRevers=False)
;--------------------------------------------------
    int i = fml.GetSize()

IF ( bRevers )
    WHILE (i)                ; (i > 0)
        i = i - 1
        Debug.Trace(i+" - " +fml.GetAt(i))
    ENDWHILE
ELSE
    int iMax = i
    i = 0
    WHILE (i < iMax)
        Debug.Trace(i+" - " +fml.GetAt(i))
        i = i + 1
    ENDWHILE
ENDIF
ENDFUNCTION

 



source: https://www.creationkit.com/index.php?title=AddForm_-_FormList , https://forums.nexusmods.com/index.php?/topic/6031618-vmad-or-form-list-which-is-quicker/

Edited by ReDragon2013
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...