A bit of background on this first. I came up with this method while making my http://www.fallout3nexus.com/downloads/file.php?id=10294. 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;variablesshort listlengthshort countlengthshort listCountref listItemref srcListref destContBegin 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 endifEND
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 GTKitchenSortedMsgendif
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.