Player Remove Item SM not firing when drinking potions.

Post » Mon Jun 18, 2012 1:58 pm

Hello,

I am working on a mod that needs to react when the player drinks a potion.
In order to do this, the "Player Remove Item" Story Manager event looked very attractive. It is supposed to start an attached quest whenever the player removes an item from her inventory.

My problem is this: When dropping items from the inventory it works fine. But when clicking a potion to drink it, nothing happens.

The Creation Kit documentation for "Player Remove Item" mentions several "Remove type", among which appears "REMOVE_TYPE_CONSUMED". This leads me to believe that consuming a potion should work. So I believe that it's a bug in Skyrim, or an unimplemented feature.

Is there any other way you can think of to have some script executing when drinking a potion? Modifying potions in the CK or their magic effects would certainly work, but then I guess it makes it incompatible with other modules that do the same...
User avatar
Kelvin
 
Posts: 3405
Joined: Sat Nov 17, 2007 10:22 am

Post » Mon Jun 18, 2012 10:40 am

I found a workaround that should be acceptable for what I want:

- attach a script to an alias to the player in the quest.
The script gets OnItemRemoved events.

- use SM event "Player Remove Item" in addition, in another script.

What happens then is this:
- When the player drops an item, both events fire.
- When the player consumes an item, only the OnItemRemoved event fires.

So with a bit of variables and logic it's possible to know when the player consumes something from the inventory.
User avatar
Lil'.KiiDD
 
Posts: 3566
Joined: Mon Nov 26, 2007 11:41 am

Post » Mon Jun 18, 2012 9:24 pm

Excellent!

However, in my tests however, OnItemRemoved doesn't execute on a player alias.
All debug notifications are displayed except for OnItemAdded, OnItemRemoved and OnLocationChanged.
Am I scripting this player alias incorrectly?
Scriptname kuEASPlayerS extends ReferenceAlias{kuertee eat and sleep player script}Float versionBool startedBool Property resetNow AutoFloat lastTimeNowEvent OnInit ()	Debug.Notification ("!kuEASPlayerS.OnInit")	RegisterForUpdate (1)EndEventFunction initGameLoaded ()	Debug.Notification ("!kuEASPlayerS.initGameLoaded")	version = 0.5	If !started		started = False		initVars ()	EndIf	RegisterForUpdate (1)	;AddInventoryEventFilter (kuFoodList)	;RemoveInventoryEventFilter (kuFoodList)EndFunctionEvent OnUpdate ()	Debug.Notification ("!kuEASPlayerS.OnUpdate")	Float timeNow = Utility.GetCurrentRealTime ()	If Math.abs (timeNow - lastTimeNow) > 60		initGameLoaded ()	ElseIf resetNow		initVars ()	EndIf	lastTimeNow = timeNow	tick ()EndEventFunction initVars ()	resetNow = FalseEndFunctionFormList Property kuFoodList AutoFunction tick ()EndFunctionEvent OnLocationChange(Location akOldLoc, Location akNewLoc)	Debug.Notification ("!kuEASPlayerS.OnLocationChange")EndEventEvent OnItemAdded (Form baseRef, Int count, ObjectReference itemRef, ObjectReference fromRef)	Debug.Notification ("!kuEASPlayerS.OnItemAdded")	;Debug.Notification ("!kuEASPlayerS.OnItemAdded " + baseRef + ", " + count + ", " + itemRef + ", " + fromRef)EndEventEvent OnItemRemoved (Form baseRef, Int count, ObjectReference itemRef, ObjectReference toRef)	Debug.Notification ("!kuEASPlayerS.OnItemRemoved")	;Debug.Notification ("!kuEASPlayerS.OnItemRemoved " + baseRef + ", " + count + ", " + itemRef + ", " + toRef)EndEvent
User avatar
April D. F
 
Posts: 3346
Joined: Wed Mar 21, 2007 8:41 pm

Post » Mon Jun 18, 2012 6:14 pm

any progress? wuold like to see how this worked out
User avatar
Kate Murrell
 
Posts: 3537
Joined: Mon Oct 16, 2006 4:02 am

Post » Mon Jun 18, 2012 9:35 pm

I can confirm that http://www.creationkit.com/OnItemRemoved_-_ObjectReference does work for a http://www.creationkit.com/ReferenceAlias_Script script pointed at the player.

I've had it working using this script:
Spoiler
ScriptName ExchangeWorldAndInventoryVersions extends ReferenceAliasFormList Property WorldList autoFormList Property InventoryList autoint Function GetIndex(FormList List, Form Member) global	If (!List.HasForm(Member))		Return -1	EndIf	int Index = 0	While (List.GetAt(Index) != Member)		Index += 1	EndWhile	Return IndexEndFunctionauto State Waiting	Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)		If (WorldList.HasForm(akBaseItem))			Actor Player = GetReference() as Actor			Player.RemoveItem(akBaseItem, aiItemCount, true)			Player.AddItem(InventoryList.GetAt(GetIndex(WorldList, akBaseItem)), aiItemCount, true)		EndIf	EndEvent	Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)		GoToState("Busy")		Utility.Wait(0.1);		GetOwningQuest().OnUpdate()		If (InventoryList.HasForm(akBaseItem))			int i = 0			While (i < aiItemCount)				Debug.OpenUserLog("PlaceAtMe")				Debug.TraceUser("PlaceAtMe", "Drop")				Debug.TraceUser("PlaceAtMe", akItemReference.PlaceAtMe(WorldList.GetAt(GetIndex(InventoryList, akBaseItem))).GetPositionZ())				i += 1			EndWhile			akItemReference.Delete()		EndIf		GoToState("Waiting")	EndEventEndStateState Busy	; Go away, I'm busy!EndState

I'm not sure what the problem might be with kuertee's script. Can you definitely confirm that the player is correctly specified as the reference at which your alias is pointing?

Cipscis
User avatar
Ash
 
Posts: 3392
Joined: Tue Jun 13, 2006 8:59 am

Post » Mon Jun 18, 2012 11:58 pm

Hey guys, the quest that script was attached to was corrupted from multiple tests. (i.e.scripts/data stays in the game even with the ESP deactivated).

So, I created a new quest and got something working.
However, I couldn't get the SM along with the OnItemRemoved working.
But I didn't find something WAAAY simpler than using the Story Manager with the OnItemRemoved () event.

In my current test mod for Eat and sleep, I check if the in-game reference (3rd parameter for OnItemRemoved () Event) is empty or not.
If it's empty, then that means the Potion was ingested.
However, I believe that it will also be empty if the Potion was put in a different container.
I thik that if the 4th parameter is also empty, then it's very likely the user consumed the potion.
I've not tested this container issue yet. (I'm at work and will test later.)
But I can guarantee that the in-game reference is empty when the Potion is ingested.

Also, another thing to keep in mind. This doesn't affect potion ingeting at all, but it was something I noticed.
OnItemRemoved () does not execute when you remove items from the Player with the function RemoveItem ().
Of note, however, is that OnItemAdded () DOES when items are added to the player with AddItem ().
In my Auto-eat function of my Eat and Sleep mod, I rely on the event OnItemRemoved ().
Because this doesn't execute with RemoveItem (), I had to force the eating script whenever I remove food from the player.
User avatar
Umpyre Records
 
Posts: 3436
Joined: Tue Nov 13, 2007 4:19 pm

Post » Mon Jun 18, 2012 4:48 pm

I think http://www.creationkit.com/OnItemRemoved_-_ObjectReference only fires if the item actually goes somewhere (or, evidently, is consumed), looking at the parameters passed into the event.

The best solution might just be to create a http://www.creationkit.com/RemoveItem_-_ObjectReference proxy function:
Function RemoveItemFireEvent(ObjectReference akContainer, Form akItemToRemove, int aiCount = 1, bool abSilent = false)	akContainer.RemoveItem(akItemToRemove, aiCount, abSilent)	akContainer.OnItemRemoved(akItemToRemove, aiCount, None, None)EndFunction

Cipscis
User avatar
He got the
 
Posts: 3399
Joined: Sat Nov 17, 2007 12:19 pm

Post » Mon Jun 18, 2012 10:54 am

Thanks guys. I've implemented your last idea Kuertee and it working, although i have not tested it in all situations yet.
here the script it tested with. only registered the debug message when i consumed it vs. dropping it:

Scriptname invEventScript extends ReferenceAliasformlist property myFormList autoEvent OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)  AddInventoryEventFilter(myFormList)   if akDestContainer == none && akItemReference == none    Debug.MessageBox("I consumed it!")  endif endEvent
User avatar
Krystina Proietti
 
Posts: 3388
Joined: Sat Dec 23, 2006 9:02 pm

Post » Mon Jun 18, 2012 6:33 pm

...
...akContainer.OnItemRemoved(akItemToRemove, aiCount, None, None)...
Cipscis
But of course! It never occured to me that events could be triggered manually in Papyrus! Though I've been programming OOO for 10 years! Hahaha! Damn knowledge block when working with the CK!

...here the script it tested with. only registered the debug message when i consumed it vs. dropping it:...
Cool! That's what I have as well.
User avatar
Steven Hardman
 
Posts: 3323
Joined: Sun Jun 10, 2007 5:12 pm


Return to V - Skyrim