Handling Inventory Items

Post » Sun May 18, 2014 1:21 pm

An example script for dumping all the items from the player into a container using an activator. Requires one container in the world and an activator with the script attached and the properties set correctly.

This script requires the use of two SKSE functions, http://www.creationkit.com/GetNumItems_-_ObjectReference and http://www.creationkit.com/GetNthForm_-_ObjectReference.

Spoiler
Scriptname _t_Test_Item_Dump extends ObjectReference ObjectReference Property _t_ref_chest  AutoActor Property PlayerRef  AutoEvent OnActivate(ObjectReference akActionRef)    If akActionRef == PlayerRef        Unburden(PlayerRef, _t_ref_chest)        _t_ref_chest.Activate(PlayerRef)    EndIfEndEventFunction Unburden(ObjectReference FromCont, ObjectReference ToCont) Global    Int iFormIndex = FromCont.GetNumItems()    int iDifItems = iFormIndex    int iTotalItems = 0    Game.DisablePlayerControls() ; make player wait for all items to be removed    Debug.Trace("Begin Removing Items")    While iFormIndex > 0        iFormIndex -= 1        Form kForm = FromCont.GetNthForm(iFormIndex)        int num_items = FromCont.GetItemCount(kForm)        iTotalItems += num_items        ; String FormName = kForm.GetName()        ; Debug.Trace("Removing " + num_items + " of " + FormName) ; a trace for every item slows it down        FromCont.RemoveItem(kForm, num_items, true, ToCont)    EndWhile    Debug.Trace("Number of Different Items: " + iDifItems)    Debug.Trace("Total Item Count: " + iTotalItems)    Game.EnablePlayerControls()EndFunction

This was a starting point for a dynamic sort script I am writing and I will post that later once I have tested it thoroughly.

After testing various methods and coming up with http://www.gamesas.com/topic/1498760-handling-inventory-items/#entry23584043, I have released a mod that allows the player to quickly stash items into any container. This does not sort, but merely "unburdens" the player of inventory items not immediately needed. http://www.nexusmods.com/skyrim/mods/53103/?

Edit: Added additional info.

Edit Again: Reformatted and Added additional info. I will likely update this entry to keep updated info at the top.

User avatar
Pumpkin
 
Posts: 3440
Joined: Sun Jun 25, 2006 10:23 am

Post » Sun May 18, 2014 1:25 pm

An example script for sorting items to various contains directly from the player's inventory using keywords. Requires 36 containers in the world (+1 if sorting for crossbows) and an activator with the script attached and the properties set correctly.

Spoiler
Scriptname _t_Keyword_Sort_Activator extends ObjectReferenceObjectReference Property _t_ref_chest_armor AutoObjectReference Property _t_ref_chest_arrows            Auto  ; 01ObjectReference Property _t_ref_chest_spell_tomes       Auto  ; 02ObjectReference Property _t_ref_chest_books             Auto  ; 03ObjectReference Property _t_ref_chest_recipes           Auto  ; 04ObjectReference Property _t_ref_chest_scrolls           Auto  ; 05ObjectReference Property _t_ref_chest_ingredients       Auto  ; 06ObjectReference Property _t_ref_chest_keys              Auto  ; 07ObjectReference Property _t_ref_chest_animal_parts      Auto  ; 08ObjectReference Property _t_ref_chest_hide              Auto  ; 09ObjectReference Property _t_ref_chest_firewood          Auto  ; 10ObjectReference Property _t_ref_chest_ingots_ores       Auto  ; 11ObjectReference Property _t_ref_chest_gems              Auto  ; 12ObjectReference Property _t_ref_chest_soul_gems         Auto  ; 13ObjectReference Property _t_ref_chest_tools             Auto  ; 14ObjectReference Property _t_ref_chest_clutter           Auto  ; 15ObjectReference Property _t_ref_chest_raw_food          Auto  ; 16ObjectReference Property _t_ref_chest_food              Auto  ; 17ObjectReference Property _t_ref_chest_poisons           Auto  ; 18ObjectReference Property _t_ref_chest_potions           Auto  ; 19ObjectReference Property _t_ref_chest_clothing          Auto  ; 20ObjectReference Property _t_ref_chest_shields           Auto  ; 21ObjectReference Property _t_ref_chest_light_armor       Auto  ; 22ObjectReference Property _t_ref_chest_heavy_armor       Auto  ; 23ObjectReference Property _t_ref_chest_jewelry           Auto  ; 24ObjectReference Property _t_ref_chest_other_armor       Auto  ; 25ObjectReference Property _t_ref_chest_swords            Auto  ; 26ObjectReference Property _t_ref_chest_greatswords       Auto  ; 27ObjectReference Property _t_ref_chest_waraxes           Auto  ; 28ObjectReference Property _t_ref_chest_battleaxes        Auto  ; 29ObjectReference Property _t_ref_chest_maces             Auto  ; 30ObjectReference Property _t_ref_chest_warhammers        Auto  ; 31ObjectReference Property _t_ref_chest_bows              Auto  ; 32ObjectReference Property _t_ref_chest_daggers           Auto  ; 33ObjectReference Property _t_ref_chest_staves            Auto  ; 34ObjectReference Property _t_ref_chest_other_weapons     Auto  ; 35ObjectReference Property _t_ref_chest_temp              Auto  ; 36Keyword Property VendorItemArrow AutoKeyword Property VendorItemSpellTome AutoKeyword Property VendorItemBook AutoKeyword Property VendorItemRecipe AutoKeyword Property VendorItemScroll AutoKeyword Property VendorItemIngredient AutoKeyword Property VendorItemKey AutoKeyword Property VendorItemAnimalPart AutoKeyword Property VendorItemAnimalHide AutoKeyword Property VendorItemFireword Auto            ; yes... Fireword vanilla mistake... ikrKeyword Property VendorItemOreIngot AutoKeyword Property VendorItemGem AutoKeyword Property VendorItemSoulGem AutoKeyword Property VendorItemTool AutoKeyword Property VendorItemClutter AutoKeyword Property VendorItemFoodRaw AutoKeyword Property VendorItemFood AutoKeyword Property VendorItemPoison AutoKeyword Property VendorItemPotion AutoKeyword Property VendorItemClothing AutoKeyword Property VendorItemArmor AutoKeyword Property ArmorShield AutoKeyword Property ArmorLight AutoKeyword Property ArmorHeavy AutoKeyword Property VendorItemJewelry AutoKeyword Property VendorItemWeapon AutoKeyword Property WeapTypeSword AutoKeyword Property WeapTypeGreatsword AutoKeyword Property WeapTypeWarAxe AutoKeyword Property WeapTypeBattleaxe AutoKeyword Property WeapTypeMace AutoKeyword Property WeapTypeWarhammer AutoKeyword Property WeapTypeBow AutoKeyword Property WeapTypeDagger AutoKeyword Property WeapTypeStaff Auto; Keyword Property WeapTypeCrossbow Auto        ; reqs DawnguardActor Property PlayerRef  AutoEvent OnActivate(ObjectReference akActionRef)    If akActionRef == PlayerRef        Unburden(PlayerRef)        _t_ref_chest_temp.Activate(PlayerRef)    EndIfEndEventFunction Unburden(ObjectReference FromCont)Int iFormIndex = FromCont.GetNumItems()    int iDifItems = iFormIndex    int iTotalItems = 0    Game.DisablePlayerControls() ; make player wait for all items to be removed    Debug.Trace("Begin Removing Items")While iFormIndex > 0  iFormIndex -= 1  Form kForm = FromCont.GetNthForm(iFormIndex)        int num_items = FromCont.GetItemCount(kForm)        iTotalItems += num_items        ObjectReference ToCont = SortDest(kForm)               ; Form Chest = ToCont.GetBaseObject()        ; String ChestName = Chest.GetName()        ; String FormName = kForm.GetName()        ; Debug.Trace("Moving " + FormName + " to " + ChestName)        ; Debug.Trace("Removing " + num_items + " of " + FormName)               FromCont.RemoveItem(kForm, num_items, true, ToCont)EndWhile    Debug.Trace("Number of Different Items: " + iDifItems)    Debug.Trace("Total Item Count: " + iTotalItems)    Game.EnablePlayerControls()EndFunction        ObjectReference Function SortDest(Form Item)           If Item.HasKeyword(VendorItemArrow)                         ; Arrows        ; move to Arrows        return _t_ref_chest_arrows    elseif Item.HasKeyword(VendorItemArmor)                     ; Armor        ; Check for Armor Type        if Item.HasKeyword(ArmorShield)                         ; Armor - Shield            ; move to Shields            return _t_ref_chest_shields        elseif Item.HasKeyword(ArmorLight)                      ; Armor - Light            ; move to Light Armor            return _t_ref_chest_light_armor        elseif Item.HasKeyword(ArmorHeavy)                      ; Armor - Heavy            ; move to Heavy Armor            return _t_ref_chest_heavy_armor        else                                                    ; Unknown Armor - Why?            ; move to Other Armor            return _t_ref_chest_other_armor        endif    elseif Item.HasKeyword(VendorItemJewelry)                   ; Armor - Jewelry        ; move to Jewelry        return _t_ref_chest_jewelry    elseif Item.HasKeyword(VendorItemClothing)                  ; Armor - Clothing        ; move to Clothing        return _t_ref_chest_clothing    elseif Item.HasKeyword(VendorItemWeapon)                    ; Weapons - All        ; Check for Weapon Type        if Item.HasKeyword(WeapTypeSword)                       ; Weapon - Sword            ; move to Swords            return _t_ref_chest_swords        elseif Item.HasKeyword(WeapTypeGreatsword)              ; Weapon - Great Sword            ; move to Great Swords            return _t_ref_chest_greatswords        elseif Item.HasKeyword(WeapTypeWarAxe)                  ; Weapon - War Axe            ; move to War Axes            return _t_ref_chest_waraxes        elseif Item.HasKeyword(WeapTypeBattleaxe)               ; Weapon - Battle Axe            ; move to Battle Axes            return _t_ref_chest_battleaxes        elseif Item.HasKeyword(WeapTypeMace)                    ; Weapon - Mace            ; move to Maces            return _t_ref_chest_maces        elseif Item.HasKeyword(WeapTypeWarhammer)               ; Weapon - Warhammer            ; move to War Hammers            return _t_ref_chest_warhammers        elseif Item.HasKeyword(WeapTypeBow)                     ; Weapon - Bow            ; move to Bows            return _t_ref_chest_bows        elseif Item.HasKeyword(WeapTypeDagger)                  ; Weapon - Dagger            ; move to Daggers            return _t_ref_chest_daggers        ; elseif Item.HasKeyword(WeapTypeCrossbow)                ; Weapon - Crossbow (reqs Dawnguard)            ; move to Crossbows            ; insert return to crossbow chest if not storing with bows        else                                                    ; Weapon - Unknown (Why?)            ; move to Other Weapons            return _t_ref_chest_other_weapons        endif    elseif Item.HasKeyword(WeapTypeStaff)                       ; Staves        ; move to Staves        return _t_ref_chest_staves    elseif Item.HasKeyword(VendorItemSpellTome)                 ; Books - Spell Tome        ; move to Spell Tomes        return _t_ref_chest_spell_tomes    elseif Item.HasKeyword(VendorItemBook)                      ; Books - Other        ; move to Books        return _t_ref_chest_books    elseif Item.HasKeyword(VendorItemRecipe)                    ; Recipes        ; move to Recipes        return _t_ref_chest_recipes    elseif Item.HasKeyword(VendorItemScroll)                    ; Scrolls        ; move to Scrolls        return _t_ref_chest_scrolls    elseif Item.HasKeyword(VendorItemIngredient)                ; Ingredients        ; move to Ingredients        return _t_ref_chest_ingredients    elseif Item.HasKeyword(VendorItemKey)                       ; Keys        ; move to Keys        return _t_ref_chest_keys    elseif Item.HasKeyword(VendorItemAnimalPart)                ; Misc - Animal Parts        ; move to Animal Parts        return _t_ref_chest_animal_parts    elseif Item.HasKeyword(VendorItemAnimalHide)                ; Misc - Hide        ; move to Hide        return _t_ref_chest_hide    elseif Item.HasKeyword(VendorItemFireword)                  ; Misc - Firewood (Clutter)        ; move to Firewood        return _t_ref_chest_firewood    elseif Item.HasKeyword(VendorItemOreIngot)                  ; Misc - Ingot/Ore (Clutter)        ; move to Ore and Ingot        return _t_ref_chest_ingots_ores    elseif Item.HasKeyword(VendorItemGem)                       ; Misc - Gems        ; move to Gems        return _t_ref_chest_gems    elseif Item.HasKeyword(VendorItemSoulGem)                   ; Misc - Soul Gem        ; move to Soul Gem        return _t_ref_chest_soul_gems    elseif Item.HasKeyword(VendorItemTool)                      ; Misc - Tool        ; move to Tools        return _t_ref_chest_tools    elseif Item.HasKeyword(VendorItemClutter)                   ; Misc - Clutter        ; move to Clutter        return _t_ref_chest_clutter    elseif Item.HasKeyword(VendorItemFoodRaw)                   ; Raw Food        ; move to Raw Food        return _t_ref_chest_raw_food    elseif Item.HasKeyword(VendorItemFood)                      ; Food        ; move to Food        return _t_ref_chest_food    elseif Item.HasKeyword(VendorItemPoison)                    ; Poisons        ; move to Poisons        return _t_ref_chest_poisons    elseif Item.HasKeyword(VendorItemPotion)                    ; Potions        ; move to Potions        return _t_ref_chest_potions    else        ; move to Temp        return _t_ref_chest_temp    endifEndFunction

Known issues:

  • Skooma and Sleeping Tree Sap only have the VendorItemFood keyword.
  • Some ingredients have only the VendorItemFood keyword.
  • Some ingredients don't have any keyword.
  • Diadem of the Savant doesn't have the keyword VendorItemJewelry, but does have the keywords ArmorHelmet, VendorItemArmor, MagicDisallowEnchanting and ClothingCirclet.
  • Does not seperate Light and Heavy Shields.
  • Does not seperate Enchanted Items.
  • Savior's Hide does not have the keyword VendorItemArmor.
  • Morvarth's Boots does not have the keyword VendorItemArmor.
  • Cure Poison does not have any keywords.

The above issues could be fixed by adding keywords in the Creation Kit.

  • Quest and equipped/worn gear are removed from the player.
  • All unsorted items are moved to a the temp chest.
  • Most misc quest items do not have keywords.
  • All vanilla non-dlc quest weapons, armor and gems have related keywords are sorted. (I had created some form lists to check these items, but this method is not provided in the example.)

I had one stolen Juniper Berry (not sure how that happened) and all in my inventory or the same chest it (SkyUI) showed them all flagged as stolen, but I moved one and it moved the stolen one first.

It took 4 minutes and 24 seconds to sort 1432 different items totaling up to 89882 of which was 75977 gold (89882 - 75977 = 13905). This was a lot slower than the sorter I wrote for oblivion which leads me to believe that keyword sorting is not good for removing items from the player. Sorting by keyword may have uses in other places. I will have ideas for a different approach, more like what I did for Oblivion. I will update this thread with the details later.

User avatar
evelina c
 
Posts: 3377
Joined: Tue Dec 19, 2006 4:28 pm

Post » Sun May 18, 2014 1:08 am

If you find a better method then sorting with keywords please let me know :)

User avatar
Rebecca Clare Smith
 
Posts: 3508
Joined: Fri Aug 04, 2006 4:13 pm

Post » Sun May 18, 2014 10:15 am

Probably your biggest problem is using GetNthForm, that is a very expensive function unfortunately, especially with a large inventory -- it has to re-walk the player's (or container's) entire inventory every time you call it, which in this case includes thousands of items. I think massive inventory editing is one of the toughest things to do efficiently with papyrus... I ran into problems with that too when working on Dynamic Potions. What would be helpful for this kind of scenario is some kind of bulk inventory get() functions that can take in a filter (like a keyword or a formType) and return a formlist/array of all forms meeting the filter criteria at once. When you do that, it's about a thousand times faster, since the inventory only needs to be walked once.

User avatar
Colton Idonthavealastna
 
Posts: 3337
Joined: Sun Sep 30, 2007 2:13 am

Post » Sun May 18, 2014 1:12 pm

Do you mean SKSE plugins or using existing functions? Could you give an example?

I know I could use RemoveItems with a form list as input, but I would need to build the form list in run time because I want to ensure the broadest compatibility.

User avatar
Trey Johnson
 
Posts: 3295
Joined: Thu Oct 11, 2007 7:00 pm

Post » Sun May 18, 2014 12:57 pm

It occurred to me that http://www.nexusmods.com/skyrim/mods/18340/? might have the source scripts packed into the BSA, so I checked. Yep. It does.

General Stores uses RemoveAlll on Form Lists, but at the start you have to "train" it to recognize many items.

User avatar
Jacob Phillips
 
Posts: 3430
Joined: Tue Aug 14, 2007 9:46 am

Post » Sun May 18, 2014 4:45 am

That formlist approach would probably be your best bet for now, you could set up formlists using vanilla items, remove them all, and then walk the remainder of the inventory to identify any non-vanilla stuff left over. I think you'll probably find that to be much faster. (And yes, I was referring to some sort of SKSE plugin/extension with bulk inventory functions, which would probably be ideal, though I don't think there's currently anything like that available)

User avatar
stephanie eastwood
 
Posts: 3526
Joined: Thu Jun 08, 2006 1:25 pm

Post » Sun May 18, 2014 2:23 am

I don't feel like going as far as writing plugins. I have some ideas coalescing in my mind. I will elaborate later.

User avatar
Lizs
 
Posts: 3497
Joined: Mon Jul 17, 2006 11:45 pm

Post » Sun May 18, 2014 2:13 am

The overhead of GetNthForm needing to re-traverse the inventory linked list structure on each call isn't really the problem. Yes on an extremely large inventory that can make a difference, but it's trivial compared to the fact that almost every Papyrus function is synced to the framerate. So each script is limited to one function call per frame (with very few exceptions).

Testing "item as Weapon" will return an answer immediately while "item.HasKeyword(VendorItemWeapon)" will make your script pause until the next frame. The very first version of your script had three function calls which means that it can process about 20 distinct items per second. Your second script averaged just over 5 items per second but that works out about right based on the average number of tests you were doing if you're getting about 60fps.

Moving groups of items at a time using FormLists is faster. You can create FormLists pre-filled with various items of specific types and use them to move many/most items relatively quickly then traverse through inventory with GetNthForm to move the items that were missed by those lists. You can even add items to the form lists as you discover them in the player's inventory.

The absolute fastest method is to place a script on a single container with an OnItemAdded event that will classify each item and move it into whatever container is needed. Then you simply do a RemoveAllItems from the player to that container and use the multi-threaded nature of Papyrus to get multiple items classified at once. One potential problem is that you might overwhelm Papyrus with a particularly large inventory and items could get stuck in the sorting container.

My Storage Helpers mod deals with inventory management and it's definitely much more difficult than it was for Oblivion. I've implemented two different methods and tried many others. The first I use is very similar to what you're doing trying and as you've discovered, it is extremely slow. The second uses a hybrid of Papyrus and a SWF movie injected into the SkyUI container menu. That works better, but it's still slower than I would like because the actual item transfer is still tied to frame rate (but at least all of my decision making isn't). I haven't actually implemented either of the other two methods above because my second method allows me to avoid transferring equipped, quest, and favorited items; transfers at a rate of about one item every two frames; and gives the player control of which items are transferred also something to watch while the process is happening.

There are two major issues you haven't addressed yet when moving items out of the player's inventory: equipped items and quest items. You can check each item to see if it is currently equipped (but only if you're processing items one by one) or you can detect as items are unequipped and restore them later. The bigger problem is that there is no way to detect which items are quest items using Papyrus. If you use the FormList or the RemoveAllItems method above, you can use a ReferenceAlias on the player with the OnObjectUnequipped function to track what the player was wearing and then return and re-equip those items after they get sorted into the other containers. A workaround for the fact that you can't detect quest items would be to return all of the persistent items (those that had a reference value for the OnItemAdded function) since all (or at least almost all) of the important quest items will be persistent.

One hybrid strategy would be to use a minimized loop to avoid transferring equipped items.
While iFormIndex > 0        iFormIndex -= 1        Form kForm = FromCont.GetNthForm(iFormIndex)        if !FromCont.IsEquipped(kForm)             FromCont.RemoveItem(kForm, 99999, true, ToCont)        endifEndWhile
Then use the OnItemAdded function on the ToCont object to do the rest of the filtering including returning any items that have a persistent reference. That would transfer 10-20 item types per second for 30-60fps. (I used 99999 instead of the actual number of items because RemoveItem won't remove more than actually exist.)
User avatar
Mimi BC
 
Posts: 3282
Joined: Sat Oct 07, 2006 10:30 pm

Post » Sun May 18, 2014 2:36 am

I am currently working on a hybrid method.

Edit: How does one check persistent? I am still wondering how the game handles preventing you from dropping quest items. There is no quest flag like in Oblivion and the Fall Out games.

User avatar
kennedy
 
Posts: 3299
Joined: Mon Oct 16, 2006 1:53 am

Post » Sun May 18, 2014 11:04 am

http://www.nexusmods.com/skyrim/mods/17574/? could use a better description of it's features. It seems a lot is implied. I skipped over it the first time I saw it, because I was not really interested in crafting containers, which is all it seems to be about from first glance. Does it sort into categories?

User avatar
Dominic Vaughan
 
Posts: 3531
Joined: Mon May 14, 2007 1:47 pm

Post » Sun May 18, 2014 1:10 am

This code merely dumps items into a container to be sorted later. I haven't written the sorting for that yet, but wanted to tackle the issue of equipped items, favorites and keeping certain items. It's meant to have some setting's altered but I haven't tackled that part yet. I'm not sure how to work with global variables yet.

It handles quest items and other items by taking them away and giving the back. Which is could be a little annoying if you have Meridia's Beacon. It seems to queue dialogue. Nothing bad, just she complains.

Some of the form list would have to be build by hand in the CK or you could use TESVEdit to take them out of http://www.nexusmods.com/skyrim/mods/18340/? like I did.

If you happen wear a quest item then you'll have to re-equip it.

Spoiler
ScriptName _t_Test_Sort_Smarter Extends ObjectReference{}ObjectReference Property PlayerRef  AutoObjectReference Property _t_ref_chest_unsorted          AutoObjectReference Property _t_ref_chest_temp              AutoFormList Property _t_List_Equipped                      AutoFormList Property _t_List_Worn_Items                    AutoFormList Property _t_List_ReEquip                       AutoFormList Property _t_List_Quest_ALL                     AutoFormList Property _t_List_Misc_Keep_All                 AutoFormList Property _t_List_Misc_Keep_One                 AutoFormList Property _t_List_Mats_Smithing_ALL             AutoFormList Property _t_List_Mats_Ingredients              AutoFormList Property _t_List_Books_All                     AutoFormList Property _t_List_Soul_Gems                     AutoFormList Property _t_List_Soul_Gems_Filled              AutoFormList Property _t_List_Soul_Gems_Empty               AutoInt Property _t_KRT_Ammo                                AutoInt Property _t_KRT_Mats                                AutoInt Property _t_KRT_Books                               AutoInt Property _t_KRT_Soul_Gems_Empty                     AutoInt Property _t_KRT_Soul_Gems_Filled                    Auto;/               Globals        _t_KRT_Ammo                         =  0        _t_KRT_Mats                         = -1        _t_KRT_Books                        = -1        _t_KRT_Soul_Gems_Empty              =  0        _t_KRT_Soul_Gems_Filled             = -1/;Event OnActivate(ObjectReference akActionRef)    If akActionRef == PlayerRef        Game.DisablePlayerControls() ; make player wait for all items to be removed        Unburden(PlayerRef,_t_ref_chest_temp, _t_ref_chest_unsorted)        ;_t_ref_chest_temp.Activate(PlayerRef)        Game.EnablePlayerControls()    EndIfEndEvent; Function Dump(ObjectReference FromActor, ObjectReference TempChest)Function Unburden(ObjectReference FromActor, ObjectReference TempChest, ObjectReference UnsortedChest)                 Int Count = FromActor.GetNumItems()    Int FirstCount = Count    int ItemsMoved = 0    int ItemsUnmoved = 0    int ItemCount = 0    Debug.Trace("---------------------------------------------------------------")    Debug.Trace("Begin Removing Items")       int Removed = 0    int ListRemoved = 0    int WasCount = Count    Debug.Trace ("___________________Item Count: " + Count)       ; Remove All Quests Items to be returned to the player    FromActor.RemoveItem(_t_List_Quest_ALL, 20, true, TempChest)       Count                = FromActor.GetNumItems()    Removed              = WasCount - Count    ListRemoved         += Removed    Debug.Trace ("__________Quest Items Removed: " + Removed)    WasCount = Count       ; Remove Gold and Lock picks to be returned to the player    FromActor.RemoveItem(_t_List_Misc_Keep_All, 999999, true, TempChest)       Count                = FromActor.GetNumItems()    Removed              = WasCount - Count    ListRemoved         += Removed    Debug.Trace ("______Mult Misc Items Removed: " + Removed)    WasCount = Count       ; Remove One of Each to be returned to the player    FromActor.RemoveItem(_t_List_Misc_Keep_One, 1, true, TempChest)       Count                = FromActor.GetNumItems()    Removed              = WasCount - Count    ListRemoved         += Removed    Debug.Trace ("____Single Misc Items Removed: " + Removed)       ; Check Equipped    bool eq_state = CheckEquipped(FromActor as Actor)       ; Remove Short List Items       ; Crafting Materials    WasCount = Count    Debug.Trace("_t_KRT_Mats: " + _t_KRT_Mats)    if _t_KRT_Mats == -1        Debug.Trace("Removing Mats")        FromActor.RemoveItem(_t_List_Mats_Smithing_ALL, 99999, true, UnsortedChest)        FromActor.RemoveItem(_t_List_Mats_Ingredients, 99999, true, UnsortedChest)    endif    Count                = FromActor.GetNumItems()    Removed              = WasCount - Count    ListRemoved         += Removed    Debug.Trace ("___Crafting Materials Removed: " + ListRemoved)       ; Books    WasCount = Count    Debug.Trace("_t_KRT_Books: " + _t_KRT_Books)    if _t_KRT_Books == -1        Debug.Trace("Removing Books")        FromActor.RemoveItem(_t_List_Books_All, 99999, true, UnsortedChest)    endif    Count                = FromActor.GetNumItems()    Removed              = WasCount - Count    ListRemoved         += Removed    Debug.Trace ("________________Books Removed: " + Removed)       ; Soul Gems    WasCount = Count    Debug.Trace("_t_KRT_Soul_Gems_Filled: " + _t_KRT_Soul_Gems_Filled)    Debug.Trace("_t_KRT_Soul_Gems_Empty: " + _t_KRT_Soul_Gems_Empty)    if _t_KRT_Soul_Gems_Filled == -1 && _t_KRT_Soul_Gems_Empty == -1        Debug.Trace("Removing All Soul Gems")        FromActor.RemoveItem(_t_List_Soul_Gems, 99999, true, UnsortedChest)    elseif _t_KRT_Soul_Gems_Filled == -1        Debug.Trace("Removing Filled Soul Gems")        FromActor.RemoveItem(_t_List_Soul_Gems_Filled, 99999, true, UnsortedChest)    elseif _t_KRT_Soul_Gems_Empty == -1        Debug.Trace("Removing Empty Soul Gems")        FromActor.RemoveItem(_t_List_Soul_Gems_Empty, 99999, true, UnsortedChest)    endif    Count                = FromActor.GetNumItems()    Removed              = WasCount - Count    ListRemoved         += Removed    Debug.Trace ("____________Soul Gems Removed: " + Removed)       ; Count = FromActor.GetNumItems()    Debug.Trace("Items moved by list: " + ListRemoved )    Debug.Trace("Items left: " + Count)    ; Int Index = 0    Int Index = Count    Int CheckCode = 0    String ItemName = ""While Index > 0        Index -= 1  Form Item = FromActor.GetNthForm(Index)        if Item            CheckCode = ItemCheck(Item, eq_state)            ; ItemName = Item.GetName()            ; Debug.Trace("Index : " + Index + " Item: " + ItemName)            if CheckCode == -1                ; Remove All                ItemCount = FromActor.GetItemCount(Item)                FromActor.RemoveItem(Item, ItemCount, true, UnsortedChest)                ItemsMoved += ItemCount            elseif CheckCode > 0                ; Reserve Amount                ItemCount = FromActor.GetItemCount(Item)                ItemCount -= CheckCode                FromActor.RemoveItem(Item, ItemCount, true, UnsortedChest)                ItemsMoved += ItemCount            else                ItemsUnmoved += 1            endif        else            Debug.Trace("NO ITEM FOUND AT INDEX: " + Index)        endifEndWhile       ReEquipItems(FromActor as Actor)       _t_List_Worn_Items.Revert()    _t_List_Equipped.Revert()    _t_List_ReEquip.Revert()    TempChest.RemoveAllItems(FromActor)    Debug.Trace("---------------------------------------------------------------")    Debug.Trace("Number of Different Items: " + FirstCount)    Debug.Trace("Total Items Moved: " + ItemsMoved)    Debug.Trace("Total Items Unmoved: " + ItemsUnmoved)    Debug.Trace("---------------------------------------------------------------")EndFunction bool Function CheckEquipped(Actor FromActor)    Form eItem       eItem = FromActor.GetWornForm(0x00000001)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00000002)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00000004)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00000008)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00000010)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00000020)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00000040)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00000080)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00000100)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00000200)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00000400)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00000800)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00001000)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)    eItem = FromActor.GetWornForm(0x00002000)    _t_List_Worn_Items.AddForm(eItem)    _t_List_ReEquip.AddForm(eItem)       int eq = 0    eItem = FromActor.GetEquippedObject(0)    if !(eItem as Spell)        _t_List_Equipped.AddForm(eItem)        _t_List_ReEquip.AddForm(eItem)        eq += 1    endif       eItem = FromActor.GetEquippedObject(1) as Weapon    if !(eItem as Spell)        _t_List_Equipped.AddForm(eItem)        _t_List_ReEquip.AddForm(eItem)        eq += 1    endif       return (eq as bool)EndFunctionInt Function ItemCheck(Form Item, bool Weap_EQ_Check = false)    ; -1 = Take; 0 = Keep; >0 == Keep that amount    int ItemTypeCode = Item.GetType()    ; Debug.Trace("ItemCheck: Type: " + ItemTypeCode + "  " + Item)    if     ItemTypeCode == 42                                   ; Ammo        if _t_KRT_Ammo == 0                 ; Keep            return 0        elseif Game.IsObjectFavorited(Item) ; Keep            return 0        else                                ; Remove All            return -1        endif    elseif ItemTypeCode == 26                                   ; Armor        if _t_List_Worn_Items.HasForm(Item)            _t_List_Worn_Items.RemoveAddedForm(Item)            return 1        elseif Game.IsObjectFavorited(Item)            return 1        else            return -1        endif    elseif ItemTypeCode == 30                                   ; Ingredient        return 0    elseif ItemTypeCode == 45                                   ; Key        return 0    elseif ItemTypeCode == 32                                   ; Misc        return -1    elseif ItemTypeCode == 27                                   ; Book        ; Debug.Trace("We missed a book: " + item)        return 0    elseif ItemTypeCode == 46                                   ; Potion/Poison/Food        if Game.IsObjectFavorited(Item)            return 0        else            return -1        endif    elseif ItemTypeCode == 23                                   ; Scroll        if Game.IsObjectFavorited(Item)            return 0        else            return -1        endif    elseif ItemTypeCode == 52                                   ; Soul Gem        ; Debug.Trace("We missed a soul gem: " + item)        return 0    elseif ItemTypeCode == 41                                   ; Weapon        if Game.IsObjectFavorited(Item)            return 2        elseif Weap_EQ_Check && _t_List_Equipped.HasForm(Item)            _t_List_Equipped.RemoveAddedForm(Item)            return 2        else            return -1        endif    endif    return 1 ; defaults to keeping itEndFunctionFunction ReEquipItems(Actor eActor)    int index = _t_List_ReEquip.GetSize()    While index > 0        index -= 1        Form eItem = _t_List_ReEquip.GetAt(index)        String ItemName = eItem.GetName()        if eActor.IsEquipped(eItem)            Debug.Trace("Already Equipped: " + ItemName)        else            Debug.Trace("       Equipping: " + ItemName)            eActor.EquipItem(eItem)        endif    EndWhileEndFunction

Edit: The idea is to sort the items later. It took 1 minute and 37 just to remove the same number of items.

Edit again: Fixed an error I have overlooked. I had not compiled the last changes. =/

Edit again: Removed unused properties.

Edit again: It took 1 min 15s after I commented-out the traces in the main loop. That's 986 different items that was not handled by RemoveItems called on Form Lists. It took a total of 2 seconds to remove 446 different items using the initial lists.

Since I am wanted to keep items some items on the player without removing them then it requires that I loop over the players inventory for items that can be Equipped and Favorited.

User avatar
Kelly John
 
Posts: 3413
Joined: Tue Jun 13, 2006 6:40 am

Post » Sun May 18, 2014 3:57 am


Storage Helpers has added features over time. Originally it was about crafting containers and had a very simple ability to move groups of items into the containers but I was so unhappy with the item move feature that I didn't highlight it.

I think you've now run into all of the issues that plagued me. I eventually gave up on the pre-defined inventory sorting strategy and just made the SWF file for injecting into SkyUI so I could use the SkyUI filtering system and gather the equipped, quest, and favorite status through the UI. As far as I can tell there's absolutely no way to detect quest items. The trick I used was to trigger the UI to transfer items instead of using RemoveItem. The UI seems to know which ones are quest items even if it won't tell you which they are.

I think you already found it, but the only way I have been able to track persistence is whether the OnAddItem/OnRemoveItem gets a non-None value in the reference argument.
User avatar
Alyna
 
Posts: 3412
Joined: Wed Aug 30, 2006 4:54 am

Post » Sun May 18, 2014 1:31 am

I was able to copy form lists from General Stores and I have made some of my own. It's tedious work, but I feel like it will be worth it in the end.

My strategy borrows from ideas in General Stores, but I am intend to make it more to my liking. I don't like the menus. For me it's clunky. I love the concept of having visual references for the various categories of storage. I don't know how I am going to solve that part though.

Being able to sort and identify inventory items will help with another project I have in mind. I don't want to reveal more until I finish with inventory management. One thing at a time. =)

Edit: In the past I wouldn't have had the patience for building these lists. Somehow I have more patience, maybe it's the inspiration of the future project and my desire to reduce inventory management.

User avatar
Lance Vannortwick
 
Posts: 3479
Joined: Thu Sep 27, 2007 5:30 pm

Post » Sun May 18, 2014 12:30 am

I am about fed up with this. =/ After doing all this work. I still hadn't tested removing a small amount of items from the player. It takes 4 seconds to deal with 69 items using the last script I posted. For me, that's just too long.

User avatar
Marcin Tomkow
 
Posts: 3399
Joined: Sun Aug 05, 2007 12:31 pm

Post » Sun May 18, 2014 1:48 pm

Sadly papyrus is slow for a lot of things and bulk data is basically the worst. I would wager an SKSE dll plugin written in C or something fast and not tied to framerate or the engine would be your best bet. It shouldn't be too hard to make one that returns a formlist containing everything in the player's inventory that isn't equipped, favorites, or quest items. SKSE dlls have access to more information than papyrus does so stuff like quest info isn't hard to get at (IIRC). Then you just pass the returned formlist to removeItem and sort from the temp chest.

User avatar
Tai Scott
 
Posts: 3446
Joined: Sat Jan 20, 2007 6:58 pm

Post » Sun May 18, 2014 1:50 pm

That's beyond my skill at this point. I have decided to scale back my lofty goals. I usually have to do that. I mainly want to reduce inventory management.

Edit: While that idea sounds great. I was thinking I will just snap-shot the worn and favorited items into form lists, dump everything with RemoveAllItems, add the items back and equip the worn items, but I just read that there is issues using http://www.creationkit.com/EquipItem_-_Actor on player enchanted items. =/

User avatar
Fanny Rouyé
 
Posts: 3316
Joined: Sun Mar 25, 2007 9:47 am

Post » Sat May 17, 2014 11:19 pm

You can use EquipItemEx (SKSE) to get around that bug.

User avatar
Laura Ellaby
 
Posts: 3355
Joined: Sun Jul 02, 2006 9:59 am

Post » Sun May 18, 2014 4:01 am

Hmmm...

So basically, you want to grab all the items in the player's inventory and separate it all into various containers by type?

I'll throw out a suggestion from the top of my head, not tested at all so might end up being slower then what you've already tried :shrug: ...

My idea is to script the various containers in a daisy-chain so that as items come in, if it's not the right type for that container, then it spits them out to the next container in the chain. Rinse & repeat until the end of the chain where it returns the item to the player if it didn't belong in any of the themed containers. This should mean that you just have to do a "playerREF.RemoveAllItems(firstChestRef, true, true)" (after first storing all the equipped items in another chest to reequip them to the player after) and then the container scripts will do the rest.

The script that gets attached to the container refs should look something like the following:

Scriptname ArmorContainerRefScript extends ObjectReferenceObjectReference Property kNextRef  AutoEvent OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)	If akBaseItem as Armor		; Item is of type Armor, leave it in here, do nothing	Else		RemoveItem(akBaseItem, aiItemCount, true, kNextRef)	EndIfEndEvent
For each container script, just change the line "If akBaseItem as XXXX" to check for whichever form type you need for that container. Then fill the "kNextRef" property with the next container reference in the chain (for the last one you fill the property with the player)

As with most things in the CK, there's loads of ways to skin a cat. The trick is to figure out the right way for your situation :)

Good luck!

- Hypno
User avatar
Arrogant SId
 
Posts: 3366
Joined: Sat May 19, 2007 11:39 am

Post » Sun May 18, 2014 9:01 am

I have already written the code that divides the items in to many containers based on what they are. My problem is the 4 seconds it takes to handle the items the player will keep. That would be the script I provided above.

User avatar
abi
 
Posts: 3405
Joined: Sat Nov 11, 2006 7:17 am

Post » Sun May 18, 2014 2:50 am

Finally I have got the Unburden Script I was looking for.

Features:

  • Does not remove equipped items
  • Does not remove favorited items
  • Does not remove keys, gold or lockpicks
  • Does not remove empty soul gems
  • Removes all recognized crafting materials (ingots, ore, leather, ingredients)
  • Removes all raw food
  • Removes all recognized books
  • Does not remove remaining misc items. This was intended to avoid moving quest items. You'll just have to handle that clutter yourself, you pack rat! =P

Issues:

It doesn't handle user made items. I had an enchanted ring marked as favorite and because it was made from a silver ring, silver rings did not get removed from my inventory.

User made potions were left in the inventory. I am not sure why. I am pretty sure the the last script did handle user made potions.

Notes:

I have two versions of the main function in the script. Scan_Inventoy did not work correctly with favorited items. It did not remove favorited arrows, but all other favorites got removed. I have not idea why. Scan_Inventoy_Redux fills a list to no purpose, but was intended in case I found that I had to move the favorited items back into the inventory. I guess I could merely comment-out the lines, but it still boggles me why the first function didn't work. I wrote Test_Favorites after the frustration of not knowing why Scan_Inventory was failing.

Looking at the log and seeing the times it takes to do certain operations has lead me to believe that I need to combine the form list used in the function FastPurge into one form list in order to speed up the process even further.

This script is not sorting items into containers. I intend to initiate that part after the player has been unburdened. This will be achieved by adding a line to the OnActivate Block where the Activator will activate the unsorted chest and the unsorted chest will run a sorting script when activated by the Unburden Activator. I will post that code after I have refined it.

I began writing this because I was not happy with http://www.nexusmods.com/skyrim/mods/18340. General stores does not handle weapons and armor. You have to manually move those items. Also, I don't like the menus. I have endorsed General Stores and I am currently using it. One thing it does have going for it is the activators themselves. I appreciate the work that went into making those wonderful custom activators.

Spoiler
ScriptName _t_Unburden_Activator_Script Extends ObjectReferenceObjectReference Property PlayerRef                      AutoObjectReference Property _t_ref_chest_unsorted          AutoFormList Property _t_List_Books_All                     AutoFormList Property _t_List_Cons_Food_Raw                 AutoFormList Property _t_List_Mats_Ingredients              AutoFormList Property _t_List_Mats_Smithing_All             AutoFormList Property _t_List_Soul_Gems_Filled              AutoFormList Property _t_List_Filter                        AutoFormList Property _t_List_Favorites                     AutoEvent OnActivate(ObjectReference akActionRef)    Debug.Trace("[t]=============================================================================")    Debug.Trace("[t] Unburden Activator Started")    Debug.Trace("[t]-----------------------------------------------------------------------------")    If akActionRef == PlayerRef        int ItemCount  = PlayerRef.GetNumItems()        int LastCount  = ItemCount        int Difference = 0        Debug.Trace("[t] Removing Standard Items... Item Count: " + ItemCount)        FastPurge(_t_ref_chest_unsorted)        ItemCount  = PlayerRef.GetNumItems()        Difference = LastCount - ItemCount        LastCount  = ItemCount        Debug.Trace("[t] Starting Scan..............Item Count: " + ItemCount + " Difference: " + Difference)        Scan_Inventory_Redux()        Debug.Trace("[t] Scan complete.")        Debug.Trace("[t] Removing remaining times...")        PlayerRef.RemoveItem(_t_List_Filter, 99999, true, _t_ref_chest_unsorted)        ItemCount  = PlayerRef.GetNumItems()        Difference = LastCount - ItemCount        LastCount  = ItemCount        Debug.Trace("[t] .......................... Item Count: " + ItemCount + " Difference: " + Difference)        _t_List_Filter.Revert()        Debug.Trace("[t]-----------------------------------------------------------------------------")    endif    Debug.Trace("[t]=============================================================================")EndEvent;/Event OnActivate(ObjectReference akActionRef)    if akActionRef == PlayerRef        Test_Favorites()    endifEndEvent /;Function FastPurge(ObjectReference ToCont)    PlayerRef.RemoveItem(_t_List_Books_All,          99999, true, ToCont)    PlayerRef.RemoveItem(_t_List_Cons_Food_Raw,      99999, true, ToCont)    PlayerRef.RemoveItem(_t_List_Mats_Ingredients,   99999, true, ToCont)    PlayerRef.RemoveItem(_t_List_Mats_Smithing_All,  99999, true, ToCont)    PlayerRef.RemoveItem(_t_List_Soul_Gems_Filled,   99999, true, ToCont)EndFunctionFunction Test_Favorites()    Actor pActor = PlayerRef as Actor    Form Item    Int ItemTypeCode    Int Index = pActor.GetNumItems()    ; Debug.Trace("Number of Items: " + Index)    String ItemName    While Index > 0        Index -= 1        Item = pActor.GetNthForm(Index)        ItemTypeCode = Item.GetType()        if     ItemTypeCode == 42                                   ; Ammo            if (Game.IsObjectFavorited(Item))                ItemName = Item.GetName()                Debug.Trace("[t] Item:" + Item + " Type: " + ItemTypeCode + " Name: " + ItemName)            endif        elseif ItemTypeCode == 26                                   ; Armor            if (Game.IsObjectFavorited(Item))                ItemName = Item.GetName()                Debug.Trace("[t] Item:" + Item + " Type: " + ItemTypeCode + " Name: " + ItemName)            endif        elseif ItemTypeCode == 46                                   ; Potion/Poison/Food            if (Game.IsObjectFavorited(Item))                ItemName = Item.GetName()                Debug.Trace("[t] Item:" + Item + " Type: " + ItemTypeCode + " Name: " + ItemName)            endif        elseif ItemTypeCode == 23                                   ; Scroll            if (Game.IsObjectFavorited(Item))                ItemName = Item.GetName()                Debug.Trace("[t] Item:" + Item + " Type: " + ItemTypeCode + " Name: " + ItemName)            endif        elseif ItemTypeCode == 41                                   ; Weapon            if (Game.IsObjectFavorited(Item))                ItemName = Item.GetName()                Debug.Trace("[t] Item:" + Item + " Type: " + ItemTypeCode + " Name: " + ItemName)            endif        endif    EndWhile   EndFunctionFunction Scan_Inventory_Redux()    Actor pActor = PlayerRef as Actor    Form Item    Int ItemTypeCode    Int Index = pActor.GetNumItems()    ; Debug.Trace("Number of Items: " + Index)    String ItemName    While Index > 0        Index -= 1        Item = pActor.GetNthForm(Index)        ItemTypeCode = Item.GetType()        if     ItemTypeCode == 42                                   ; Ammo            if (Game.IsObjectFavorited(Item))                _t_List_Favorites.AddForm(Item)            elseif pActor.IsEquipped(Item) == false                _t_List_Filter.AddForm(Item)            endif        elseif ItemTypeCode == 26                                   ; Armor            if (Game.IsObjectFavorited(Item))                _t_List_Favorites.AddForm(Item)            elseif pActor.IsEquipped(Item) == false                _t_List_Filter.AddForm(Item)            endif        elseif ItemTypeCode == 46                                   ; Potion/Poison/Food            if (Game.IsObjectFavorited(Item))                _t_List_Favorites.AddForm(Item)            else                _t_List_Filter.AddForm(Item)            endif        elseif ItemTypeCode == 23                                   ; Scroll            if (Game.IsObjectFavorited(Item))                _t_List_Favorites.AddForm(Item)            elseif pActor.IsEquipped(Item) == false                _t_List_Filter.AddForm(Item)            endif        elseif ItemTypeCode == 41                                   ; Weapon            if (Game.IsObjectFavorited(Item))                _t_List_Favorites.AddForm(Item)            elseif pActor.IsEquipped(Item) == false                _t_List_Filter.AddForm(Item)            endif        endif    EndWhile   EndFunctionFunction Scan_Inventory()    Actor pActor = PlayerRef as Actor    Form Item    Int ItemTypeCode    Int Index = pActor.GetNumItems()    ; Debug.Trace("Number of Items: " + Index)    String ItemName    While Index > 0        Index -= 1        Item = pActor.GetNthForm(Index)        ItemTypeCode = Item.GetType()        if     ItemTypeCode == 42                                   ; Ammo            if !(Game.IsObjectFavorited(Item))                _t_List_Filter.AddForm(Item)            endif        elseif ItemTypeCode == 26                                   ; Armor            if !(Game.IsObjectFavorited(Item))                _t_List_Filter.AddForm(Item)            elseif pActor.IsEquipped(Item) == false                _t_List_Filter.AddForm(Item)            endif        elseif ItemTypeCode == 46                                   ; Potion/Poison/Food            if !(Game.IsObjectFavorited(Item))                _t_List_Filter.AddForm(Item)            endif        elseif ItemTypeCode == 23                                   ; Scroll            if !(Game.IsObjectFavorited(Item))                _t_List_Filter.AddForm(Item)            endif        elseif ItemTypeCode == 41                                   ; Weapon            if !(Game.IsObjectFavorited(Item))                _t_List_Filter.AddForm(Item)            elseif pActor.IsEquipped(Item) == false                _t_List_Filter.AddForm(Item)            endif        else            ItemName = Item.GetName()            Debug.Trace("[t] Item:" + Item + " Type: " + ItemTypeCode + " Name: " + ItemName)        endif    EndWhile   EndFunction

The log below shows the three runs. The second run was ran on what was left behind. The player is still encumbered at this point. The last run is after manually removing the remaining items and was done to show a best case. The error shown is due to the form list _t_List_Filter being empty. I think I will solve this by putting a torch in the list in the CK and the adding one torch back to the inventory at the end.

28 seconds for 1216 items

5 seconds for 182 items

1 second for 79 items

Spoiler
[04/16/2014 - 07:08:24AM] [t]=============================================================================
[04/16/2014 - 07:08:24AM] [t] Unburden Activator Started
[04/16/2014 - 07:08:24AM] [t]-----------------------------------------------------------------------------
[04/16/2014 - 07:08:24AM] [t] Removing Standard Items... Item Count: 1216
[04/16/2014 - 07:08:26AM] [t] Starting Scan..............Item Count: 954 Difference: 262
[04/16/2014 - 07:09:01AM] [t] Scan complete.
[04/16/2014 - 07:09:01AM] [t] Removing remaining times...
[04/16/2014 - 07:09:02AM] [t] .......................... Item Count: 182 Difference: 772
[04/16/2014 - 07:09:02AM] [t]-----------------------------------------------------------------------------
[04/16/2014 - 07:09:02AM] [t]=============================================================================
[04/16/2014 - 07:16:34AM] [t]=============================================================================
[04/16/2014 - 07:16:34AM] [t] Unburden Activator Started
[04/16/2014 - 07:16:34AM] [t]-----------------------------------------------------------------------------
[04/16/2014 - 07:16:34AM] [t] Removing Standard Items... Item Count: 182
[04/16/2014 - 07:16:34AM] [t] Starting Scan..............Item Count: 182 Difference: 0
[04/16/2014 - 07:16:39AM] [t] Scan complete.
[04/16/2014 - 07:16:39AM] [t] Removing remaining times...
[04/16/2014 - 07:16:39AM] Error: (36004F10): is not a valid inventory item.
stack:
[ (00000014)].Actor.RemoveItem() - "" Line ?
[ (360012DB)]._t_Unburden_Activator_Script.OnActivate() - "_t_Unburden_Activator_Script.psc" Line 38
[04/16/2014 - 07:16:39AM] [t] .......................... Item Count: 182 Difference: 0
[04/16/2014 - 07:16:39AM] [t]-----------------------------------------------------------------------------
[04/16/2014 - 07:16:39AM] [t]=============================================================================
[04/16/2014 - 07:22:52AM] [t]=============================================================================
[04/16/2014 - 07:22:52AM] [t] Unburden Activator Started
[04/16/2014 - 07:22:52AM] [t]-----------------------------------------------------------------------------
[04/16/2014 - 07:22:52AM] [t] Removing Standard Items... Item Count: 79
[04/16/2014 - 07:22:52AM] [t] Starting Scan..............Item Count: 79 Difference: 0
[04/16/2014 - 07:22:53AM] [t] Scan complete.
[04/16/2014 - 07:22:53AM] [t] Removing remaining times...
[04/16/2014 - 07:22:53AM] Error: (36004F10): is not a valid inventory item.
stack:
[ (00000014)].Actor.RemoveItem() - "" Line ?
[ (360012DB)]._t_Unburden_Activator_Script.OnActivate() - "_t_Unburden_Activator_Script.psc" Line 38
[04/16/2014 - 07:22:53AM] [t] .......................... Item Count: 79 Difference: 0
[04/16/2014 - 07:22:53AM] [t]-----------------------------------------------------------------------------
[04/16/2014 - 07:22:53AM] [t]=============================================================================

Edit: Return lines were missing from the script. Removed a some unnecessary lines.

User avatar
Kat Lehmann
 
Posts: 3409
Joined: Tue Jun 27, 2006 6:24 am

Post » Sun May 18, 2014 2:56 am

After testing I have realized that player made potions cannot be handled by adding them to a form list. I am not sure why. The form list has the items. I have ran a test as follows:

  • Add all potions to a formlist
  • Removed all items using the form list
  • reverted the form list
  • shown the form list contents
  • Added all potions remaining potions to the formlist using the same method as before
  • shown the form list contents
User avatar
mike
 
Posts: 3432
Joined: Fri Jul 27, 2007 6:51 pm

Post » Sun May 18, 2014 6:41 am

Very nice. And if you sort into very specific containers it's not that big of a problem if a quest item is grabbed by accident. The player can always go back and find it. Player made potions are stored in the savegame and have a mod index value of FF. How many mods do you have? If aren't running more than 127 you might want to try making a few dummy mods to get enough in your game that items from some mods with a load order number of 128 or higher make it into your lists. The problem could either be with just base forms stored in the save game or with items over the magic 128 boundary point.
User avatar
Cat
 
Posts: 3451
Joined: Mon Dec 18, 2006 5:10 am

Post » Sun May 18, 2014 4:13 am

It still took 2 seconds on the same amount of times, using a merged list rather than 5 separate lists. Basically, no difference is discernible.

User avatar
vanuza
 
Posts: 3522
Joined: Fri Sep 22, 2006 11:14 pm

Post » Sun May 18, 2014 12:34 am

I am not sure I understand all that, but I only have 53 mods.

User avatar
Pat RiMsey
 
Posts: 3306
Joined: Fri Oct 19, 2007 1:22 am

Next

Return to V - Skyrim

cron