Any way to sort items in containers? (alphabetically)

Post » Wed Jun 20, 2012 10:35 am

I have some empty chests and when I store some armors or weapons in that.. its all a mess.. no alphabetic sort and I spend much time to find what I want.
with creation kit, I can fix that?

Thank you and sorry my bad english :)
User avatar
Pat RiMsey
 
Posts: 3306
Joined: Fri Oct 19, 2007 1:22 am

Post » Wed Jun 20, 2012 8:56 am

Alas, there isn't even a way to iterate through objects in a container, let alone do any sorting.
User avatar
Amanda Leis
 
Posts: 3518
Joined: Sun Dec 24, 2006 1:57 am

Post » Wed Jun 20, 2012 8:57 pm

Doesn'T SkyUI provide that ability? It rellies on SKSE, but if you merely want it for your gameplay and not for use in your mod, you really should have a look at it. If you need it for your mod just hang in there and wait until they finished Papyrus integration for SKSE.
User avatar
Prue
 
Posts: 3425
Joined: Sun Feb 11, 2007 4:27 am

Post » Wed Jun 20, 2012 8:14 pm

Doesn'T SkyUI provide that ability? It rellies on SKSE, but if you merely want it for your gameplay and not for use in your mod, you really should have a look at it. If you need it for your mod just hang in there and wait until they finished Papyrus integration for SKSE.


ok, I will tell (try, cuz my english sux) all history
I made a mod of Breezehome where I put a secret room in same cell...
there I duplicate the playerhousechest (no item respawn)
ok, then I have one chest for each kind of item (one only for armor, one only for weapons, one only for food, etc etc)
at this point everything works perfectly
the problem is, at gameplay my chests with armor or weapons have no sorting... no sorting by name, value, damage nor by "putting order"... nothing.. I rly want to change this...
I never heard about SkyUI (yes, I'm a noob, this I know) so, if have any way to change that I will be very grateful for some instructions :smile:

PS: I dont add nothing new in mod, just using what CK have by default (no-new paterns, nothing).
PS2: the game without mods have this "no-sorting" problem.. its native

Thank you for your patience :biggrin:
User avatar
Avril Louise
 
Posts: 3408
Joined: Thu Jun 15, 2006 10:37 pm

Post » Wed Jun 20, 2012 10:44 am

OK so you need that in your mod. Well as I said for this I'm afraid you need to wait for external tools such as SKSE to provide the functionality, or have a look at how they did it in SkyUI (they actualy extended the menu functionality of skyrims UI). The Problem is that Papyrus lacks even the most basic functions to make such sorting operations possible: There's no way to acces Itemweight, Itemvalue or Itemname. For the sorting by name it also lacks the functionality to split up strings into the single characters.
User avatar
Richard Dixon
 
Posts: 3461
Joined: Thu Jun 07, 2007 1:29 pm

Post » Wed Jun 20, 2012 1:53 pm

I see, thats sad... well I will investigate these other tools what u mentioned

thx bro
User avatar
Natasha Biss
 
Posts: 3491
Joined: Mon Jul 10, 2006 8:47 am

Post » Wed Jun 20, 2012 5:14 pm

Ah, actually you can iterate through the items in a container. It's just not straightforward - and the only way to sort your items into usable categories is by using more than one container. I've been working on something like this myself because, it seems, we share a common source of exasperation in this game. There are two approaches to filtering items - one uses keywords attached to the item and the other uses FormLists which include the item. Also, if you use my approach you may need to link your containers in a chain.
.
ScriptName zqzzSlSorter extends ObjectReference{This script removes items from zqzzCsSort and places them in linked containers according to classification};Activator Property zqzzCsSort  Auto;Keyword for types of weaponsKeyword 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 AutoKeyword Property VendorItemArrow Auto;Keyword for types of ArmorKeyword Property ArmorLight AutoKeyword Property ArmorHeavy AutoKeyword Property ArmorShield AutoKeyword Property ArmorHelmet AutoKeyword Property ArmorCuirass AutoKeyword Property ArmorGauntlets AutoKeyword Property ArmorBoots AutoKeyword Property ArmorJewelry AutoKeyword Property ArmorClothing Auto;Keyword for enchanted objectsKeyword Property MagicDisallowEnchanting Auto;Keyword for Other GearKeyword Property VendorItemGem AutoKeyword Property VendorItemJewelry Auto;Keyword DESIRED for favourite objects...??????????????????????;Keywords don't work as filtersEvent OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer); If akSourceContainer == Self.GetNthLinkedRef(-1);  Debug.Trace("The player game me " + aiItemCount + "x " + akBaseItem)  debug.Notification("OnitemAddedFiredSuccessfully")    If akBaseItem.HasKeyword(WeapTypeDagger) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(21))  ElseIf akBaseItem.HasKeyword(WeapTypeDagger)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(1));................LineWorksCorrectly  ElseIf akBaseItem.HasKeyword(WeapTypeBow) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(22))  ElseIf akBaseItem.HasKeyword(WeapTypeBow)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(2))  ElseIf akBaseItem.HasKeyword(VendorItemArrow) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(23))  ElseIf akBaseItem.HasKeyword(VendorItemArrow)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(3))  ElseIf akBaseItem.HasKeyword(WeapTypeSword) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(24))  ElseIf akBaseItem.HasKeyword(WeapTypeSword)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(4))  ElseIf akBaseItem.HasKeyword(WeapTypeWarAxe) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(25))  ElseIf akBaseItem.HasKeyword(WeapTypeWarAxe)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(5))  ElseIf akBaseItem.HasKeyword(WeapTypeMace) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(26))  ElseIf akBaseItem.HasKeyword(WeapTypeMace)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(6))  ElseIf akBaseItem.HasKeyword(ArmorShield) && akBaseItem.HasKeyword(ArmorLight) && akBaseItem.HasKeyword(MagicDisallowEnchanting);................FAIL due to keyword bug   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(27))  ElseIf akBaseItem.HasKeyword(ArmorShield) && akBaseItem.HasKeyword(ArmorLight);................FAIL due to keyword bug   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(7))  ElseIf akBaseItem.HasKeyword(WeapTypeGreatSword) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(28))  ElseIf akBaseItem.HasKeyword(WeapTypeGreatSword)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(8))  ElseIf akBaseItem.HasKeyword(WeapTypeBattleAxe) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(29))  ElseIf akBaseItem.HasKeyword(WeapTypeBattleAxe)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(9))  ElseIf akBaseItem.HasKeyword(WeapTypeWarHammer) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(30))  ElseIf akBaseItem.HasKeyword(WeapTypeWarHammer)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(10))  ElseIf akBaseItem.HasKeyword(WeapTypeStaff) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(31))  ElseIf akBaseItem.HasKeyword(WeapTypeStaff)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(11))  ElseIf akBaseItem.HasKeyword(ArmorShield) && akBaseItem.HasKeyword(ArmorHeavy) && akBaseItem.HasKeyword(MagicDisallowEnchanting);.................FAIL due to keyword bug   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(32))  ElseIf akBaseItem.HasKeyword(ArmorShield) && akBaseItem.HasKeyword(ArmorHeavy);.................FAIL due to keyword bug   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(12))  ElseIf akBaseItem.HasKeyword(ArmorHelmet) && akBaseItem.HasKeyword(ArmorLight) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(33))  ElseIf akBaseItem.HasKeyword(ArmorHelmet) && akBaseItem.HasKeyword(ArmorLight)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(13))  ElseIf akBaseItem.HasKeyword(ArmorCuirass) && akBaseItem.HasKeyword(ArmorLight) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(34))  ElseIf akBaseItem.HasKeyword(ArmorCuirass) && akBaseItem.HasKeyword(ArmorLight)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(14))  ElseIf akBaseItem.HasKeyword(ArmorGauntlets) && akBaseItem.HasKeyword(ArmorLight) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(35))  ElseIf akBaseItem.HasKeyword(ArmorGauntlets) && akBaseItem.HasKeyword(ArmorLight)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(15))  ElseIf akBaseItem.HasKeyword(ArmorBoots) && akBaseItem.HasKeyword(ArmorLight) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(36))  ElseIf akBaseItem.HasKeyword(ArmorBoots) && akBaseItem.HasKeyword(ArmorLight)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(16))  ElseIf akBaseItem.HasKeyword(ArmorHelmet) && akBaseItem.HasKeyword(ArmorHeavy) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(37))  ElseIf akBaseItem.HasKeyword(ArmorHelmet) && akBaseItem.HasKeyword(ArmorHeavy)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(17))  ElseIf akBaseItem.HasKeyword(ArmorCuirass) && akBaseItem.HasKeyword(ArmorHeavy) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(38))  ElseIf akBaseItem.HasKeyword(ArmorCuirass) && akBaseItem.HasKeyword(ArmorHeavy)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(18))  ElseIf akBaseItem.HasKeyword(ArmorGauntlets) && akBaseItem.HasKeyword(ArmorHeavy) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(39))  ElseIf akBaseItem.HasKeyword(ArmorGauntlets) && akBaseItem.HasKeyword(ArmorHeavy)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(19))  ElseIf akBaseItem.HasKeyword(ArmorBoots) && akBaseItem.HasKeyword(ArmorHeavy) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(40))  ElseIf akBaseItem.HasKeyword(ArmorBoots) && akBaseItem.HasKeyword(ArmorHeavy)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(20))  ElseIf (akBaseItem.HasKeyword(ArmorJewelry) || akBaseItem.HasKeyword(VendorItemJewelry)) && akBaseItem.HasKeyword(MagicDisallowEnchanting)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(42))  ElseIf akBaseItem.HasKeyword(ArmorJewelry) || akBaseItem.HasKeyword(VendorItemJewelry)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(41))  ElseIf akBaseItem.HasKeyword(VendorItemGem)   Self.RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(43))  Else;If generic keywords such as VendorItemArmor, VendorItemWeapon, etc.  EndIf; else;  Debug.Trace("I got " + aiItemCount + "x " + akBaseItem + " from another container"); endIfendEvent
.
Et Voila! Inventory iteration in Papyrus! This actually does work, for the most part. As you can see, I'm not quite done yet and you may have realized that not all enchanted items have the MagicDisallowEnchanting keyword. So, it might be best if you bundle the enchanted gear in with the unenchanted gear unless you plan to place your own keywords or set up your own FormLists. In that case I suggest you set up "special item" catchall containers in each major category to collect all the gear from other Plug-ins which will slip past your FormLists and your keywords.
.
Having said this, if you think you need to improve your English then I could recommend the literature of the 19th century (1800-1899). This period has plenty of good material, in a wide variety of subjects. If you choose a topic of interest to you, which was covered during the period, you can follow the history of this topic's development through what are called "primary sources" - which is much more reliable than getting it secondhand or third-hand from someone who may not even have read those sources. More relevant to English skills, most of this material was written at a much higher standard of English proficiency than anything you'll see today - which means that if you get into a disagreement with a grammarian, it won't take you long to produce real, valid examples in the form of fully cited quotes.
.
I'm telling you this because it is very difficult to become confident in your expression if everyone keeps changing their story about what is or is not "correct" expression and no-one can offer constructive criticism. Sadly, such equivocal advice, regarding expression, tends to be a characteristic of English-speaking cultures. E.g. describing consecutive subordinate clauses, separated by commas, as "stilted" is not meagrely a non-constructive criticism it's just plain wrong, or misleading. The correct and constructive criticism would point out that consecutive subordinate clauses are separated by a colon followed by an em-dash; not by a comma.
.
Of course, having the focus momentarily stolen by other programs, causing loss of keystrokes, can lead one to believe one might be losing ones mind, never mind ones English proficiency!
.
[EDIT] Ha Ha! You'll never guess; it's a grammatical error and it's all mine! And now it's been eradicated.[/EDIT]
User avatar
Stephanie Nieves
 
Posts: 3407
Joined: Mon Apr 02, 2007 10:52 pm

Post » Wed Jun 20, 2012 6:54 am

You can call http://www.creationkit.com/ObjectReference.RemoveItem_(Papyrus) implicitly.

Self.RemoveItem()

RemoveItem()

Also, you could speed it up by conditionalizing around mutually exclusive keywords, having separate 'ElseIf' sections while simultaneously removing the need for most of the '&&'.

Spoiler
ScriptName zqzzSlSorter extends ObjectReference{This script removes items from zqzzCsSort and places them in linked containers according to classification};Activator Property zqzzCsSort  Auto;Keyword for types of weaponsKeyword 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 AutoKeyword Property VendorItemArrow Auto;Keyword for types of ArmorKeyword Property ArmorLight AutoKeyword Property ArmorHeavy AutoKeyword Property ArmorShield AutoKeyword Property ArmorHelmet AutoKeyword Property ArmorCuirass AutoKeyword Property ArmorGauntlets AutoKeyword Property ArmorBoots AutoKeyword Property ArmorJewelry AutoKeyword Property ArmorClothing Auto;Keyword for enchanted objectsKeyword Property MagicDisallowEnchanting Auto;Keyword for Other GearKeyword Property VendorItemGem AutoKeyword Property VendorItemJewelry Auto;Keyword DESIRED for favourite objects...??????????????????????;Keywords don't work as filtersEvent OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)	If akBaseItem.HasKeyword(WeapTypeDagger)		If akBaseItem.HasKeyword(MagicDisallowEnchanting)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(21))		Else			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(1));................LineWorksCorrectly		EndIf	ElseIf akBaseItem.HasKeyword(WeapTypeBow)		If akBaseItem.HasKeyword(MagicDisallowEnchanting)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(22))		Else				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(2))		EndIf	ElseIf akBaseItem.HasKeyword(VendorItemArrow)		If akBaseItem.HasKeyword(MagicDisallowEnchanting)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(23))		Else			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(3))		EndIf	ElseIf akBaseItem.HasKeyword(WeapTypeSword)		If akBaseItem.HasKeyword(MagicDisallowEnchanting)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(24))		Else			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(4))		EndIf	ElseIf akBaseItem.HasKeyword(WeapTypeWarAxe)		If akBaseItem.HasKeyword(MagicDisallowEnchanting)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(25))		ElseIf akBaseItem.HasKeyword(WeapTypeWarAxe)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(5))		EndIf	ElseIf akBaseItem.HasKeyword(WeapTypeMace)		If akBaseItem.HasKeyword(MagicDisallowEnchanting)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(26))		Else			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(6))		EndIf	ElseIf akBaseItem.HasKeyword(ArmorShield)		If akBaseItem.HasKeyword(ArmorLight)			If akBaseItem.HasKeyword(MagicDisallowEnchanting);................FAIL due to keyword bug				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(27))			Else;If akBaseItem.HasKeyword(ArmorLight);................FAIL due to keyword bug				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(7))			EndIf		ElseIf akBaseItem.HasKeyword(ArmorHeavy)			If akBaseItem.HasKeyword(MagicDisallowEnchanting);.................FAIL due to keyword bug				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(32))			Else;If akBaseItem.HasKeyword(ArmorHeavy);.................FAIL due to keyword bug				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(12))			EndIf		EndIf	ElseIf akBaseItem.HasKeyword(WeapTypeGreatSword)		If akBaseItem.HasKeyword(MagicDisallowEnchanting)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(28))		Else			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(8))		EndIf	ElseIf akBaseItem.HasKeyword(WeapTypeBattleAxe)		If akBaseItem.HasKeyword(MagicDisallowEnchanting)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(29))		Else			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(9))		EndIf	ElseIf akBaseItem.HasKeyword(WeapTypeWarHammer)		If akBaseItem.HasKeyword(MagicDisallowEnchanting)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(30))		Else			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(10))		EndIf	ElseIf akBaseItem.HasKeyword(WeapTypeStaff)		If akBaseItem.HasKeyword(MagicDisallowEnchanting)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(31))		Else			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(11))		EndIf	ElseIf akBaseItem.HasKeyword(ArmorHelmet)		If akBaseItem.HasKeyword(ArmorLight)			If akBaseItem.HasKeyword(MagicDisallowEnchanting)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(33))			Else				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(13))			EndIf		Else			If akBaseItem.HasKeyword(MagicDisallowEnchanting)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(37))			Else				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(17))			EndIf		EndIf	ElseIf akBaseItem.HasKeyword(ArmorCuirass)		If akBaseItem.HasKeyword(ArmorLight)			If akBaseItem.HasKeyword(MagicDisallowEnchanting)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(34))			Else				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(14))			EndIf		ElseIf akBaseItem.HasKeyword(ArmorHeavy)			If akBaseItem.HasKeyword(MagicDisallowEnchanting)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(38))			Else				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(18))			EndIf		EndIf	ElseIf akBaseItem.HasKeyword(ArmorGauntlets)		If akBaseItem.HasKeyword(ArmorLight)			If akBaseItem.HasKeyword(MagicDisallowEnchanting)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(35))			Else					RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(15))			EndIf		ElseIf akBaseItem.HasKeyword(ArmorHeavy)			If akBaseItem.HasKeyword(MagicDisallowEnchanting)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(39))			Else				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(19))			EndIf		EndIf		ElseIf akBaseItem.HasKeyword(ArmorBoots)		If akBaseItem.HasKeyword(ArmorLight)			If akBaseItem.HasKeyword(MagicDisallowEnchanting)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(36))			Else				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(16))			EndIf		ElseIf akBaseItem.HasKeyword(ArmorHeavy)			If akBaseItem.HasKeyword(MagicDisallowEnchanting)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(40))			Else				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(20))			EndIf		EndIf	ElseIf (akBaseItem.HasKeyword(ArmorJewelry) || akBaseItem.HasKeyword(VendorItemJewelry))		If akBaseItem.HasKeyword(MagicDisallowEnchanting)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(42))		Else				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(41))		EndIf	ElseIf akBaseItem.HasKeyword(VendorItemGem)		RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(43));	Else;If generic keywords such as VendorItemArmor, VendorItemWeapon, etc.	EndIfEndEvent 
Might be that fixes the "Keyword Bug", by not checking for multiple keywords in the same line.
User avatar
Agnieszka Bak
 
Posts: 3540
Joined: Fri Jun 16, 2006 4:15 pm

Post » Wed Jun 20, 2012 12:55 pm

You can call http://www.creationkit.com/ObjectReference.RemoveItem_(Papyrus) implicitly.

Self.RemoveItem()

RemoveItem()

Also, you could speed it up by conditionalizing around mutually exclusive keywords, having separate 'ElseIf' sections while simultaneously removing the need for most of the '&&'.
.
It could use speeding up - but is there a line limit on the size of the scripts used in Skyrim?
User avatar
chinadoll
 
Posts: 3401
Joined: Tue Aug 22, 2006 5:09 am

Post » Wed Jun 20, 2012 5:32 pm


.
It could use speeding up - but is there a line limit on the size of the scripts used in Skyrim?
Not that I've seen as a PSC can be HUGE. Either way, I've gotten much larger scripts to work without any indication of a maximum character count. Also, I added a somewhat optimized version above.

Edit: Come to think of it, it would be even faster if the primary check was for MagicDisallowEnchanting
User avatar
Keeley Stevens
 
Posts: 3398
Joined: Wed Sep 06, 2006 6:04 pm

Post » Wed Jun 20, 2012 5:30 pm

There's not a keyword bug, in the sense of papyrus failing to detect them.

The vanilla shields do not have the Armor type keywords, so you can't sort by something that isn't there.


A high level check on the object type might improve the speed too.

if (akBaseItem As Weapon) etc...
User avatar
Jack Bryan
 
Posts: 3449
Joined: Wed May 16, 2007 2:31 am

Post » Wed Jun 20, 2012 7:45 am

If string functions were available, you could check the item name for the substring "Shield" and dynamically add a keyword.
User avatar
Miranda Taylor
 
Posts: 3406
Joined: Sat Feb 24, 2007 3:39 pm

Post » Wed Jun 20, 2012 3:56 pm

There's not a keyword bug, in the sense of papyrus failing to detect them.

The vanilla shields do not have the Armor type keywords, so you can't sort by something that isn't there.


A high level check on the object type might improve the speed too.

if (akBaseItem As Weapon) etc...
.
Thank you - any idea where I might find a list of valid akBaseItem identifiers? The Wiki still doesn't have these sort of details.
User avatar
Verity Hurding
 
Posts: 3455
Joined: Sat Jul 22, 2006 1:29 pm

Post » Wed Jun 20, 2012 4:16 pm

Not that I've seen as a PSC can be HUGE. Either way, I've gotten much larger scripts to work without any indication of a maximum character count. Also, I added a somewhat optimized version above.

Edit: Come to think of it, it would be even faster if the primary check was for MagicDisallowEnchanting
.
Thank you for the example provided above. Untangling some of this stuff is not exactly easy - and your code really expresses what you were saying very well. Thanks again.
User avatar
chinadoll
 
Posts: 3401
Joined: Tue Aug 22, 2006 5:09 am

Post » Wed Jun 20, 2012 10:49 am


.
Thank you for the example provided above. Untangling some of this stuff is not exactly easy - and your code really expresses what you were saying very well. Thanks again.
No prob :) I fixed up a few goofs from me editing it so it'll compile now and should do the same things faster.

Here's a version with the conditions hinged on the MagicDisallowEnchanting keyword. Should be faster still...
Spoiler
ScriptName zqzzSlSorter extends ObjectReferenceFormList Property StuffYouAreSortingFLST 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 AutoKeyword Property VendorItemArrow AutoKeyword Property ArmorLight AutoKeyword Property ArmorHeavy AutoKeyword Property ArmorShield AutoKeyword Property ArmorHelmet AutoKeyword Property ArmorCuirass AutoKeyword Property ArmorGauntlets AutoKeyword Property ArmorBoots AutoKeyword Property ArmorJewelry AutoKeyword Property ArmorClothing AutoKeyword Property MagicDisallowEnchanting AutoKeyword Property VendorItemGem AutoKeyword Property VendorItemJewelry AutoEvent OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)	If !StuffYouAreSortingFLST.HasForm(akBaseItem)		Return ; Even a ginormous FLST will return HasForm quickly	ElseIf akBaseItem.HasKeyword(VendorItemGem)		RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(43))	ElseIf akBaseItem.HasKeyword(MagicDisallowEnchanting)		If akBaseItem.HasKeyword(WeapTypeDagger)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(21))		ElseIf akBaseItem.HasKeyword(WeapTypeBow)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(22))		ElseIf akBaseItem.HasKeyword(VendorItemArrow)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(23))		ElseIf akBaseItem.HasKeyword(WeapTypeSword)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(24))		ElseIf akBaseItem.HasKeyword(WeapTypeWarAxe)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(25))		ElseIf akBaseItem.HasKeyword(WeapTypeMace)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(26))		ElseIf akBaseItem.HasKeyword(WeapTypeGreatSword)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(28))		ElseIf akBaseItem.HasKeyword(WeapTypeBattleAxe)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(29))		ElseIf akBaseItem.HasKeyword(WeapTypeWarHammer)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(30))		ElseIf akBaseItem.HasKeyword(WeapTypeStaff)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(31))		ElseIf akBaseItem.HasKeyword(ArmorLight)			If akBaseItem.HasKeyword(ArmorShield)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(27))			ElseIf akBaseItem.HasKeyword(ArmorHelmet)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(33))			ElseIf akBaseItem.HasKeyword(ArmorCuirass)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(34))			ElseIf akBaseItem.HasKeyword(ArmorGauntlets)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(35))			ElseIf akBaseItem.HasKeyword(ArmorBoots)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(36))			EndIf		ElseIf akBaseItem.HasKeyword(ArmorHeavy)			If akBaseItem.HasKeyword(ArmorShield)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(32))			ElseIf akBaseItem.HasKeyword(ArmorHelmet)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(37))			ElseIf akBaseItem.HasKeyword(ArmorCuirass)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(38))			ElseIf akBaseItem.HasKeyword(ArmorGauntlets)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(39))			ElseIf akBaseItem.HasKeyword(ArmorBoots)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(40))			EndIf			ElseIf (akBaseItem.HasKeyword(ArmorJewelry) || akBaseItem.HasKeyword(VendorItemJewelry))			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(42))		EndIf	Else ; If !akBaseItem.HasKeyword(MagicDisallowEnchanting)		If akBaseItem.HasKeyword(WeapTypeDagger)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(1))		ElseIf akBaseItem.HasKeyword(WeapTypeBow)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(2))		ElseIf akBaseItem.HasKeyword(VendorItemArrow)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(3))		ElseIf akBaseItem.HasKeyword(WeapTypeSword)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(4))		ElseIf akBaseItem.HasKeyword(WeapTypeWarAxe)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(5))		ElseIf akBaseItem.HasKeyword(WeapTypeMace)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(6))		ElseIf akBaseItem.HasKeyword(WeapTypeGreatSword)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(8))		ElseIf akBaseItem.HasKeyword(WeapTypeBattleAxe)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(9))		ElseIf akBaseItem.HasKeyword(WeapTypeWarHammer)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(10))		ElseIf akBaseItem.HasKeyword(WeapTypeStaff)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(11))		ElseIf akBaseItem.HasKeyword(ArmorLight)			If akBaseItem.HasKeyword(ArmorShield)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(7))			ElseIf akBaseItem.HasKeyword(ArmorHelmet)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(13))			ElseIf akBaseItem.HasKeyword(ArmorCuirass)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(14))			ElseIf akBaseItem.HasKeyword(ArmorGauntlets)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(15))			ElseIf akBaseItem.HasKeyword(ArmorBoots)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(16))			ElseIf (akBaseItem.HasKeyword(ArmorJewelry) || akBaseItem.HasKeyword(VendorItemJewelry))			EndIf		ElseIf akBaseItem.HasKeyword(ArmorHeavy)			If akBaseItem.HasKeyword(ArmorShield)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(12))			ElseIf akBaseItem.HasKeyword(ArmorHelmet)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(17))			ElseIf akBaseItem.HasKeyword(ArmorCuirass)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(18))			ElseIf akBaseItem.HasKeyword(ArmorGauntlets)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(19))			ElseIf akBaseItem.HasKeyword(ArmorBoots)				RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(20))			EndIf		ElseIf akBaseItem.HasKeyword(ArmorJewelry) || akBaseItem.HasKeyword(VendorItemJewelry)			RemoveItem(akBaseItem, aiItemCount, TRUE, Self.GetNthLinkedRef(41))		EndIf	EndIf	EndEvent
Light/Heavy shields: You could make FormLists, then check 'If YourHeavyShieldsFLST.HasForm(akBaseItem)'.
User avatar
Jessie Rae Brouillette
 
Posts: 3469
Joined: Mon Dec 11, 2006 9:50 am

Post » Wed Jun 20, 2012 12:42 pm

No prob :smile: I fixed up a few goofs from me editing it so it'll compile now and should do the same things faster. Here's a version with the conditions hinged on the MagicDisallowEnchanting keyword. Should be faster still... Light/Heavy shields: You could make FormLists, then check 'If YourHeavyShieldsFLST.HasForm(akBaseItem)'.
.
Thank you. I modified the code to bypass the !StuffYouAreSortingFLST condition because the initial container is the universal catchall for the system; if it doesn't sort, then there it should stay as it is labelled the "Goods Inward" container.
.
Once I get a handle on what all the base item names are (i.e. valid akBaseItem categories) I'll probably farm out the appropriate parts of the algorithm to "Special Weapons", "Special Armor", etc so that major categories also have their own catchall containers.
.
While I was at it, I checked to see if those keywords were interoperable (between plug-ins). I set up "Bernarde's Bow" (of paralysis) in a special weapon mod with its own "Enchanted" keyword. Then in my Questfall Tower mod, I set up the "Enchanted" keyword again (but in this separate mod it is on a separate form). This may sound crazy to some people but if keywords are accessed exclusively by their form ID and not by the text of the keyword, then they strike me as redundant because the FormList serves precisely the same objective with the exception of being easier to set up and faster to check. So, I went on to set up the sorter with the option to sort the bow as enchanted if it had the enchanted keyword. It failed to sort Bernarde's Bow correctly because the engine treats the keyword system the same as the FormList system; by referring exclusively to form IDs. This means that the only advantage keywords have for this purpose is that they tend to be inherited if they are already set up in a master that everyone uses. Other than that, FormLists would appear to be a better choice.
.
...Unless, of course, there is a special way to invoke keywords that tells Papyrus that you're looking for items that have a given keyword irrespective of the keyword form. E.g. I would have set it up so that:
.
If akBaseItem.HasKeyword(*Enchanted); the asterisk implying having any keyword form with the following "Keyword ID".
.
Alas! It doesn't compile like that, although I wonder if there might be another way.
.
It is also possible that something along the line of those base item categories might do the trick, especially if they happened to be deployed as a hierarchy. However, the wiki has nothing on this and I don't know where else to look for a complete set of valid names for base items. I.e. which can be used in the way http://www.gamesas.com/user/660219-tunaisafish/ suggested:
.
if (akBaseItem As Weapon) ; i.e.

ElseIf (akBaseItem As WhatElse) ; ???

EndIf
.
I'll still be using the FormLists to filter for enchanted gear (which will miss all of the items that the player enchants) - unless there is an undocumented function, or even a bug, which singles out the enchanted gear from the unenchanted gear. Speaking of bugs, in answer to http://www.gamesas.com/user/660219-tunaisafish/, the "Keyword Bug" refers to a bug in my code which fails to account for the limitation of light/heavy armor keywords to armor items which are not shields. Apparently there is a reason for this, so it's in Bethesda's specs, so it's not their bug. I may wind up dumping all the shields in light/heavy FormLists as well - and it's real nice to be decided on which way I'll jump if that set of Base Item names is insufficient to the entire task.
User avatar
Da Missz
 
Posts: 3438
Joined: Fri Mar 30, 2007 4:42 pm

Post » Wed Jun 20, 2012 10:14 pm

Thank you - any idea where I might find a list of valid akBaseItem identifiers? The Wiki still doesn't have these sort of details.

yw.
You can test the cast of akBaseItem to any of http://www.creationkit.com/Category:Script_Objects type of Objects. Obviously not all are inventory items though.


Edit:

The names of those Script Objects closely relate to where you'll find them in the CK, so you could filter off things like Potion, Book and SoulGem etc.

Yeah it's a shame that the light/Heavy keywords are not on shields too. Those keywords are used for the Armor Perks, where you get a bonus for matching gloves/boots/body/head armor. I'm not sure they are used elsewhere. If Beth didn't need them then they didn't bother adding them.

I think all the shields have the WeapMaterial* keywords though, so that could save you creating a formlist.

For mod compatibility, the keyword system is better as the keyword FormID's are stored on the items. So a new correctly keyworded item should work fine with your sorter.
Well, it's better for the Steam crowd that has never heard of making patches to merge Formlists.

The only way you'd be able to detect keywords added by other mods is to make your mod dependent on the other mod as a Master.
SKSE may give us more options in the future though.
User avatar
glot
 
Posts: 3297
Joined: Mon Jul 17, 2006 1:41 pm

Post » Wed Jun 20, 2012 10:40 pm

yw.
You can test the cast of akBaseItem to any of http://www.creationkit.com/Category:Script_Objects type of Objects. Obviously not all are inventory items though.


Edit:

The names of those Script Objects closely relate to where you'll find them in the CK, so you could filter off things like Potion, Book and SoulGem etc.

Yeah it's a shame that the light/Heavy keywords are not on shields too. Those keywords are used for the Armor Perks, where you get a bonus for matching gloves/boots/body/head armor. I'm not sure they are used elsewhere. If Beth didn't need them then they didn't bother adding them.

I think all the shields have the WeapMaterial* keywords though, so that could save you creating a formlist.

For mod compatibility, the keyword system is better as the keyword FormID's are stored on the items. So a new correctly keyworded item should work fine with your sorter.
Well, it's better for the Steam crowd that has never heard of making patches to merge Formlists.

The only way you'd be able to detect keywords added by other mods is to make your mod dependent on the other mod as a Master.
SKSE may give us more options in the future though.
.
Thank you. I'll start by implementing that base-object sort into separate major category catch-all containers - and give them their own keyword sorts. Then I'll fill in the gaps with FormLists.
User avatar
Love iz not
 
Posts: 3377
Joined: Sat Aug 25, 2007 8:55 pm

Post » Wed Jun 20, 2012 9:22 am

... dynamically add a keyword.

How? Been looking for a way to attach keywords at runtime, haven't found one.
User avatar
Gill Mackin
 
Posts: 3384
Joined: Sat Dec 16, 2006 9:58 pm

Post » Wed Jun 20, 2012 1:15 pm

damn! and I thinking that keywords for smithing menu was "advanced" ahahahha

well, definitely Idk how to deploy these codes and scripts, its necessary another specific program? or only CK is already enough?
any tutorial that you guys recommend to work with papyrus?

thx u all for ur replies
User avatar
nath
 
Posts: 3463
Joined: Mon Jan 22, 2007 5:34 am

Post » Wed Jun 20, 2012 7:06 am

I found http://www.creationkit.com/Notepad%2B%2B_Setup very useful - and the wiki answers some of the basic questions. Once you are familiar with the not-so-integrated aspects of the development environment have another look at the code posted by http://www.gamesas.com/user/408976-justinother/. If I ever finish the container placements, I hope to get stuck into the rest of the code which I plan to divide up between key category "catch-all" containers - which I'll post back here when I'm done.
User avatar
Roisan Sweeney
 
Posts: 3462
Joined: Sun Aug 13, 2006 8:28 pm

Post » Wed Jun 20, 2012 3:38 pm

Just a no-brainer question..

GetItemCount can use keywords.

RemoveItem, can this use keywords as well? Can it be in a formlist? Lol
User avatar
I love YOu
 
Posts: 3505
Joined: Wed Aug 09, 2006 12:05 pm


Return to V - Skyrim