Jump to content

[LE] FormList - RandomInt question


maxarturo

Recommended Posts

Hi once again.


Is there a way to generate a 'RandomInt' an choose a random reference from inside a 'FormList'.


Before i removed all 'FormLists' from my mod, i did experiment with this, but i didn't bother too much with it.

The issue back then, except the slowness of FormLists, was that no matter what 'RandomInt' was generated it would always run the first reference in the FormList, no to mention the 100 maximum 'RandomInt' limit, but anyway... that's another issue.


There is a big chance that i did a potato on those experiments that were made just before i decided to delete all FormLists and never bother with them again.


I'm asking this question cause lately i've been very busy at work and my free time has been reduced to almost '0', and i would hate to loose 1 weekend experimenting in something that maybe it can not be done, while i could invest that time to actually do some work on the mod.


Thank you very much and have a nice weekend.

Link to comment
Share on other sites

If you are doing multiple random forms from the same list then this would be better:

Int MaxEntry = MyFormList.GetSize() - 1
Form RandomFormOne = MyFormList.GetAt(Utility.RandomInt(0,MaxEntry)
Form RandomFormTwo = MyFormList.GetAt(Utility.RandomInt(0,MaxEntry)

And if you want multiple random forms without repeats:

Int MaxEntry = MyFormList.GetSize() - 1
Int RandomEntryOne = Utility.RandomInt(0,MaxEntry)
Int RandomEntryTwo = Utility.RandomInt(0,MaxEntry)
Int RandomEntryThree = Utility.RandomInt(0,MaxEntry)
While RandomEntryTwo == RandomEntryOne
  ;when RET is the same as REO roll again
  RandomEntryTwo = Utility.RandomInt(0,MaxEntry)
EndWhile
While (RandomEntryThree == RandomEntryTwo) || (RandomEntryThree == RandomEntryTwo)
  ;when RETh is the same as RET or REO roll again
  RandomEntryThree = Utility.RandomInt(0,MaxEntry)
EndWhile
Form RandomFormOne = MyFormList.GetAt(RandomEntryOne)
Form RandomFormTwo = MyFormList.GetAt(RandomEntryTwo)
Form RandomFormThree = MyFormList.GetAt(RandomEntryThree)

And if you want to go down the rabbit hole like I did tonight...

 

  Reveal hidden contents

 

 

There are just examples to show that it is not always best or possible to string everything in a single line. :cool:

Link to comment
Share on other sites

Yes I agree if you're going to do multiple forms that way is better. For a single instance though I prefer to keep it in the same line. Also you're missing some brackets:

 

Int MaxEntry = MyFormList.GetSize() - 1
Form RandomFormOne = MyFormList.GetAt(Utility.RandomInt(0,MaxEntry))
Form RandomFormTwo = MyFormList.GetAt(Utility.RandomInt(0,MaxEntry))
Link to comment
Share on other sites

Thank you dylbill & IsharaMeradin for your reply and interest.


I'll look at your suggestions some time later today, after i get off from work.


I don't have time right now and i just took a quick look at them, and i have 3 questions.


@ dylbill

1) What does the minus one "-1" represent in:

Form RandomForm = MyFormList.GetAt(Utility.RandomInt(0, (MyFormlist.GetSize() - 1)))


2) Which line from the 2 lines you posted is faster?, and what's the difference?.


@ dylbill & IsharaMeradin

3) Is calling a "RandomInt" fanction for a reference inside a "FormList" faster than calling / checking for a reference inside a "FormList", which we all know is slow, and the bigger the "FormList" is, the slower the function.


* I might have some more questions later on, when i get to actually see / study / start contracting what i have in mind.



And again, thank you both very much, you have no idea how much time you both have saved me, precious time!!, that for the next month+ i won't have available.

Link to comment
Share on other sites

The first line I posted is faster because it doesn't use the formlist.getsize() function. The difference is that the second line sets the max for the randomInt as the size of the formlist, while using just Utility.RandomInt() gets a random Int between 0 and 100. The - 1 is because formlists and pretty much everything in the ck and papyrus are 0 based. You have to add a -1 because let's say the formlist has 10 forms, the possible entries are from 0 to 9, not 0 to 10.

 

If speed is your concern, using arrays is most certainly faster.

Edited by dylbill
Link to comment
Share on other sites

  On 10/3/2020 at 6:51 AM, dylbill said:

 

Yes I agree if you're going to do multiple forms that way is better. For a single instance though I prefer to keep it in the same line. Also you're missing some brackets:

 

Int MaxEntry = MyFormList.GetSize() - 1
Form RandomFormOne = MyFormList.GetAt(Utility.RandomInt(0,MaxEntry))
Form RandomFormTwo = MyFormList.GetAt(Utility.RandomInt(0,MaxEntry))

 

That is why I don't like nesting too many things in a single line. Easy to loose track of the brackets and "puddles".

 

 

@maxarturo

I do not know about the speed of things. I know that arrays are faster in general. But if you need a list that is used by multiple scripts / records, a formlist is the way to go. Especially if it is not viable to link to a master script containing the array.

Link to comment
Share on other sites

It's easy to access array's from other scripts if you set them up as properties.

 

In one script:

Scriptname MyScript extends Quest
ObjectReference[] Property MyRefs Auto 

In another script:

MyScript Property ScriptRef auto ;In the ck, choose the quest the script is attached to. 

Event SomeEvent()
    Int MaxEntry = ScriptRef.MyRefs.Length - 1    
    ScriptRef.MyRefs[Utility.RandomInt(0, MaxEntry)].SomeFunction() ;random entry from array 
EndEvent

Arrays and Formlists both have advantages and disadvantages. Arrays are faster because you don't need to use a Get function to get the form. Formlists can have multiple types of forms, where arrays cannot. Also, formlists can be multi-dimensional, meaning you can have a formlist of formlists where as in papyrus you cannot have an array of arrays.

 

Here's how to get a random entry from a formlist of formlists:

 

Formlist Property MyFormLists Auto ; a formlist of formlists

Event SomeEvent()
    Int MaxEntryA = MyFormlists.GetSize() - 1 
    FormList ListA = MyFormlists.GetAt(Utility.RandomInt(0, MaxEntryA)) as formlist ;finds random formlist
    
    Int MaxEntryB = ListA.GetSize() 
    Form RandomForm = MyFormlists.GetAt(Utility.RandomInt(0, MaxEntryB)) ;finds random form
EndEvent
Link to comment
Share on other sites

  • Recently Browsing   0 members

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