Jump to content

Sorting Scripts


Gribbleshnibit8

Recommended Posts

Alright, what follows is a method for creating easily expandable, very adaptable script for sorting (or just checking) on records contained in a form list. This will require that the reader has a pretty decent understanding of scripting and fose. A good understanding of form lists helps as well.

 

A bit of background on this first. I came up with this method while making my Survival Tent. I needed a way to sort items into many containers. My first method involved a unique script for each container. This script had an if block for each item to be sorted. It was cumbersome, difficult to maintain, and overall not a very good method. I set out to find a solution that was easy and modular.

 

The script I used requires a single form list. The list should contain everything that is to be sorted (or had work done with it). The other thing that is required (for sorting) is a named ref container to add the items to. The script here is written so that only two edits need to be made to allow it to work. The two lines that must be changed are set srcList to and set destCont to. So an example would look like this.

 

scn GTKitchenSCRIPT

;variables
short listlength
short countlength
short listCount
ref listItem
ref srcList
ref destCont

Begin OnActivate

set srcList to GTKitchenList
set destCont to GTKitchenRef

if (isControlPressed 27)
	
	set listlength to ListGetCount srcList
	set countlength to 0
	Label 1
	set listItem to ListGetNthForm srcList countlength
	set listCount to Player.getItemCount listItem
	if listCount > 0
		Player.RemoveItem listItem listCount 1
		destCont.addItem listItem listCount
	Endif
	set countlength to (1+countlength)
	if countlength < listlength
		Goto 1
	Endif

	showMessage GTKitchenSortedMsg

else

	destCont.activate player 0

endif

END

What is happening here? Well, upon activating the container srcList is set to GTKitchenList, in this case, a form list made up of kitchen items (ex. Pots, pans, spatulas, cups, etc). The destList is set to a named container that is running this script (in this usage, the container would have to be a unique container made specifically for this script. Or, the script could be run from a unique activator, and the container could just be a named ref that the items go into. Theoretically, this could be run from a console as well.)

 

The main body of the script only runs if the player is pressing the grab key. If they are, then the script first sets a variable to the length of the list, then initializes a count variable (this is only necessary if you use multiple sort blocks in the same activate. I only did this because that's how I was taught to code. Fallout automatically initializes all variables to 0). I'll break the rest down into a line-by-line description of what is going on, for those who want to know.

 

Here we will assume that the list GTKitchenList contains the following items in this order: Pot, Spatula, Spoon, Drinking Glass.

 

This next part is where the magic happens. Starting at set listItem to, the code is now setting a variable to the first object contained in the list (the Pot). ListGetNthForm gets the Nth form the of specified list. In this instance, it is getting the countLength (0) form of the srcList (GTKitcheList), the pot.

 

The next line, set listCount to determines how many Pots the player has in their inventory, and sets the variable listCount to that number.

 

This part is only run if the player actually has any of the items in their inventory (this helps keep the impact of the script to a minimum). If the player does in fact have Pot with them, then the item is removed from their inventory and added to the specified container.

 

Here we increment a counter countLength. This counter is used for two things. First, it is used to determine if we have reached the end of the list. Second, it also tells us which item in the list we are on when using ListGetNthForm.

 

The next if statement checks if the countLength is less than the listLength. If it is, then we go back to the predetermined point designated as Label 1. From here, the entire process is repeated until countLength is equal to listLength, at which point we know that we have gone through the entire list, and can now end. Once done, it is set to display a message, telling the player that the desired action has been completed. As setup now, this message will actually be displayed even if no items are actually removed.

 

To fix this you could add a flag variable in the if listCount > 0 block that would be used to determine if an item has been removed. You would then alter the message section to be along the lines of:

 

if flag > 0
showMessage GTKitchenSortedMsg
endif

The last line before the END is the action to perform if the grab key was not pressed down. In this instance, we want to activate the container in the normal way.

 

 

Now, the beauty of this code is that it's not just tied into being used only for sorting items. With a few very basic tweaks, it can be used to perform a check on any form list. In this next example, we are checking a list that contains all the different ants in the game, and incrementing a counter to determine how many total have been killed.

 

Begin GameMode
			set srcList to AntList
			
			set listlength to ListGetCount srcList
				set countlength to 0
				Label 1
				set listItem to ListGetNthForm srcList countlength
				set tempKill to getKillCount listItem
				set killCount to (killCount + tempKill)
				set countlength to (1+countlength)
				if countlength < listlength
					Goto 1
				Endif
				
END

Here I am using a list of ants. The first part is the same, the only change here is that, instead of only doing the work when an items is found, we want to increment a variable for every item in the list. To do this, I have a variable tempKill that is set to the getKillCount for the first item in the list. The variable killCount is then incremented by this number. In order to just add the number to any previous numbers, we add the tempKill to killCount and then set killCount to this new number. The rest is the same as before, where we increment the counter, and check if that puts us at the end of the list or not.

 

I'm sure there are plenty more uses for this method of list checking. And I'm pretty sure that I'm not the first one to do this (though I haven't found an example on the forums). However, I've explained it as best I can, and have given an idea for other uses of this method of list crawling. I'm sure it's not the most streamlined method, and would probably cause a bit of lag on a list containing hundreds of items (due to the goto command) but it works very well for lists containing less than 100 items.

 

As stated, I have used this in my own mod, and it works flawlessly. The beauty of this method is how easy it is to add items to the list from another mod. I'll explain how to do that tomorrow.

 

Also, I would like to thank kaburke for his help in streamlining this method. I managed to get the basics in, but he helped get it cleaned up.

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 months later...

yes.. use a terminal and the way anglewraith explained.

 

example code from my sorting set

 

this goes inside the terminal script area..

int listnumF
int myCount
int formrefnumF
ref formref


Label 1
set formrefnumF to ListGetCount LokiMiscApparelList
if listnumF <= formrefnumF
set formref to listgetnthform LokiMiscApparelList listnumF
set myCount to player.getitemcount formref
player.removeitem formref myCount 1
LokiMiscApparelLocker.additem formref myCount
set listnumF to listnumF + 1
goto 1
endif
set listnumF to 0
Label 2
set formrefnumF to ListGetCount LokiClothesContainerSorter
if listnumF <= formrefnumF
set formref to listgetnthform LokiClothesContainerSorter listnumF
set myCount to player.getitemcount formref
player.removeitem formref myCount 1
LokiClothesContainerLocker.additem formref myCount
set listnumF to listnumF + 1
goto 2
endif
set listnumF to 0
Label 3
set formrefnumF to ListGetCount LokiLightArmorContainerList
if listnumF <= formrefnumF
set formref to listgetnthform LokiLightArmorContainerList listnumF
set myCount to player.getitemcount formref
player.removeitem formref myCount 1
LokiLightArmorContainerLocker.additem formref myCount
set listnumF to listnumF + 1
goto 3
endif
set listnumF to 0
Label 4
set formrefnumF to ListGetCount LokiHeavyArmorContainerList
if listnumF <= formrefnumF
set formref to listgetnthform LokiHeavyArmorContainerList listnumF
set myCount to player.getitemcount formref
player.removeitem formref myCount 1
LokiHeavyArmorContainerLocker.additem formref myCount
set listnumF to listnumF + 1
goto 4
endif
set listnumF to 0

 

edit: this is not the only way i'm sure.. :)

Link to comment
Share on other sites

  • Recently Browsing   0 members

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