Gribbleshnibit8 Posted July 2, 2010 Share Posted July 2, 2010 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 ENDWhat 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 endifThe 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 ENDHere 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 More sharing options...
angelwraith Posted July 10, 2010 Share Posted July 10, 2010 hehe i did something very much like this in march:http://thenexusforums.com/index.php?showtopic=188154 Link to comment Share on other sites More sharing options...
dewdkorn6969 Posted September 18, 2010 Share Posted September 18, 2010 anyway to get this to sort into multiple containers with one activator and different form lists? Link to comment Share on other sites More sharing options...
sinchiruna Posted September 18, 2010 Share Posted September 18, 2010 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 More sharing options...
Recommended Posts