Jump to content

[SOLUTION] Bypass 128 Array Element Limit - No F4SE


Recommended Posts

Here's how to create a Papyrus Array of arbitrary size and type, using just vanilla capabilities:

; declare desired array type (example: a struct called MyDesiredType) and it's size (example: 500 elements)
MyDesiredType[] myArray
Int size = 500

; for each element in the desired array...
ObjectReference newRef
Int i = 0
While (i < size)
  ; ...place dummy object at xmarker in helper cell
  ; (force persistence as, ideally, the helper cell is not in loaded area)
  newRef = markerInHelperCell.PlaceAtMe(dummyForm, 1, true, true, false)
  ; ...reflink the placed dummy to the marker with whatever keyword
  newRef.SetLinkedRef(markerInHelperCell, kwdWorkshopItem)
  i += 1
EndWhile
newRef = none
                
; ask the engine to hand us an objectreference array with the 500 dummies we linked to the marker
ObjectReference[] linkedRefs = markerInHelperCell.GetRefsLinkedToMe(kwdWorkshopItem)

; ask the engine to create a copy of the array and to recast the copy into the desired type
myArray = (linkedRefs as Var[]) as MyDesiredType[]

; clean up all the dummy refs
i = linkedRefs.Lenght - 1
While (i > -1)
  linkedRefs[i].Delete()
  i -= 1
EndWhile

; done: myArray has 500 elements.

Papyrus VM may prohibit you from creating large Arrays - but you can coerce the engine to create one via GetLinkedRefs() and then leverage Var[] casting magic to change the type.
It wont be fast due to the PlaceAtMe() call, but it works.

NOTE:

If MyDesiredType is incompatible with ObjectReference, every element in myArray will be initialized to <none>.
If the types are compatible, then the elements will contain the dummy references. You definitely don't want that, so add an intermediary cast through an incompatible type in this case:

; using Location as the incompatible type here
myObjectReferenceArray = (((linkedRefs as Var[]) as Location[]) as Var[]) as ObjectReference[]

 

 

Enjoy.

  • Like 2
Link to comment
Share on other sites

If placeatme makes it slow, you maybe could use FindAllReferencesOfType which will also create arrays bigger than 128 elements, so you just need to use placeatme once to spawn as many of the objects (with aiCount param) which you will later add to the array with findallreferencesoftype. You just need to figure out the clean up, removing the spawned objects from the cell. Maybe you could create a type of object that removes itself with a certain event to avoid removing them in a loop.

Edited by DieFeM
  • Like 1
Link to comment
Share on other sites

  • Recently Browsing   0 members

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