Difference between revisions of "OnItemRemoved - ObjectReference"
Jump to navigation
Jump to search
imported>DavidJCobb m (→Notes: Added the trick to cancel events.) |
imported>DavidJCobb m (→Notes: moved the thing) |
||
(One intermediate revision by the same user not shown) | |||
Line 35: | Line 35: | ||
**If something calls [[RemoveAllItems - ObjectReference|RemoveAllItems]] and you don't use an inventory event filter, then for every type of item removed from the object's inventory, one call to your OnItemRemoved event handler will be queued. If the player is holding a wide variety of items, then Skyrim will queue up more calls than it can even keep track of, causing an instant stack dump. This may negatively impact your own script as well as other scripts written by other people. | **If something calls [[RemoveAllItems - ObjectReference|RemoveAllItems]] and you don't use an inventory event filter, then for every type of item removed from the object's inventory, one call to your OnItemRemoved event handler will be queued. If the player is holding a wide variety of items, then Skyrim will queue up more calls than it can even keep track of, causing an instant stack dump. This may negatively impact your own script as well as other scripts written by other people. | ||
***The "Diplomatic Immunity" quest is a good testcase for this; getting thrown in jail may also work. | ***The "Diplomatic Immunity" quest is a good testcase for this; getting thrown in jail may also work. | ||
***You can detect RemoveAllItems calls by making sure that the player always has a weightless non-playable item on their person, and using an inventory event filter to listen for that item's removal. Under that circumstance, only a removal of all items will ever cause your OnItemRemoved handler to fire. | |||
*If the item is consumed by any means (crafting, charging, poisoning, eat/drink) the dest parameter is None and most likely, but not always, the reference is None too. | *If the item is consumed by any means (crafting, charging, poisoning, eat/drink) the dest parameter is None and most likely, but not always, the reference is None too. | ||
* If player uses a poison to apply it to a weapon the event is fired twice: before and after the confirmation dialogue. If canceled in the confirmation dialogue then is not fired twice. | * If player uses a poison to apply it to a weapon the event is fired twice: before and after the confirmation dialogue. If canceled in the confirmation dialogue then is not fired twice. | ||
*If you need to temporarily stop OnItemAdded and OnItemRemoved calls from being queued, you can use AddInventoryEventFilter with an empty FormList as an argument. To resume listening for item additions and removals, you can call [[RemoveAllInventoryEventFilters - ObjectReference|RemoveAllInventoryEventFilters]]. | *If you need to temporarily stop OnItemAdded and OnItemRemoved calls from being queued, you can use AddInventoryEventFilter with an empty FormList as an argument. To resume listening for item additions and removals, you can call [[RemoveAllInventoryEventFilters - ObjectReference|RemoveAllInventoryEventFilters]]. | ||
**This trick stops OnItemRemoved calls from ''being queued.'' It doesn't prevent the execution of function calls that have already been queued. To wit, using this trick from inside of OnItemRemoved won't stop Skyrim from dumping stacks when something calls RemoveAllItems(), because the first OnItemRemoved call only executes after the other hundred or so have been queued. You'd have to stop listening to inventory events before the item removals ever take place. | **This trick stops OnItemRemoved calls from ''being queued.'' It doesn't prevent the execution of function calls that have already been queued. To wit, using this trick from inside of OnItemRemoved won't stop Skyrim from dumping stacks when something calls RemoveAllItems(), because the first OnItemRemoved call only executes after the other hundred or so have been queued. You'd have to stop listening to inventory events before the item removals ever take place. | ||
*Remember that you can point multiple reference aliases at the player. Each can have their own inventory event filters and inventory event handlers, so you can filter OnItemAdded and OnItemRemoved differently. | |||
== See Also == | == See Also == |
Latest revision as of 15:48, 14 March 2015
Member of: ObjectReference Script
Event received when an item is removed from this object's container.
Syntax[edit | edit source]
Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
Parameters[edit | edit source]
- akBaseItem: The base object for the item that was removed from this container.
- aiItemCount: The number of items removed from this container.
- akItemReference: The specific reference removed from the container, if any. Will be None if a non-persistant object is moved to a different container; a persistant or not item used in crafting, (most likely) when consumed. If a non-persistant item is dropped from inventory into the world the generated reference is received.
- akDestContainer: The container that the object(s) went to. If None, then the object was dropped into the world, used in crafting or consumed.
Examples[edit | edit source]
Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
if !akDestContainer
Debug.Trace("I dropped " + aiItemCount + "x " + akBaseItem + " into the world")
elseif akDestContainer == Game.GetPlayer()
Debug.Trace("I gave the player " + aiItemCount + "x " + akBaseItem)
else
Debug.Trace("I gave " + aiItemCount + "x " + akBaseItem + " to another container")
endIf
endEvent
Notes[edit | edit source]
- If you only care about certain kinds of objects, you should also use AddInventoryEventFilter to filter out any events for things you aren't interested in.
- Refer to the notes for OnItemAdded to get an idea of how important this is.
- If something calls RemoveAllItems and you don't use an inventory event filter, then for every type of item removed from the object's inventory, one call to your OnItemRemoved event handler will be queued. If the player is holding a wide variety of items, then Skyrim will queue up more calls than it can even keep track of, causing an instant stack dump. This may negatively impact your own script as well as other scripts written by other people.
- The "Diplomatic Immunity" quest is a good testcase for this; getting thrown in jail may also work.
- You can detect RemoveAllItems calls by making sure that the player always has a weightless non-playable item on their person, and using an inventory event filter to listen for that item's removal. Under that circumstance, only a removal of all items will ever cause your OnItemRemoved handler to fire.
- If the item is consumed by any means (crafting, charging, poisoning, eat/drink) the dest parameter is None and most likely, but not always, the reference is None too.
- If player uses a poison to apply it to a weapon the event is fired twice: before and after the confirmation dialogue. If canceled in the confirmation dialogue then is not fired twice.
- If you need to temporarily stop OnItemAdded and OnItemRemoved calls from being queued, you can use AddInventoryEventFilter with an empty FormList as an argument. To resume listening for item additions and removals, you can call RemoveAllInventoryEventFilters.
- This trick stops OnItemRemoved calls from being queued. It doesn't prevent the execution of function calls that have already been queued. To wit, using this trick from inside of OnItemRemoved won't stop Skyrim from dumping stacks when something calls RemoveAllItems(), because the first OnItemRemoved call only executes after the other hundred or so have been queued. You'd have to stop listening to inventory events before the item removals ever take place.
- Remember that you can point multiple reference aliases at the player. Each can have their own inventory event filters and inventory event handlers, so you can filter OnItemAdded and OnItemRemoved differently.