Jump to content

A puzzle for today


Recommended Posts

I hope this actually makes sense :smile:.

 

I have a mod that is complete with the exception of one problem I can't seem to iron out.

 

Among the "things" added by my mod are what I call "Enchanted Containers". There are multiple types, each type can carry an unlimited quantity of very specific types of items. For example:

 

The Enchanted Ingredient Pouch weighs 5 pounds regardless of the quantity of Alchemy ingredients are actually in it. The script looks at the keywords associated with each item the player attempts to add, items that have the keyword VendorItemIngredient are allowed, all other items are put back into the player's inventory.

 

The Enchanted Gem Bag weighs 1 pound regardless of the quantity of gems and jewelry it contains. Acceptable items are determined by keywords associated with items the player attempts to add. In the case of this container, there are seven acceptable keywords, for example, VendorItemJewelry. However in the case of this container, the Left handed rings are spit back out into the player's inventory.

 

Okay, now for the issue.

I have three mods, all in esp files (in relative load order).

- A mod that adds Left-handed rings

- A mod that adds a number of alchemy ingredients

- My enchanted containers mod

 

In the case of the mod with alchemy ingredients, all new items have the expected keyword associated with them and they all go right into the container as expected.

 

Since there is only one keyword, the script of short and simple.

 

Scriptname aaCh18_FilterContainerItems extends ObjectReference

Keyword Property VendorTypeKeyword Auto

Actor Property PlayerREF Auto

 

Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)

 

If akSourceContainer==PlayerREF

If !akBaseItem.HasKeyword(VendorTypeKeyword)

RemoveItem(akBaseItem, aiItemCount, True, akSourceContainer)

Debug.MessageBox("Invalid Item")

EndIf

EndIf

EndEvent

 

In the case of the mod with the Left-handed rings, all new items have the expected keyword(s) associated with them and they do NOT go into the container as expected.

 

For this container the keywords are maintained in a FormList:

VendorItemSoulGem

VendorItemJewelry

VendorItemGem

ArmorJewelry

ClothingCirclet

ClothingRing

ClothingNecklace

The script is more complex for this container since it has to check a number of keywords:

Scriptname aaCh18_FilterOnKeywordFormlist extends ObjectReference

FormList Property ElligibleKeywordsFLST Auto

Actor Property PlayerREF Auto

Event OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)

If akSourceContainer == PlayerREF

Int iCount = ElligibleKeywordsFLST.GetSize()

Bool bAcceptable = False

While iCount && !bAcceptable

 

iCount -= 1

Keyword kReference = ElligibleKeywordsFLST.GetAt(iCount) as Keyword

If akBaseItem.HasKeyWord(kReference)

bAcceptable = true

Endif

 

EndWhile

If bAcceptable == False

RemoveItem(akBaseItem, aiItemCount, True, akSourceContainer)

Endif

EndIf

EndEvent

This script is supposed to set bAcceptable to False then loop through the keywords, as soon as one matches bAcceptable gets changed to True and execution jumps out of the loop.

 

I want my mod to work with others as well as possible so I'd like to resolve this issue. I'm sure it will happen with others if I don't.

 

Thanks in advance for any help or suggestions,

Chemist18

 

PS. I've coded in a number of different languages, Papyrus is still quite new to me.

Edited by Chemist18
Link to comment
Share on other sites

Your code should work. I implemented something similar previously.

 

A couple suggestions:

  • It may be possible to accomplish this with less code by using the AddInventoryEventFilter method with a FormList argument. That way only qualifying objects raise events to your code.
  • Otherwise, since it is likely that you will have more keywords in your filter FormList than in most objects, I would flip the code so that it tests each keyword of the item against your filter list. This would result in fewer iterations and perform slightly better.
  • It is known that many items in generic Skyrim have missing and bad keyword assignments (e.g., the ingredient Garlic has the keyword VendorItemFood assigned to it and not VendorItemIngredient). Your code will work as designed, but the data it is operating on will cause it to behave differently than expected. You may have better accuracy testing by form type than by keyword. For example: akBaseItem.GetType() == 30 will always evaluate to True for any Ingredient, including Garlic.

All the best.

Link to comment
Share on other sites

Thanks :).

 

I've checked all the items that are not working properly and they do have the proper keywords.

 

I particularly like the akBaseItem.GetType() statement though I think the jewelry pieces share a form type with all armor.

 

Your suggestion of looping through an item's keywords makes good sense. I think as long as my formlist stays at a length of seven forms It'll be okay as-is, otherwise I will definitely switch the strategy.

Link to comment
Share on other sites

  • 2 weeks later...

The AddInventoryEventFilter would only work if he was using it to test specifically for items that didn't belong in the container, but that would require a lot more code. Better to test for items that belong.

 

Also, checking against inventory type would be good for all those items that don't belong simply due to the wrong type, such as weapons.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...