Jump to content

[LE] Sorting Formlists.


irswat

Recommended Posts

I want to add a QuickCommand function that keeps track of what items, spells, weapons are used, and keep this list sorted according to frequency of use, for performance purposes, and perhaps for a signature weapons/armor mod down the line.

I created a FormList called QuickCommands. When a form is used it is check against this formlist. If the form does not exist in the form list it is added, and a running tally is started in a parallel integer array. If the form already exists in the formlist the tally is incremented. Then the FormList and integer array are sorted in descending order. This is the code I'm trying to use, but I'm getting errors about how I'm using GetAt.

function QuickCMDs(form CMDForm)
	int iCMDForm
	
	if QuickCommands.Find(CMDForm)==-1
		QuickCommands.AddForm(CMDForm)
		iCMDForm=QuickCommands.Find(CMDForm)
		fQuickCommands[iCMDForm]=1
	elseif QuickCommands.Find(CMDForm)>=0
		iCMDForm=QuickCommands.Find(CMDForm)
		fQuickCommands[iCMDForm]=fQuickCommands[iCMDForm]+1
	endif
	
	;sort QUICK COMMANDS
	SortQuickCMD()
	
endFunction

function SortQuickCMD()
	int QuickCMDSize=QuickCommands.GetSize()
	int inner=0
	int outter=0
	int temp1
	form form1
	while (outter<QuickCMDSize)
		while (inner<QuickCMDSize)
			if fQuickCommands[inner]<fQuickCommands[inner+1]
				temp1=fQuickCommands[inner]
				form1=QuickCommands.GetAt(inner)
				fQuickCommands[inner]=fQuickCommands[inner+1]
				QuickCommands[inner]=GetAt.QuickCommands(inner+1)
				fQuickCommands[inner+1]=temp1
				QuickCommands[inner+1]=form1
				inner+=1
			endif
		endwhile
		outter+=1
	endWhile

endFunction

here is the error log:

 

C:\Games\steamapps\common\skyrim\Data\Scripts\Source\SVE_ParserEngine.psc(2629,4): only arrays can be indexed

C:\Games\steamapps\common\skyrim\Data\Scripts\Source\SVE_ParserEngine.psc(2629,17): type mismatch while assigning to a none (cast missing or types unrelated)
C:\Games\steamapps\common\skyrim\Data\Scripts\Source\SVE_ParserEngine.psc(2631,4): only arrays can be indexed
C:\Games\steamapps\common\skyrim\Data\Scripts\Source\SVE_ParserEngine.psc(2631,17): type mismatch while assigning to a none (cast missing or types unrelated)

the two lines papyrus doesn't seem to like are:

QuickCommands[inner]=QuickCommands.GetAt(inner+1)

QuickCommands[inner+1]=form1

is there an alternative way to work with formlists as if they were arrays? Is there a way to save arrays so I can keep a running tally of usage frequency?

 

Link to comment
Share on other sites

There isn't a whole lot of documentation out there. This compiles. I will report back whether it works for future users.

function SortQuickCMD()
	int QuickCMDSize=QuickCMDFormList.GetSize()
	int inner=0
	int outter=0
	int temp1
	form form1
	
	QuickCommands=QuickCMDFormList.ToArray()
	QuickCMDFormList.Revert()
	
	while (outter<QuickCMDSize)
		while (inner<QuickCMDSize)
			if fQuickCommands[inner]<fQuickCommands[inner+1]
				temp1=fQuickCommands[inner]
				form1=QuickCommands[inner]
				fQuickCommands[inner]=fQuickCommands[inner+1]
				QuickCommands[inner]=QuickCommands[inner+1]
				fQuickCommands[inner+1]=temp1
				QuickCommands[inner+1]=form1
				inner+=1
			endif
		endwhile
		outter+=1
	endWhile

	QuickCMDFormList.AddForms(QuickCommands)
endFunction
Link to comment
Share on other sites

Well those error codes are pretty easy to solve! :laugh:

You use parenthesis with formlists, not brackets! That's why it's giving you that nonsense about arrays and indexing!

 

And for the "Adds all forms in an array to a formlist" thing, just use a while loop that cycles through the whole array and have it add all the items in that array to the formlist.

Like so:

FormList Property ExampleList Auto
(Insert Example Array here)

Function EXF()
Int Index = 0
Int ArraySize = ExampleArray.Length (I think this is the right function? Don't use arrays a whole lot)
While Index < ArraySize
ExampleList.Addform(ExampleArray[Index] as Form)
Index +=1
EndWhile
EndFunction

Also, if you're trying to increment int values (I think that's what that odd chunk of code is in the middle there?) You can just use += like I did with the index value.

 

Sorry for the late response by the way, took me a bit to puzzle some of this out and I'm admittedly very easily sidetracked! :laugh:

Link to comment
Share on other sites

thanks I found two useful functions that do what I need ToArray and AddForms.

Notice I use += when increment the inner and outer counters. This is a bubble sorting method. It will order the frequency array in descending order, as well as the parallel form array, and then dump the form array to a formlist.

Being able to check a command against the 30 most commonly used forms is extraordinarily faster than checking that command against all forms in the game. It is some what redundant however because currently commands only check against items and spells the player has in their inventory. My original method was checking commands against form lists with hundreds of forms containing, for example, every weapon in the game, but this was unacceptably slow. Checking for a command against 30 items in a players inventory however, is pretty fast! Perhaps I will do something like, if player has more than 100 items in their inventory, or if they have over 100 spells, I will first check against this quicklist, before checking inventory.

Edited by irswat
Link to comment
Share on other sites

  • 8 months later...

I just had the same problem in Fallout 4 and this thread helped me solve it. Posting here as thanks, and because I think it will work in Skyrim too.

 

ERROR VERSION:

If bSorted || (ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i])) ; ITEM HAS BEEN SORTED
  flStorageList[i].AddForm(akBaseItem) ; YO DAWG. Add form to formlist inside formlist array!
  bSorted = True

  If gvDevTracking.GetValue() == 1
    Debug.Notification("DCS: " + akBaseItem + " is " + strSortedItems[i] + ".")
  EndIf

EndIf
COMPILED VERSION:

If bSorted || (ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i])) ; ITEM HAS BEEN SORTED
  (flStorageList.GetAt(i) as FormList).AddForm(akBaseItem) ; YO DAWG. Add form to formlist inside formlist array!
  bSorted = True

  If gvDevTracking.GetValue() == 1
    Debug.Notification("DCS: " + akBaseItem + " is " + strSortedItems[i] + ".")
  EndIf

EndIf
Search engine keywords to help frustrated coders find this thread: multidimensional array, multi dimensional, 3d, nested arrays, formlist within a formlist, formlist of formlists, solved, solution
Link to comment
Share on other sites

  • Recently Browsing   0 members

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