I just tested this fact. http://www.nexusmods.com/skyrim/mods/18340/? is able to handle player created potions and player enchanted gear.
Looking at General Stores scripts it seems that it handles user created items by iterating over the the formlist and removing each item at a time. Considering this, I decided to test the time difference between the FormList Method (shown in the Scan_Inventory_Redux function in the last example) and Remove-As-You-Crawl Method with 954 different items (not to mention the count of each different item) there is a one second difference in the time it takes. The FormList method is 1 second faster but also failed to move 78 different items. Therefor the Remove-As-You-Crawl Method is superior due to the fact that player made items are not moved by the FormList Method.
Take note that both methods crawl over the inventory and that the real slowdown is the iteration over the items using GetNthForm. This is necessary to avoid moving equipped and favorited items.
Another method that I have not tested here is the use of RemoveAllItems(ToCont, True). I could get all the equipped items, but I would not be able to make note of all the favorite items. This method would add two complications. One being that the user would have to define items to keep separately from the UI's favorite feature and that the player character would spend some amount of time naked before being re-equipped. These are complications that I want to avoid entirely.
Below is the sorting script I was testing. It worked last I checked.
Edit: Some lists are marked in comments as "sort out." The idea is to sort these items into a container from the sub categories or elsewhere (where noted) to present them, temporarily, into another container for viewing. This part I have not yet written. The following script merely separates items into containers where they will be stored.
ScriptName _t_Test_Sorting_Container Extends ObjectReference{}; ################################ CHESTS #####################################ObjectReference Property _t_ref_chest_arrows Auto ; aka ammoObjectReference Property _t_ref_chest_armor_all Auto ; sort outObjectReference Property _t_ref_chest_armor_clothing AutoObjectReference Property _t_ref_chest_armor_heavy AutoObjectReference Property _t_ref_chest_armor_light AutoObjectReference Property _t_ref_chest_armor_shields AutoObjectReference Property _t_ref_chest_armor_jewelry Auto; ObjectReference Property _t_ref_chest_other_armor Auto why do I have this?ObjectReference Property _t_ref_chest_books_all Auto ; sort outObjectReference Property _t_ref_chest_books_spell_tomes Auto ;ObjectReference Property _t_ref_chest_books_recipes Auto ;ObjectReference Property _t_ref_chest_books_skill Auto ;ObjectReference Property _t_ref_chest_books_other Auto ;ObjectReference Property _t_ref_chest_books_bound Auto ;ObjectReference Property _t_ref_chest_cons_food_all Auto ; sort outObjectReference Property _t_ref_chest_cons_food_cooked AutoObjectReference Property _t_ref_chest_cons_food_raw Auto ; sort out food raw / ingredients from ingredientsObjectReference Property _t_ref_chest_cons_pots_all Auto ; sort outObjectReference Property _t_ref_chest_cons_pots_buffs AutoObjectReference Property _t_ref_chest_cons_pots_restore AutoObjectReference Property _t_ref_chest_cons_pots_poisons AutoObjectReference Property _t_ref_chest_cons_scrolls AutoObjectReference Property _t_ref_chest_mats_ingredients AutoObjectReference Property _t_ref_chest_mats_smithing_all Auto ; sort outObjectReference Property _t_ref_chest_mats_smithing AutoObjectReference Property _t_ref_chest_mats_smelting AutoObjectReference Property _t_ref_chest_mats_tanning AutoObjectReference Property _t_ref_chest_mats_gems Auto ; sort outObjectReference Property _t_ref_chest_misc_clutter AutoObjectReference Property _t_ref_chest_misc_animal_parts AutoObjectReference Property _t_ref_chest_soul_gems AutoObjectReference Property _t_ref_chest_weap_all Auto ; sort outObjectReference Property _t_ref_chest_weap_swords AutoObjectReference Property _t_ref_chest_weap_greatswords AutoObjectReference Property _t_ref_chest_weap_waraxes AutoObjectReference Property _t_ref_chest_weap_battleaxes AutoObjectReference Property _t_ref_chest_weap_maces AutoObjectReference Property _t_ref_chest_weap_warhammers AutoObjectReference Property _t_ref_chest_weap_bows AutoObjectReference Property _t_ref_chest_weap_daggers AutoObjectReference Property _t_ref_chest_weap_staves AutoObjectReference Property _t_ref_chest_temp AutoObjectReference Property _t_ref_chest_unsorted Auto; ################################# LISTS #####################################FormList Property _t_List_Ammo AutoFormList Property _t_List_Armor_All Auto ; sort out from all armorFormList Property _t_List_Armor_Clothing AutoFormList Property _t_List_Armor_Heavy AutoFormList Property _t_List_Armor_Light AutoFormList Property _t_List_Armor_Shields AutoFormList Property _t_List_Armor_Jewelry AutoFormList Property _t_List_Books_All Auto ; sort out from all booksFormList Property _t_List_Books_Spell_Tomes AutoFormList Property _t_List_Books_Recipes AutoFormList Property _t_List_Books_Skill AutoFormList Property _t_List_Books_Other AutoFormList Property _t_List_Books_Bound AutoFormList Property _t_List_Cons_Food_All Auto ; sort out from all foodFormList Property _t_List_Cons_Food_Cooked AutoFormList Property _t_List_Cons_Food_Raw AutoFormList Property _t_List_Cons_Food_Raw_Ingredients Auto ; sort out to raw/ingredients - no chestFormList Property _t_List_Cons_Potions_ALL Auto ; sort out from all potionsFormList Property _t_List_Cons_Potions_Buffs AutoFormList Property _t_List_Cons_Potions_Restore AutoFormList Property _t_List_Cons_Potions_Poisons AutoFormList Property _t_List_Cons_Scrolls AutoFormList Property _t_List_Mats_Ingredients AutoFormList Property _t_List_Mats_Ingredients_Smithing Auto ; sort out to smithing/ingredients - no chestFormList Property _t_List_Mats_Smithing_All Auto ; sort out from all materialsFormList Property _t_List_Mats_Smithing AutoFormList Property _t_List_Mats_Smelting AutoFormList Property _t_List_Mats_Tanning AutoFormList Property _t_List_Mats_Gems Auto ; sort out from smithingFormList Property _t_List_Misc_Animal_Parts AutoFormList Property _t_List_Soul_Gems_ALL AutoFormList Property _t_List_Misc_Clutter AutoFormList Property _t_List_Weap_All Auto ; sort out from all weaponsFormList Property _t_List_Weap_Swords AutoFormList Property _t_List_Weap_Greatswords AutoFormList Property _t_List_Weap_Waraxes AutoFormList Property _t_List_Weap_Battlaxes AutoFormList Property _t_List_Weap_Maces AutoFormList Property _t_List_Weap_Warhammers AutoFormList Property _t_List_Weap_Bows AutoFormList Property _t_List_Weap_Daggers AutoFormList Property _t_List_Weap_Staves Auto;---------------------------- Discovery Lists ---------------------------------FormList Property _t_List_Disc_Ammo AutoFormList Property _t_List_Disc_Armor_All AutoFormList Property _t_List_Disc_Armor_Clothing AutoFormList Property _t_List_Disc_Armor_Heavy AutoFormList Property _t_List_Disc_Armor_Light AutoFormList Property _t_List_Disc_Armor_Shields AutoFormList Property _t_List_Disc_Armor_Jewelry AutoFormList Property _t_List_Disc_Books_All AutoFormList Property _t_List_Disc_Books_Bound Auto ; need special function to check against model path. The idea is to seperate notes and journals into other. Not like there would be many mod added books anyway.FormList Property _t_List_Disc_Books_Other AutoFormList Property _t_List_Disc_Books_Recipes AutoFormList Property _t_List_Disc_Books_Skill AutoFormList Property _t_List_Disc_Books_Spell_Tomes AutoFormList Property _t_List_Disc_Cons_Food_All AutoFormList Property _t_List_Disc_Cons_Food_Cooked AutoFormList Property _t_List_Disc_Cons_Food_Raw AutoFormList Property _t_List_Disc_Cons_Food_Raw_Ingredients AutoFormList Property _t_List_Disc_Cons_Potions_ALL AutoFormList Property _t_List_Disc_Cons_Potions_Buffs Auto ; restorative potions will sort here too unless predefinedFormList Property _t_List_Disc_Cons_Potions_Restore Auto ; need special function for checking effects - this may yet be limited where anyone has expanded potion effectsFormList Property _t_List_Disc_Cons_Potions_Poisons AutoFormList Property _t_List_Disc_Cons_Scrolls AutoFormList Property _t_List_Disc_Mats_Ingredients AutoFormList Property _t_List_Disc_Mats_Ingredients_Smithing AutoFormList Property _t_List_Disc_Mats_Smithing_All AutoFormList Property _t_List_Disc_Mats_Smithing AutoFormList Property _t_List_Disc_Mats_Smelting AutoFormList Property _t_List_Disc_Mats_Tanning AutoFormList Property _t_List_Disc_Mats_Gems AutoFormList Property _t_List_Disc_Misc_Animal_Parts AutoFormList Property _t_List_Disc_Misc_Clutter Auto; FormList Property _t_List_Disc_Soul_Gems_ALL Auto ; would/has anyone really add more soul gems?FormList Property _t_List_Disc_Weap_All AutoFormList Property _t_List_Disc_Weap_Swords AutoFormList Property _t_List_Disc_Weap_Greatswords AutoFormList Property _t_List_Disc_Weap_Waraxes AutoFormList Property _t_List_Disc_Weap_Battlaxes AutoFormList Property _t_List_Disc_Weap_Maces AutoFormList Property _t_List_Disc_Weap_Warhammers AutoFormList Property _t_List_Disc_Weap_Bows AutoFormList Property _t_List_Disc_Weap_Daggers AutoFormList Property _t_List_Disc_Weap_Staves Auto; User defines items that will be destroyed on cell reset.; Items removed from Junk will be unlearned.FormList Property _t_List_Disc_Misc_Junk Auto; #############################################################################Keyword Property ArmorClothing AutoKeyword Property ArmorHeavy AutoKeyword Property ArmorJewelry AutoKeyword Property ArmorLight AutoKeyword Property ArmorShield AutoKeyword Property GiftApothecarySpecial AutoKeyword Property GiftPriestSpecial AutoKeyword Property GiftThiefSpecial AutoKeyword Property GiftWarriorSpecial AutoKeyword Property GiftWizardSpecial AutoKeyword Property VendorItemAnimalHide AutoKeyword Property VendorItemAnimalPart AutoKeyword Property VendorItemClothing AutoKeyword Property VendorItemClutter AutoKeyword Property VendorItemFireword AutoKeyword Property VendorItemFood AutoKeyword Property VendorItemFoodRaw AutoKeyword Property VendorItemGem AutoKeyword Property VendorItemJewelry AutoKeyword Property VendorItemOreIngot AutoKeyword Property VendorItemPoison AutoKeyword Property VendorItemPotion AutoKeyword Property VendorItemRecipe AutoKeyword Property VendorItemSpellTome AutoKeyword Property VendorItemTool AutoKeyword Property WeapTypeBattleaxe AutoKeyword Property WeapTypeBow AutoKeyword Property WeapTypeDagger AutoKeyword Property WeapTypeGreatsword AutoKeyword Property WeapTypeMace AutoKeyword Property WeapTypeStaff AutoKeyword Property WeapTypeSword AutoKeyword Property WeapTypeWaraxe AutoKeyword Property WeapTypeWarhammer Auto; #############################################################################ObjectReference Property _t_ref_sorting_activator AutoObjectReference Property PlayerRef AutoBool Property Report_Error AutoEvent OnActivate(ObjectReference akActionRef) Report_Error = False if akActionRef == _t_ref_sorting_activator ; Debug.MessageBox("Activator Activated Unsorted Chest") Sort_Unsorted() elseif akActionRef == PlayerRef _t_ref_chest_unsorted.Activate(PlayerRef,true) endif if Report_Error Debug.MessageBox("[triloth] An error or errors has occurred in function" + \ "HandleUnkown of Sorting Container. If not enabled, enable logging to" + \ "see the details.") endif EndEventFunction Sort_Unsorted() { Sort items using form lists, then call SortUnkown on the remaining items. } ; PREDEFINED ; Ammo Debug.Trace("=========================================================================") Debug.Trace("[t] Begin Sorting Unsorted.") Debug.Trace("=========================================================================") Int NumItems = _t_ref_chest_unsorted.GetNumItems() Debug.Trace("[t] Items = " + NumItems) _t_ref_chest_unsorted.RemoveItem(_t_List_Ammo, 99999, true, _t_ref_chest_arrows) ; Armor _t_ref_chest_unsorted.RemoveItem(_t_List_Armor_Clothing, 99999, true, _t_ref_chest_armor_clothing) _t_ref_chest_unsorted.RemoveItem(_t_List_Armor_Heavy, 99999, true, _t_ref_chest_armor_heavy) _t_ref_chest_unsorted.RemoveItem(_t_List_Armor_Light, 99999, true, _t_ref_chest_armor_light) _t_ref_chest_unsorted.RemoveItem(_t_List_Armor_Shields, 99999, true, _t_ref_chest_armor_shields) _t_ref_chest_unsorted.RemoveItem(_t_List_Armor_Jewelry, 99999, true, _t_ref_chest_armor_jewelry) ; Books _t_ref_chest_unsorted.RemoveItem(_t_List_Books_Spell_Tomes, 99999, true, _t_ref_chest_books_spell_tomes) _t_ref_chest_unsorted.RemoveItem(_t_List_Books_Recipes, 99999, true, _t_ref_chest_books_recipes) _t_ref_chest_unsorted.RemoveItem(_t_List_Books_Skill, 99999, true, _t_ref_chest_books_skill) _t_ref_chest_unsorted.RemoveItem(_t_List_Books_Other, 99999, true, _t_ref_chest_books_other) _t_ref_chest_unsorted.RemoveItem(_t_List_Books_Bound, 99999, true, _t_ref_chest_books_bound) ; Consumables - Food _t_ref_chest_unsorted.RemoveItem(_t_List_Cons_Food_Cooked, 99999, true, _t_ref_chest_cons_food_cooked) _t_ref_chest_unsorted.RemoveItem(_t_List_Cons_Food_Raw, 99999, true, _t_ref_chest_cons_food_raw) ; Consumables - Potions _t_ref_chest_unsorted.RemoveItem(_t_List_Cons_Potions_Buffs, 99999, true, _t_ref_chest_cons_pots_buffs) _t_ref_chest_unsorted.RemoveItem(_t_List_Cons_Potions_Restore, 99999, true, _t_ref_chest_cons_pots_restore) _t_ref_chest_unsorted.RemoveItem(_t_List_Cons_Potions_Poisons, 99999, true, _t_ref_chest_cons_pots_poisons) ; Consumables - Scrolls _t_ref_chest_unsorted.RemoveItem(_t_List_Cons_Scrolls, 99999, true, _t_ref_chest_cons_scrolls) ; Materials _t_ref_chest_unsorted.RemoveItem(_t_List_Mats_Ingredients, 99999, true, _t_ref_chest_mats_ingredients) _t_ref_chest_unsorted.RemoveItem(_t_List_Mats_Smithing, 99999, true, _t_ref_chest_mats_smithing) _t_ref_chest_unsorted.RemoveItem(_t_List_Mats_Smelting, 99999, true, _t_ref_chest_mats_smelting) _t_ref_chest_unsorted.RemoveItem(_t_List_Mats_Tanning, 99999, true, _t_ref_chest_mats_tanning) ; Misc _t_ref_chest_unsorted.RemoveItem(_t_List_Misc_Animal_Parts, 99999, true, _t_ref_chest_misc_animal_parts) _t_ref_chest_unsorted.RemoveItem(_t_List_Soul_Gems_ALL, 99999, true, _t_ref_chest_soul_gems) _t_ref_chest_unsorted.RemoveItem(_t_List_Misc_Clutter, 99999, true, _t_ref_chest_misc_clutter) ; Weapons _t_ref_chest_unsorted.RemoveItem(_t_List_Weap_Swords, 99999, true, _t_ref_chest_weap_swords) _t_ref_chest_unsorted.RemoveItem(_t_List_Weap_Greatswords, 99999, true, _t_ref_chest_weap_greatswords) _t_ref_chest_unsorted.RemoveItem(_t_List_Weap_Waraxes, 99999, true, _t_ref_chest_weap_waraxes) _t_ref_chest_unsorted.RemoveItem(_t_List_Weap_Battlaxes, 99999, true, _t_ref_chest_weap_battleaxes) _t_ref_chest_unsorted.RemoveItem(_t_List_Weap_Maces, 99999, true, _t_ref_chest_weap_maces) _t_ref_chest_unsorted.RemoveItem(_t_List_Weap_Warhammers, 99999, true, _t_ref_chest_weap_warhammers) _t_ref_chest_unsorted.RemoveItem(_t_List_Weap_Bows, 99999, true, _t_ref_chest_weap_bows) _t_ref_chest_unsorted.RemoveItem(_t_List_Weap_Daggers, 99999, true, _t_ref_chest_weap_daggers) _t_ref_chest_unsorted.RemoveItem(_t_List_Weap_Staves, 99999, true, _t_ref_chest_weap_staves) ; DISCOVERED ;/ ; Ammo _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Ammo, 99999, true, _t_ref_chest_arrows) ; Armor _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Armor_Clothing, 99999, true, _t_ref_chest_armor_clothing) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Armor_Heavy, 99999, true, _t_ref_chest_armor_heavy) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Armor_Light, 99999, true, _t_ref_chest_armor_light) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Armor_Shields, 99999, true, _t_ref_chest_armor_shields) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Armor_Jewelry, 99999, true, _t_ref_chest_armor_jewelry) ; Books _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Books_Spell_Tomes, 99999, true, _t_ref_chest_books_spell_tomes) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Books_Recipes, 99999, true, _t_ref_chest_books_recipes) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Books_Skill, 99999, true, _t_ref_chest_books_skill) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Books_Other, 99999, true, _t_ref_chest_books_other) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Books_Bound, 99999, true, _t_ref_chest_books_bound) ; Consumables - Food _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Cons_Food_Cooked, 99999, true, _t_ref_chest_cons_food_cooked) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Cons_Food_Raw, 99999, true, _t_ref_chest_cons_food_raw) ; Consumables - Potions _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Cons_Potions_Buffs, 99999, true, _t_ref_chest_cons_pots_buffs) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Cons_Potions_Restore, 99999, true, _t_ref_chest_cons_pots_restore) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Cons_Potions_Poisons, 99999, true, _t_ref_chest_cons_pots_poisons) ; Consumables - Scrolls _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Cons_Scrolls, 99999, true, _t_ref_chest_cons_scrolls) ; Materials _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Mats_Ingredients, 99999, true, _t_ref_chest_mats_ingredients) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Mats_Smithing, 99999, true, _t_ref_chest_mats_smithing) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Mats_Smelting, 99999, true, _t_ref_chest_mats_smelting) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Mats_Tanning, 99999, true, _t_ref_chest_mats_tanning) ; Misc _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Misc_Animal_Parts, 99999, true, _t_ref_chest_misc_animal_parts) ;_t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Soul_Gems_ALL, 99999, true, _t_ref_chest_soul_gems) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Misc_Clutter, 99999, true, _t_ref_chest_misc_clutter) ; Weapons _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Weap_Swords, 99999, true, _t_ref_chest_weap_swords) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Weap_Greatswords, 99999, true, _t_ref_chest_weap_greatswords) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Weap_Waraxes, 99999, true, _t_ref_chest_weap_waraxes) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Weap_Battlaxes, 99999, true, _t_ref_chest_weap_battleaxes) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Weap_Maces, 99999, true, _t_ref_chest_weap_maces) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Weap_Warhammers, 99999, true, _t_ref_chest_weap_warhammers) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Weap_Bows, 99999, true, _t_ref_chest_weap_bows) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Weap_Daggers, 99999, true, _t_ref_chest_weap_daggers) _t_ref_chest_unsorted.RemoveItem(_t_List_Disc_Weap_Staves, 99999, true, _t_ref_chest_weap_staves) /; Int RemovedItems = NumItems NumItems = _t_ref_chest_unsorted.GetNumItems() RemovedItems -= NumItems Debug.Trace("[t] Items after list method = " + RemovedItems) SortUnkown() NumItems = _t_ref_chest_unsorted.GetNumItems() Debug.Trace("[t] =========================================================================") Debug.Trace("[t] Completed Complex Sorting Pass. Items Remaining: " + NumItems) Debug.Trace("[t] =========================================================================")EndFunctionFunction SortUnkown() { Rescan the remaining items starting with comparisons from the result of Form.GetType, then check for keywords relative to the item type. } Form Item Int Index = _t_ref_chest_unsorted.GetNumItems()While Index > 0 Index -= 1 Item = _t_ref_chest_unsorted.GetNthForm(Index) HandleUnkown(Item)EndWhileEndFunction; BELOW BE DRAGONS!!!Function SetListTo(Form Item, FormList DiscList, ObjectReference ToCont) DiscList.AddForm(Item) _t_ref_chest_unsorted.RemoveItem(Item, 99999, true, ToCont)EndFunctionFunction HandleUnkown(Form Item) ; -1 = Take; 0 = Keep; >0 == Keep that amount int ItemTypeCode = Item.GetType() ; Debug.Trace("ItemCheck: Type: " + ItemTypeCode + " " + Item) int Count = 0 bool type_test = false if ItemTypeCode == 42 ; Ammo SetListTo(Item, _t_List_Disc_Ammo, _t_ref_chest_arrows) elseif ItemTypeCode == 26 ; Armor Checks ; Check for Armor Type type_test = true if Item.HasKeyword(ArmorShield) ; Armor - Shield SetListTo(Item, _t_List_Disc_Armor_Shields, _t_ref_chest_armor_shields) elseif Item.HasKeyword(ArmorLight) ; Armor - Light SetListTo(Item, _t_List_Disc_Armor_Light, _t_ref_chest_armor_light) elseif Item.HasKeyword(ArmorHeavy) ; Armor - Heavy SetListTo(Item, _t_List_Disc_Armor_Heavy, _t_ref_chest_armor_heavy) elseif Item.HasKeyword(VendorItemJewelry) ; Armor - Jewelry SetListTo(Item, _t_List_Disc_Armor_Jewelry, _t_ref_chest_armor_jewelry) elseif Item.HasKeyword(ArmorJewelry) ; Armor - Jewelry SetListTo(Item, _t_List_Disc_Armor_Jewelry, _t_ref_chest_armor_jewelry) elseif Item.HasKeyword(ArmorClothing) ; Armor - Clothing ; checked last because some items have keywords for jewelry and clothing SetListTo(Item, _t_List_Disc_Armor_Clothing, _t_ref_chest_armor_clothing) elseif Item.HasKeyword(VendorItemClothing) ; Armor - Clothing ; checked last because some items have keywords for jewelry and clothing SetListTo(Item, _t_List_Disc_Armor_Clothing, _t_ref_chest_armor_clothing) else type_test = false endif if type_test ; Armor - ALL _t_List_Disc_Armor_All.AddForm(Item) ; Parent Category else ; Armor Type Unknown ; This is actually a bug in the item. The item ; needs the proper keywords for perks and vendors. ; It could also be possible that it's a non-playable item. Report_Error = True Debug.Trace("[t] Armor missing ArmorType keyword: " + Item) endif elseif ItemTypeCode == 30 ; Ingredient if Item.HasKeyword(VendorItemFoodRaw) ; Ingredient/FoodRaw SetListTo(Item, _t_List_Disc_Cons_Food_Raw_Ingredients, _t_ref_chest_mats_ingredients) else SetListTo(Item, _t_List_Disc_Mats_Ingredients, _t_ref_chest_mats_ingredients) endif ; elseif ItemTypeCode == 45 ; Key elseif ItemTypeCode == 32 ; Misc if Item.HasKeyword(VendorItemAnimalHide) ; Misc - Hide (Tanning) ; this will not catch fur armor because fur would have been caught above SetListTo(Item, _t_List_Disc_Mats_Tanning, _t_ref_chest_mats_tanning) elseif Item.HasKeyword(VendorItemGem) ; Misc - Gem (Smithing) SetListTo(Item, _t_List_Disc_Mats_Smithing, _t_ref_chest_mats_smithing) elseif Item.HasKeyword(VendorItemOreIngot) ; Misc - Ore/Ingot (Smithing All/Smithing/Smelting) ; This does not conform to the level of separation I have for vanilla items. Therefore, I am forced to include these items in the Smelting, Smithing and Smithing All categories. SetListTo(Item, _t_List_Disc_Mats_Smelting, _t_ref_chest_mats_smelting) _t_List_Disc_Mats_Smithing.AddForm(Item) _t_List_Disc_Mats_Smithing_All.AddForm(Item) ; Parent Category elseif Item.HasKeyword(VendorItemTool) ; Misc - Tool (Clutter) SetListTo(Item, _t_List_Disc_Misc_Clutter, _t_ref_chest_misc_clutter) elseif Item.HasKeyword(VendorItemClutter) ; Misc - Clutter SetListTo(Item, _t_List_Disc_Misc_Clutter, _t_ref_chest_misc_clutter) elseif Item.HasKeyword(VendorItemAnimalPart) ; Misc - Animal Part SetListTo(Item, _t_List_Disc_Misc_Animal_Parts, _t_ref_chest_misc_animal_parts) elseif Item.HasKeyword(VendorItemFireword) ; Misc - Firewood (Smelting); yes I spelled the key word correctly SetListTo(Item, _t_List_Disc_Mats_Smelting, _t_ref_chest_mats_smelting) else Debug.Trace("[t] Misc Item failed checks " + Item.GetName() + Item ) ; Misc - Unsorted (sent to clutter) _t_ref_chest_unsorted.RemoveItem(Item, 99999, true, _t_ref_chest_misc_clutter) endif elseif ItemTypeCode == 27 ; Book - ALL _t_List_Disc_Books_All.AddForm(Item) if Item.HasKeyword(VendorItemSpellTome) ; Book - Spell Tome SetListTo(Item, _t_List_Disc_Books_Spell_Tomes, _t_ref_chest_books_spell_tomes) elseif Item.HasKeyword(VendorItemRecipe) ; Book - Recipe SetListTo(Item, _t_List_Disc_Books_Recipes, _t_ref_chest_books_recipes) elseif Item.HasKeyword(GiftApothecarySpecial) ; Book - Skill Book SetListTo(Item, _t_List_Disc_Books_Skill, _t_ref_chest_books_skill) elseif Item.HasKeyword(GiftThiefSpecial) ; Book - Skill Book SetListTo(Item, _t_List_Disc_Books_Skill, _t_ref_chest_books_skill) elseif Item.HasKeyword(GiftWarriorSpecial) ; Book - Skill Book SetListTo(Item, _t_List_Disc_Books_Skill, _t_ref_chest_books_skill) elseif Item.HasKeyword(GiftWizardSpecial) ; Book - Skill Book SetListTo(Item, _t_List_Disc_Books_Skill, _t_ref_chest_books_skill) elseif Item.HasKeyword(GiftPriestSpecial) ; Book - Skill Book SetListTo(Item, _t_List_Disc_Books_Skill, _t_ref_chest_books_skill) else ; Book - Other SetListTo(Item, _t_List_Disc_Books_Other, _t_ref_chest_books_other) endif elseif ItemTypeCode == 46 ; Potion/Poison/Food if Item.HasKeyword(VendorItemPotion) ; Potion/Potions All SetListTo(Item, _t_List_Disc_Cons_Potions_Buffs, _t_ref_chest_cons_pots_buffs) _t_List_Disc_Cons_Potions_ALL.AddForm(Item) elseif Item.HasKeyword(VendorItemPoison) ; Poison/Potions All SetListTo(Item, _t_List_Disc_Cons_Potions_Poisons, _t_ref_chest_cons_pots_poisons) _t_List_Disc_Cons_Potions_ALL.AddForm(Item) elseif Item.HasKeyword(VendorItemFood) ; Food - Raw/ Food - All (If using for vanilla sort, Mammoth Steak will end up here due to vanilla error. It has both key words so does Mammoth Meat) SetListTo(Item, _t_List_Disc_Cons_Food_Raw, _t_ref_chest_cons_food_raw) _t_List_Disc_Cons_Food_All.AddForm(Item) elseif Item.HasKeyword(VendorItemFoodRaw) ; Food - Cooked / Food - All SetListTo(Item, _t_List_Disc_Cons_Food_Cooked, _t_ref_chest_cons_food_cooked) _t_List_Disc_Cons_Food_All.AddForm(Item) endif elseif ItemTypeCode == 23 ; Scroll SetListTo(Item, _t_List_Disc_Cons_Scrolls, _t_ref_chest_cons_scrolls) ; elseif ItemTypeCode == 52 ; Soul Gem elseif ItemTypeCode == 41 ; Weapons Check type_test = true if Item.HasKeyword(WeapTypeBattleaxe) ; Weapon - Battle Axe SetListTo(Item, _t_List_Disc_Weap_Battlaxes, \ _t_ref_chest_weap_battleaxes) elseif Item.HasKeyword(WeapTypeBow) ; Weapon - Bow SetListTo(Item, _t_List_Disc_Weap_Bows, \ _t_ref_chest_weap_bows) elseif Item.HasKeyword(WeapTypeDagger) ; Weapon - Dagger SetListTo(Item, _t_List_Disc_Weap_Daggers, \ _t_ref_chest_weap_daggers) elseif Item.HasKeyword(WeapTypeGreatsword) ; Weapon - Great Sword SetListTo(Item, _t_List_Disc_Weap_Greatswords, \ _t_ref_chest_weap_greatswords) elseif Item.HasKeyword(WeapTypeMace) ; Weapon - Mace SetListTo(Item, _t_List_Disc_Weap_Maces, \ _t_ref_chest_weap_maces) elseif Item.HasKeyword(WeapTypeStaff) ; Weapon - Staff SetListTo(Item, _t_List_Disc_Weap_Staves, \ _t_ref_chest_weap_staves) elseif Item.HasKeyword(WeapTypeSword) ; Weapon - Sword SetListTo(Item, _t_List_Disc_Weap_Swords, \ _t_ref_chest_weap_swords) elseif Item.HasKeyword(WeapTypeWaraxe) ; Weapon - War Axe SetListTo(Item, _t_List_Disc_Weap_Waraxes, \ _t_ref_chest_weap_waraxes) elseif Item.HasKeyword(WeapTypeWarhammer) ; Weapon - War Hammer SetListTo(Item, _t_List_Disc_Weap_Warhammers, \ _t_ref_chest_weap_warhammers) else type_test = false endif if type_test ; Weapon - ALL _t_List_Disc_Weap_All.AddForm(Item) else ; Weapon Type Unknown ; This is actually a bug in the item. The item ; needs the proper keywords for perks and vendors. ; It could also be possible that it's a non-playable item. Report_Error = True Debug.Trace("[t] Weapon missing WeaponType keyword: " + Item) endif else ; Nothing to do here. The item apparently failed all checks ever. ; Fail mod is fail? Can SkyUI even recognize this thing? Report_Error = True Debug.Trace("[t] Inventory item failed to sort: " + Item) endif EndFunction
It's been a while since I worked on sorting. It's not that I don't intend to work out sorting it's just that I am working out other aspects of Dragonborn's Entourage at the moment. Some of the features I intend to include work well on their own and I intended to release them as seperate mods. So far, I have released http://www.nexusmods.com/skyrim/mods/53103/?.
I am currently working on my ability to check all aspects of armor and weapons so that I might create custom objects. I would like to overcome certain difficulties in dealing with player enchantments. For instance, while testing Quick Stash I discovered that a player enchanted silver ring is counted as a silver ring while iterating over the contents of a container. I also discovered that SkyUI's Focus Group Feature does not recognize the difference between a silver ring and a player enchanted silver ring. I had made the mistake of enchanting several silver rings with different enchantments to be equipped with focus groups and discovered my rings weren't switching.
It may seem simple enough to remember this fact and to always use different rings for enchanting, but I don't like the limitation and I feel that it would be useful to come up with a way of overcoming this limitation through papyrus scripting. I have an idea involving blank base items that get filled out with other item's data in order to become completely unique items at the base level and therefore overcome the limitation. I am currently working on that feature and intend to release it separately one I got it worked out. I think I will call it, Gear Saver.
I just released an skse plugin, which adds the following functions to papyrus:
GetNumItemsWithKeyword(Keyword Key, bool getTotalCount = false)
and
GetNthFormWithKeyword(Keyword Key, int KeywordIndex)
Both functions run as fast as GetNumItems() and GetNthForm(Int Index)
After discovering your discussion here i thought they might be usefull for you..
http://www.nexusmods.com/skyrim/mods/53320/?
I am not sure that I can have a use for these yet, but I will keep them in mind. They may be useful to others who are considering this type of problem.
Thank you for your consideration.
The concept of Gear Saver is proving to be a difficult task. It seems that I would have to create a blank item for every armor slot keyword and material type as well as create corresponding armor addons and tempering constructible objects.
I discovered that items without armor slot keywords cannot be enchanted. The Enchanter lets you select the item, but it does not let you set any enchantments. I added the keyword ArmorBoots and discovered I could then enchant the item with http://www.uesp.net/wiki/Skyrim:Enchanting_Effects. There is no SKSE function for adding keywords to an item so this means the keywords have to be set in the CK.
Armor Slot Keywords:
I have tested each of these individually to see if they all relate to enchanting. I wouldn't say that some of these are completely redundant (like ArmorHelmet, ClothingCirclet and ClothingRing), but as far as enchanting is concerned they are. So this begs the question: How else are these keywords used (other than http://www.creationkit.com/Armor_Script#SKSE_Member_Functions that use these keywords internally)? If it doesn't cause problems, could reduce the list to:
Material Type Keywords:
Besides these, more are added by armor mods. I didn't even cover DLC Content and there may be more that aren't prefixed as ArmorMaterial. Keywords are necessary for perks for matching sets. I was thinking that I could reduce the number of combinations to focus solely on materials used in tempering recipes, until I noticed that some tempering recipes have more than one material requirement (I haven't gotten around to smithing in game yet.). Then again I could focus it down some. Possibly with the following catagories:
It should also be noted that not all vanilla items falling in the above categories require all the same materials in order to temper. One example is the the Daedric Shield, which only required Ebony, where a Daedric Helmet also requires a Daedra Heart and Leather Strips.
That still means that I will have to create at least 44 blank base items and 44 tempering recipes for these blank items. Already I have given up on the idea of Gear Saver, which would merely be a basic version of a more advanced idea I am (was?) working on for copying one items appearance while using another items stats. I know there are mods that are based on WoW's Transmogrify concept, but I found their limitations or implementations lacking. I am learning that some of these limitations exist for reasons other than simply how it worked in WoW.
WEAPONS!!! I have only been digging into armor and speaking about armor. I have not even touched on weapons yet. So to include weapons the number of blank base items and tempering recipes goes up.
Not wanting to give up on my advanced concept, which I intend to call Hallowed Smithing (this name seems to be unique at the moment). I could make all Hallowed items require a limited set of materials and justify this with the idea that the Hallowing changes the tempering requirements. Although I have to set a limit on the number of Hallowed Items the player can have, I wanted to at least make it so that the player can have multiple items for each gear slot. Personally, I would like to use SkyUI's Focus group to equip items with different enchantments depending on how I am about to attack or what spells I am planning to cast or even what kind of attacks or spells are being directed at me. This is one of the main reasons I decided to move towards this basic concept in the first place.
Other than the considerations for player enchanting and tempering, the number of base blank forms has to be limited for the obvious reason that they have to be created in the CK. The idea in-game is that the Hallowing "creates a connection" between the items and the player and that there can only be so many. But this raises another issue. Once the limit is reached how do I release previously hallowed forms from the connection? I answered this with "breaking the connection destroys the item." The Hallowed Smithing is to be handled by a single NPC. In order to justify this in game in an immersive way, He will need the item returned to him in order to break the connection.
Given these limitations and justifications, Problems could arise from the player losing Hallowed items. I can easily prevent Hallowed Items from being sold by not adding Vendor Keywords. Setting the gold value to 0 would remove the player's incentive to sell the items, but selling to vendors is not the only way to lose an item. I could force the items into an alias and I had even considered making them quest items so that they could be located through quest markers if the player happens to loose track of where he stored one, but I'd also like to be able to give Hallowed Items to followers (another reason for wanting to have multiple sets).
Giving items to followers has been known as a way of losing items too. Sometimes it's as if the follower's inventory is completely reset or something. I have seen specifically body slot items and cloaks vanish. I was surprised the last time I lost Lydia that she didn't "eat" any gear items. I swear I left her in the inn in Winterhold waiting, but I found her in Dragonsreach and had to "hire" her again.
Nothing I can think of will resolve this issue of needing to know what has become of a Hallowed Item before I can justify "breaking the connection." Simply, which item of all the items that are currently in use would I choose and why if not simply hand-picked by the player to be "recycled" into a new Hallowed Item? If I can't prevent Hallowed Items from being lost forever then potentially I could run out of items to be recycled.
I don't know how other mod authors are handling this concept or if they have even ruled out these kinds of complications.
Arriving at this point in the writing... which is mostly a self dialogue with elements of research and project documentation... I stopped to go dig up the mods which similar concepts.
http://www.nexusmods.com/skyrim/mods/33902/? It doesn't require patches for mod added items, but does not use new base forms thus NPCs would end up using the changed items.
http://www.nexusmods.com/skyrim/mods/50773/? Seems to use new base forms, but requires patches for mod added items.
There was another (that I can't find right now) that allowed you to make the items at the tanning rack, but this would require patches for mod added items--not to mention the tedium of creating recipes for every possible combination by hand.
Is there some way to possibly wear items that would essentially hide the worn armor and thus achieve the ultimate goal of having the look you want with stats you need without altering the base forms of existing items?
If I could overcome the issue of lost items then I could move forward with this concept as is.
I am open to suggestions. I posted this here because this is directly related to my research into handling inventory items. I am also open to other suggestion related to inventory items and reducing time spent in inventory management.
Edit: fixed the link to Transmogrification - Copy Armor Stats by Dienes
Hello and welcome to my madness as of about one year ago.
First trying to create blank objects by hand lies even more madness and also repetitive stress injury and mod incompatibility. A skyproc patcher is perfect for that though. Either internally that you use and then just release the created esp or that you release so users can run on their load order and it makes compatible with their mods as well.
Second is that blank armors aren't really a solution to transmogrifying armors anyway since there is no way to add armor addons to an armor. So you can't properly make your blank armor look like whatever armor it is transmuted into. I believe armor addons suffer the same problem that keywords do that the skse people aren't certain they can safely modify them without breaking other stuff which is why there aren't already add or remove functions. You could request they look into it again but be polite and don't get your hopes up.
Weapons however are less unreasonable. They don't have addons so skse can correctly modify nearly everything about them (no keywords and in the 1.7.0 beta setResist() function crashes the game if you pass it none which is what most weapons use as their resist type). I've got a mod in the works that does some cool things with them if I ever get some bugs worked out / beta testers ever beta test.
For keeping the items one option would be for the vendor/blacksmith npc to offer to recall missing items for a fee. When the item is created force it into an alias. Delete the item in the alias and create a new one and give that one to the player. Its quite hard to track where a specific item is because of how papyrus and the game work plus an outstanding bug with persistent ObjectReferences and containers so faking it is easier. Just have the NPC explain that recalling the item will blah blah no tempering or enchantments.
In conclusion skyrim is not a game we play but a game the devs are playing in which we are the pieces and they win when we go mad.
The problem is knowing if an item is lost or identifying the lost item. For where I am standing having the item is key to "recycling" it. I intend to handle a list of items and I can't see anyway of differentiating them.
As for the armor addon problem. It seems to me that I have that covered. I just discovered one feature that I hadn't realized would be an issue. I discovered it while examining an armor addon for the forsworn helmet. It has Additional Races for Khajiit and Argonian. I could simply deny the user the ability to copy the properties of that piece. Unless.... GetModelNthTextureSet is pointing at Nth Additonal Races Model Paths... Other than that business... you don't have to set ArmorAddons... I use blank armor addons and set their properties.
Here's a Basic Clone Function I was testing. It basically clones all aspects that I was aware of when I wrote it and gets called on Maintenance to refresh it settings.
Function Clone_Armor(Armor origin, Armor dest, String Name) ; GET Values ======================================================================== int AR = origin.GetAR() int WC = origin.GetWeightClass() string MPM = origin.GetModelPath(false) string MPF = origin.GetModelPath(true) int slotmask = origin.GetSlotMask() Enchantment Ench = origin.GetEnchantment() ; SET Values ======================================================================== dest.SetAR(AR) dest.SetWeightClass(WC) dest.SetModelPath(MPM,false) if MPF dest.SetModelPath(MPF,true) endif dest.SetSlotMask(slotmask) if Ench dest.SetEnchantment(Ench) endif dest.SetName(Name) ; Handle Armor Addon ================================================================ ; Supposedly there is only 1... ; Additional Races cannot be set, maybe that won't be a problem ; Texture Sets... why is there functions for this? I don't see this in the CK. ArmorAddon AA = origin.GetNthArmorAddon(0) string AAMP_M_FP = AA.GetModelPath(true,false) string AAMP_F_FP = AA.GetModelPath(true,true) string AAMP_M = AA.GetModelPath(false,false) string AAMP_F = AA.GetModelPath(false,true) int AAslotmask = AA.GetSlotMask() ArmorAddon AAC = dest.GetNthArmorAddon(0) if AAMP_M_FP AAC.SetModelPath(AAMP_M_FP, true, false) endif if AAMP_F_FP AAC.SetModelPath(AAMP_F_FP, true, true) endif if AAMP_M AAC.SetModelPath(AAMP_M, false, false) endif if AAMP_F AAC.SetModelPath(AAMP_F, false, true) endif AAC.SetSlotMask(AAslotmask) ; DONE ==============================================================================EndFunction
Edit: You can see where I had questions about some functions in the comments. That was copied fresh out of the Maintenance Quest Script. I tested it yesterday.
Edit: Again... Nevermind I was confused about what Additional Races meant. I still don't get the http://www.creationkit.com/ArmorAddon_Script... They aren't documented yet. At any rate, I can certainly check to see what additional races are set and see if an armor addon excludes a "required" race.
I just noticed the Show All checkbox on the Armor Form Dialogue next to the Armor Addon Pane. When Looking at the Forsworn Helmet (000D8D52), it shows the other two armor addons that are designed individually for Argonians and Khajiits. My example above doesn't iterate over Armor Addons nor does it check to see if there is more than one. I had assumed there was only one to deal with, since I had not seen any armor with more than one Armor Addon. Rather than work around this problem, I could simply exclude it from the being used as a visual template, OR I could simply ignore Armor Addons for other races and hope it doesn't clip. I'd rather not create 3 armor addons per blank armor item.
Bam! It just hit me. Have all the "recall options" displayed in a Barter Menu. Fee is a temporary Item value and that's how the service is charged as well as it gives the player an immersive way to recognize what he is missing. This completely solves the issue of lost Hallowed Items.
Using blank ArmorAddons and filling them in is a solution but kinda a partial one. Most armors only use one Addon but some use multiple, usually for racial variants but I think not always. And often but not always the general one is first but sometimes it can be in any position so you can't just assume. I believe I've seen armors that used multiple addons to construct the actual armor and not just racial alternatives so if you only copied one of them you would only get part of the look.
You also need to copy all the other info about the Armor addon or it won't work right. You have to loop through the Additional races or the armor won't show up on them or might not even equip at all for them, same with texture sets but you will need to loop for first person = true, female = true, and both = true. I'm pretty sure textureSets refer to the male/female world model MO2S entries in tesedit. Not sure what they are in the ck. I don't recall what they do exactly but I do remember an issue with lootification not setting them right and it messing up a mod and having to fix it at one point.
I was avoiding the addition races part by defining that in blank object's Armor Addon. Like I said the other Armor Addon's was a gotcha for me.
My example shows the textures sets being copied. It's the GetModelNthTextureSet and related functions that get me. I can't find anything that could be referencing in the CK. The Forsworn helmet has Armor Addons for 2 races that aren't covered in primary Armor Addon and those point to different... shall we say... worn models. It was a gotcha for me when I first started testing a blank armor that I needed to set an Armor Addon and set the paths for them in order for them to show on the character. I totally missed the fact that the paths on the Armor Form where merely the world object models. Once I set those then boots I was testing actually showed up.
About armor that uses multiple armor addons to create it's appearance. I just did that as a test to see if I could. I combined the forsworn Helmet, Cuirass, Boots and Gauntlets into one armor piece for with no other values set than the visuals as a test to see if I could do it and if that could be the part of the solution to an armor that could cover up the functional pieces. I have already tested using 2 items worn at the same time as boots. One for the appearance and the other for the stats. (I going to start calling the appearance piece the vanity armor... got the idea for Allods Online.)
There is a catch to this method. With the functional armor not having any armor addons, one could essentially where as many under the vanity as you have. I have tested this with the boots. What just came to mind and I have not tested is what would happen if I attached an armor addon with no visual data set. My original idea (and I tested this) was using a script attached to the stat armor (sounds like a good term) to check for potential stat armor stacking. It worked as implemented, but my test was only handling the potential of a copy of itself being stacked. I am sure I could expand that concept, but I'd rather not have to if I can find a "cleaner" solution to preventing the stacking.
I was aware of the potential for stacking because I have some broken masks (bandanas worn on the face) which I believe was introduced into my game by OBIS. I discovered that they didn't have any armor addons. I already new they were invisible and that was one of the reasons I investigated them. I have a test key which I use to scan my inventory or the contents of containers and display data relevant to Armor and Weapons--well not all, as I am finding out. After I had added the code to gather Armor Addon data, I checked my logs for info on those bandanas. Using this key (not really a key much like my Quick Stash key), I was able to discover other craziness with slotmasks defined in armor forms (which is what I was looking for in the first place). I actually have this wacky function that breaks down the slot masks to determine what slots are combined:
Function Slot_Mask_Info(int _mask_, int tabs = 0) int mask_check = _mask_ int slot_check = 0x40000000 String Slots = "" ; Print("MASK FUNC " + _mask_ + " AND " + slot_check ) While _mask_ > 0 if _mask_ > slot_check ; Print("MASK FUNC " + _mask_ + " > " + slot_check) _mask_ -= slot_check mask_check = slot_check slot_check /= 2 elseif _mask_ == slot_check ; Print("MASK FUNC " + _mask_ + " == " + slot_check) _mask_ = 0 ; end of the line mask_check = slot_check else ; Print("MASK FUNC " + _mask_ + " ELSE " + slot_check) slot_check /= 2 mask_check = 0 endif if mask_check if mask_check == 0x80000000 ; can't use this number... it's too big. It becomes a negative. Slots += "(61) FX01, " elseif mask_check == 0x40000000 Slots += "(60) misc/FX*, " elseif mask_check == 0x20000000 Slots += "(59) right arm*, " elseif mask_check == 0x10000000 Slots += "(58) left arm*, " elseif mask_check == 0x08000000 Slots += "(57) shoulder*, " elseif mask_check == 0x04000000 Slots += "(56) chest 2nd*, " elseif mask_check == 0x02000000 Slots += "(55) face alt*, " elseif mask_check == 0x01000000 Slots += "(54) left leg*, " elseif mask_check == 0x00800000 Slots += "(53) right leg*, " elseif mask_check == 0x00400000 Slots += "(52) pelvis 2nd*, " elseif mask_check == 0x00200000 Slots += "(51) deprecated, " elseif mask_check == 0x00100000 Slots += "(50) deprecated, " elseif mask_check == 0x00080000 Slots += "(49) pelvis 1st*, " elseif mask_check == 0x00040000 Slots += "(48) misc/FX*, " elseif mask_check == 0x00020000 Slots += "(47) back*, " elseif mask_check == 0x00010000 Slots += "(46) chest 1st*, " elseif mask_check == 0x00008000 Slots += "(45) neck*, " elseif mask_check == 0x00004000 Slots += "(44) face/mouth*, " elseif mask_check == 0x00002000 Slots += "(43) ears, " elseif mask_check == 0x00001000 Slots += "(42) circlet, " elseif mask_check == 0x00000800 Slots += "(41) long hair, " elseif mask_check == 0x00000400 Slots += "(40) tail, " elseif mask_check == 0x00000200 Slots += "(39) shield, " elseif mask_check == 0x00000100 Slots += "(38) calves, " elseif mask_check == 0x00000080 Slots += "(37) feet, " elseif mask_check == 0x00000040 Slots += "(36) ring, " elseif mask_check == 0x00000020 Slots += "(35) amulet, " elseif mask_check == 0x00000010 Slots += "(34) forearms, " elseif mask_check == 0x00000008 Slots += "(33) hands, " elseif mask_check == 0x00000004 Slots += "(32) body (full), " elseif mask_check == 0x00000002 Slots += "(31) hair, " elseif mask_check == 0x00000001 Slots += "(30) head" else Slots += " ???? " endif endif EndWhile Print("Slots: " + Slots + "["+_mask_+"]", 3 + tabs)EndFunction
TL;DR (long story short)
I did rename the items. I still didn't equip them with the focus group hot key. Maybe SkyUI has a way of distinguishing the items that is not accessable in Papyrus. I am under the impression that it uses Flash (I am assuming as in Adobe Flash I have just read things in forums.). My test didn't work out.
I didn't already have a silver ring assigned to favorites. I had a named player enchanted silver ring assigned already when I created two more named player enchanted silver rings and assigned them to different focus groups. I take your word for it. I could simply be mistaken. You seem to know what you are talking about. I reverted to a previous save then decided to start working on the current project after this happened.
Fail Test as inspiration to mod. Oh well. I still want to work on my Hallowed Smithing concept. =D
Edit: All three rings had different names.
Edit Again: After a second look at the functions you listed. I realized... I didn't actually equip two new rings before testing. Maybe it simply didn't have the unique IDs because I had never equipped them.
Did you try equipping the item manually after it was favorited before testing? I am sure I didn't test that.
if (hasItemMinCount) { // Case 1: Type already equipped in both hands. if (itemData.isTypeWorn && itemData.isTypeWornLeft) { isTargetSlotInUse = true; } // Case 2: Type already equipped in right hand. else if (itemData.isTypeWorn) { isTargetSlotInUse = targetEquipSlot == GetRightHandSlot() || targetEquipSlot == NULL; } // Case 3: Type already equipped in left hand. else if (itemData.isTypeWornLeft) { isTargetSlotInUse = targetEquipSlot == GetLeftHandSlot(); } // Case 4: Type not equipped yet. else { isTargetSlotInUse = false; } } // This also returns if the target slot is in use by another weapon of the same type. // Could handle this, but switching them here causes a bug (0 damage) for some reason. // So we just skip it. Can be handled on the Papyrus side. if (isTargetSlotInUse || !hasItemMinCount) return;
if (a_item == PlayerREF.GetEquippedObject(kHand) && a_itemId != PlayerREF.GetEquippedItemId(kHand)) UnequipHand(kHand) ; same type, different item => unequip first avoid damage-related bug when swapping for enhanced item endIf
; It's not a shield, just equip it if slot is free elseIf (! LogicalAnd(_usedOutfitMask,slotMask))+ if (a_item == PlayerREF.GetWornForm(slotMask) && a_itemId != PlayerREF.GetWornItemId(slotMask))+ PlayerREF.UnequipItemEx(a_item)+ endIf PlayerREF.EquipItemById(a_item, a_itemId, equipSlot = 0, equipSound = _silenceEquipSounds) _usedOutfitMask += slotMask endIf return true(Note: During my tests, it sometimes failed to equip the new ring but only unequipped the old one. Probably a timing issue between unequip and equip?)
After testing, I have determined I can work out the layering concept, but the method is proving to be too elusive, unnatural and cumbersome to implement. I don't even wish to spread this disease upon the community. Stadards exist to keep things compatible and it would break immersion to add such an alien concept to the inventory screen. I use SkyUI. I have from the first time I ran the game. I don't have any clue what this looks like in the vanilla inventory menu, but in SkyUI it's terrible.
Short version: Layering Concept is bad. Mmmkay.
Next Step: Seeing if I can Clone the Forsworn Helmet (Forsworn Headress) without leaving out the Armor Addons for the the Argonian and Khajiit races.
@ schlangster
I hadn't noticed you're the mod Author of SkyUI.
Are you suggesting that I make the change and compile or do you intend to release an Update for SkyUI?
Edit: Nevermind. That file is not in my source.
Doh. Didn't think to look in the BSA. I have unpacked scripts from there, so it's not a new concept for me. GitHub works too... too bad it didn't detect my Skyrim install and put them there for me.
I have changed and compiled. Thanks.